예제 #1
0
def arc_download_core(st_avail, event, input_dics, target_path, client_arclink,
                      client_syngine, req_cli, info_station):
    """
    downloading the waveforms, reponse files (StationXML) and metadata
    this function should be normally called by some higher-level functions
    :param st_avail:
    :param event:
    :param input_dics:
    :param target_path:
    :param client_arclink:
    :param client_syngine:
    :param req_cli:
    :param info_station:
    :return:
    """
    dummy = 'initializing'

    t11 = datetime.now()
    identifier = 0
    st_id = '%s.%s.%s.%s' % (st_avail[0], st_avail[1], st_avail[2],
                             st_avail[3])
    try:
        if st_avail[2] == '--' or st_avail[2] == '  ':
            st_avail[2] = ''

        if input_dics['cut_time_phase']:
            t_start, t_end = calculate_time_phase(event, st_avail)
        else:
            t_start = event['t1']
            t_end = event['t2']

        if input_dics['min_azi'] or input_dics['max_azi'] or \
                input_dics['min_epi'] or input_dics['max_epi']:
            dist, azi, bazi = gps2DistAzimuth(event['latitude'],
                                              event['longitude'],
                                              float(st_avail[4]),
                                              float(st_avail[5]))
            epi_dist = dist / 111.194 / 1000.
            if input_dics['min_epi']:
                if epi_dist < input_dics['min_epi']:
                    raise Exception('%s out of epi range: %s' %
                                    (st_id, epi_dist))
            if input_dics['max_epi']:
                if epi_dist > input_dics['max_epi']:
                    raise Exception('%s out of epi range: %s' %
                                    (st_id, epi_dist))
            if input_dics['min_azi']:
                if azi < input_dics['min_azi']:
                    raise Exception('%s outo f Azimuth range: %s' %
                                    (st_id, azi))
            if input_dics['max_azi']:
                if azi > input_dics['max_azi']:
                    raise Exception('%s out of Azimuth range: %s' %
                                    (st_id, azi))

        if input_dics['waveform']:
            dummy = 'waveform'
            if (not os.path.isfile(os.path.join(target_path, 'raw', st_id))) \
                    or input_dics['force_waveform']:

                if hasattr(client_arclink, 'save_waveforms'):
                    client_arclink.save_waveforms(
                        os.path.join(target_path, 'raw', st_id), st_avail[0],
                        st_avail[1], st_avail[2], st_avail[3], t_start, t_end)
                elif hasattr(client_arclink, 'saveWaveform'):
                    client_arclink.saveWaveform(
                        os.path.join(target_path, 'raw', st_id), st_avail[0],
                        st_avail[1], st_avail[2], st_avail[3], t_start, t_end)
                identifier += 10
                print('%s -- %s -- saving waveform for: %s  ---> DONE' \
                      % (info_station, req_cli, st_id))
            else:
                identifier += 1

        if input_dics['response']:
            dummy = 'response'
            if (not os.path.isfile(os.path.join(target_path, 'resp',
                                                'STXML.' + st_id))) \
                    or input_dics['force_response']:
                if (not os.path.isfile(os.path.join(target_path, 'resp',
                                                    'DATALESS.' + st_id))) \
                        or input_dics['force_response']:
                    if hasattr(client_arclink, 'save_response'):
                        client_arclink.save_response(
                            os.path.join(target_path, 'resp',
                                         'DATALESS.%s' % st_id), st_avail[0],
                            st_avail[1], st_avail[2], st_avail[3], t_start,
                            t_end)
                    if hasattr(client_arclink, 'saveResponse'):
                        client_arclink.saveResponse(
                            os.path.join(target_path, 'resp',
                                         'DATALESS.%s' % st_id), st_avail[0],
                            st_avail[1], st_avail[2], st_avail[3], t_start,
                            t_end)
                    identifier += 100
                    print("%s -- %s -- saving response for: %s  ---> DONE" \
                          % (info_station, req_cli, st_id))
                else:
                    identifier += 1
            else:
                identifier += 1

        if input_dics['syngine']:
            dummy = 'syngine_waveform'
            syn_dirpath = os.path.join(
                target_path, 'syngine_%s' % input_dics['syngine_bg_model'])
            if not os.path.isdir(syn_dirpath):
                os.makedirs(syn_dirpath)
            if (not os.path.isfile(os.path.join(syn_dirpath, st_id)))\
                    or input_dics['force_waveform']:

                if input_dics['syngine_geocentric_lat']:
                    rcvlatitude = geocen_calc(float(st_avail[4]))
                    evlatitude = geocen_calc(event['latitude'])
                else:
                    rcvlatitude = float(st_avail[4])
                    evlatitude = event['latitude']

                if not event['focal_mechanism']:
                    syngine_momenttensor = None
                else:
                    syngine_momenttensor = event['focal_mechanism']

                # XXX some other arguments
                # sourcedoublecouple=None,
                # dt=None
                # kernelwidth=None
                # sourceforce=None
                # label=None
                syn_st = client_syngine.get_waveforms(
                    model=input_dics['syngine_bg_model'],
                    receiverlatitude=rcvlatitude,
                    receiverlongitude=float(st_avail[5]),
                    networkcode=st_avail[0],
                    stationcode=st_avail[1],
                    sourcelatitude=evlatitude,
                    sourcelongitude=event['longitude'],
                    sourcedepthinmeters=float(event['depth']) * 1000.,
                    origintime=event['datetime'],
                    components=st_avail[3][-1],
                    units=input_dics['syngine_units'],
                    sourcemomenttensor=syngine_momenttensor,
                    starttime=t_start,
                    endtime=t_end)[0]

                syn_st.stats.location = st_avail[2]
                syn_st.stats.channel = st_avail[3]
                syn_st.write(os.path.join(syn_dirpath, st_id), format='mseed')

                identifier += 1000
                print('%s -- %s -- saving syngine for: %s  ---> DONE' \
                      % (info_station, req_cli, st_id))
            else:
                identifier += 1

        # if identifier in [0, 2, 10, 11, 100]:
        #     raise Exception("CODE: %s will not be registered! (666)"
        #                     % identifier)
        t22 = datetime.now()
    except Exception as error:
        t22 = datetime.now()

        if len(st_avail) != 0:
            ee = '%s -- %s -- %s -- %s\n' % (req_cli, dummy, st_id, error)
        else:
            ee = '%s: There is no available station for this event.' % req_cli
        Exception_file = open(os.path.join(target_path, 'info', 'exception'),
                              'at+')
        Exception_file.writelines(ee)
        Exception_file.close()
