844 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			844 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/usr/bin/env python
 | 
						|
# -*- coding: utf-8 -*-
 | 
						|
 | 
						|
import glob
 | 
						|
import obspy.core.event as ope
 | 
						|
import os
 | 
						|
import scipy.io as sio
 | 
						|
import warnings
 | 
						|
from obspy.core import UTCDateTime
 | 
						|
 | 
						|
from pylot.core.io.inputs import AutoPickParameter
 | 
						|
from pylot.core.io.location import create_arrival, create_event, \
 | 
						|
    create_magnitude, create_origin, create_pick
 | 
						|
from pylot.core.pick.utils import select_for_phase
 | 
						|
from pylot.core.util.utils import getOwner, full_range, four_digits
 | 
						|
 | 
						|
def add_amplitudes(event, amplitudes):
 | 
						|
    amplitude_list = []
 | 
						|
    for pick in event.picks:
 | 
						|
        try:
 | 
						|
            a0 = amplitudes[pick.waveform_id.station_code]
 | 
						|
            amplitude = ope.Amplitude(generic_amplitude=a0 * 1e-3)
 | 
						|
            amplitude.unit = 'm'
 | 
						|
            amplitude.category = 'point'
 | 
						|
            amplitude.waveform_id = pick.waveform_id
 | 
						|
            amplitude.magnitude_hint = 'ML'
 | 
						|
            amplitude.pick_id = pick.resource_id
 | 
						|
            amplitude.type = 'AML'
 | 
						|
            amplitude_list.append(amplitude)
 | 
						|
        except KeyError:
 | 
						|
            continue
 | 
						|
    event.amplitudes = amplitude_list
 | 
						|
    return event
 | 
						|
 | 
						|
def readPILOTEvent(phasfn=None, locfn=None, authority_id='RUB', **kwargs):
 | 
						|
    """
 | 
						|
    readPILOTEvent - function
 | 
						|
 | 
						|
    Reads Matlab PHASES and LOC files written by Matlab versions of PILOT and
 | 
						|
    converts the data into an ObsPy Event object which is returned to the
 | 
						|
    calling program.
 | 
						|
 | 
						|
    :rtype : ~obspy.core.event.Event
 | 
						|
    :param eventID:
 | 
						|
    :param authority:
 | 
						|
    :param kwargs:
 | 
						|
    :param phasfn: filename of the old PILOT Matlab PHASES file
 | 
						|
    :param locfn: filename of the old PILOT Matlab LOC file
 | 
						|
    :return event:  event object containing event and phase information
 | 
						|
    """
 | 
						|
    if phasfn is not None and os.path.isfile(phasfn):
 | 
						|
        phases = sio.loadmat(phasfn)
 | 
						|
        phasctime = UTCDateTime(os.path.getmtime(phasfn))
 | 
						|
        phasauthor = getOwner(phasfn)
 | 
						|
    else:
 | 
						|
        phases = None
 | 
						|
        phasctime = None
 | 
						|
        phasauthor = None
 | 
						|
    if locfn is not None and os.path.isfile(locfn):
 | 
						|
        loc = sio.loadmat(locfn)
 | 
						|
        locctime = UTCDateTime(os.path.getmtime(locfn))
 | 
						|
        locauthor = getOwner(locfn)
 | 
						|
    else:
 | 
						|
        loc = None
 | 
						|
        locctime = None
 | 
						|
        locauthor = None
 | 
						|
    pickcinfo = ope.CreationInfo(agency_id=authority_id,
 | 
						|
                                 author=phasauthor,
 | 
						|
                                 creation_time=phasctime)
 | 
						|
    loccinfo = ope.CreationInfo(agency_id=authority_id,
 | 
						|
                                author=locauthor,
 | 
						|
                                creation_time=locctime)
 | 
						|
 | 
						|
    eventNum = str(loc['ID'][0])
 | 
						|
 | 
						|
    # retrieve eventID for the actual database
 | 
						|
    idsplit = eventNum.split('.')
 | 
						|
 | 
						|
    # retrieve date information
 | 
						|
    julday = int(idsplit[1])
 | 
						|
    year = int(idsplit[2])
 | 
						|
    hour = int(loc['hh'])
 | 
						|
    minute = int(loc['mm'])
 | 
						|
    second = int(loc['ss'])
 | 
						|
 | 
						|
    year = four_digits(year)
 | 
						|
 | 
						|
    eventDate = UTCDateTime(year=year, julday=julday, hour=hour,
 | 
						|
                            minute=minute, second=second)
 | 
						|
 | 
						|
    stations = [stat for stat in phases['stat'][0:-1:3]]
 | 
						|
 | 
						|
    lat = float(loc['LAT'])
 | 
						|
    lon = float(loc['LON'])
 | 
						|
    dep = float(loc['DEP'])
 | 
						|
 | 
						|
    event = create_event(eventDate, loccinfo, originloc=(lat, lon, dep),
 | 
						|
                         etype='earthquake', resID=eventNum,
 | 
						|
                         authority_id=authority_id)
 | 
						|
 | 
						|
    picks = picksdict_from_pilot(phasfn)
 | 
						|
 | 
						|
    event.picks = picks_from_picksdict(picks, creation_info=pickcinfo)
 | 
						|
 | 
						|
    if event.origins:
 | 
						|
        origin = event.origins[0]
 | 
						|
        magnitude = create_magnitude(origin.get('id'), loccinfo)
 | 
						|
        magnitude.mag = float(loc['Mnet'])
 | 
						|
        magnitude.magnitude_type = 'Ml'
 | 
						|
        event.magnitudes.append(magnitude)
 | 
						|
    return event
 | 
						|
 | 
						|
 | 
						|
