Exemple #1
0
def _qc_event(
    event: Event,
    min_stations: int = None,
    auto_picks: bool = True,
    auto_event: bool = True,
    event_type: Union[list, str] = None,
) -> tuple:
    """
    QC an individual event - removes picks in place.

    Returns
    -------
    tuple of (event: Event, keep: bool)
    """
    if event_type is not None and isinstance(event_type, str):
        event_type = [event_type]
    if event_type is not None and event.event_type not in event_type:
        return event, False
    elif not auto_event:
        if "manual" not in [ori.evaluation_mode for ori in event.origins]:
            return event, False
    if not auto_picks:
        pick_ids_to_remove = [
            p.resource_id for p in event.picks
            if p.evaluation_mode == "automatic"
        ]
        # remove arrivals and amplitudes and station_magnitudes
        event.picks = [
            p for p in event.picks if p.resource_id not in pick_ids_to_remove
        ]
        event = remove_unreferenced(event)[0]
    stations = {p.waveform_id.station_code for p in event.picks}
    if len(stations) < min_stations:
        return event, False
    return event, True
Exemple #2
0
 def __init__(self, parent=None, evtdata=None):
     self._parent = parent
     if self.getParent():
         self.comp = parent.getComponent()
     else:
         self.comp = 'Z'
         self.wfdata = Stream()
     self._new = False
     if isinstance(evtdata, ObsPyEvent) or isinstance(evtdata, Event):
         pass
     elif isinstance(evtdata, dict):
         evt = readPILOTEvent(**evtdata)
         evtdata = evt
     elif isinstance(evtdata, str):
         try:
             cat = read_events(evtdata)
             if len(cat) is not 1:
                 raise ValueError('ambiguous event information for file: '
                                  '{file}'.format(file=evtdata))
             evtdata = cat[0]
         except TypeError as e:
             if 'Unknown format for file' in e.message:
                 if 'PHASES' in evtdata:
                     picks = picksdict_from_pilot(evtdata)
                     evtdata = ObsPyEvent()
                     evtdata.picks = picks_from_picksdict(picks)
                 elif 'LOC' in evtdata:
                     raise NotImplementedError('PILOT location information '
                                               'read support not yet '
                                               'implemeted.')
                 else:
                     raise e
             else:
                 raise e
     else:  # create an empty Event object
         self.setNew()
         evtdata = ObsPyEvent()
         evtdata.picks = []
     self.evtdata = evtdata
     self.wforiginal = None
     self.cuttimes = None
     self.dirty = False
                  latitude=str(lat[x]), 
                  depth=str(dep[x]))
        magnitude = Magnitude(mag = ml[x], magnitude_type = "M", origin_id = (str(orid[x]))) 
        arrival = Arrival(pick_id = rd, phase = str(phase[x])) 
        event.picks.append(picks) 
        event.origins.append(origin)
        origin.arrivals.append(arrival) 
        event.magnitudes.append(magnitude)
    db_catalog.append(event)


#Only include picks for stations used 
all_picks=[]
for event in db_catalog:
    stations = ['KCT', 'KMPB', 'KCR', 'KHMB', 'KCS', 'KCO', 'KMR', 'KPP']                
    event.picks = [pick for pick in event.picks if pick.waveform_id.station_code in stations]
    all_picks+= [(pick.waveform_id.station_code, pick.waveform_id.channel_code) for pick in event.picks]

new_catalog=Catalog()
for event in db_catalog:
    event.picks = [pick for pick in event.picks if (pick.waveform_id.station_code, pick.waveform_id.channel_code) in all_picks]
    new_catalog.append(event)

# count number of picks for each event in catalog
n_picks = [len(event.picks) for event in new_catalog] 

#Save catalog
new_catalog.write("DB_Event_Catalog" + '.xml', "QUAKEML")

# =============================================================================
# ## 2. LOAD CATALOG IF AVAILABLE 
Exemple #4
0
def stalta_pick(stream,
                stalen,
                ltalen,
                trig_on,
                trig_off,
                freqmin=False,
                freqmax=False,
                show=False):
    """
    Basic sta/lta picker, suggest using alternative in obspy.

    Simple sta/lta (short-term average/long-term average) picker, using
    obspy's :func:`obspy.signal.trigger.classic_sta_lta` routine to generate
    the characteristic function.

    Currently very basic quick wrapper, there are many other (better) options
    in obspy in the :mod:`obspy.signal.trigger` module.

    :type stream: obspy.core.stream.Stream
    :param stream: The stream to pick on, can be any number of channels.
    :type stalen: float
    :param stalen: Length of the short-term average window in seconds.
    :type ltalen: float
    :param ltalen: Length of the long-term average window in seconds.
    :type trig_on: float
    :param trig_on: sta/lta ratio to trigger a detection/pick
    :type trig_off: float
    :param trig_off: sta/lta ratio to turn the trigger off - no further picks\
        will be made between exceeding trig_on until trig_off is reached.
    :type freqmin: float
    :param freqmin: Low-cut frequency in Hz for bandpass filter
    :type freqmax: float
    :param freqmax: High-cut frequency in Hz for bandpass filter
    :type show: bool
    :param show: Show picks on waveform.

    :returns: :class:`obspy.core.event.event.Event`

    .. rubric:: Example

    >>> from obspy import read
    >>> from eqcorrscan.utils.picker import stalta_pick
    >>> st = read()
    >>> event = stalta_pick(st, stalen=0.2, ltalen=4, trig_on=10,
    ...             trig_off=1, freqmin=3.0, freqmax=20.0)
    >>> print(event.creation_info.author)
    EQcorrscan

    .. warning::
        This function is not designed for accurate picking, rather it can give
        a first idea of whether picks may be possible.  Proceed with caution.
    """
    event = Event()
    event.origins.append(Origin())
    event.creation_info = CreationInfo(author='EQcorrscan',
                                       creation_time=UTCDateTime())
    event.comments.append(Comment(text='stalta'))
    picks = []
    for tr in stream:
        # We are going to assume, for now, that if the pick is made on the
        # horizontal channel then it is an S, otherwise we will assume it is
        # a P-phase: obviously a bad assumption...
        if tr.stats.channel[-1] == 'Z':
            phase = 'P'
        else:
            phase = 'S'
        if freqmin and freqmax:
            tr.detrend('simple')
            tr.filter('bandpass',
                      freqmin=freqmin,
                      freqmax=freqmax,
                      corners=3,
                      zerophase=True)
        df = tr.stats.sampling_rate
        cft = classic_sta_lta(tr.data, int(stalen * df), int(ltalen * df))
        triggers = trigger_onset(cft, trig_on, trig_off)
        for trigger in triggers:
            on = tr.stats.starttime + (trigger[0] / df)
            # off = tr.stats.starttime + (trigger[1] / df)
            wav_id = WaveformStreamID(station_code=tr.stats.station,
                                      channel_code=tr.stats.channel,
                                      network_code=tr.stats.network)
            p = Pick(waveform_id=wav_id, phase_hint=phase, time=on)
            Logger.info('Pick made: {0}'.format(p))
            picks.append(p)
    # QC picks
    pick_stations = list(set([pick.waveform_id.station_code
                              for pick in picks]))
    for pick_station in pick_stations:
        station_picks = [
            pick for pick in picks
            if pick.waveform_id.station_code == pick_station
        ]
        # If P-pick is after S-picks, remove it.
        p_time = [
            pick.time for pick in station_picks if pick.phase_hint == 'P'
        ]
        s_time = [
            pick.time for pick in station_picks if pick.phase_hint == 'S'
        ]
        if p_time > s_time:
            p_pick = [pick for pick in station_picks if pick.phase_hint == 'P']
            for pick in p_pick:
                Logger.info('P pick after S pick, removing P pick')
                picks.remove(pick)
    event.picks = picks
    if show:
        plotting.pretty_template_plot(stream,
                                      event=event,
                                      title='Autopicks',
                                      size=(8, 9))
    if len(event.picks) > 0:
        event.origins[0].time = min([pick.time for pick in event.picks]) - 1
        # event.origins[0].latitude = float('nan')
        # event.origins[0].longitude = float('nan')
    # Set arbitrary origin time
    return event