예제 #2
0
def plot_sta_ev_ray(input_dics, events):
    """
    plot stations, events and ray paths on a map using basemap.
    :param input_dics:
    :param events:
    :return:
    """
    plt.figure(figsize=(20., 10.))
    plt_stations = input_dics['plot_sta']
    plt_availability = input_dics['plot_availability']
    plt_events = input_dics['plot_ev']
    plt_ray_path = input_dics['plot_ray']

    if input_dics['evlatmin'] is None:
        evlatmin = -90
        evlatmax = +90
        evlonmin = -180
        evlonmax = +180
        glob_map = True
    else:
        evlatmin = input_dics['evlatmin']
        evlatmax = input_dics['evlatmax']
        evlonmin = input_dics['evlonmin']
        evlonmax = input_dics['evlonmax']
        glob_map = False

    if plt_ray_path:
        # # hammer, kav7, cyl, mbtfpq, moll
        m = Basemap(projection='moll', lon_0=input_dics['plot_lon0'])
        parallels = np.arange(-90, 90, 30.)
        m.drawparallels(parallels, fontsize=24)
        meridians = np.arange(-180., 180., 60.)
        m.drawmeridians(meridians, fontsize=24)
        width_beach = 10e5
        width_station = 50
    elif not glob_map:
        m = Basemap(projection='cyl', llcrnrlat=evlatmin, urcrnrlat=evlatmax,
                    llcrnrlon=evlonmin, urcrnrlon=evlonmax)
        parallels = np.arange(-90, 90, 5.)
        m.drawparallels(parallels, fontsize=12)
        meridians = np.arange(-180., 180., 5.)
        m.drawmeridians(meridians, fontsize=12)
        width_beach = 5
        width_station = 10
    elif glob_map:
        m = Basemap(projection='moll', lon_0=input_dics['plot_lon0'])
        parallels = np.arange(-90, 90, 30.)
        m.drawparallels(parallels, fontsize=24)
        meridians = np.arange(-180., 180., 60.)
        m.drawmeridians(meridians, fontsize=24)
        width_beach = 5e5
        width_station = 50
    else:
        sys.exit('[ERROR] can not continue, error:\n%s' % input_dics)

    raw_input_resp = raw_input_built('choose the map style:\n'
                                     '1. bluemarble (PIL should be installed)\n'
                                     '2. etopo (PIL should be installed)\n'
                                     '3. shadedrelief (PIL should be installed)\n'
                                     '4. simple\n')
    if int(raw_input_resp) == 1:
        m.bluemarble(scale=0.5)
    elif int(raw_input_resp) == 2:
        m.etopo(scale=0.5)
    elif int(raw_input_resp) == 3:
        m.shadedrelief(scale=0.1)
    else:
        m.fillcontinents()

    for ei in range(len(events)):
        if plt_events:
            if input_dics['plot_focal']:
                if not events[ei]['focal_mechanism']:
                    print('[ERROR] moment tensor does not exist!')
                    continue
                x, y = m(events[ei]['longitude'],
                         events[ei]['latitude'])
                focmecs = [float(events[ei]['focal_mechanism'][0]),
                           float(events[ei]['focal_mechanism'][1]),
                           float(events[ei]['focal_mechanism'][2]),
                           float(events[ei]['focal_mechanism'][3]),
                           float(events[ei]['focal_mechanism'][4]),
                           float(events[ei]['focal_mechanism'][5])]
                try:
                    ax = plt.gca()
                    b = Beach(focmecs, xy=(x, y), facecolor='blue',
                              width=width_beach, linewidth=1, alpha=0.85)
                    b.set_zorder(10)
                    ax.add_collection(b)
                except Exception as error:
                    print("[WARNING: %s -- %s]" % (error, focmecs))
                    continue
            else:
                x, y = m(events[ei]['longitude'],
                         events[ei]['latitude'])
                magnitude = float(events[ei]['magnitude'])
                m.scatter(x, y, color="blue", s=10*magnitude,
                          edgecolors='none', marker="o",
                          zorder=5, alpha=0.65)
        if plt_stations or plt_availability or plt_ray_path:
            target_path = locate(input_dics['datapath'],
                                 events[ei]['event_id'])
            if len(target_path) == 0:
                continue
            if len(target_path) > 1:
                print("[LOCAL] more than one path was found for the event:")
                print(target_path)
                print("[INFO] use the first one:")
                target_path = target_path[0]
                print(target_path)
            else:
                print("[LOCAL] Path:")
                target_path = target_path[0]
                print(target_path)

            update_sta_ev_file(target_path, events[ei])
            if not input_dics['plot_availability']:
                sta_ev_arr = np.loadtxt(os.path.join(target_path,
                                                     'info', 'station_event'),
                                        delimiter=',', dtype=bytes, ndmin=2).astype(np.str)
            else:
                sta_ev_arr = np.loadtxt(os.path.join(target_path,
                                                     'info',
                                                     'availability.txt'),
                                        delimiter=',', dtype=bytes, ndmin=2).astype(np.str)
            sta_ev_arr = sta_ev_arr.astype(np.object)

            if events[ei]['magnitude'] > 0:
                del_index = []
                for sti in range(len(sta_ev_arr)):

                    if not plot_filter_station(input_dics, sta_ev_arr[sti]):
                        del_index.append(sti)

                    dist, azi, bazi = gps2DistAzimuth(
                        events[ei]['latitude'],
                        events[ei]['longitude'],
                        float(sta_ev_arr[sti, 4]),
                        float(sta_ev_arr[sti, 5]))

                    epi_dist = dist/111.194/1000.
                    if input_dics['min_azi'] or input_dics['max_azi'] or \
                            input_dics['min_epi'] or input_dics['max_epi']:
                        if input_dics['min_epi']:
                            if epi_dist < input_dics['min_epi']:
                                del_index.append(sti)
                        if input_dics['max_epi']:
                            if epi_dist > input_dics['max_epi']:
                                del_index.append(sti)
                        if input_dics['min_azi']:
                            if azi < input_dics['min_azi']:
                                del_index.append(sti)
                        if input_dics['max_azi']:
                            if azi > input_dics['max_azi']:
                                del_index.append(sti)

                del_index = list(set(del_index))
                del_index.sort(reverse=True)
                for di in del_index:
                    sta_ev_arr = np.delete(sta_ev_arr, (di), axis=0)

        if plt_stations or plt_availability:
            if len(sta_ev_arr) > 0:
                x, y = m(sta_ev_arr[:, 5], sta_ev_arr[:, 4])
                m.scatter(x, y, color='red', s=width_station,
                          edgecolors='none', marker='v',
                          zorder=4, alpha=0.9)

        if plt_ray_path:
            for si in range(len(sta_ev_arr)):
                gcline = m.drawgreatcircle(float(events[ei]['longitude']),
                                           float(events[ei]['latitude']),
                                           float(sta_ev_arr[si][5]),
                                           float(sta_ev_arr[si][4]),
                                           color='k', alpha=0.0)

                gcx, gcy = gcline[0].get_data()
                gcx_diff = gcx[0:-1] - gcx[1:]
                gcy_diff = gcy[0:-1] - gcy[1:]
                if np.max(abs(gcx_diff))/abs(gcx_diff[0]) > 300:
                    gcx_max_arg = abs(gcx_diff).argmax()
                    plt.plot(gcx[0:gcx_max_arg], gcy[0:gcx_max_arg],
                             color='k', alpha=0.1)
                    plt.plot(gcx[gcx_max_arg+1:], gcy[gcx_max_arg+1:],
                             color='k', alpha=0.1)
                elif np.max(abs(gcy_diff))/abs(gcy_diff[0]) > 400:
                    gcy_max_arg = abs(gcy_diff).argmax()
                    plt.plot(gcy[0:gcy_max_arg], gcy[0:gcy_max_arg],
                             color='k', alpha=0.1)
                    plt.plot(gcy[gcy_max_arg+1:], gcy[gcy_max_arg+1:],
                             color='k', alpha=0.1)
                else:
                    m.drawgreatcircle(float(events[ei]['longitude']),
                                      float(events[ei]['latitude']),
                                      float(sta_ev_arr[si][5]),
                                      float(sta_ev_arr[si][4]),
                                      color='k', alpha=0.1)

    plt.savefig(os.path.join(input_dics['plot_save'],
                             'event_station.%s' % input_dics['plot_format']))
    plt.show()