def picksdict_from_pilot(fn):
 | 
						|
    from pylot.core.util.defaults import TIMEERROR_DEFAULTS
 | 
						|
    picks = dict()
 | 
						|
    phases_pilot = sio.loadmat(fn)
 | 
						|
    stations = stations_from_pilot(phases_pilot['stat'])
 | 
						|
    params = AutoPickParameter(TIMEERROR_DEFAULTS)
 | 
						|
    timeerrors = dict(P=params.get('timeerrorsP'),
 | 
						|
                      S=params.get('timeerrorsS'))
 | 
						|
    for n, station in enumerate(stations):
 | 
						|
        phases = dict()
 | 
						|
        for onset_name in 'PS':
 | 
						|
            onset_label = '{0}time'.format(onset_name)
 | 
						|
            pick = phases_pilot[onset_label][n]
 | 
						|
            if not pick[0]:
 | 
						|
                continue
 | 
						|
            pick = convert_pilot_times(pick)
 | 
						|
            uncertainty_label = '{0}weight'.format(onset_name.lower())
 | 
						|
            ierror = phases_pilot[uncertainty_label][0, n]
 | 
						|
            try:
 | 
						|
                spe = timeerrors[onset_name][ierror]
 | 
						|
            except IndexError as e:
 | 
						|
                print(e.message + '\ntake two times the largest default error value')
 | 
						|
                spe = timeerrors[onset_name][-1] * 2
 | 
						|
            phases[onset_name] = dict(mpp=pick, spe=spe, weight=ierror)
 | 
						|
        picks[station] = phases
 | 
						|
 | 
						|
    return picks
 | 
						|
 | 
						|
 | 
						|
def stations_from_pilot(stat_array):
 | 
						|
    stations = list()
 | 
						|
    cur_stat = None
 | 
						|
    for stat in stat_array:
 | 
						|
        stat = stat.strip()
 | 
						|
        if stat == cur_stat:
 | 
						|
            continue
 | 
						|
        cur_stat = stat
 | 
						|
        if stat not in stations:
 | 
						|
            stations.append(stat)
 | 
						|
        else:
 | 
						|
            warnings.warn('station {0} listed at least twice, might corrupt '
 | 
						|
                          'phase times', RuntimeWarning)
 | 
						|
 | 
						|
    return stations
 | 
						|
 | 
						|
 | 
						|
def convert_pilot_times(time_array):
 | 
						|
    times = [int(time) for time in time_array]
 | 
						|
    microseconds = int((time_array[-1] - times[-1]) * 1e6)
 | 
						|
    times.append(microseconds)
 | 
						|
    return UTCDateTime(*times)
 | 
						|
 | 
						|
 | 
						|
def picksdict_from_obs(fn):
 | 
						|
    picks = dict()
 | 
						|
    station_name = str()
 | 
						|
    for line in open(fn, 'r'):
 | 
						|
        if line.startswith('#'):
 | 
						|
            continue
 | 
						|
        else:
 | 
						|
            phase_line = line.split()
 | 
						|
            if not station_name == phase_line[0]:
 | 
						|
                phase = dict()
 | 
						|
            station_name = phase_line[0]
 | 
						|
            phase_name = phase_line[4].upper()
 | 
						|
            pick = UTCDateTime(phase_line[6] + phase_line[7] + phase_line[8])
 | 
						|
            phase[phase_name] = dict(mpp=pick, fm=phase_line[5])
 | 
						|
            picks[station_name] = phase
 | 
						|
    return picks
 | 
						|
 | 
						|
 | 
						|
def picksdict_from_picks(evt):
 | 
						|
    """
 | 
						|
    Takes an Event object and return the pick dictionary commonly used within
 | 
						|
    PyLoT
 | 
						|
    :param evt: Event object contain all available information
 | 
						|
    :type evt: `~obspy.core.event.Event`
 | 
						|
    :return: pick dictionary
 | 
						|
    """
 | 
						|
    picks = {}
 | 
						|
    for pick in evt.picks:
 | 
						|
        phase = {}
 | 
						|
        station = pick.waveform_id.station_code
 | 
						|
        channel = pick.waveform_id.channel_code
 | 
						|
        try:
 | 
						|
            onsets = picks[station]
 | 
						|
        except KeyError as e:
 | 
						|
            #print(e)
 | 
						|
            onsets = {}
 | 
						|
        mpp = pick.time
 | 
						|
        spe = pick.time_errors.uncertainty
 | 
						|
        try:
 | 
						|
            lpp = mpp + pick.time_errors.upper_uncertainty
 | 
						|
            epp = mpp - pick.time_errors.lower_uncertainty
 | 
						|
        except TypeError as e:
 | 
						|
            msg = e.message + ',\n falling back to symmetric uncertainties'
 | 
						|
            warnings.warn(msg)
 | 
						|
            lpp = mpp + spe
 | 
						|
            epp = mpp - spe
 | 
						|
        phase['mpp'] = mpp
 | 
						|
        phase['epp'] = epp
 | 
						|
        phase['lpp'] = lpp
 | 
						|
        phase['spe'] = spe
 | 
						|
        phase['channel'] = channel
 | 
						|
        try:
 | 
						|
            picker = str(pick.method_id)
 | 
						|
            if picker.startswith('smi:local/'):
 | 
						|
                picker = picker.split('smi:local/')[1]
 | 
						|
            phase['picker'] = picker
 | 
						|
        except IndexError:
 | 
						|
            pass
 | 
						|
 | 
						|
        onsets[pick.phase_hint] = phase.copy()
 | 
						|
        picks[station] = onsets.copy()
 | 
						|
    return picks
 | 
						|
 | 
						|