def _dbs_associator(start_time,
                    end_time,
                    moving_window,
                    tbl,
                    pair_n,
                    save_dir,
                    station_list,
                    consider_combination=False):

    if consider_combination == True:
        if platform.system() == 'Windows':
            Y2000_writer = open(save_dir + "\\" + "Y2000.phs", "w")
        else:
            Y2000_writer = open(save_dir + "/" + "Y2000.phs", "w")

        traceNmae_dic = dict()
        st = datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S.%f')
        et = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S.%f')
        total_t = et - st
        evid = 0
        tt = st
        pbar = tqdm(total=int(np.ceil(total_t.total_seconds() /
                                      moving_window)),
                    ncols=100)
        while tt < et:

            detections = tbl[(tbl.event_start_time >= tt) & (
                tbl.event_start_time < tt + timedelta(seconds=moving_window))]
            pbar.update()
            if len(detections) >= pair_n:
                evid += 1

                yr = "{:>4}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [0].split('-')[0])
                mo = "{:>2}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [0].split('-')[1])
                dy = "{:>2}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [0].split('-')[2])
                hr = "{:>2}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [1].split(':')[0])
                mi = "{:>2}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [1].split(':')[1])
                sec = "{:>4}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [1].split(':')[2])
                st_lat_DMS = _decimalDegrees2DMS(
                    float(detections.iloc[0]['stlat']), "Latitude")
                st_lon_DMS = _decimalDegrees2DMS(
                    float(detections.iloc[0]['stlon']), "Longitude")
                depth = 5.0
                mag = 0.0

                # QuakeML
                print(detections.iloc[0]['event_start_time'])

                if len(detections) / pair_n <= 2:
                    ch = pair_n
                else:
                    ch = int(len(detections) - pair_n)

                picks = []
                for ns in range(ch, len(detections) + 1):
                    comb = 0
                    for ind in list(combinations(detections.index, ns)):
                        comb += 1
                        selected_detections = detections.loc[ind, :]
                        sorted_detections = selected_detections.sort_values(
                            'p_arrival_time')

                        Y2000_writer.write(
                            "%4d%2d%2d%2d%2d%4.2f%2.0f%1s%4.2f%3.0f%1s%4.2f%5.2f%3.2f\n"
                            % (int(yr), int(mo), int(dy), int(hr), int(mi),
                               float(sec), float(st_lat_DMS[0]),
                               str(st_lat_DMS[1]), float(st_lat_DMS[2]),
                               float(st_lon_DMS[0]), str(st_lon_DMS[1]),
                               float(st_lon_DMS[2]), float(depth), float(mag)))

                        station_buffer = []
                        row_buffer = []
                        tr_names = []
                        tr_names2 = []
                        for _, row in sorted_detections.iterrows():

                            trace_name = row['traceID'] + '*' + row[
                                'station'] + '*' + str(row['event_start_time'])
                            p_unc = row['p_unc']
                            p_prob = row['p_prob']
                            s_unc = row['s_unc']
                            s_prob = row['s_prob']

                            if p_unc:
                                Pweihgt = _weighcalculator_prob(p_prob *
                                                                (1 - p_unc))
                            else:
                                Pweihgt = _weighcalculator_prob(p_prob)
                            try:
                                Pweihgt = int(Pweihgt)
                            except Exception:
                                Pweihgt = 4

                            if s_unc:
                                Sweihgt = _weighcalculator_prob(s_prob *
                                                                (1 - s_unc))
                            else:
                                Sweihgt = _weighcalculator_prob(s_prob)
                            try:
                                Sweihgt = int(Sweihgt)
                            except Exception:
                                Sweihgt = 4

                            station = "{:<5}".format(row['station'])
                            network = "{:<2}".format(row['network'])
                            try:
                                yrp = "{:>4}".format(
                                    str(row['p_arrival_time']).split(' ')
                                    [0].split('-')[0])
                                mop = "{:>2}".format(
                                    str(row['p_arrival_time']).split(' ')
                                    [0].split('-')[1])
                                dyp = "{:>2}".format(
                                    str(row['p_arrival_time']).split(' ')
                                    [0].split('-')[2])
                                hrp = "{:>2}".format(
                                    str(row['p_arrival_time']).split(' ')
                                    [1].split(':')[0])
                                mip = "{:>2}".format(
                                    str(row['p_arrival_time']).split(' ')
                                    [1].split(':')[1])
                                sec_p = "{:>4}".format(
                                    str(row['p_arrival_time']).split(' ')
                                    [1].split(':')[2])
                                p = Pick(time=UTCDateTime(
                                    row['p_arrival_time']),
                                         waveform_id=WaveformStreamID(
                                             network_code=network,
                                             station_code=station.rstrip()),
                                         phase_hint="P")
                                picks.append(p)
                            except Exception:
                                sec_p = None

                            try:
                                yrs = "{:>4}".format(
                                    str(row['s_arrival_time']).split(' ')
                                    [0].split('-')[0])
                                mos = "{:>2}".format(
                                    str(row['s_arrival_time']).split(' ')
                                    [0].split('-')[1])
                                dys = "{:>2}".format(
                                    str(row['s_arrival_time']).split(' ')
                                    [0].split('-')[2])
                                hrs = "{:>2}".format(
                                    str(row['s_arrival_time']).split(' ')
                                    [1].split(':')[0])
                                mis = "{:>2}".format(
                                    str(row['s_arrival_time']).split(' ')
                                    [1].split(':')[1])
                                sec_s = "{:>4}".format(
                                    str(row['s_arrival_time']).split(' ')
                                    [1].split(':')[2])
                                p = Pick(time=UTCDateTime(
                                    row['p_arrival_time']),
                                         waveform_id=WaveformStreamID(
                                             network_code=network,
                                             station_code=station.rstrip()),
                                         phase_hint="S")
                                picks.append(p)
                            except Exception:
                                sec_s = None

                            if row['station'] not in station_buffer:
                                tr_names.append(trace_name)
                                station_buffer.append(row['station'])
                                if sec_s:
                                    Y2000_writer.write(
                                        "%5s%2s  HHE     %4d%2d%2d%2d%2d%5.2f       %5.2fES %1d\n"
                                        %
                                        (station, network, int(yrs), int(mos),
                                         int(dys), int(hrs), int(mis),
                                         float(0.0), float(sec_s), Sweihgt))
                                if sec_p:
                                    Y2000_writer.write(
                                        "%5s%2s  HHZ IP %1d%4d%2d%2d%2d%2d%5.2f       %5.2f   0\n"
                                        % (station, network, Pweihgt, int(yrp),
                                           int(mop), int(dyp), int(hrp),
                                           int(mip), float(sec_p), float(0.0)))
                            else:
                                tr_names2.append(trace_name)
                                if sec_s:
                                    row_buffer.append(
                                        "%5s%2s  HHE     %4d%2d%2d%2d%2d%5.2f       %5.2fES %1d\n"
                                        %
                                        (station, network, int(yrs), int(mos),
                                         int(dys), int(hrs), int(mis), 0.0,
                                         float(sec_s), Sweihgt))
                                if sec_p:
                                    row_buffer.append(
                                        "%5s%2s  HHZ IP %1d%4d%2d%2d%2d%2d%5.2f       %5.2f   0\n"
                                        % (station, network, Pweihgt, int(yrp),
                                           int(mop), int(dyp), int(hrp),
                                           int(mip), float(sec_p), float(0.0)))
                        Y2000_writer.write("{:<62}".format(' ') + "%10d" %
                                           (evid) + '\n')

                traceNmae_dic[str(evid)] = tr_names

                if len(row_buffer) >= 2 * pair_n:
                    Y2000_writer.write(
                        "%4d%2d%2d%2d%2d%4.2f%2.0f%1s%4.2f%3.0f%1s%4.2f%5.2f%3.2f\n"
                        % (int(yr), int(mo), int(dy), int(hr), int(mi),
                           float(sec), float(st_lat_DMS[0]), str(
                               st_lat_DMS[1]), float(st_lat_DMS[2]),
                           float(st_lon_DMS[0]), str(st_lon_DMS[1]),
                           float(st_lon_DMS[2]), float(depth), float(mag)))
                    for rr in row_buffer:
                        Y2000_writer.write(rr)

                    Y2000_writer.write("{:<62}".format(' ') + "%10d" % (evid) +
                                       '\n')
                    traceNmae_dic[str(evid)] = tr_names2

            tt += timedelta(seconds=moving_window)

    #   plt.scatter(LTTP, TTP, s=10, marker='o', c='b', alpha=0.4, label='P')
    #   plt.scatter(LTTS, TTS, s=10, marker='o', c='r', alpha=0.4, label='S')
    #   plt.legend('upper right')
    #   plt.show()

        print('The Number of Realizations: ' + str(evid) + '\n', flush=True)

        jj = json.dumps(traceNmae_dic)
        if platform.system() == 'Windows':
            f = open(save_dir + "\\" + "traceNmae_dic.json", "w")
        else:
            f = open(save_dir + "/" + "traceNmae_dic.json", "w")
        f.write(jj)
        f.close()

    else:
        if platform.system() == 'Windows':
            Y2000_writer = open(save_dir + "\\" + "Y2000.phs", "w")
        else:
            Y2000_writer = open(save_dir + "/" + "Y2000.phs", "w")

        cat = Catalog()
        traceNmae_dic = dict()
        st = datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S.%f')
        et = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S.%f')
        total_t = et - st
        evid = 200000
        evidd = 100000
        tt = st
        pbar = tqdm(total=int(np.ceil(total_t.total_seconds() /
                                      moving_window)))
        while tt < et:

            detections = tbl[(tbl.event_start_time >= tt) & (
                tbl.event_start_time < tt + timedelta(seconds=moving_window))]
            pbar.update()
            if len(detections) >= pair_n:

                yr = "{:>4}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [0].split('-')[0])
                mo = "{:>2}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [0].split('-')[1])
                dy = "{:>2}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [0].split('-')[2])
                hr = "{:>2}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [1].split(':')[0])
                mi = "{:>2}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [1].split(':')[1])
                sec = "{:>4}".format(
                    str(detections.iloc[0]['event_start_time']).split(' ')
                    [1].split(':')[2])
                st_lat_DMS = _decimalDegrees2DMS(
                    float(detections.iloc[0]['stlat']), "Latitude")
                st_lon_DMS = _decimalDegrees2DMS(
                    float(detections.iloc[0]['stlon']), "Longitude")
                depth = 5.0
                mag = 0.0

                Y2000_writer.write(
                    "%4d%2d%2d%2d%2d%4.2f%2.0f%1s%4.2f%3.0f%1s%4.2f%5.2f%3.2f\n"
                    % (int(yr), int(mo), int(dy), int(hr), int(mi), float(sec),
                       float(st_lat_DMS[0]), str(st_lat_DMS[1]),
                       float(st_lat_DMS[2]), float(st_lon_DMS[0]),
                       str(st_lon_DMS[1]), float(
                           st_lon_DMS[2]), float(depth), float(mag)))
                event = Event()
                origin = Origin(time=UTCDateTime(
                    detections.iloc[0]['event_start_time']),
                                longitude=detections.iloc[0]['stlon'],
                                latitude=detections.iloc[0]['stlat'],
                                method="EqTransformer")
                event.origins.append(origin)

                station_buffer = []
                row_buffer = []
                sorted_detections = detections.sort_values('p_arrival_time')
                tr_names = []
                tr_names2 = []
                picks = []
                for _, row in sorted_detections.iterrows():
                    trace_name = row['traceID'] + '*' + row[
                        'station'] + '*' + str(row['event_start_time'])
                    p_unc = row['p_unc']
                    p_prob = row['p_prob']
                    s_unc = row['s_unc']
                    s_prob = row['s_prob']

                    if p_unc:
                        Pweihgt = _weighcalculator_prob(p_prob * (1 - p_unc))
                    else:
                        Pweihgt = _weighcalculator_prob(p_prob)
                    try:
                        Pweihgt = int(Pweihgt)
                    except Exception:
                        Pweihgt = 4

                    if s_unc:
                        Sweihgt = _weighcalculator_prob(s_prob * (1 - s_unc))
                    else:
                        Sweihgt = _weighcalculator_prob(s_prob)
                    try:
                        Sweihgt = int(Sweihgt)
                    except Exception:
                        Sweihgt = 4

                    station = "{:<5}".format(row['station'])
                    network = "{:<2}".format(row['network'])

                    try:
                        yrp = "{:>4}".format(
                            str(row['p_arrival_time']).split(' ')[0].split('-')
                            [0])
                        mop = "{:>2}".format(
                            str(row['p_arrival_time']).split(' ')[0].split('-')
                            [1])
                        dyp = "{:>2}".format(
                            str(row['p_arrival_time']).split(' ')[0].split('-')
                            [2])
                        hrp = "{:>2}".format(
                            str(row['p_arrival_time']).split(' ')[1].split(':')
                            [0])
                        mip = "{:>2}".format(
                            str(row['p_arrival_time']).split(' ')[1].split(':')
                            [1])
                        sec_p = "{:>4}".format(
                            str(row['p_arrival_time']).split(' ')[1].split(':')
                            [2])
                        p = Pick(time=UTCDateTime(row['p_arrival_time']),
                                 waveform_id=WaveformStreamID(
                                     network_code=network,
                                     station_code=station.rstrip()),
                                 phase_hint="P",
                                 method_id="EqTransformer")
                        picks.append(p)
                    except Exception:
                        sec_p = None

                    try:
                        yrs = "{:>4}".format(
                            str(row['s_arrival_time']).split(' ')[0].split('-')
                            [0])
                        mos = "{:>2}".format(
                            str(row['s_arrival_time']).split(' ')[0].split('-')
                            [1])
                        dys = "{:>2}".format(
                            str(row['s_arrival_time']).split(' ')[0].split('-')
                            [2])
                        hrs = "{:>2}".format(
                            str(row['s_arrival_time']).split(' ')[1].split(':')
                            [0])
                        mis = "{:>2}".format(
                            str(row['s_arrival_time']).split(' ')[1].split(':')
                            [1])
                        sec_s = "{:>4}".format(
                            str(row['s_arrival_time']).split(' ')[1].split(':')
                            [2])
                        p = Pick(time=UTCDateTime(row['s_arrival_time']),
                                 waveform_id=WaveformStreamID(
                                     network_code=network,
                                     station_code=station.rstrip()),
                                 phase_hint="S",
                                 method_id="EqTransformer")
                        picks.append(p)
                    except Exception:
                        sec_s = None

                    if row['station'] not in station_buffer:
                        tr_names.append(trace_name)
                        station_buffer.append(row['station'])
                        if sec_s:
                            Y2000_writer.write(
                                "%5s%2s  HHE     %4d%2d%2d%2d%2d%5.2f       %5.2fES %1d\n"
                                % (station, network, int(yrs), int(mos),
                                   int(dys), int(hrs), int(mis), float(0.0),
                                   float(sec_s), Sweihgt))
                        if sec_p:
                            Y2000_writer.write(
                                "%5s%2s  HHZ IP %1d%4d%2d%2d%2d%2d%5.2f       %5.2f   0\n"
                                % (station, network, Pweihgt, int(yrp),
                                   int(mop), int(dyp), int(hrp), int(mip),
                                   float(sec_p), float(0.0)))
                    else:
                        tr_names2.append(trace_name)
                        if sec_s:
                            row_buffer.append(
                                "%5s%2s  HHE     %4d%2d%2d%2d%2d%5.2f       %5.2fES %1d\n"
                                % (station, network, int(yrs), int(mos),
                                   int(dys), int(hrs), int(mis), 0.0,
                                   float(sec_s), Sweihgt))
                        if sec_p:
                            row_buffer.append(
                                "%5s%2s  HHZ IP %1d%4d%2d%2d%2d%2d%5.2f       %5.2f   0\n"
                                % (station, network, Pweihgt, int(yrp),
                                   int(mop), int(dyp), int(hrp), int(mip),
                                   float(sec_p), float(0.0)))
                event.picks = picks
                event.preferred_origin_id = event.origins[0].resource_id
                cat.append(event)

                evid += 1
                Y2000_writer.write("{:<62}".format(' ') + "%10d" % (evid) +
                                   '\n')
                traceNmae_dic[str(evid)] = tr_names

                if len(row_buffer) >= 2 * pair_n:
                    Y2000_writer.write(
                        "%4d%2d%2d%2d%2d%4.2f%2.0f%1s%4.2f%3.0f%1s%4.2f%5.2f%3.2f\n"
                        % (int(yr), int(mo), int(dy), int(hr), int(mi),
                           float(sec), float(st_lat_DMS[0]), str(
                               st_lat_DMS[1]), float(st_lat_DMS[2]),
                           float(st_lon_DMS[0]), str(st_lon_DMS[1]),
                           float(st_lon_DMS[2]), float(depth), float(mag)))
                    for rr in row_buffer:
                        Y2000_writer.write(rr)

                    evid += 1
                    Y2000_writer.write("{:<62}".format(' ') + "%10d" % (evid) +
                                       '\n')
                    traceNmae_dic[str(evid)] = tr_names2

                elif len(row_buffer) < pair_n and len(row_buffer) != 0:
                    evidd += 1
                    traceNmae_dic[str(evidd)] = tr_names2

            elif len(detections) < pair_n and len(detections) != 0:
                tr_names = []
                for _, row in detections.iterrows():
                    trace_name = row['traceID']
                    tr_names.append(trace_name)
                evidd += 1
                traceNmae_dic[str(evidd)] = tr_names

            tt += timedelta(seconds=moving_window)

        print('The Number of Associated Events: ' + str(evid - 200000) + '\n',
              flush=True)

        jj = json.dumps(traceNmae_dic)
        if platform.system() == 'Windows':
            f = open(save_dir + "\\" + "traceNmae_dic.json", "w")
        else:
            f = open(save_dir + "/" + "traceNmae_dic.json", "w")

        f.write(jj)
        f.close()
        print(cat.__str__(print_all=True))
        cat.write(save_dir + "/associations.xml", format="QUAKEML")