예제 #3
0
def arc_download_core(st_avail, event, input_dics, target_path,
                      client_arclink, client_syngine, req_cli, info_station):
    """
    downloading the waveforms, reponse files (StationXML) and metadata
    this function should be normally called by some higher-level functions
    :param st_avail:
    :param event:
    :param input_dics:
    :param target_path:
    :param client_arclink:
    :param client_syngine:
    :param req_cli:
    :param info_station:
    :return:
    """
    dummy = 'initializing'

    t11 = datetime.now()
    identifier = 0
    st_id = '%s.%s.%s.%s' % (st_avail[0], st_avail[1],
                             st_avail[2], st_avail[3])
    try:
        if st_avail[2] == '--' or st_avail[2] == '  ':
                st_avail[2] = ''

        if input_dics['cut_time_phase']:
            t_start, t_end = calculate_time_phase(event, st_avail)
        else:
            t_start = event['t1']
            t_end = event['t2']

        if input_dics['min_azi'] or input_dics['max_azi'] or \
                input_dics['min_epi'] or input_dics['max_epi']:
            dist, azi, bazi = gps2DistAzimuth(event['latitude'],
                                              event['longitude'],
                                              float(st_avail[4]),
                                              float(st_avail[5]))
            epi_dist = dist/111.194/1000.
            if input_dics['min_epi']:
                if epi_dist < input_dics['min_epi']:
                    raise Exception('%s out of epi range: %s'
                                    % (st_id, epi_dist))
            if input_dics['max_epi']:
                if epi_dist > input_dics['max_epi']:
                    raise Exception('%s out of epi range: %s'
                                    % (st_id, epi_dist))
            if input_dics['min_azi']:
                if azi < input_dics['min_azi']:
                    raise Exception('%s outo f Azimuth range: %s'
                                    % (st_id, azi))
            if input_dics['max_azi']:
                if azi > input_dics['max_azi']:
                    raise Exception('%s out of Azimuth range: %s'
                                    % (st_id, azi))

        if input_dics['waveform']:
            dummy = 'waveform'
            if (not os.path.isfile(os.path.join(target_path, 'raw', st_id))) \
                    or input_dics['force_waveform']:

                if hasattr(client_arclink, 'save_waveforms'):
                    client_arclink.save_waveforms(os.path.join(target_path,
                                                               'raw', st_id),
                                                  st_avail[0], st_avail[1],
                                                  st_avail[2], st_avail[3],
                                                  t_start, t_end)
                elif hasattr(client_arclink, 'saveWaveform'):
                    client_arclink.saveWaveform(os.path.join(target_path,
                                                             'raw', st_id),
                                                st_avail[0], st_avail[1],
                                                st_avail[2], st_avail[3],
                                                t_start, t_end)
                identifier += 10
                print('%s -- %s -- saving waveform for: %s  ---> DONE' \
                      % (info_station, req_cli, st_id))
            else:
                identifier += 1

        if input_dics['response']:
            dummy = 'response'
            if (not os.path.isfile(os.path.join(target_path, 'resp',
                                                'STXML.' + st_id))) \
                    or input_dics['force_response']:
                if (not os.path.isfile(os.path.join(target_path, 'resp',
                                                    'DATALESS.' + st_id))) \
                        or input_dics['force_response']:
                    if hasattr(client_arclink, 'save_response'):
                        client_arclink.save_response(
                            os.path.join(target_path, 'resp',
                                         'DATALESS.%s' % st_id),
                            st_avail[0], st_avail[1], st_avail[2], st_avail[3],
                            t_start, t_end)
                    if hasattr(client_arclink, 'saveResponse'):
                        client_arclink.saveResponse(
                            os.path.join(target_path, 'resp',
                                         'DATALESS.%s' % st_id),
                            st_avail[0], st_avail[1], st_avail[2], st_avail[3],
                            t_start, t_end)
                    if input_dics['dataless2xml']:
                        try:
                            datalessResp = read_inventory(
                                os.path.join(target_path, 'resp', 'DATALESS.%s' % st_id))
                            datalessResp.write(os.path.join(
                                target_path, 'resp', 'STXML.%s' % st_id), format='STATIONXML')
                            os.remove(os.path.join(target_path, 'resp', 'DATALESS.%s' % st_id))
                        except Exception as error:
                            pass
                    identifier += 100
                    print("%s -- %s -- saving response for: %s  ---> DONE" \
                          % (info_station, req_cli, st_id))
                else:
                    identifier += 1
            else:
                identifier += 1

        if input_dics['syngine']:
            dummy = 'syngine_waveform'
            syn_dirpath = os.path.join(
                target_path, 'syngine_%s' % input_dics['syngine_bg_model'])
            if not os.path.isdir(syn_dirpath):
                os.makedirs(syn_dirpath)
            if (not os.path.isfile(os.path.join(syn_dirpath, st_id)))\
                    or input_dics['force_waveform']:

                if input_dics['syngine_geocentric_lat']:
                    rcvlatitude = geocen_calc(float(st_avail[4]))
                    evlatitude = geocen_calc(event['latitude'])
                else:
                    rcvlatitude = float(st_avail[4])
                    evlatitude = event['latitude']

                if not event['focal_mechanism']:
                    syngine_momenttensor = None
                else:
                    syngine_momenttensor = event['focal_mechanism']

                # XXX some other arguments
                # sourcedoublecouple=None,
                # dt=None
                # kernelwidth=None
                # sourceforce=None
                # label=None
                syn_st = client_syngine.get_waveforms(
                    model=input_dics['syngine_bg_model'],
                    receiverlatitude=rcvlatitude,
                    receiverlongitude=float(st_avail[5]),
                    networkcode=st_avail[0],
                    stationcode=st_avail[1],
                    sourcelatitude=evlatitude,
                    sourcelongitude=event['longitude'],
                    sourcedepthinmeters=float(event['depth'])*1000.,
                    origintime=event['datetime'],
                    components=st_avail[3][-1],
                    units=input_dics['syngine_units'],
                    sourcemomenttensor=syngine_momenttensor,
                    starttime=t_start,
                    endtime=t_end)[0]

                syn_st.stats.location = st_avail[2]
                syn_st.stats.channel = st_avail[3]
                syn_st.write(os.path.join(syn_dirpath, st_id),
                             format='mseed')

                identifier += 1000
                print('%s -- %s -- saving syngine for: %s  ---> DONE' \
                      % (info_station, req_cli, st_id))
            else:
                identifier += 1

        # if identifier in [0, 2, 10, 11, 100]:
        #     raise Exception("CODE: %s will not be registered! (666)"
        #                     % identifier)
        t22 = datetime.now()
    except Exception as error:
        t22 = datetime.now()

        if len(st_avail) != 0:
            ee = '%s -- %s -- %s -- %s\n' % (req_cli, dummy, st_id, error)
        else:
            ee = '%s: There is no available station for this event.' % req_cli
        Exception_file = open(os.path.join(target_path,
                                           'info', 'exception'), 'at+')
        Exception_file.writelines(ee)
        Exception_file.close()