def picks_from_picksdict(picks, creation_info=None):
 | 
						|
    picks_list = list()
 | 
						|
    for station, onsets in picks.items():
 | 
						|
        for label, phase in onsets.items():
 | 
						|
            if not isinstance(phase, dict):
 | 
						|
                continue
 | 
						|
            onset = phase['mpp']
 | 
						|
            try:
 | 
						|
            	ccode = phase['channel']
 | 
						|
            	ncode = phase['network']
 | 
						|
            except:
 | 
						|
                continue
 | 
						|
            pick = ope.Pick()
 | 
						|
            if creation_info:
 | 
						|
                pick.creation_info = creation_info
 | 
						|
            pick.time = onset
 | 
						|
            error = phase['spe']
 | 
						|
            pick.time_errors.uncertainty = error
 | 
						|
            try:
 | 
						|
                epp = phase['epp']
 | 
						|
                lpp = phase['lpp']
 | 
						|
                pick.time_errors.lower_uncertainty = onset - epp
 | 
						|
                pick.time_errors.upper_uncertainty = lpp - onset
 | 
						|
            except KeyError as e:
 | 
						|
                warnings.warn(e.message, RuntimeWarning)
 | 
						|
            try:
 | 
						|
                picker = phase['picker']
 | 
						|
            except KeyError as e:
 | 
						|
                warnings.warn(e.message, RuntimeWarning)
 | 
						|
                picker = 'Unknown'
 | 
						|
            pick.phase_hint = label
 | 
						|
            pick.method_id = ope.ResourceIdentifier(id=picker)
 | 
						|
            pick.waveform_id = ope.WaveformStreamID(station_code=station,
 | 
						|
                                                      channel_code=ccode,
 | 
						|
                                                      network_code=ncode)
 | 
						|
            try:
 | 
						|
                polarity = phase['fm']
 | 
						|
                if polarity == 'U' or '+':
 | 
						|
                    pick.polarity = 'positive'
 | 
						|
                elif polarity == 'D' or '-':
 | 
						|
                    pick.polarity = 'negative'
 | 
						|
                else:
 | 
						|
                    pick.polarity = 'undecidable'
 | 
						|
            except KeyError as e:
 | 
						|
                if 'fm' in e.message: # no polarity information found for this phase
 | 
						|
                    pass
 | 
						|
                else:
 | 
						|
                    raise e
 | 
						|
            picks_list.append(pick)
 | 
						|
    return picks_list
 | 
						|
 | 
						|
 | 
						|
def reassess_pilot_db(root_dir, db_dir, out_dir=None, fn_param=None, verbosity=0):
 | 
						|
    import glob
 | 
						|
 | 
						|
    db_root = os.path.join(root_dir, db_dir)
 | 
						|
    evt_list = glob.glob1(db_root,'e????.???.??')
 | 
						|
 | 
						|
    for evt in evt_list:
 | 
						|
        if verbosity > 0:
 | 
						|
            print('Reassessing event {0}'.format(evt))
 | 
						|
        reassess_pilot_event(root_dir, db_dir, evt, out_dir, fn_param, verbosity)
 | 
						|
 | 
						|
 | 
						|
 | 
						|