Exemple #6
0
def full_test_event():
    """
    Function to generate a basic, full test event
    """
    test_event = Event()
    test_event.origins.append(Origin())
    test_event.origins[0].time = UTCDateTime("2012-03-26") + 1.2
    test_event.event_descriptions.append(EventDescription())
    test_event.event_descriptions[0].text = 'LE'
    test_event.origins[0].latitude = 45.0
    test_event.origins[0].longitude = 25.0
    test_event.origins[0].depth = 15000
    test_event.creation_info = CreationInfo(agency_id='TES')
    test_event.origins[0].quality = OriginQuality(standard_error=0.01)
    test_event.magnitudes.append(Magnitude())
    test_event.magnitudes[0].mag = 0.1
    test_event.magnitudes[0].magnitude_type = 'ML'
    test_event.magnitudes[0].creation_info = CreationInfo('TES')
    test_event.magnitudes[0].origin_id = test_event.origins[0].resource_id
    test_event.magnitudes.append(Magnitude())
    test_event.magnitudes[1].mag = 0.5
    test_event.magnitudes[1].magnitude_type = 'Mc'
    test_event.magnitudes[1].creation_info = CreationInfo('TES')
    test_event.magnitudes[1].origin_id = test_event.origins[0].resource_id
    test_event.magnitudes.append(Magnitude())
    test_event.magnitudes[2].mag = 1.3
    test_event.magnitudes[2].magnitude_type = 'Ms'
    test_event.magnitudes[2].creation_info = CreationInfo('TES')
    test_event.magnitudes[2].origin_id = test_event.origins[0].resource_id

    # Define the test pick
    _waveform_id_1 = WaveformStreamID(station_code='FOZ', channel_code='SHZ',
                                      network_code='NZ')
    _waveform_id_2 = WaveformStreamID(station_code='WTSZ', channel_code='BH1',
                                      network_code=' ')
    # Pick to associate with amplitude - 0
    test_event.picks = [
        Pick(waveform_id=_waveform_id_1, phase_hint='IAML',
             polarity='undecidable', time=UTCDateTime("2012-03-26") + 1.68,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_1, onset='impulsive', phase_hint='PN',
             polarity='positive', time=UTCDateTime("2012-03-26") + 1.68,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_1, phase_hint='IAML',
             polarity='undecidable', time=UTCDateTime("2012-03-26") + 1.68,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_2, onset='impulsive', phase_hint='SG',
             polarity='undecidable', time=UTCDateTime("2012-03-26") + 1.72,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_2, onset='impulsive', phase_hint='PN',
             polarity='undecidable', time=UTCDateTime("2012-03-26") + 1.62,
             evaluation_mode="automatic")]
    # Test a generic local magnitude amplitude pick
    test_event.amplitudes = [
        Amplitude(generic_amplitude=2.0, period=0.4,
                  pick_id=test_event.picks[0].resource_id,
                  waveform_id=test_event.picks[0].waveform_id, unit='m',
                  magnitude_hint='ML', category='point', type='AML'),
        Amplitude(generic_amplitude=10,
                  pick_id=test_event.picks[1].resource_id,
                  waveform_id=test_event.picks[1].waveform_id, type='END',
                  category='duration', unit='s', magnitude_hint='Mc',
                  snr=2.3),
        Amplitude(generic_amplitude=5.0, period=0.6,
                  pick_id=test_event.picks[2].resource_id,
                  waveform_id=test_event.picks[0].waveform_id, unit='m',
                  category='point', type='AML')]
    test_event.origins[0].arrivals = [
        Arrival(time_weight=0, phase=test_event.picks[1].phase_hint,
                pick_id=test_event.picks[1].resource_id),
        Arrival(time_weight=2, phase=test_event.picks[3].phase_hint,
                pick_id=test_event.picks[3].resource_id,
                backazimuth_residual=5, time_residual=0.2, distance=15,
                azimuth=25),
        Arrival(time_weight=2, phase=test_event.picks[4].phase_hint,
                pick_id=test_event.picks[4].resource_id,
                backazimuth_residual=5, time_residual=0.2, distance=15,
                azimuth=25)]
    return test_event