예제 #4
0
def plot_waveform(input_dics, events):
    """
    plot waveforms arranged by the epicentral distance
    :param input_dics:
    :param events:
    :return:
    """
    # plt.rc('font', family='serif')
    for ei in range(len(events)):
        target_path = locate(input_dics['datapath'], events[ei]['event_id'])
        if len(target_path) == 0:
            continue
        if len(target_path) > 1:
            print("[LOCAL] more than one path was found for the event:")
            print(target_path)
            print("[INFO] use the first one:")
            target_path = target_path[0]
            print(target_path)
        else:
            print("[LOCAL] Path:")
            target_path = target_path[0]
            print(target_path)

        update_sta_ev_file(target_path, events[ei])
        sta_ev_arr = np.loadtxt(
            os.path.join(target_path, 'info', 'station_event'),
            delimiter=',', dtype=bytes, ndmin=2).astype(np.str)
        sta_ev_arr = sta_ev_arr.astype(np.object)
        del_index = []
        for sti in range(len(sta_ev_arr)):
            if not plot_filter_station(input_dics, sta_ev_arr[sti]):
                del_index.append(sti)
        del_index.sort(reverse=True)
        for di in del_index:
            sta_ev_arr[di] = np.delete(sta_ev_arr, (di), axis=0)

        for si in range(len(sta_ev_arr)):
            sta_id = sta_ev_arr[si, 0] + '.' + sta_ev_arr[si, 1] + '.' + \
                     sta_ev_arr[si, 2] + '.' + sta_ev_arr[si, 3]
            try:
                tr = read(os.path.join(target_path,
                                       input_dics['plot_dir_name'],
                                       sta_id))[0]
                time_diff = tr.stats.starttime - events[ei]['datetime']
                taxis = tr.times() + time_diff

                dist, azi, bazi = gps2DistAzimuth(events[ei]['latitude'],
                                                  events[ei]['longitude'],
                                                  float(sta_ev_arr[si, 4]),
                                                  float(sta_ev_arr[si, 5]))
                epi_dist = dist/111.194/1000.
                if input_dics['min_azi'] or input_dics['max_azi'] or \
                        input_dics['min_epi'] or input_dics['max_epi']:
                    if input_dics['min_epi']:
                        if epi_dist < input_dics['min_epi']:
                            continue
                    if input_dics['max_epi']:
                        if epi_dist > input_dics['max_epi']:
                            continue
                    if input_dics['min_azi']:
                        if azi < input_dics['min_azi']:
                            continue
                    if input_dics['max_azi']:
                        if azi > input_dics['max_azi']:
                            continue
                plt.plot(taxis, tr.normalize().data + epi_dist, c='k',
                         alpha=0.7)
            except:
                continue

    plt.xlabel('Time (sec)', size=24)
    plt.ylabel('Distance (deg)', size=24)
    plt.xticks(size=18)
    plt.yticks(size=18)
    plt.tight_layout()
    plt.savefig(os.path.join(input_dics['plot_save'],
                             'waveforms.%s' % input_dics['plot_format']))
    plt.show()