def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None, verbosity=0):
 | 
						|
    from obspy import read
 | 
						|
 | 
						|
    from pylot.core.io.inputs import AutoPickParameter
 | 
						|
    from pylot.core.pick.utils import earllatepicker
 | 
						|
 | 
						|
    if fn_param is None:
 | 
						|
        import pylot.core.util.defaults as defaults
 | 
						|
        fn_param = defaults.AUTOMATIC_DEFAULTS
 | 
						|
 | 
						|
    default = AutoPickParameter(fn_param, verbosity)
 | 
						|
 | 
						|
    search_base = os.path.join(root_dir, db_dir, event_id)
 | 
						|
    phases_file = glob.glob(os.path.join(search_base, 'PHASES.mat'))
 | 
						|
    if not phases_file:
 | 
						|
        return
 | 
						|
    if verbosity > 1:
 | 
						|
        print('Opening PILOT phases file: {fn}'.format(fn=phases_file[0]))
 | 
						|
    picks_dict = picksdict_from_pilot(phases_file[0])
 | 
						|
    if verbosity > 0:
 | 
						|
        print('Dictionary read from PHASES.mat:\n{0}'.format(picks_dict))
 | 
						|
    datacheck = list()
 | 
						|
    info = None
 | 
						|
    for station in picks_dict.keys():
 | 
						|
        fn_pattern = os.path.join(search_base, '{0}*'.format(station))
 | 
						|
        try:
 | 
						|
            st = read(fn_pattern)
 | 
						|
        except TypeError as e:
 | 
						|
            if 'Unknown format for file' in e.message:
 | 
						|
                try:
 | 
						|
                    st = read(fn_pattern, format='GSE2')
 | 
						|
                except ValueError as e:
 | 
						|
                    if e.message == 'second must be in 0..59':
 | 
						|
                        info = 'A known Error was raised. Please find the list of corrupted files and double-check these files.'
 | 
						|
                        datacheck.append(fn_pattern + ' (time info)\n')
 | 
						|
                        continue
 | 
						|
                    else:
 | 
						|
                        raise ValueError(e.message)
 | 
						|
                except Exception as e:
 | 
						|
                    if 'No file matching file pattern:' in e.message:
 | 
						|
                        if verbosity > 0:
 | 
						|
                            warnings.warn('no waveform data found for station {station}'.format(station=station), RuntimeWarning)
 | 
						|
                        datacheck.append(fn_pattern + ' (no data)\n')
 | 
						|
                        continue
 | 
						|
                    else:
 | 
						|
                        raise e
 | 
						|
            else:
 | 
						|
                raise e
 | 
						|
        for phase in picks_dict[station].keys():
 | 
						|
            try:
 | 
						|
                mpp = picks_dict[station][phase]['mpp']
 | 
						|
            except KeyError as e:
 | 
						|
                print(e.message, station)
 | 
						|
                continue
 | 
						|
            sel_st = select_for_phase(st, phase)
 | 
						|
            if not sel_st:
 | 
						|
                msg = 'no waveform data found for station {station}'.format(station=station)
 | 
						|
                warnings.warn(msg, RuntimeWarning)
 | 
						|
                continue
 | 
						|
            stime, etime = full_range(sel_st)
 | 
						|
            rel_pick = mpp - stime
 | 
						|
            epp, lpp, spe = earllatepicker(sel_st,
 | 
						|
                                           default.get('nfac{0}'.format(phase)),
 | 
						|
                                           default.get('tsnrz' if phase == 'P' else 'tsnrh'),
 | 
						|
                                           Pick1=rel_pick,
 | 
						|
                                           iplot=None,
 | 
						|
                                           verbosity=0)
 | 
						|
            if epp is None or lpp is None:
 | 
						|
                continue
 | 
						|
            epp = stime + epp
 | 
						|
            lpp = stime + lpp
 | 
						|
            min_diff = 3 * st[0].stats.delta
 | 
						|
            if lpp - mpp < min_diff:
 | 
						|
                lpp = mpp + min_diff
 | 
						|
            if mpp - epp < min_diff:
 | 
						|
                epp = mpp - min_diff
 | 
						|
            picks_dict[station][phase] = dict(epp=epp, mpp=mpp, lpp=lpp, spe=spe)
 | 
						|
    if datacheck:
 | 
						|
        if info:
 | 
						|
            if verbosity > 0:
 | 
						|
                print(info + ': {0}'.format(search_base))
 | 
						|
        fncheck = open(os.path.join(search_base, 'datacheck_list'), 'w')
 | 
						|
        fncheck.writelines(datacheck)
 | 
						|
        fncheck.close()
 | 
						|
        del datacheck
 | 
						|
    # create Event object for export
 | 
						|
    evt = ope.Event(resource_id=event_id)
 | 
						|
    evt.picks = picks_from_picksdict(picks_dict)
 | 
						|
    # write phase information to file
 | 
						|
    if not out_dir:
 | 
						|
        fnout_prefix = os.path.join(root_dir, db_dir, event_id, '{0}.'.format(event_id))
 | 
						|
    else:
 | 
						|
        out_dir = os.path.join(out_dir, db_dir)
 | 
						|
        if not os.path.isdir(out_dir):
 | 
						|
            os.makedirs(out_dir)
 | 
						|
        fnout_prefix = os.path.join(out_dir, '{0}.'.format(event_id))
 | 
						|
    evt.write(fnout_prefix + 'xml', format='QUAKEML')
 | 
						|
    #evt.write(fnout_prefix + 'cnv', format='VELEST')
 | 
						|
 | 
						|
 | 
						|