Exemple #7
0
def full_test_event():
    """
    Function to generate a basic, full test event
    """
    test_event = Event()
    test_event.origins.append(Origin(
        time=UTCDateTime("2012-03-26") + 1.2, latitude=45.0, longitude=25.0,
        depth=15000))
    test_event.event_descriptions.append(EventDescription())
    test_event.event_descriptions[0].text = 'LE'
    test_event.creation_info = CreationInfo(agency_id='TES')
    test_event.magnitudes.append(Magnitude(
        mag=0.1, magnitude_type='ML', creation_info=CreationInfo('TES'),
        origin_id=test_event.origins[0].resource_id))
    test_event.magnitudes.append(Magnitude(
        mag=0.5, magnitude_type='Mc', creation_info=CreationInfo('TES'),
        origin_id=test_event.origins[0].resource_id))
    test_event.magnitudes.append(Magnitude(
        mag=1.3, magnitude_type='Ms', creation_info=CreationInfo('TES'),
        origin_id=test_event.origins[0].resource_id))

    # Define the test pick
    _waveform_id_1 = WaveformStreamID(station_code='FOZ', channel_code='SHZ',
                                      network_code='NZ')
    _waveform_id_2 = WaveformStreamID(station_code='WTSZ', channel_code='BH1',
                                      network_code=' ')
    # Pick to associate with amplitude - 0
    test_event.picks = [
        Pick(waveform_id=_waveform_id_1, phase_hint='IAML',
             polarity='undecidable', time=UTCDateTime("2012-03-26") + 1.68,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_1, onset='impulsive', phase_hint='PN',
             polarity='positive', time=UTCDateTime("2012-03-26") + 1.68,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_1, phase_hint='IAML',
             polarity='undecidable', time=UTCDateTime("2012-03-26") + 1.68,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_2, onset='impulsive', phase_hint='SG',
             polarity='undecidable', time=UTCDateTime("2012-03-26") + 1.72,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_2, onset='impulsive', phase_hint='PN',
             polarity='undecidable', time=UTCDateTime("2012-03-26") + 1.62,
             evaluation_mode="automatic")]
    # Test a generic local magnitude amplitude pick
    test_event.amplitudes = [
        Amplitude(generic_amplitude=2.0, period=0.4,
                  pick_id=test_event.picks[0].resource_id,
                  waveform_id=test_event.picks[0].waveform_id, unit='m',
                  magnitude_hint='ML', category='point', type='AML'),
        Amplitude(generic_amplitude=10,
                  pick_id=test_event.picks[1].resource_id,
                  waveform_id=test_event.picks[1].waveform_id, type='END',
                  category='duration', unit='s', magnitude_hint='Mc',
                  snr=2.3),
        Amplitude(generic_amplitude=5.0, period=0.6,
                  pick_id=test_event.picks[2].resource_id,
                  waveform_id=test_event.picks[0].waveform_id, unit='m',
                  category='point', type='AML')]
    test_event.origins[0].arrivals = [
        Arrival(time_weight=0, phase=test_event.picks[1].phase_hint,
                pick_id=test_event.picks[1].resource_id),
        Arrival(time_weight=2, phase=test_event.picks[3].phase_hint,
                pick_id=test_event.picks[3].resource_id,
                backazimuth_residual=5, time_residual=0.2, distance=15,
                azimuth=25),
        Arrival(time_weight=2, phase=test_event.picks[4].phase_hint,
                pick_id=test_event.picks[4].resource_id,
                backazimuth_residual=5, time_residual=0.2, distance=15,
                azimuth=25)]
    # Add in error info (line E)
    test_event.origins[0].quality = OriginQuality(
        standard_error=0.01, azimuthal_gap=36)
    # Origin uncertainty in Seisan is output as long-lat-depth, quakeML has
    # semi-major and semi-minor
    test_event.origins[0].origin_uncertainty = OriginUncertainty(
        confidence_ellipsoid=ConfidenceEllipsoid(
            semi_major_axis_length=3000, semi_minor_axis_length=1000,
            semi_intermediate_axis_length=2000, major_axis_plunge=20,
            major_axis_azimuth=100, major_axis_rotation=4))
    test_event.origins[0].time_errors = QuantityError(uncertainty=0.5)
    # Add in fault-plane solution info (line F) - Note have to check program
    # used to determine which fields are filled....
    test_event.focal_mechanisms.append(FocalMechanism(
        nodal_planes=NodalPlanes(nodal_plane_1=NodalPlane(
            strike=180, dip=20, rake=30, strike_errors=QuantityError(10),
            dip_errors=QuantityError(10), rake_errors=QuantityError(20))),
        method_id=ResourceIdentifier("smi:nc.anss.org/focalMechanism/FPFIT"),
        creation_info=CreationInfo(agency_id="NC"), misfit=0.5,
        station_distribution_ratio=0.8))
    # Need to test high-precision origin and that it is preferred origin.
    # Moment tensor includes another origin
    test_event.origins.append(Origin(
        time=UTCDateTime("2012-03-26") + 1.2, latitude=45.1, longitude=25.2,
        depth=14500))
    test_event.magnitudes.append(Magnitude(
        mag=0.1, magnitude_type='MW', creation_info=CreationInfo('TES'),
        origin_id=test_event.origins[-1].resource_id))
    # Moment tensors go with focal-mechanisms
    test_event.focal_mechanisms.append(FocalMechanism(
        moment_tensor=MomentTensor(
            derived_origin_id=test_event.origins[-1].resource_id,
            moment_magnitude_id=test_event.magnitudes[-1].resource_id,
            scalar_moment=100, tensor=Tensor(
                m_rr=100, m_tt=100, m_pp=10, m_rt=1, m_rp=20, m_tp=15),
            method_id=ResourceIdentifier(
                'smi:nc.anss.org/momentTensor/BLAH'))))
    return test_event
Exemple #8
0
def outputOBSPY(hp, event=None, only_fm_picks=False):
    """
    Make an Event which includes the current focal mechanism information from HASH
    
    Use the 'only_fm_picks' flag to only include the picks HASH used for the FocalMechanism.
    This flag will replace the 'picks' and 'arrivals' lists of existing events with new ones.
    
    Inputs
    -------
    hp    : hashpy.HashPype instance
    
    event : obspy.core.event.Event
    
    only_fm_picks : bool of whether to overwrite the picks/arrivals lists
    
    
    Returns
    -------
    obspy.core.event.Event
    
    Event will be new if no event was input, FocalMech added to existing event
    """
    # Returns new (or updates existing) Event with HASH solution
    n = hp.npol
    if event is None:
        event = Event(focal_mechanisms=[], picks=[], origins=[])
        origin = Origin(arrivals=[])
        origin.time = UTCDateTime(hp.tstamp)
        origin.latitude = hp.qlat
        origin.longitude = hp.qlon
        origin.depth = hp.qdep
        origin.creation_info = CreationInfo(version=hp.icusp)
        origin.resource_id = ResourceIdentifier('smi:hash/Origin/{0}'.format(
            hp.icusp))
        for _i in range(n):
            p = Pick()
            p.creation_info = CreationInfo(version=hp.arid[_i])
            p.resource_id = ResourceIdentifier('smi:nsl/Pick/{0}'.format(
                p.creation_info.version))
            p.waveform_id = WaveformStreamID(network_code=hp.snet[_i],
                                             station_code=hp.sname[_i],
                                             channel_code=hp.scomp[_i])
            if hp.p_pol[_i] > 0:
                p.polarity = 'positive'
            else:
                p.polarity = 'negative'
            a = Arrival()
            a.creation_info = CreationInfo(version=hp.arid[_i])
            a.resource_id = ResourceIdentifier('smi:nsl/Arrival/{0}'.format(
                p.creation_info.version))
            a.azimuth = hp.p_azi_mc[_i, 0]
            a.takeoff_angle = 180. - hp.p_the_mc[_i, 0]
            a.pick_id = p.resource_id
            origin.arrivals.append(a)
            event.picks.append(p)
        event.origins.append(origin)
        event.preferred_origin_id = origin.resource_id.resource_id
    else:  # just update the changes
        origin = event.preferred_origin()
        picks = []
        arrivals = []
        for _i in range(n):
            ind = hp.p_index[_i]
            a = origin.arrivals[ind]
            p = a.pick_id.getReferredObject()
            a.takeoff_angle = hp.p_the_mc[_i, 0]
            picks.append(p)
            arrivals.append(a)
        if only_fm_picks:
            origin.arrivals = arrivals
            event.picks = picks
    # Use me double couple calculator and populate planes/axes etc
    x = hp._best_quality_index
    # Put all the mechanisms into the 'focal_mechanisms' list, mark "best" as preferred
    for s in range(hp.nmult):
        dc = DoubleCouple([hp.str_avg[s], hp.dip_avg[s], hp.rak_avg[s]])
        ax = dc.axis
        focal_mech = FocalMechanism()
        focal_mech.creation_info = CreationInfo(creation_time=UTCDateTime(),
                                                author=hp.author)
        focal_mech.triggering_origin_id = origin.resource_id
        focal_mech.resource_id = ResourceIdentifier(
            'smi:hash/FocalMechanism/{0}/{1}'.format(hp.icusp, s + 1))
        focal_mech.method_id = ResourceIdentifier('HASH')
        focal_mech.nodal_planes = NodalPlanes()
        focal_mech.nodal_planes.nodal_plane_1 = NodalPlane(*dc.plane1)
        focal_mech.nodal_planes.nodal_plane_2 = NodalPlane(*dc.plane2)
        focal_mech.principal_axes = PrincipalAxes()
        focal_mech.principal_axes.t_axis = Axis(azimuth=ax['T']['azimuth'],
                                                plunge=ax['T']['dip'])
        focal_mech.principal_axes.p_axis = Axis(azimuth=ax['P']['azimuth'],
                                                plunge=ax['P']['dip'])
        focal_mech.station_polarity_count = n
        focal_mech.azimuthal_gap = hp.magap
        focal_mech.misfit = hp.mfrac[s]
        focal_mech.station_distribution_ratio = hp.stdr[s]
        focal_mech.comments.append(
            Comment(
                hp.qual[s],
                resource_id=ResourceIdentifier(
                    focal_mech.resource_id.resource_id + '/comment/quality')))
        #----------------------------------------
        event.focal_mechanisms.append(focal_mech)
        if s == x:
            event.preferred_focal_mechanism_id = focal_mech.resource_id.resource_id
    return event
