def cgps_traces(files, tensor_info, data_prop): """Write json dictionary with specified properties for cGPS data :param files: list of waveform files in sac format :param tensor_info: dictionary with moment tensor information :param data_prop: dictionary with waveform properties :type files: list :type tensor_info: dict :type data_prop: dict .. warning:: Make sure the filters of cGPS data agree with the values in sampling_filter.json! """ if len(files) == 0: return event_lat = tensor_info['lat'] event_lon = tensor_info['lon'] depth = tensor_info['depth'] origin_time = tensor_info['date_origin'] headers = [SACTrace.read(file) for file in files] dt_cgps = headers[0].delta dt_cgps = round(dt_cgps, 1) values = [mng._distazbaz(header.stla, header.stlo, event_lat, event_lon)\ for header in headers] distances = [value[0] for value in values] zipped = zip(distances, headers) arrivals = [np.sqrt(dist**2 + depth**2) / 5 + header.b for dist, header in zipped] duration = duration_strong_motion(distances, arrivals, tensor_info, dt_cgps) filter0 = data_prop['strong_filter'] n0, n1 = data_prop['wavelet_scales'] wavelet_weight = wavelets_strong_motion( duration, filter0, dt_cgps, n0, n1, cgps=True) info_traces = [] vertical = ['LXZ', 'LHZ', 'LYZ'] headers = [SACTrace.read(file) for file in files] streams = [read(file) for file in files] channels = [header.kcmpnm for header in headers] weights = [1.2 if not channel in vertical else 0.6 for file, channel in\ zip(files, channels)] for file, header, stream, weight in zip(files, headers, streams, weights): start = origin_time - stream[0].stats.starttime distance, azimuth, back_azimuth = mng._distazbaz( header.stla, header.stlo, event_lat, event_lon) info = _dict_trace( file, header.kstnm, header.kcmpnm, azimuth, distance / 111.11, dt_cgps, duration, int(start // dt_cgps), weight, wavelet_weight, [], location=[header.stla, header.stlo]) info_traces.append(info) with open('cgps_waves.json','w') as f: json.dump( info_traces, f, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) return info_traces
def tele_body_traces(files, tensor_info, data_prop): """Write json dictionary with specified properties for teleseismic data :param files: list of waveform files in sac format :param tensor_info: dictionary with moment tensor information :param data_prop: dictionary with waveform properties :type files: list :type tensor_info: dict :type data_prop: dict .. warning:: Make sure the filters of teleseismic data agree with the values in sampling_filter.json! """ if len(files) == 0: return origin_time = tensor_info['date_origin'] headers = [SACTrace.read(file) for file in files] streams = [read(file) for file in files] dt = headers[0].delta dt = round(dt, 1) n0, n1 = data_prop['wavelet_scales'] filter0 = data_prop['tele_filter'] duration = duration_tele_waves(tensor_info, dt) wavelet_weight0, wavelet_weight1 = wavelets_body_waves( duration, filter0, dt, n0, n1) info_traces = [] event_lat = tensor_info['lat'] event_lon = tensor_info['lon'] depth = tensor_info['depth'] model = TauPyModel(model="ak135f_no_mud") for file, header, stream in zip(files, headers, streams): __failsafe(filter0, header) distance, azimuth, back_azimuth = mng._distazbaz( header.stla, header.stlo, event_lat, event_lon) arrivals = mng.theoretic_arrivals(model, distance / 111.11, depth) if header.kcmpnm == 'BHZ': arrival = arrivals['p_arrival'][0].time weight = 1.0 wavelet_weight = wavelet_weight0 elif header.kcmpnm == 'SH': arrival = arrivals['s_arrival'][0].time weight = 0.5 wavelet_weight = wavelet_weight1 starttime = stream[0].stats.starttime begin = starttime - origin_time n_start_obs = int((arrival - begin) / dt + 0.5) info = _dict_trace( file, header.kstnm, header.kcmpnm, azimuth, distance / 111.11, dt, duration, n_start_obs, weight, wavelet_weight, [], ##!!!!!!!!!! location=[header.stla, header.stlo], derivative=False) info_traces.append(info) with open('tele_waves.json','w') as f: json.dump( info_traces, f, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) return info_traces
def tele_surf_traces(files, tensor_info, data_prop): """Write json dictionary with specified properties for surface wave data :param files: list of waveform files in sac format :param tensor_info: dictionary with moment tensor information :param data_prop: dictionary with waveform properties :type files: list :type tensor_info: dict :type data_prop: dict """ if len(files) == 0: return n0, n1 = data_prop['wavelet_scales'] wavelet_weight = wavelets_surf_tele(n0, n1) info_traces = [] headers = [SACTrace.read(file) for file in files] event_lat = tensor_info['lat'] event_lon = tensor_info['lon'] for file, header in zip(files, headers): npts = header.npts n_start = int(-header.b / 4.0) if npts < n_start: continue if npts + n_start < 0: continue length = 900 if 900 >= (npts - n_start): length = npts - n_start if n_start > 0 else npts distance, azimuth, back_azimuth = mng._distazbaz( header.stla, header.stlo, event_lat, event_lon) info = _dict_trace(file, header.kstnm, header.kcmpnm, azimuth, distance / 111.11, 4.0, length, n_start, 1.0, wavelet_weight, [], location=[header.stla, header.stlo]) info_traces.append(info) with open('surf_waves.json', 'w') as f: json.dump(info_traces, f, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) return info_traces
def tele_body_traces(files, tensor_info, data_prop): """Write json dictionary with specified properties for teleseismic data :param files: list of waveform files in sac format :param tensor_info: dictionary with moment tensor information :param data_prop: dictionary with waveform properties :type files: list :type tensor_info: dict :type data_prop: dict .. warning:: Make sure the filters of teleseismic data agree with the values in sampling_filter.json! """ if len(files) == 0: return headers = [SACTrace.read(file) for file in files] dt = headers[0].delta dt = round(dt, 1) n0, n1 = data_prop['wavelet_scales'] print('Wavelet: ', n0, n1) filter0 = data_prop['tele_filter'] duration = duration_tele_waves(tensor_info, dt) wavelet_weight0, wavelet_weight1 = wavelets_body_waves( duration, filter0, dt, n0, n1) info_traces = [] event_lat = tensor_info['lat'] event_lon = tensor_info['lon'] for file, header in zip(files, headers): if header.kcmpnm == 'BHZ': n_start_obs = int((header.t1 - header.b) / dt + 0.5) weight = 1.0 wavelet_weight = wavelet_weight0 elif header.kcmpnm == 'SH': n_start_obs = int((header.t5 - header.b) / dt + 0.5) weight = 0.5 wavelet_weight = wavelet_weight1 __failsafe(filter0, header) distance, azimuth, back_azimuth = mng._distazbaz( header.stla, header.stlo, event_lat, event_lon) info = _dict_trace(file, header.kstnm, header.kcmpnm, azimuth, distance / 111.11, dt, duration, n_start_obs, weight, wavelet_weight, [], location=[header.stla, header.stlo]) info_traces.append(info) with open('tele_waves.json', 'w') as f: json.dump(info_traces, f, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) return info_traces
def strong_motion_traces(files, tensor_info, data_prop): """Write json dictionary with specified properties for strong motion data :param files: list of waveform files in sac format :param tensor_info: dictionary with moment tensor information :param data_prop: dictionary with waveform properties :type files: list :type tensor_info: dict :type data_prop: dict .. warning:: Make sure the filters of strong motion data agree with the values in sampling_filter.json! """ if len(files) == 0: return event_lat = tensor_info['lat'] event_lon = tensor_info['lon'] headers = [SACTrace.read(file) for file in files] dt_strong = headers[0].delta dt_strong = round(dt_strong, 1) starts = [header.o if header.o else 0 for header in headers] #20 values = [mng._distazbaz(header.stla, header.stlo, event_lat, event_lon)\ for header in headers] distances = [value[0] for value in values] arrivals = [header.t1 if header.t1 else 0 for header in headers] filter0 = data_prop['strong_filter'] seismic_moment = tensor_info['moment_mag'] # outliers = strong_outliers(files, tensor_info) if seismic_moment < 2 * 10**26: outliers = strong_outliers2(files, distances, tensor_info) else: outliers = strong_outliers(files, tensor_info) duration = duration_strong_motion(distances, arrivals, tensor_info, dt_strong) n0, n1 = data_prop['wavelet_scales'] wavelet_weight = wavelets_strong_motion(duration, filter0, dt_strong, n0, n1) black_list = {'PB02': ['HNE', 'HNN', 'HLE', 'HLN'], 'PX02': ['HNE', 'HLE']} info_traces = [] outlier_traces = [] headers = [SACTrace.read(file) for file in files] streams = [read(file) for file in files] weights = [1.0 for st, file in zip(streams, files)] weights = [0 if header.kstnm in black_list\ and header.kcmpnm in black_list[header.kstnm] else weight\ for weight, header in zip(weights, headers)] # weights = [0 if file in outliers else weight\ # for file, weight in zip(files, weights)] for file, header, start, weight, stream in zip(files, headers, starts, weights, streams): # __failsafe(filter0, header) distance, azimuth, back_azimuth = mng._distazbaz( header.stla, header.stlo, event_lat, event_lon) info = _dict_trace(file, header.kstnm, header.kcmpnm, azimuth, distance / 111.11, dt_strong, duration, int(start / dt_strong), weight, wavelet_weight, [], location=[header.stla, header.stlo]) info_traces.append(info) with open('strong_motion_waves.json', 'w') as f: json.dump(info_traces, f, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) with open('outlier_strong_motion_waves.json', 'w') as f: json.dump(outlier_traces, f, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) return info_traces
def input_chen_tele_body(tensor_info, data_prop): """We write some text files, which are based on teleseismic body wave data, as inputs for Chen's scripts. :param tensor_info: dictionary with moment tensor information :param data_prop: dictionary with properties of waveform data :type tensor_info: dict :type data_prop: dict .. warning:: Make sure the filters of teleseismic data agree with the values in sampling_filter.json! """ if not os.path.isfile('tele_waves.json'): return traces_info = json.load(open('tele_waves.json')) date_origin = tensor_info['date_origin'] dt = traces_info[0]['dt'] dt = round(dt, 1) filtro = data_prop['tele_filter'] low_freq = filtro['low_freq'] high_freq = filtro['high_freq'] with open('filtro_tele', 'w') as outfile: outfile.write('Corners: {} {}\n'.format(low_freq, high_freq)) outfile.write('dt: {}'.format(dt)) nsta = len(traces_info) model = TauPyModel(model="ak135f_no_mud") depth = tensor_info['depth'] event_lat = tensor_info['lat'] event_lon = tensor_info['lon'] string = '{0:2d} FAR GDSN {1:>6} {1:>6}BHZ.DAT {2:5.2f} {3:6.2f} '\ '{4:5.2f} {5:6.2f} {6:6.2f} 0 0 {7} {8} {9} 1 0\n' sin_fun = lambda p: p * 3.6 / 111.12 angle_fun = lambda p:\ np.arctan2(sin_fun(p), np.sqrt(1 - sin_fun(p)**2)) * 180.0 / np.pi string_fun1 = lambda i, name, dist, az, lat, lon, p_slowness, disp_or_vel:\ string.format( i, name, dist, az, lat, lon, angle_fun(p_slowness), disp_or_vel, 1.0, 0) string_fun2 = lambda i, name, dist, az, lat, lon, s_slowness, disp_or_vel:\ string.format( i, name, dist, az, lat, lon, angle_fun(s_slowness), disp_or_vel, 4.0, 2) with open('Readlp.das', 'w') as outfile: outfile.write('30 30 30 0 0 0 0 0 0 1.1e+20\n') outfile.write('3 10 {}\n{}{}{}{}{}{}.{}\n{}\n'.format( dt, date_origin.year, date_origin.month, date_origin.day, date_origin.hour, date_origin.minute, date_origin.second, date_origin.microsecond, nsta)) i = 0 for file in traces_info: #header in headers: name = file['name'] channel = file['component'] lat, lon = file['location'] dist, az, back_azimuth = mng._distazbaz(lat, lon, event_lat, event_lon) dist = kilometers2degrees(dist) derivative = False if not 'derivative' in file\ else file['derivative'] derivative = int(derivative) arrivals = mng.theoretic_arrivals(model, dist, depth) p_slowness = arrivals['p_slowness'] s_slowness = arrivals['s_slowness'] if channel == 'BHZ': outfile.write( string_fun1(i + 1, name, dist, az, lat, lon, p_slowness, derivative)) else: outfile.write( string_fun2(i + 1, name, dist, az, lat, lon, s_slowness, derivative)) i = i + 1 with open('Wave.tele', 'w') as file1, open('Obser.tele', 'w') as file2: write_files_wavelet_observed(file1, file2, dt, data_prop, traces_info) # # instrumental response common to all body waves # string2 = '\n3\n' + '0. 0.\n' * 3 + '4\n-6.17E-03 6.17E-03\n'\ '-6.17E-03 -6.17E-03\n-39.18 49.12\n-39.18 '\ '-49.12\n3948\n' with open('instrumental_response', 'w') as outfile: outfile.write('{}\n'.format(nsta)) outfile.write(string2 * len(traces_info)) write_wavelet_freqs(dt, 'Wavelets_tele_body') with open('Weight', 'w') as outfile: for info in traces_info: sta = info['name'] channel = info['component'] weight = info['trace_weight'] outfile.write('{} {} {}\n'.format(weight, sta, channel)) return 'tele_body'
def point_sources_param(segments, tensor_info, rise_time): """We define the point sources of the fault segments, given properties of the fault segments, and hypocenter location given by the moment tensor. :param tensor_info: dictionary with hypocenter, centroid and moment tensor information. :param segments: dictionary with info about the fault segments :param rise_time: dictionary with info about the frise time function :type tensor_info: dict :type np_plane_info: dict :type rise_time: dict :returns: array with data for all point sources for all fault segments. .. rubric:: Example: >>> import json >>> tensor_info = { 'time_shift': 40.0, 'depth': 25.0, 'moment_mag': 10 ** 28, 'lat': -19.5, 'lon': -70.5, 'centroid_lat': -20, 'centroid_lon': -70 } >>> segments_data = json.load(open('segments_data.json')) >>> segments = segments_data['segments'] >>> rise_time = segments_data['rise_time'] >>> point_sources = point_sources_param(segments, tensor_info, rise_time) .. note:: If we detect a point source above ground level (negative depth), we throw error. """ event_lat = tensor_info['lat'] event_lon = tensor_info['lon'] depth = tensor_info['depth'] delta_x = segments[0]['delta_x'] delta_y = segments[0]['delta_y'] rupture_vel = segments[0]['rupture_vel'] subfaults = {'delta_x': delta_x, 'delta_y': delta_y} subfaults2 = _point_sources_def(rise_time, rupture_vel, subfaults) nx_ps = subfaults2['nx_ps'] ny_ps = subfaults2['ny_ps'] dx = subfaults2['dx'] dy = subfaults2['dy'] nx = int(nx_ps / 2.0 + 0.51) ny = int(ny_ps / 2.0 + 0.51) deg2rad = np.pi / 180.0 point_sources = [[]] * len(segments) ref_coords = [[]] * len(segments) # # first we define reference coordinates! # for i, segment in enumerate(segments): strike = segment["strike"] dip = segment['dip'] hyp_stk = segment['hyp_stk'] hyp_dip = segment['hyp_dip'] if i == 0: ref_coords[0] = [event_lat, event_lon, depth] lat0 = event_lat lon0 = event_lon x_center = hyp_stk * delta_x + nx * dx y_center = hyp_dip * delta_y + ny * dy for j, segment2 in enumerate(segments): neighbours = segment2['neighbours'] segment1 = [neighbour for neighbour in neighbours\ if neighbour['neighbour'] == i] if len(segment1) == 0: continue neighbour = segment1[0] n_stk, n_dip = neighbour['neighbour_connect_subfault'] x = n_stk * delta_x - x_center + dx * 0 y = n_dip * delta_y - y_center + dy * 0 dep_ref = y * np.sin(dip * deg2rad) + depth lat_ref, lon_ref = __lat_lon(strike, dip, x, y, lat0, lon0) ref_coords[j] = [lat_ref, lon_ref, dep_ref] else: for j, segment2 in enumerate(segments): neighbours = segment2['neighbours'] segment1 = [neighbour for neighbour in neighbours\ if neighbour['neighbour'] == i] if len(segment1) == 0: continue neighbour = segment1[0] n1_stk, n1_dip = neighbour['connect_subfault'] n2_stk, n2_dip = neighbour['neighbour_connect_subfault'] x = (n2_stk - n1_stk) * delta_x + 0 * dx y = (n2_dip - n1_dip) * delta_y + 0 * dy lat0, lon0, depth_0 = ref_coords[i] dip2 = segments[j]['dip'] dep_ref = depth_0 + y * np.sin(dip2 * deg2rad) lat_ref, lon_ref = __lat_lon(strike, dip, x, y, lat0, lon0) ref_coords[j] = [lat_ref, lon_ref, dep_ref] # # now we define the point sources for the segments # point_sources = [[]] * len(segments) for i, (segment, ref_coord) in enumerate(zip(segments, ref_coords)): strike = segment["strike"] dip = segment['dip'] n_sub_x = segment['n_sub_x'] n_sub_y = segment['n_sub_y'] hyp_stk = segment['hyp_stk'] hyp_dip = segment['hyp_dip'] matrix = np.zeros((n_sub_y, n_sub_x, ny_ps, nx_ps, 7)) # # we give location of hypocenter relative to the fault segment # x_center = hyp_stk * delta_x + nx * dx y_center = hyp_dip * delta_y + ny * dy lat0, lon0, depth0 = ref_coord for k2 in range(n_sub_y): for j2 in range(n_sub_x): for k1 in range(ny_ps): for j1 in range(nx_ps): # # distance from the point source to the hypocenter over rupture surface # x = (j2 + 1) * delta_x + (j1 + 1) * dx - x_center y = (k2 + 1) * delta_y + (k1 + 1) * dy - y_center distance = np.sqrt(x**2 + y**2) t1 = distance / rupture_vel # # depth of point source # if i > 0: neighbours = segment['neighbours'] neighbour = neighbours[0] n_stk, n_dip = neighbour['connect_subfault'] x_center2 = n_stk * delta_x y_center2 = n_dip * delta_y x = (j2 + 1) * delta_x + (j1 + 1) * dx - x_center2 y = (k2 + 1) * delta_y + (k1 + 1) * dy - y_center2 dep = y * np.sin(dip * deg2rad) + depth0 if dep < 0.1: raise Exception( 'Point source is above the ground!') lat, lon = __lat_lon(strike, dip, x, y, lat0, lon0) # # distance over earth surface # dist, az, baz = mng._distazbaz(lat, lon, event_lat, event_lon) matrix[k2, j2, k1, j1, :] =\ lat, lon, dep, distance, t1, dist, az point_sources[i] = matrix return point_sources
def strong_motion_traces(files, tensor_info, data_prop): """Write json dictionary with specified properties for strong motion data :param files: list of waveform files in sac format :param tensor_info: dictionary with moment tensor information :param data_prop: dictionary with waveform properties :type files: list :type tensor_info: dict :type data_prop: dict .. warning:: Make sure the filters of strong motion data agree with the values in sampling_filter.json! """ if len(files) == 0: return event_lat = tensor_info['lat'] event_lon = tensor_info['lon'] depth = tensor_info['depth'] origin_time = tensor_info['date_origin'] headers = [SACTrace.read(file) for file in files] dt_strong = headers[0].delta dt_strong = round(dt_strong, 1) values = [mng._distazbaz(header.stla, header.stlo, event_lat, event_lon)\ for header in headers] distances = [value[0] for value in values] zipped = zip(distances, headers) arrivals = [np.sqrt(dist**2 + depth**2) / 5 + header.b for dist, header in zipped] filter0 = data_prop['strong_filter'] seismic_moment = tensor_info['moment_mag'] # outliers = strong_outliers(files, tensor_info) if seismic_moment < 2 * 10 ** 26: outliers = strong_outliers2(files, distances, tensor_info) else: outliers = strong_outliers(files, tensor_info) duration = duration_strong_motion( distances, arrivals, tensor_info, dt_strong) n0, n1 = data_prop['wavelet_scales'] wavelet_weight = wavelets_strong_motion( duration, filter0, dt_strong, n0, n1) black_list = { 'PB02': [ 'HNE', 'HNN', 'HLE', 'HLN' ], 'PX02': [ 'HNE', 'HLE' ] } info_traces = [] outlier_traces = [] headers = [SACTrace.read(file) for file in files] streams = [read(file) for file in files] weights = [1.0 for st, file in zip(streams, files)] weights = [0 if header.kstnm in black_list\ and header.kcmpnm in black_list[header.kstnm] else weight\ for weight, header in zip(weights, headers)] zipped = zip(files, headers, weights, streams, arrivals) stat_list = ['KUSD', 'GMLD', 'CESE', 'DIDI', 'YKAV', 'FOCM', 'AKS', 'DATC', 'GOMA', 'KRBN'] for file, header, weight, stream, arrival in zipped: # if not header.kstnm in stat_list: # continue # weight = near_field_weight(tensor_info, header.stla, header.stlo) # weight = 0 if header.kstnm in black_list\ # and header.kcmpnm in black_list[header.kstnm] else weight start = origin_time - stream[0].stats.starttime distance, azimuth, back_azimuth = mng._distazbaz( header.stla, header.stlo, event_lat, event_lon) info = _dict_trace( file, header.kstnm, header.kcmpnm, azimuth, distance / 111.11, dt_strong, duration, int(start / dt_strong), weight, wavelet_weight, [], location=[header.stla, header.stlo]) info_traces.append(info) with open('strong_motion_waves.json','w') as f: json.dump( info_traces, f, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) with open('outlier_strong_motion_waves.json','w') as f: json.dump( outlier_traces, f, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) return info_traces