def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
 | 
						|
    """
 | 
						|
    Function of methods to write phases to the following standard file
 | 
						|
    formats used for locating earthquakes:
 | 
						|
 | 
						|
    HYPO71, NLLoc, VELEST, HYPOSAT, and hypoDD
 | 
						|
 | 
						|
    :param: arrivals
 | 
						|
    :type: dictionary containing all phase information including
 | 
						|
           station ID, phase, first motion, weight (uncertainty),
 | 
						|
           ....
 | 
						|
 | 
						|
    :param: fformat
 | 
						|
    :type:  string, chosen file format (location routine),
 | 
						|
            choose between NLLoc, HYPO71, HYPOSAT, VELEST,
 | 
						|
            HYPOINVERSE, and hypoDD
 | 
						|
 | 
						|
    :param: filename, full path and name of phase file
 | 
						|
    :type:  string
 | 
						|
 | 
						|
    :param: parameter, all input information
 | 
						|
    :type:  object
 | 
						|
 | 
						|
    :param: eventinfo, optional, needed for VELEST-cnv file 
 | 
						|
            and FOCMEC- and HASH-input files 
 | 
						|
    :type:  `obspy.core.event.Event` object
 | 
						|
    """ 
 | 
						|
 | 
						|
    if fformat == 'NLLoc':
 | 
						|
        print ("Writing phases to %s for NLLoc" % filename)
 | 
						|
        fid = open("%s" % filename, 'w')
 | 
						|
        # write header
 | 
						|
        fid.write('# EQEVENT: %s Label: EQ%s  Loc:  X 0.00  Y 0.00  Z 10.00  OT 0.00 \n' %
 | 
						|
                  (parameter.get('database'), parameter.get('eventID')))
 | 
						|
        for key in arrivals:
 | 
						|
            # P onsets
 | 
						|
            if arrivals[key].has_key('P'):
 | 
						|
                try:
 | 
						|
                    fm = arrivals[key]['P']['fm']
 | 
						|
                except KeyError as e:
 | 
						|
                    print(e)
 | 
						|
                    fm = None
 | 
						|
                if fm == None:
 | 
						|
                    fm = '?'
 | 
						|
                onset = arrivals[key]['P']['mpp']
 | 
						|
                year = onset.year
 | 
						|
                month = onset.month
 | 
						|
                day = onset.day
 | 
						|
                hh = onset.hour
 | 
						|
                mm = onset.minute
 | 
						|
                ss = onset.second
 | 
						|
                ms = onset.microsecond
 | 
						|
                ss_ms = ss + ms / 1000000.0
 | 
						|
                pweight = 1 # use pick
 | 
						|
                try:
 | 
						|
                    if arrivals[key]['P']['weight'] >= 4:
 | 
						|
                        pweight = 0  # do not use pick
 | 
						|
                except KeyError as e:
 | 
						|
                    print(e.message + '; no weight set during processing')
 | 
						|
                fid.write('%s ? ? ? P   %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 %d \n' % (key,
 | 
						|
                                                                                           fm,
 | 
						|
                                                                                           year,
 | 
						|
                                                                                           month,
 | 
						|
                                                                                           day,
 | 
						|
                                                                                           hh,
 | 
						|
                                                                                           mm,
 | 
						|
                                                                                           ss_ms,
 | 
						|
                                                                                           pweight))
 | 
						|
            # S onsets
 | 
						|
            if arrivals[key].has_key('S') and arrivals[key]['S']:
 | 
						|
                fm = '?'
 | 
						|
                onset = arrivals[key]['S']['mpp']
 | 
						|
                year = onset.year
 | 
						|
                month = onset.month
 | 
						|
                day = onset.day
 | 
						|
                hh = onset.hour
 | 
						|
                mm = onset.minute
 | 
						|
                ss = onset.second
 | 
						|
                ms = onset.microsecond
 | 
						|
                ss_ms = ss + ms / 1000000.0
 | 
						|
                sweight = 1 # use pick
 | 
						|
                try:
 | 
						|
                    if arrivals[key]['S']['weight'] >= 4:
 | 
						|
                        sweight = 0  # do not use pick
 | 
						|
                except KeyError as e:
 | 
						|
                    print(str(e) + '; no weight set during processing')
 | 
						|
                fid.write('%s ? ? ? S   %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 %d \n' % (key,
 | 
						|
                                                                                           fm,
 | 
						|
                                                                                           year,
 | 
						|
                                                                                           month,
 | 
						|
                                                                                           day,
 | 
						|
                                                                                           hh,
 | 
						|
                                                                                           mm,
 | 
						|
                                                                                           ss_ms,
 | 
						|
                                                                                           sweight))
 | 
						|
 | 
						|
        fid.close()
 | 
						|
    elif fformat == 'HYPO71':
 | 
						|
        print ("Writing phases to %s for HYPO71" % filename)
 | 
						|
        fid = open("%s" % filename, 'w')
 | 
						|
        # write header
 | 
						|
        fid.write('                                                                %s\n' %
 | 
						|
                                                                            parameter.get('eventID'))
 | 
						|
        for key in arrivals:
 | 
						|
            if arrivals[key]['P']['weight'] < 4:
 | 
						|
                stat = key
 | 
						|
                if len(stat) > 4: # HYPO71 handles only 4-string station IDs
 | 
						|
                    stat = stat[1:5]
 | 
						|
                Ponset = arrivals[key]['P']['mpp']
 | 
						|
                Sonset = arrivals[key]['S']['mpp']
 | 
						|
                pweight = arrivals[key]['P']['weight']
 | 
						|
                sweight = arrivals[key]['S']['weight']
 | 
						|
                fm = arrivals[key]['P']['fm']
 | 
						|
                if fm is None:
 | 
						|
                    fm = '-'
 | 
						|
                Ao = arrivals[key]['S']['Ao']
 | 
						|
                if Ao is None:
 | 
						|
                    Ao = ''
 | 
						|
                else:
 | 
						|
                    Ao = str('%7.2f' % Ao)
 | 
						|
                year = Ponset.year
 | 
						|
                if year >= 2000:
 | 
						|
                    year = year - 2000
 | 
						|
                else:
 | 
						|
                    year = year - 1900
 | 
						|
                month = Ponset.month
 | 
						|
                day = Ponset.day
 | 
						|
                hh = Ponset.hour
 | 
						|
                mm = Ponset.minute
 | 
						|
                ss = Ponset.second
 | 
						|
                ms = Ponset.microsecond
 | 
						|
                ss_ms = ss + ms / 1000000.0
 | 
						|
                if pweight < 2:
 | 
						|
                    pstr = 'I'
 | 
						|
                elif pweight >= 2:
 | 
						|
                    pstr = 'E'
 | 
						|
                if arrivals[key]['S']['weight'] < 4:
 | 
						|
                    Sss = Sonset.second
 | 
						|
                    Sms = Sonset.microsecond
 | 
						|
                    Sss_ms = Sss + Sms / 1000000.0
 | 
						|
                    Sss_ms = str('%5.02f' % Sss_ms)
 | 
						|
                    if sweight < 2:
 | 
						|
                        sstr = 'I'
 | 
						|
                    elif sweight >= 2:
 | 
						|
                        sstr = 'E'
 | 
						|
                    fid.write('%-4s%sP%s%d %02d%02d%02d%02d%02d%5.2f       %s%sS %d   %s\n' % (stat,
 | 
						|
                                                                                             pstr,
 | 
						|
                                                                                             fm,
 | 
						|
                                                                                             pweight,
 | 
						|
                                                                                             year,
 | 
						|
                                                                                             month,
 | 
						|
                                                                                             day,
 | 
						|
                                                                                             hh,
 | 
						|
                                                                                             mm,
 | 
						|
                                                                                             ss_ms,
 | 
						|
                                                                                             Sss_ms,
 | 
						|
                                                                                             sstr,
 | 
						|
                                                                                             sweight,
 | 
						|
                                                                                             Ao))
 | 
						|
                else:
 | 
						|
                    fid.write('%-4s%sP%s%d %02d%02d%02d%02d%02d%5.2f                  %s\n' % (stat,
 | 
						|
                                                                                             pstr,
 | 
						|
                                                                                             fm,
 | 
						|
                                                                                             pweight,
 | 
						|
                                                                                             year,
 | 
						|
                                                                                             month,
 | 
						|
                                                                                             day,
 | 
						|
                                                                                             hh,
 | 
						|
                                                                                             mm,
 | 
						|
                                                                                             ss_ms,
 | 
						|
                                                                                             Ao))
 | 
						|
 | 
						|
        fid.close()
 | 
						|
 | 
						|
    elif fformat == 'HYPOSAT':
 | 
						|
        print ("Writing phases to %s for HYPOSAT" % filename)
 | 
						|
        fid = open("%s" % filename, 'w')
 | 
						|
        # write header
 | 
						|
        fid.write('%s, event %s \n' % (parameter.get('database'), parameter.get('eventID')))
 | 
						|
        errP = parameter.get('timeerrorsP')
 | 
						|
        errS = parameter.get('timeerrorsS')
 | 
						|
        for key in arrivals:
 | 
						|
            # P onsets
 | 
						|
            if arrivals[key].has_key('P'):
 | 
						|
                if arrivals[key]['P']['weight'] < 4:
 | 
						|
                    Ponset = arrivals[key]['P']['mpp']
 | 
						|
                    pyear = Ponset.year
 | 
						|
                    pmonth = Ponset.month
 | 
						|
                    pday = Ponset.day
 | 
						|
                    phh = Ponset.hour
 | 
						|
                    pmm = Ponset.minute
 | 
						|
                    pss = Ponset.second
 | 
						|
                    pms = Ponset.microsecond
 | 
						|
                    Pss = pss + pms / 1000000.0
 | 
						|
                    # use symmetrized picking error as std
 | 
						|
                    # (read the HYPOSAT manual)
 | 
						|
                    pstd = arrivals[key]['P']['spe']
 | 
						|
                    fid.write('%-5s P1       %4.0f %02d %02d %02d %02d %05.02f   %5.3f -999.   0.00 -999.  0.00\n' 
 | 
						|
                              % (key, pyear, pmonth, pday, phh, pmm, Pss, pstd))
 | 
						|
            # S onsets
 | 
						|
            if arrivals[key].has_key('S') and arrivals[key]['S']:
 | 
						|
                if arrivals[key]['S']['weight'] < 4:
 | 
						|
                    Sonset = arrivals[key]['S']['mpp']
 | 
						|
                    syear = Sonset.year
 | 
						|
                    smonth = Sonset.month
 | 
						|
                    sday = Sonset.day
 | 
						|
                    shh = Sonset.hour
 | 
						|
                    smm = Sonset.minute
 | 
						|
                    sss = Sonset.second
 | 
						|
                    sms = Sonset.microsecond
 | 
						|
                    Sss = sss + sms / 1000000.0
 | 
						|
                    sstd = arrivals[key]['S']['spe']
 | 
						|
                    fid.write('%-5s S1       %4.0f %02d %02d %02d %02d %05.02f   %5.3f -999.   0.00 -999.  0.00\n' 
 | 
						|
                              % (key, syear, smonth, sday, shh, smm, Sss, sstd))
 | 
						|
        fid.close()
 | 
						|
 | 
						|
    elif fformat == 'VELEST':
 | 
						|
        print ("Writing phases to %s for VELEST" % filename)
 | 
						|
        fid = open("%s" % filename, 'w')
 | 
						|
        # get informations needed in cnv-file
 | 
						|
        # check, whether latitude is N or S and longitude is E or W
 | 
						|
        eventsource = eventinfo.origins[0]
 | 
						|
        if eventsource['latitude'] < 0:
 | 
						|
            cns = 'S'
 | 
						|
        else:
 | 
						|
            cns = 'N'
 | 
						|
        if eventsource['longitude'] < 0:
 | 
						|
            cew = 'W'
 | 
						|
        else:
 | 
						|
            cew = 'E'
 | 
						|
        # get last two integers of origin year
 | 
						|
        stime = eventsource['time']
 | 
						|
        if stime.year - 2000 >= 0:
 | 
						|
           syear = stime.year - 2000
 | 
						|
        else:
 | 
						|
           syear = stime.year - 1900
 | 
						|
        ifx = 0 # default value, see VELEST manual, pp. 22-23
 | 
						|
        # write header
 | 
						|
        fid.write('%s%02d%02d %02d%02d %05.2f %7.4f%c %8.4f%c %7.2f %6.2f     %02.0f  0.0 0.03  1.0  1.0\n' % (
 | 
						|
                   syear, stime.month, stime.day, stime.hour, stime.minute, stime.second, eventsource['latitude'],
 | 
						|
                   cns, eventsource['longitude'], cew, eventsource['depth'],eventinfo.magnitudes[0]['mag'], ifx))
 | 
						|
        n = 0
 | 
						|
        for key in arrivals:
 | 
						|
            # P onsets
 | 
						|
            if arrivals[key].has_key('P'):
 | 
						|
                if arrivals[key]['P']['weight'] < 4:
 | 
						|
                    n += 1
 | 
						|
                    stat = key
 | 
						|
                    if len(stat) > 4: # VELEST handles only 4-string station IDs
 | 
						|
                        stat = stat[1:5]
 | 
						|
                    Ponset = arrivals[key]['P']['mpp']
 | 
						|
                    Pweight = arrivals[key]['P']['weight']
 | 
						|
                    Prt = Ponset - stime # onset time relative to source time
 | 
						|
                    if n % 6 is not 0:
 | 
						|
                        fid.write('%-4sP%d%6.2f' % (stat, Pweight, Prt))  
 | 
						|
                    else:
 | 
						|
                        fid.write('%-4sP%d%6.2f\n' % (stat, Pweight, Prt))  
 | 
						|
            # S onsets
 | 
						|
            if arrivals[key].has_key('S'):
 | 
						|
                if arrivals[key]['S']['weight'] < 4:
 | 
						|
                    n += 1
 | 
						|
                    stat = key
 | 
						|
                    if len(stat) > 4: # VELEST handles only 4-string station IDs
 | 
						|
                        stat = stat[1:5]
 | 
						|
                    Sonset = arrivals[key]['S']['mpp']
 | 
						|
                    Sweight = arrivals[key]['S']['weight']
 | 
						|
                    Srt = Ponset - stime # onset time relative to source time
 | 
						|
                    if n % 6 is not 0:
 | 
						|
                        fid.write('%-4sS%d%6.2f' % (stat, Sweight, Srt))  
 | 
						|
                    else:
 | 
						|
                        fid.write('%-4sS%d%6.2f\n' % (stat, Sweight, Srt))  
 | 
						|
        fid.close()
 | 
						|
 | 
						|
    elif fformat == 'hypoDD':
 | 
						|
        print ("Writing phases to %s for hypoDD" % filename)
 | 
						|
        fid = open("%s" % filename, 'w')
 | 
						|
        # get event information needed for hypoDD-phase file
 | 
						|
        eventsource = eventinfo.origins[0]
 | 
						|
        stime = eventsource['time']
 | 
						|
        event = parameter.get('eventID')
 | 
						|
        hddID = event.split('.')[0][1:5]
 | 
						|
        # write header
 | 
						|
        fid.write('# %d  %d %d %d %d %5.2f %7.4f +%6.4f %7.4f %4.2f 0.1 0.5 %4.2f      %s\n' % (
 | 
						|
                      stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second, 
 | 
						|
                      eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000,
 | 
						|
                      eventinfo.magnitudes[0]['mag'], eventsource['quality']['standard_error'], hddID))
 | 
						|
        for key in arrivals:
 | 
						|
            if arrivals[key].has_key('P'):
 | 
						|
                # P onsets
 | 
						|
                if arrivals[key]['P']['weight'] < 4:
 | 
						|
                    Ponset = arrivals[key]['P']['mpp']
 | 
						|
                    Prt = Ponset - stime # onset time relative to source time
 | 
						|
                    fid.write('%s    %6.3f  1  P\n' % (key, Prt)) 
 | 
						|
                # S onsets
 | 
						|
                if arrivals[key]['S']['weight'] < 4:
 | 
						|
                    Sonset = arrivals[key]['S']['mpp']
 | 
						|
                    Srt = Sonset - stime # onset time relative to source time
 | 
						|
                    fid.write('%-5s    %6.3f  1  S\n' % (key, Srt)) 
 | 
						|
 | 
						|
        fid.close()
 | 
						|
 | 
						|
    elif fformat == 'FOCMEC':
 | 
						|
        print ("Writing phases to %s for FOCMEC" % filename)
 | 
						|
        fid = open("%s" % filename, 'w')
 | 
						|
        # get event information needed for FOCMEC-input file
 | 
						|
        eventsource = eventinfo.origins[0]
 | 
						|
        stime = eventsource['time']
 | 
						|
        # write header line including event information
 | 
						|
        fid.write('%s %d%02d%02d%02d%02d%02.0f %7.4f %6.4f %3.1f %3.1f\n' % (parameter.get('eventID'),
 | 
						|
                   stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second,
 | 
						|
                   eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000,
 | 
						|
                   eventinfo.magnitudes[0]['mag']))
 | 
						|
        picks = eventinfo.picks
 | 
						|
        for key in arrivals:
 | 
						|
            if arrivals[key].has_key('P'):
 | 
						|
                if arrivals[key]['P']['weight'] < 4 and arrivals[key]['P']['fm'] is not None:
 | 
						|
                    stat = key
 | 
						|
                    for i in range(len(picks)):
 | 
						|
                         station = picks[i].waveform_id.station_code
 | 
						|
                         if station == stat:
 | 
						|
                             # get resource ID
 | 
						|
                             resid_picks = picks[i].get('resource_id')
 | 
						|
                             # find same ID in eventinfo
 | 
						|
                             # there it is the pick_id!!
 | 
						|
                             for j in range(len(eventinfo.origins[0].arrivals)):
 | 
						|
                                 resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
 | 
						|
                                 if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
 | 
						|
                                     if len(stat) > 4: # FOCMEC handles only 4-string station IDs
 | 
						|
                                         stat = stat[1:5]
 | 
						|
                                     az = eventinfo.origins[0].arrivals[j].get('azimuth')
 | 
						|
                                     inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
 | 
						|
                                     fid.write('%-4s  %6.2f  %6.2f%s \n' % (stat,
 | 
						|
                                                                        az,
 | 
						|
                                                                        inz,
 | 
						|
                                                    arrivals[key]['P']['fm']))
 | 
						|
                                     break
 | 
						|
 | 
						|
        fid.close()
 | 
						|
 | 
						|
    elif fformat == 'HASH':
 | 
						|
        # two different input files for 
 | 
						|
        # HASH-driver 1 and 2 (see HASH manual!)
 | 
						|
        filename1 = filename + 'drv1' + '.phase'
 | 
						|
        filename2 = filename + 'drv2' + '.phase'
 | 
						|
        print ("Writing phases to %s for HASH for HASH-driver 1" % filename1)
 | 
						|
        fid1 = open("%s" % filename1, 'w')
 | 
						|
        print ("Writing phases to %s for HASH for HASH-driver 2" % filename2)
 | 
						|
        fid2 = open("%s" % filename2, 'w')
 | 
						|
        # get event information needed for HASH-input file
 | 
						|
        eventsource = eventinfo.origins[0]
 | 
						|
        event = parameter.get('eventID')
 | 
						|
        hashID = event.split('.')[0][1:5]
 | 
						|
        latdeg = eventsource['latitude']
 | 
						|
        latmin = eventsource['latitude'] * 60 / 10000
 | 
						|
        londeg = eventsource['longitude']
 | 
						|
        lonmin = eventsource['longitude'] * 60 / 10000
 | 
						|
        erh = 1 / 2 * (eventsource.origin_uncertainty['min_horizontal_uncertainty'] +
 | 
						|
                       eventsource.origin_uncertainty['max_horizontal_uncertainty']) / 1000
 | 
						|
        erz = eventsource.depth_errors['uncertainty']
 | 
						|
        stime = eventsource['time']
 | 
						|
        if stime.year - 2000 >= 0:
 | 
						|
           syear = stime.year - 2000
 | 
						|
        else:
 | 
						|
           syear = stime.year - 1900
 | 
						|
        picks = eventinfo.picks
 | 
						|
        # write header line including event information
 | 
						|
        # for HASH-driver 1
 | 
						|
        fid1.write('%s%02d%02d%02d%02d%5.2f%2dN%5.2f%3dE%5.2f%6.3f%4.2f%5.2f%5.2f%s\n' % (syear,
 | 
						|
                             stime.month, stime.day, stime.hour, stime.minute, stime.second, 
 | 
						|
                                       latdeg, latmin, londeg, lonmin, eventsource['depth'], 
 | 
						|
                                                   eventinfo.magnitudes[0]['mag'], erh, erz, 
 | 
						|
                                                                                    hashID))
 | 
						|
        # write header line including event information
 | 
						|
        # for HASH-driver 2
 | 
						|
        fid2.write('%d%02d%02d%02d%02d%5.2f%dN%5.2f%3dE%6.2f%5.2f    %d                                          %5.2f %5.2f                                        %4.2f      %s \n' % (syear, stime.month, stime.day, 
 | 
						|
                                               stime.hour, stime.minute, stime.second, 
 | 
						|
                                                         latdeg,latmin,londeg, lonmin, 
 | 
						|
                                                                 eventsource['depth'], 
 | 
						|
                                           eventsource['quality']['used_phase_count'],
 | 
						|
                                               erh, erz, eventinfo.magnitudes[0]['mag'],
 | 
						|
                                                                                hashID))
 | 
						|
 | 
						|
        # write phase lines
 | 
						|
        for key in arrivals:
 | 
						|
            if arrivals[key].has_key('P'):
 | 
						|
                if arrivals[key]['P']['weight'] < 4 and arrivals[key]['P']['fm'] is not None:
 | 
						|
                    stat = key
 | 
						|
                    ccode = arrivals[key]['P']['channel']
 | 
						|
                    ncode = arrivals[key]['P']['network']
 | 
						|
 | 
						|
                    if arrivals[key]['P']['weight'] < 2:
 | 
						|
                        Pqual='I'
 | 
						|
                    else:
 | 
						|
                        Pqual='E'
 | 
						|
                    
 | 
						|
                    for i in range(len(picks)):
 | 
						|
                         station = picks[i].waveform_id.station_code
 | 
						|
                         if station == stat:
 | 
						|
                             # get resource ID
 | 
						|
                             resid_picks = picks[i].get('resource_id')
 | 
						|
                             # find same ID in eventinfo
 | 
						|
                             # there it is the pick_id!!
 | 
						|
                             for j in range(len(eventinfo.origins[0].arrivals)):
 | 
						|
                                 resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
 | 
						|
                                 if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
 | 
						|
                                     if len(stat) > 4: # HASH handles only 4-string station IDs
 | 
						|
                                         stat = stat[1:5]
 | 
						|
                                     az = eventinfo.origins[0].arrivals[j].get('azimuth')
 | 
						|
                                     inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
 | 
						|
                                     dist = eventinfo.origins[0].arrivals[j].get('distance') 
 | 
						|
                                     # write phase line for HASH-driver 1
 | 
						|
                                     fid1.write('%-4s%sP%s%d                   0                                   %3.1f          %03d %03d   2     1   %s\n' % (stat, Pqual, arrivals[key]['P']['fm'], arrivals[key]['P']['weight'], 
 | 
						|
                                                                               dist, inz, az, ccode))
 | 
						|
                                     # write phase line for HASH-driver 2
 | 
						|
                                     fid2.write('%-4s %s   %s %s %s                    \n' % (
 | 
						|
                                                                                           stat,
 | 
						|
                                                                                          ncode,
 | 
						|
                                                                                          ccode,
 | 
						|
                                                                                          Pqual,
 | 
						|
                                                                       arrivals[key]['P']['fm']))
 | 
						|
                                     break
 | 
						|
 | 
						|
        fid1.write('                                    %s' % hashID)
 | 
						|
        fid1.close()
 | 
						|
        fid2.close()
 | 
						|
 | 
						|
 | 
						|
def merge_picks(event, picks):
 | 
						|
    """
 | 
						|
    takes an event object and a list of picks and searches for matching
 | 
						|
    entries by comparing station name and phase_hint and overwrites the time
 | 
						|
    and time_errors value of the event picks' with those from the picks
 | 
						|
    without changing the resource identifiers
 | 
						|
    :param event: `obspy.core.event.Event` object (e.g. from NLLoc output)
 | 
						|
    :param picks: list of `obspy.core.event.Pick` objects containing the
 | 
						|
    original time and time_errors values
 | 
						|
    :return: merged `obspy.core.event.Event` object
 | 
						|
    """
 | 
						|
    for pick in picks:
 | 
						|
        time = pick.time
 | 
						|
        err = pick.time_errors
 | 
						|
        phase = pick.phase_hint
 | 
						|
        station = pick.waveform_id.station_code
 | 
						|
        method = pick.method_id
 | 
						|
        for p in event.picks:
 | 
						|
            if p.waveform_id.station_code == station and p.phase_hint == phase:
 | 
						|
                p.time, p.time_errors, p.method_id = time, err, method
 | 
						|
        del time, err, phase, station, method
 | 
						|
    return event
 |