Exemple #9
0
def stalta_pick(stream,
                stalen,
                ltalen,
                trig_on,
                trig_off,
                freqmin=False,
                freqmax=False,
                debug=0,
                show=False):
    """
    Basic sta/lta picker, suggest using alternative in obspy.
    Simple sta-lta (short-term average/long-term average) picker, using \
    obspy's stalta routine to generate the characteristic function.

    Currently very basic quick wrapper, there are many other (better) options \
    in obspy, found \
    `here <http://docs.obspy.org/packages/autogen/obspy.signal.trigger.html>`_.

    :type stream: obspy.Stream
    :param stream: The stream to pick on, can be any number of channels.
    :type stalen: float
    :param stalen: Length of the short-term average window in seconds.
    :type ltalen: float
    :param ltalen: Length of the long-term average window in seconds.
    :type trig_on: float
    :param trig_on: sta/lta ratio to trigger a detection/pick
    :type trig_off: float
    :param trig_off: sta/lta ratio to turn the trigger off - no further picks\
        will be made between exceeding trig_on until trig_off is reached.
    :type freqmin: float
    :param freqmin: Low-cut frequency in Hz for bandpass filter
    :type freqmax: float
    :param freqmax: High-cut frequency in Hz for bandpass filter
    :type debug: int
    :param debug: Debug output level from 0-5.
    :type show: bool
    :param show: Show picks on waveform.

    :returns: obspy.core.event.Event

    .. rubric:: Example

    >>> from obspy import read
    >>> from eqcorrscan.utils.picker import stalta_pick
    >>> st = read()
    >>> event = stalta_pick(st, stalen=0.2, ltalen=4, trig_on=10,
    ...             trig_off=1, freqmin=3.0, freqmax=20.0)
    >>> event.creation_info.author
    'EQcorrscan'
    """
    from obspy.signal.trigger import classic_sta_lta, trigger_onset
    from obspy.signal.trigger import plot_trigger
    from obspy import UTCDateTime
    from obspy.core.event import Event, Pick, WaveformStreamID
    from obspy.core.event import CreationInfo, Comment, Origin
    import eqcorrscan.utils.plotting as plotting

    event = Event()
    event.origins.append(Origin())
    event.creation_info = CreationInfo(author='EQcorrscan',
                                       creation_time=UTCDateTime())
    event.comments.append(Comment(text='stalta'))
    picks = []
    for tr in stream:
        # We are going to assume, for now, that if the pick is made on the
        # horizontal channel then it is an S, otherwise we will assume it is
        # a P-phase: obviously a bad assumption...
        if tr.stats.channel[-1] == 'Z':
            phase = 'P'
        else:
            phase = 'S'
        if freqmin and freqmax:
            tr.detrend('simple')
            tr.filter('bandpass',
                      freqmin=freqmin,
                      freqmax=freqmax,
                      corners=3,
                      zerophase=True)
        df = tr.stats.sampling_rate
        cft = classic_sta_lta(tr.data, int(stalen * df), int(ltalen * df))
        if debug > 3:
            plot_trigger(tr, cft, trig_on, trig_off)
        triggers = trigger_onset(cft, trig_on, trig_off)
        for trigger in triggers:
            on = tr.stats.starttime + (trigger[0] / df)
            # off = tr.stats.starttime + (trigger[1] / df)
            wav_id = WaveformStreamID(station_code=tr.stats.station,
                                      channel_code=tr.stats.channel,
                                      network_code=tr.stats.network)
            pick = Pick(waveform_id=wav_id, phase_hint=phase, time=on)
            if debug > 2:
                print('Pick made:')
                print(pick)
            picks.append(pick)
    # QC picks
    del pick
    pick_stations = list(set([pick.waveform_id.station_code
                              for pick in picks]))
    for pick_station in pick_stations:
        station_picks = [
            pick for pick in picks
            if pick.waveform_id.station_code == pick_station
        ]
        # If P-pick is after S-picks, remove it.
        p_time = [
            pick.time for pick in station_picks if pick.phase_hint == 'P'
        ]
        s_time = [
            pick.time for pick in station_picks if pick.phase_hint == 'S'
        ]
        if p_time > s_time:
            p_pick = [pick for pick in station_picks if pick.phase_hint == 'P']
            for pick in p_pick:
                print('P pick after S pick, removing P pick')
                picks.remove(pick)
    if show:
        plotting.pretty_template_plot(stream,
                                      picks=picks,
                                      title='Autopicks',
                                      size=(8, 9))
    event.picks = picks
    event.origins[0].time = min([pick.time for pick in event.picks]) - 1
    event.origins[0].latitude = float('nan')
    event.origins[0].longitude = float('nan')
    # Set arbitrary origin time
    return event
