예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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'
예제 #7
0
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
예제 #8
0
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