예제 #5
0
def create_ev_sta_kml(input_dics, events):
    """
    create event/station/ray in KML format readable by Google-Earth
    :param input_dics:
    :param events:
    :return:
    """
    try:
        from pykml.factory import KML_ElementMaker as KML
        from lxml import etree
    except:
        sys.exit('[ERROR] pykml should be installed first!')

    if not os.path.isdir('kml_dir'):
        os.mkdir('kml_dir')
    else:
        print('[INFO] kml_dir already exists!')

    # create a document element with multiple label style
    kmlobj = KML.kml(KML.Document())
    counter = 0
    for ei in range(len(events)):
        print(events[ei]['event_id'])
        counter += 1

        ev_date = '%04i/%02i/%02i-%02i:%02i:%02i' \
                  % (events[ei]['datetime'].year,
                     events[ei]['datetime'].month,
                     events[ei]['datetime'].day,
                     events[ei]['datetime'].hour,
                     events[ei]['datetime'].minute,
                     events[ei]['datetime'].second
                     )

        if input_dics['plot_focal']:
            try:
                focmecs = [float(events[ei]['focal_mechanism'][0]),
                           float(events[ei]['focal_mechanism'][1]),
                           float(events[ei]['focal_mechanism'][2]),
                           float(events[ei]['focal_mechanism'][3]),
                           float(events[ei]['focal_mechanism'][4]),
                           float(events[ei]['focal_mechanism'][5])]
            except:
                print("WARNING: 'focal_mechanism' does not exist!")
                focmecs = [1, 1, 1, 0, 0, 0]
        else:
            focmecs = [1, 1, 1, 0, 0, 0]

        if 0 <= events[ei]['depth'] < 70:
            event_color = 'red'
        elif 70 <= events[ei]['depth'] < 300:
            event_color = 'green'
        else:
            event_color = 'blue'

        try:
            Beachball(focmecs,
                      outfile=os.path.join(
                          'kml_dir', events[ei]['event_id'] + '.png'),
                      facecolor=event_color,
                      edgecolor=event_color)
        except Exception as error:
            print(error)
            print(focmecs)
            continue
        plt.close()
        plt.clf()

        if input_dics['plot_ev'] or input_dics['plot_ray']:
            kmlobj.Document.append(
                KML.Style(
                    KML.IconStyle(
                        KML.Icon(KML.href(os.path.join(
                            events[ei]['event_id'] + '.png')),
                        ),
                        KML.scale(events[ei]['magnitude']/2.),
                        KML.heading(0.0),
                    ),
                    id='beach_ball_%i' % counter
                ),
            )

            kmlobj.Document.append(
                KML.Placemark(
                    KML.name(events[ei]['event_id']),
                    KML.ExtendedData(
                        KML.Data(
                            KML.value('%s' % events[ei]['event_id']),
                            name='event_id'
                        ),
                        KML.Data(
                            KML.value('%s' % events[ei]['magnitude']),
                            name='magnitude'
                        ),
                        KML.Data(
                            KML.value('%s' % ev_date),
                            name='datetime'
                        ),
                        KML.Data(
                            KML.value('%s' % events[ei]['depth']),
                            name='depth'
                        ),
                        KML.Data(
                            KML.value('%s' % events[ei]['latitude']),
                            name='latitude'
                        ),
                        KML.Data(
                            KML.value('%s' % events[ei]['longitude']),
                            name='longitude'
                        ),
                    ),
                    KML.styleUrl('#beach_ball_%i' % counter),
                    # KML.Point(KML.coordinates(events[ei]['longitude'], ',',
                    #                           events[ei]['latitude'], ',',
                    #                           700000 -
                    #                           abs(events[ei]['depth']*1000)),
                    #           KML.altitudeMode('absolute')
                    #           ),
                    KML.Point(KML.coordinates(events[ei]['longitude'], ',',
                                              events[ei]['latitude'], ',',
                                              0.),
                              KML.altitudeMode('absolute')
                              ),
                ),
            )

        if input_dics['plot_sta'] or input_dics['plot_ray']:
            target_path = locate(input_dics['datapath'],
                                 events[ei]['event_id'])
            if len(target_path) < 1:
                continue
            if len(target_path) > 1:
                print("[LOCAL] more than one path was found for the event:")
                print(target_path)
                print("[INFO] use the first one:")
                target_path = target_path[0]
                print(target_path)
            else:
                print("[LOCAL] Path:")
                target_path = target_path[0]
                print(target_path)

            update_sta_ev_file(target_path, events[ei])
            sta_ev_arr = np.loadtxt(os.path.join(target_path,
                                                 'info', 'station_event'),
                                    delimiter=',', dtype=bytes, ndmin=2).astype(np.str)
            sta_ev_arr = sta_ev_arr.astype(np.object)
            del_index = []
            for sti in range(len(sta_ev_arr)):

                if not plot_filter_station(input_dics, sta_ev_arr[sti]):
                    del_index.append(sti)

                dist, azi, bazi = gps2DistAzimuth(events[ei]['latitude'],
                                                  events[ei]['longitude'],
                                                  float(sta_ev_arr[sti, 4]),
                                                  float(sta_ev_arr[sti, 5]))

                epi_dist = dist/111.194/1000.
                if input_dics['min_azi'] or input_dics['max_azi'] or \
                        input_dics['min_epi'] or input_dics['max_epi']:
                    if input_dics['min_epi']:
                        if epi_dist < input_dics['min_epi']:
                            del_index.append(sti)
                    if input_dics['max_epi']:
                        if epi_dist > input_dics['max_epi']:
                            del_index.append(sti)
                    if input_dics['min_azi']:
                        if azi < input_dics['min_azi']:
                            del_index.append(sti)
                    if input_dics['max_azi']:
                        if azi > input_dics['max_azi']:
                            del_index.append(sti)

            del_index = list(set(del_index))
            del_index.sort(reverse=True)
            for di in del_index:
                sta_ev_arr = np.delete(sta_ev_arr, (di), axis=0)

            kmlobj.Document.append(
                KML.Style(
                    KML.IconStyle(
                        KML.scale(2.5),
                        KML.heading(0.0),
                    ),
                    id='station'
                ),
            )
            kmlobj.Document.append(
                KML.Style(
                    KML.LineStyle(
                        KML.width(1.0),
                        # KML.color('ff33ccff'),
                        KML.color('2333ccff'),
                    ),
                    id='great_circle_distance'
                ),
            )
            for sti in sta_ev_arr:
                dist, azi, bazi = gps2DistAzimuth(events[ei]['latitude'],
                                                  events[ei]['longitude'],
                                                  float(sti[4]),
                                                  float(sti[5]))
                epi_dist = dist/111.194/1000.
                sta_id = '%s.%s.%s.%s' % (sti[0], sti[1], sti[2], sti[3])
                kmlobj.Document.append(
                    KML.Placemark(
                        KML.name(sta_id),
                        KML.ExtendedData(
                            KML.Data(
                                KML.value('%s' % sta_id),
                                name='StationID'
                            ),
                            KML.Data(
                                KML.value('%s' % epi_dist),
                                name='Distance'
                            ),
                            KML.Data(
                                KML.value('%s' % sti[6]),
                                name='Elevation'
                            ),
                            KML.Data(
                                KML.value('%s' % sti[7]),
                                name='Depth'
                            ),
                            KML.Data(
                                KML.value('%s' % bazi),
                                name='Back-Azimuth'
                            ),
                            KML.Data(
                                KML.value('%s' % azi),
                                name='Azimuth'
                            ),
                            KML.Data(
                                KML.value('%s' % events[ei]['event_id']),
                                name='EventID'
                            ),
                            KML.Data(
                                KML.value('%s' % sti[8]),
                                name='Source'
                            ),
                        ),
                        KML.styleUrl('station'),
                        KML.Point(KML.coordinates(
                            float(sti[5]), ',', float(sti[4]))
                        ),
                    ),
                )
                if input_dics['plot_ray']:
                    kmlobj.Document.append(
                        KML.Placemark(
                            KML.name(sta_id),
                            KML.ExtendedData(
                                KML.Data(
                                    KML.value('%s' % sta_id),
                                    name='StationID'
                                ),
                            ),
                            KML.styleUrl('great_circle_distance'),
                            KML.LineString(KML.coordinates(
                                '%s,%s,0\n'
                                '%s,%s,0' % (float(sti[5]),
                                             float(sti[4]),
                                             events[ei]['longitude'],
                                             events[ei]['latitude'])),
                                KML.tessellate(1)),
                        ),
                    )
    kml_outfile = file(os.path.join(
        'kml_dir',
        'kml_output.kml'), 'w')
    kml_outfile.write(etree.tostring(kmlobj, pretty_print=True))
    sys.exit('[INFO] KML file is stored in ./kml_dir!')