Exemple #10
0
def plot_detection(grid,
                   receivers,
                   frames,
                   tmin_frames,
                   deltat_cf,
                   imax,
                   iframe,
                   xpeak,
                   ypeak,
                   zpeak,
                   tr_stackmax,
                   tpeaks,
                   apeaks,
                   detector_threshold,
                   wmin,
                   wmax,
                   pdata,
                   trs_raw,
                   fmin,
                   fmax,
                   idetection,
                   tpeaksearch,
                   movie=False,
                   save_filename=None,
                   show=True,
                   event=None):
    from matplotlib import pyplot as plt
    from matplotlib import cm
    from matplotlib.animation import FuncAnimation

    nsls = set(tr.nslc_id[:3] for tr in trs_raw)
    receivers_on = [r for r in receivers if r.codes in nsls]
    receivers_off = [r for r in receivers if r.codes not in nsls]

    distances = grid.distances(receivers)

    plot.mpl_init(fontsize=9)

    fig = plt.figure(figsize=plot.mpl_papersize('a4', 'landscape'))

    axes = plt.subplot2grid((2, 3), (0, 2), aspect=1.0)
    plot.mpl_labelspace(axes)

    axes2 = plt.subplot2grid((2, 3), (1, 2))
    plot.mpl_labelspace(axes2)

    axes3 = plt.subplot2grid((2, 3), (0, 1), rowspan=2)
    axes4 = plt.subplot2grid((2, 3), (0, 0), rowspan=2)
    if grid.distance_max() > km:
        dist_units = km
        axes.set_xlabel('Easting [km]')
        axes.set_ylabel('Northing [km]')
        axes4.set_ylabel('Distance [km]')
    else:
        dist_units = 1.0
        axes.set_xlabel('Easting [m]')
        axes.set_ylabel('Northing [m]')
        axes4.set_ylabel('Distance [m]')

    axes.locator_params(nbins=6, tight=True)

    axes2.set_xlabel('Time [s]')
    axes2.set_ylabel('Detector level')

    axes3.set_xlabel('Time [s]')
    for el in axes3.get_yticklabels():
        el.set_visible(False)

    axes4.set_xlabel('Time [s]')

    tpeak_current = tmin_frames + deltat_cf * iframe
    t0 = tpeak_current
    tduration = 2.0 * tpeaksearch

    axes2.axvspan(tr_stackmax.tmin - t0,
                  wmin - t0,
                  color=plot.mpl_color('aluminium2'))

    axes2.axvspan(wmax - t0,
                  tr_stackmax.tmax - t0,
                  color=plot.mpl_color('aluminium2'))

    axes2.axvspan(tpeak_current - 0.5 * tduration - t0,
                  tpeak_current + 0.5 * tduration - t0,
                  color=plot.mpl_color('scarletred2'),
                  alpha=0.3,
                  lw=0.)

    axes2.set_xlim(tr_stackmax.tmin - t0, tr_stackmax.tmax - t0)

    axes2.axhline(detector_threshold,
                  color=plot.mpl_color('aluminium6'),
                  lw=2.)

    t = tr_stackmax.get_xdata()
    amp = tr_stackmax.get_ydata()
    axes2.plot(t - t0, amp, color=plot.mpl_color('scarletred2'), lw=1.)

    for tpeak, apeak in zip(tpeaks, apeaks):
        axes2.plot(tpeak - t0, apeak, '*', ms=20., mfc='white', mec='black')

    station_index = dict((rec.codes, i) for (i, rec) in enumerate(receivers))

    dists_all = []
    amps = []
    shifts = []
    pdata2 = []
    for trs, shift_table, shifter in pdata:
        trs = [tr.copy() for tr in trs]
        dists = []
        for tr in trs:
            istation = station_index[tr.nslc_id[:3]]
            shift = shift_table[imax, istation]
            tr2 = tr.chop(tpeak_current - 0.5 * tduration + shift,
                          tpeak_current + 0.5 * tduration + shift,
                          inplace=False)

            dists.append(distances[imax, istation])
            amp = tr2.get_ydata() * shifter.weight
            amps.append(num.max(num.abs(amp)))
            shifts.append(shift)

        pdata2.append((trs, dists, shift_table, shifter))
        dists_all.extend(dists)

    dist_min = min(dists_all)
    dist_max = max(dists_all)

    shift_min = min(shifts)
    shift_max = max(shifts)

    amp_max = max(amps)

    scalefactor = (dist_max - dist_min) / len(trs) * 0.5

    axes3.set_xlim(-0.5 * tduration + shift_min, 0.5 * tduration + shift_max)
    axes3.set_ylim((dist_min - scalefactor) / dist_units,
                   (dist_max + scalefactor) / dist_units)

    axes4.set_xlim(-0.5 * tduration + shift_min, 0.5 * tduration + shift_max)
    axes4.set_ylim((dist_min - scalefactor) / dist_units,
                   (dist_max + scalefactor) / dist_units)

    axes3.axvline(0., color=plot.mpl_color('aluminium3'), lw=2.)

    nsl_have = set()
    phase_markers = []
    picks = []
    for ishifter, (trs, dists, shift_table, shifter) in enumerate(pdata2):
        color = plot.mpl_graph_color(ishifter)

        for tr, dist in zip(trs, dists):
            tmint = tr.tmin
            tr = tr.chop(tpeak_current - 0.5 * tduration + shift_min,
                         tpeak_current + 0.5 * tduration + shift_max,
                         inplace=False)

            nsl = tr.nslc_id[:3]
            istation = station_index[nsl]
            shift = shift_table[imax, istation]

            phase_markers.append(
                PhaseMarker([(nsl[0], nsl[1], "", nsl[2])],
                            tmin=tmint + shift,
                            tmax=tmint + shift,
                            phasename=shifter.name,
                            event_time=t0,
                            event_hash=idetection))
            p = Pick(time=UTCDateTime(tmint + shift),
                     waveform_id=WaveformStreamID(network_code=nsl[0],
                                                  station_code=nsl[1]),
                     phase_hint=shifter.name,
                     method_id="lassie")
            picks.append(p)
            axes3.plot(shift,
                       dist / dist_units,
                       '|',
                       mew=2,
                       mec=color,
                       ms=10,
                       zorder=2)

            t = tr.get_xdata()
            amp = tr.get_ydata() * shifter.weight
            amp /= amp_max
            axes3.plot(
                t - t0,
                (dist + scalefactor * amp + ishifter * scalefactor * 0.1) /
                dist_units,
                color=color,
                zorder=1)

            if nsl not in nsl_have:
                axes3.annotate('.'.join(nsl),
                               xy=(t[0] - t0, dist / dist_units),
                               xytext=(10., 0.),
                               textcoords='offset points',
                               verticalalignment='top')

                nsl_have.add(nsl)

        for tr in trs_raw:
            istation = station_index[tr.nslc_id[:3]]
            dist = distances[imax, istation]
            shift = shift_table[imax, istation]

            tr = tr.copy()

            tr.highpass(4, fmin, demean=True)
            tr.lowpass(4, fmax, demean=False)

            tr.chop(tpeak_current - 0.5 * tduration + shift_min,
                    tpeak_current + 0.5 * tduration + shift_max)

            t = tr.get_xdata()
            amp = tr.get_ydata().astype(num.float)
            amp = amp / num.max(num.abs(amp))

            axes4.plot(t - t0, (dist + scalefactor * amp) / dist_units,
                       color='black',
                       alpha=0.5,
                       zorder=1)

            axes4.plot(shift,
                       dist / dist_units,
                       '|',
                       mew=2,
                       mec=color,
                       ms=10,
                       zorder=2)
    PhaseMarker.save_markers(phase_markers,
                             "%s.pym" % (save_filename[:-4]),
                             fdigits=3)
    event_obspy = Event()
    origin = Origin(time=UTCDateTime(t0),
                    longitude=event.lon,
                    latitude=event.lat,
                    method="lassie")
    event_obspy.origins.append(origin)
    event_obspy.picks = picks
    cat = Catalog()
    cat.append(event_obspy)
    cat.write(save_filename[:-4] + ".qml", format="QUAKEML")
    nframes = frames.shape[1]

    iframe_min = max(0, int(round(iframe - 0.5 * tduration / deltat_cf)))
    iframe_max = min(nframes - 1,
                     int(round(iframe + 0.5 * tduration / deltat_cf)))

    amax = frames[imax, iframe]

    axes.set_xlim(grid.ymin / dist_units, grid.ymax / dist_units)
    axes.set_ylim(grid.xmin / dist_units, grid.xmax / dist_units)

    cmap = cm.YlOrBr
    system = ('ne', grid.lat, grid.lon)

    static_artists = []
    static_artists.extend(
        plot_receivers(axes,
                       receivers_on,
                       system=system,
                       units=dist_units,
                       style=dict(mfc='black', ms=5.0)))

    static_artists.extend(
        plot_receivers(axes,
                       receivers_off,
                       system=system,
                       units=dist_units,
                       style=dict(mfc='none', ms=5.0)))

    static_artists.extend(
        axes.plot(ypeak / dist_units,
                  xpeak / dist_units,
                  '*',
                  ms=20.,
                  mec='black',
                  mfc='white'))

    static_artists.append(
        fig.suptitle('%06i - %s' % (idetection, util.time_to_str(t0))))

    frame_artists = []
    progress_artists = []

    def update(iframe):
        if iframe is not None:
            frame = frames[:, iframe]
            if not progress_artists:
                progress_artists[:] = [
                    axes2.axvline(tmin_frames - t0 + deltat_cf * iframe,
                                  color=plot.mpl_color('scarletred3'),
                                  alpha=0.5,
                                  lw=2.)
                ]

            else:
                progress_artists[0].set_xdata(tmin_frames - t0 +
                                              deltat_cf * iframe)

        else:
            frame = num.max(frames[:, iframe_min:iframe_max + 1], axis=1)

        frame_artists[:] = grid.plot(axes,
                                     frame,
                                     amin=0.0,
                                     amax=amax,
                                     cmap=cmap,
                                     system=system,
                                     artists=frame_artists,
                                     units=dist_units,
                                     shading='gouraud')

        return frame_artists + progress_artists + static_artists

    if movie:
        ani = FuncAnimation(
            fig,
            update,
            frames=list(range(iframe_min, iframe_max + 1))[::10] + [None],
            interval=20.,
            repeat=False,
            blit=True)

    else:
        ani = None
        update(None)

    if save_filename:
        fig.savefig(save_filename)

    if show:
        plt.show()
    else:
        plt.close()

    del ani
Exemple #11
0
def outputOBSPY(hp, event=None, only_fm_picks=False):
    """
    Make an Event which includes the current focal mechanism information from HASH
    
    Use the 'only_fm_picks' flag to only include the picks HASH used for the FocalMechanism.
    This flag will replace the 'picks' and 'arrivals' lists of existing events with new ones.
    
    Inputs
    -------
    hp    : hashpy.HashPype instance
    
    event : obspy.core.event.Event
    
    only_fm_picks : bool of whether to overwrite the picks/arrivals lists
    
    
    Returns
    -------
    obspy.core.event.Event
    
    Event will be new if no event was input, FocalMech added to existing event
    """
    # Returns new (or updates existing) Event with HASH solution
    n = hp.npol
    if event is None:
	event = Event(focal_mechanisms=[], picks=[], origins=[])
	origin = Origin(arrivals=[])
	origin.time = UTCDateTime(hp.tstamp)
	origin.latitude = hp.qlat
	origin.longitude = hp.qlon
	origin.depth = hp.qdep
	origin.creation_info = CreationInfo(version=hp.icusp)
	origin.resource_id = ResourceIdentifier('smi:hash/Origin/{0}'.format(hp.icusp))
	for _i in range(n):
	    p = Pick()
	    p.creation_info = CreationInfo(version=hp.arid[_i])
	    p.resource_id = ResourceIdentifier('smi:hash/Pick/{0}'.format(p.creation_info.version))
	    p.waveform_id = WaveformStreamID(network_code=hp.snet[_i], station_code=hp.sname[_i], channel_code=hp.scomp[_i])
	    if hp.p_pol[_i] > 0:
		p.polarity = 'positive'
	    else:
		p.polarity = 'negative'
	    a = Arrival()
	    a.creation_info = CreationInfo(version=hp.arid[_i])
	    a.resource_id = ResourceIdentifier('smi:hash/Arrival/{0}'.format(p.creation_info.version))
	    a.azimuth = hp.p_azi_mc[_i,0]
	    a.takeoff_angle = 180. - hp.p_the_mc[_i,0]
	    a.pick_id = p.resource_id
	    origin.arrivals.append(a)
	    event.picks.append(p)
	event.origins.append(origin)
	event.preferred_origin_id = str(origin.resource_id)
    else: # just update the changes
	origin = event.preferred_origin()
	picks = []
	arrivals = []
	for _i in range(n):
	    ind = hp.p_index[_i]
	    a = origin.arrivals[ind]
	    p = a.pick_id.getReferredObject()
	    a.takeoff_angle = hp.p_the_mc[_i,0]
	    picks.append(p)
	    arrivals.append(a)
	if only_fm_picks:
	    origin.arrivals = arrivals
	    event.picks = picks
    # Use me double couple calculator and populate planes/axes etc
    x = hp._best_quality_index
    # Put all the mechanisms into the 'focal_mechanisms' list, mark "best" as preferred
    for s in range(hp.nmult):
        dc = DoubleCouple([hp.str_avg[s], hp.dip_avg[s], hp.rak_avg[s]])
        ax = dc.axis
        focal_mech = FocalMechanism()
        focal_mech.creation_info = CreationInfo(creation_time=UTCDateTime(), author=hp.author)
        focal_mech.triggering_origin_id = origin.resource_id
        focal_mech.resource_id = ResourceIdentifier('smi:hash/FocalMechanism/{0}/{1}'.format(hp.icusp, s+1))
        focal_mech.method_id = ResourceIdentifier('HASH')
        focal_mech.nodal_planes = NodalPlanes()
        focal_mech.nodal_planes.nodal_plane_1 = NodalPlane(*dc.plane1)
        focal_mech.nodal_planes.nodal_plane_2 = NodalPlane(*dc.plane2)
        focal_mech.principal_axes = PrincipalAxes()
        focal_mech.principal_axes.t_axis = Axis(azimuth=ax['T']['azimuth'], plunge=ax['T']['dip'])
        focal_mech.principal_axes.p_axis = Axis(azimuth=ax['P']['azimuth'], plunge=ax['P']['dip'])
        focal_mech.station_polarity_count = n
        focal_mech.azimuthal_gap = hp.magap
        focal_mech.misfit = hp.mfrac[s]
        focal_mech.station_distribution_ratio = hp.stdr[s]
        focal_mech.comments.append(
            Comment(hp.qual[s], resource_id=ResourceIdentifier(str(focal_mech.resource_id) + '/comment/quality'))
            )
        #----------------------------------------
        event.focal_mechanisms.append(focal_mech)
        if s == x:
            event.preferred_focal_mechanism_id = str(focal_mech.resource_id)
    return event
Exemple #12
0
def stalta_pick(stream, stalen, ltalen, trig_on, trig_off, freqmin=False,
                freqmax=False, debug=0, show=False):
    """
    Basic sta/lta picker, suggest using alternative in obspy.
    Simple sta-lta (short-term average/long-term average) picker, using \
    obspy's stalta routine to generate the characteristic function.

    Currently very basic quick wrapper, there are many other (better) options \
    in obspy, found \
    `here <http://docs.obspy.org/packages/autogen/obspy.signal.trigger.html>`_.

    :type stream: obspy.Stream
    :param stream: The stream to pick on, can be any number of channels.
    :type stalen: float
    :param stalen: Length of the short-term average window in seconds.
    :type ltalen: float
    :param ltalen: Length of the long-term average window in seconds.
    :type trig_on: float
    :param trig_on: sta/lta ratio to trigger a detection/pick
    :type trig_off: float
    :param trig_off: sta/lta ratio to turn the trigger off - no further picks\
        will be made between exceeding trig_on until trig_off is reached.
    :type freqmin: float
    :param freqmin: Low-cut frequency in Hz for bandpass filter
    :type freqmax: float
    :param freqmax: High-cut frequency in Hz for bandpass filter
    :type debug: int
    :param debug: Debug output level from 0-5.
    :type show: bool
    :param show: Show picks on waveform.

    :returns: obspy.core.event.Event

    .. rubric:: Example

    >>> from obspy import read
    >>> from eqcorrscan.utils.picker import stalta_pick
    >>> st = read()
    >>> event = stalta_pick(st, stalen=0.2, ltalen=4, trig_on=10,
    ...             trig_off=1, freqmin=3.0, freqmax=20.0)
    >>> event.creation_info.author
    'EQcorrscan'
    """
    from obspy.signal.trigger import classic_sta_lta, trigger_onset
    from obspy.signal.trigger import plot_trigger
    from obspy import UTCDateTime
    from obspy.core.event import Event, Pick, WaveformStreamID
    from obspy.core.event import CreationInfo, Comment, Origin
    import eqcorrscan.utils.plotting as plotting

    event = Event()
    event.origins.append(Origin())
    event.creation_info = CreationInfo(author='EQcorrscan',
                                       creation_time=UTCDateTime())
    event.comments.append(Comment(text='stalta'))
    picks = []
    for tr in stream:
        # We are going to assume, for now, that if the pick is made on the
        # horizontal channel then it is an S, otherwise we will assume it is
        # a P-phase: obviously a bad assumption...
        if tr.stats.channel[-1] == 'Z':
            phase = 'P'
        else:
            phase = 'S'
        if freqmin and freqmax:
            tr.detrend('simple')
            tr.filter('bandpass', freqmin=freqmin, freqmax=freqmax,
                      corners=3, zerophase=True)
        df = tr.stats.sampling_rate
        cft = classic_sta_lta(tr.data, int(stalen * df), int(ltalen * df))
        if debug > 3:
            plot_trigger(tr, cft, trig_on, trig_off)
        triggers = trigger_onset(cft, trig_on, trig_off)
        for trigger in triggers:
            on = tr.stats.starttime + (trigger[0] / df)
            # off = tr.stats.starttime + (trigger[1] / df)
            wav_id = WaveformStreamID(station_code=tr.stats.station,
                                      channel_code=tr.stats.channel,
                                      network_code=tr.stats.network)
            pick = Pick(waveform_id=wav_id, phase_hint=phase, time=on)
            if debug > 2:
                print('Pick made:')
                print(pick)
            picks.append(pick)
    # QC picks
    del pick
    pick_stations = list(set([pick.waveform_id.station_code for pick in picks]))
    for pick_station in pick_stations:
        station_picks = [pick for pick in picks if
                         pick.waveform_id.station_code == pick_station]
        # If P-pick is after S-picks, remove it.
        p_time = [pick.time for pick in station_picks if pick.phase_hint == 'P']
        s_time = [pick.time for pick in station_picks if pick.phase_hint == 'S']
        if p_time > s_time:
            p_pick = [pick for pick in station_picks if pick.phase_hint == 'P']
            for pick in p_pick:
                print('P pick after S pick, removing P pick')
                picks.remove(pick)
    if show:
        plotting.pretty_template_plot(stream, picks=picks, title='Autopicks',
                                      size=(8, 9))
    event.picks = picks
    event.origins[0].time = min([pick.time for pick in event.picks]) - 1
    event.origins[0].latitude = float('nan')
    event.origins[0].longitude = float('nan')
    # Set arbitrary origin time
    return event
Exemple #13
0
def full_test_event():
    """
    Function to generate a basic, full test event
    """
    test_event = Event()
    test_event.origins.append(
        Origin(time=UTCDateTime("2012-03-26") + 1.2,
               latitude=45.0,
               longitude=25.0,
               depth=15000))
    test_event.event_descriptions.append(EventDescription())
    test_event.event_descriptions[0].text = 'LE'
    test_event.creation_info = CreationInfo(agency_id='TES')
    test_event.magnitudes.append(
        Magnitude(mag=0.1,
                  magnitude_type='ML',
                  creation_info=CreationInfo('TES'),
                  origin_id=test_event.origins[0].resource_id))
    test_event.magnitudes.append(
        Magnitude(mag=0.5,
                  magnitude_type='Mc',
                  creation_info=CreationInfo('TES'),
                  origin_id=test_event.origins[0].resource_id))
    test_event.magnitudes.append(
        Magnitude(mag=1.3,
                  magnitude_type='Ms',
                  creation_info=CreationInfo('TES'),
                  origin_id=test_event.origins[0].resource_id))

    # Define the test pick
    _waveform_id_1 = WaveformStreamID(station_code='FOZ',
                                      channel_code='SHZ',
                                      network_code='NZ')
    _waveform_id_2 = WaveformStreamID(station_code='WTSZ',
                                      channel_code='BH1',
                                      network_code=' ')
    # Pick to associate with amplitude - 0
    test_event.picks = [
        Pick(waveform_id=_waveform_id_1,
             phase_hint='IAML',
             polarity='undecidable',
             time=UTCDateTime("2012-03-26") + 1.68,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_1,
             onset='impulsive',
             phase_hint='PN',
             polarity='positive',
             time=UTCDateTime("2012-03-26") + 1.68,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_1,
             phase_hint='IAML',
             polarity='undecidable',
             time=UTCDateTime("2012-03-26") + 1.68,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_2,
             onset='impulsive',
             phase_hint='SG',
             polarity='undecidable',
             time=UTCDateTime("2012-03-26") + 1.72,
             evaluation_mode="manual"),
        Pick(waveform_id=_waveform_id_2,
             onset='impulsive',
             phase_hint='PN',
             polarity='undecidable',
             time=UTCDateTime("2012-03-26") + 1.62,
             evaluation_mode="automatic")
    ]
    # Test a generic local magnitude amplitude pick
    test_event.amplitudes = [
        Amplitude(generic_amplitude=2.0,
                  period=0.4,
                  pick_id=test_event.picks[0].resource_id,
                  waveform_id=test_event.picks[0].waveform_id,
                  unit='m',
                  magnitude_hint='ML',
                  category='point',
                  type='AML'),
        Amplitude(generic_amplitude=10,
                  pick_id=test_event.picks[1].resource_id,
                  waveform_id=test_event.picks[1].waveform_id,
                  type='END',
                  category='duration',
                  unit='s',
                  magnitude_hint='Mc',
                  snr=2.3),
        Amplitude(generic_amplitude=5.0,
                  period=0.6,
                  pick_id=test_event.picks[2].resource_id,
                  waveform_id=test_event.picks[0].waveform_id,
                  unit='m',
                  category='point',
                  type='AML')
    ]
    test_event.origins[0].arrivals = [
        Arrival(time_weight=0,
                phase=test_event.picks[1].phase_hint,
                pick_id=test_event.picks[1].resource_id),
        Arrival(time_weight=2,
                phase=test_event.picks[3].phase_hint,
                pick_id=test_event.picks[3].resource_id,
                backazimuth_residual=5,
                time_residual=0.2,
                distance=15,
                azimuth=25),
        Arrival(time_weight=2,
                phase=test_event.picks[4].phase_hint,
                pick_id=test_event.picks[4].resource_id,
                backazimuth_residual=5,
                time_residual=0.2,
                distance=15,
                azimuth=25)
    ]
    # Add in error info (line E)
    test_event.origins[0].quality = OriginQuality(standard_error=0.01,
                                                  azimuthal_gap=36)
    # Origin uncertainty in Seisan is output as long-lat-depth, quakeML has
    # semi-major and semi-minor
    test_event.origins[0].origin_uncertainty = OriginUncertainty(
        confidence_ellipsoid=ConfidenceEllipsoid(
            semi_major_axis_length=3000,
            semi_minor_axis_length=1000,
            semi_intermediate_axis_length=2000,
            major_axis_plunge=20,
            major_axis_azimuth=100,
            major_axis_rotation=4))
    test_event.origins[0].time_errors = QuantityError(uncertainty=0.5)
    # Add in fault-plane solution info (line F) - Note have to check program
    # used to determine which fields are filled....
    test_event.focal_mechanisms.append(
        FocalMechanism(nodal_planes=NodalPlanes(
            nodal_plane_1=NodalPlane(strike=180,
                                     dip=20,
                                     rake=30,
                                     strike_errors=QuantityError(10),
                                     dip_errors=QuantityError(10),
                                     rake_errors=QuantityError(20))),
                       method_id=ResourceIdentifier(
                           "smi:nc.anss.org/focalMechanism/FPFIT"),
                       creation_info=CreationInfo(agency_id="NC"),
                       misfit=0.5,
                       station_distribution_ratio=0.8))
    # Need to test high-precision origin and that it is preferred origin.
    # Moment tensor includes another origin
    test_event.origins.append(
        Origin(time=UTCDateTime("2012-03-26") + 1.2,
               latitude=45.1,
               longitude=25.2,
               depth=14500))
    test_event.magnitudes.append(
        Magnitude(mag=0.1,
                  magnitude_type='MW',
                  creation_info=CreationInfo('TES'),
                  origin_id=test_event.origins[-1].resource_id))
    # Moment tensors go with focal-mechanisms
    test_event.focal_mechanisms.append(
        FocalMechanism(moment_tensor=MomentTensor(
            derived_origin_id=test_event.origins[-1].resource_id,
            moment_magnitude_id=test_event.magnitudes[-1].resource_id,
            scalar_moment=100,
            tensor=Tensor(
                m_rr=100, m_tt=100, m_pp=10, m_rt=1, m_rp=20, m_tp=15),
            method_id=ResourceIdentifier(
                'smi:nc.anss.org/momentTensor/BLAH'))))
    return test_event
Exemple #14
0
def setEventData(eventParser, arrivals, count):
    global originCount
    global eventCount
    global pickCount
    creation_info = CreationInfo(
        author='niket_engdahl_parser',
        creation_time=UTCDateTime(),
        agency_uri=ResourceIdentifier(id='smi:engdahl.ga.gov.au/ga-engdahl'),
        agency_id='ga-engdahl')

    #   magnitudeSurface = Magnitude(resource_id=ResourceIdentifier(id='smi:engdahl.ga.gov.au/origin/'+str(originCount)+'#netMag.Ms'),
    #                         mag=eventParser.ms,
    #                         magnitude_type='Ms',
    #                         origin_id=ResourceIdentifier(id='smi:engdahl.ga.gov.au/origin/'+str(originCount)),
    #                         azimuthal_gap=eventParser.openaz2,
    #                         creation_info=creation_info)
    origin = Origin(
        resource_id=ResourceIdentifier(id='smi:engdahl.ga.gov.au/origin/' +
                                       str(originCount)),
        time=UTCDateTime(int(str(2000 + int(eventParser.iyr))),
                         int(eventParser.mon), int(eventParser.iday),
                         int(eventParser.ihr), int(eventParser.min),
                         int(eventParser.sec.split('.')[0]),
                         int(eventParser.sec.split('.')[1] + '0')),
        longitude=eventParser.glon,
        latitude=eventParser.glat,
        depth=float(eventParser.depth) *
        1000,  # engdahl files report kms, obspy expects m
        depth_errors=eventParser.sedep,
        method_id=ResourceIdentifier(id='EHB'),
        earth_model_id=ResourceIdentifier(id='ak135'),
        quality=OriginQuality(associated_phase_count=len(arrivals),
                              used_phase_count=len(arrivals),
                              standard_error=eventParser.se,
                              azimuthal_gap=eventParser.openaz2),
        evaluation_mode='automatic',
        creation_info=creation_info)

    magnitude = Magnitude(
        resource_id=ResourceIdentifier(id='smi:engdahl.ga.gov.au/origin/' +
                                       str(originCount) + '#netMag.Mb'),
        mag=eventParser.mb,
        magnitude_type='Mb',
        origin_id=ResourceIdentifier(id='smi:engdahl.ga.gov.au/origin/' +
                                     str(originCount)),
        azimuthal_gap=eventParser.openaz1,
        creation_info=creation_info)

    originCount += 1

    pickList = []
    arrivalList = []
    pPhaseArrival = None
    for arrParser in arrivals:
        pickOnset = None
        pol = None

        if arrParser.year and arrParser.month and arrParser.day and arrParser.station:
            pPhaseArrival = arrParser
        else:
            arrParser.year = pPhaseArrival.year
            arrParser.day = pPhaseArrival.day
            arrParser.month = pPhaseArrival.month
            arrParser.station = pPhaseArrival.station
            arrParser.delta = pPhaseArrival.delta
            arrParser.dtdd = pPhaseArrival.dtdd
            arrParser.backaz = pPhaseArrival.backaz
            arrParser.focalDip = pPhaseArrival.focalDip
            arrParser.angleAzimuth = pPhaseArrival.angleAzimuth

        if arrParser.phase1 == 'LR' or arrParser.phase2 == 'LR' or arrParser.hour == '24':
            continue

        if arrParser.phase1.startswith('i'):
            pickOnset = PickOnset.impulsive
            if arrParser.fm == '+':
                pol = PickPolarity.positive
            elif arrParser.fm == '-':
                pol = PickPolarity.negative
        elif arrParser.phase1.startswith('e'):
            pickOnset = PickOnset.emergent

        pick = Pick(
            resource_id=ResourceIdentifier(id='smi:engdahl.ga.gov.au/pick/' +
                                           str(pickCount)),
            time=UTCDateTime(int(str(2000 + int(arrParser.year))),
                             int(arrParser.month), int(arrParser.day),
                             int(arrParser.hour), int(arrParser.minute),
                             int(arrParser.second.split('.')[0]),
                             int(arrParser.second.split('.')[1] + '0')),
            waveform_id=WaveformStreamID(network_code='',
                                         station_code=arrParser.station,
                                         channel_code='BHZ'),
            methodID=ResourceIdentifier('STA/LTA'),
            backazimuth=arrParser.backaz if arrParser.backaz else None,
            onset=pickOnset,
            phase_hint=arrParser.phase,
            polarity=pol,
            evaluation_mode='automatic',
            # TO-DO
            comment='populate all the remaining fields here as key value',
            creation_info=creation_info)
        if not arrParser.backaz:
            print "arrParser.backaz is empty. printing the arrParser for debugging"
        pickCount += 1
        pickList.append(pick)

        arrival = Arrival(
            pick_id=ResourceIdentifier(id='smi:engdahl.ga.gov.au/pick/' +
                                       str(pickCount - 1)),
            phase=arrParser.phase if arrParser.phase else None,
            azimuth=arrParser.backaz if arrParser.backaz else None,
            distance=arrParser.delta if arrParser.delta else None,
            # if the * has some significance, it should be accounted for. ignoring for now.
            time_residual=arrParser.residual.rstrip('*'),
            time_weight=arrParser.wgt if arrParser.wgt else None,
            backazimuth_weight=arrParser.wgt if arrParser.wgt else None)
        arrivalList.append(arrival)
        if not arrParser.wgt:
            print "arrParser.wgt is empty. printing the arrParser for debugging"


#          pprint.pprint(arrParser)

    origin.arrivals = arrivalList

    event = Event(resource_id=ResourceIdentifier(
        id='smi:engdahl.ga.gov.au/event/' + str(eventCount)),
                  creation_info=creation_info,
                  event_type='earthquake')

    eventCount += 1

    event.picks = pickList
    event.origins = [
        origin,
    ]
    event.magnitudes = [
        magnitude,
    ]
    event.preferred_origin_id = origin.resource_id
    event.preferred_magnitude_id = magnitude.resource_id
    return event