def _read_picks(f, new_event): """ Internal pick reader. Use read_nordic instead. :type f: file :param f: File open in read mode :type wav_names: list :param wav_names: List of waveform files in the sfile :type new_event: :class:`~obspy.core.event.event.Event` :param new_event: event to associate picks with. :returns: :class:`~obspy.core.event.event.Event` """ f.seek(0) evtime = new_event.origins[0].time pickline = [] # Set a default, ignored later unless overwritten snr = None for lineno, line in enumerate(f): if line[79] == '7': header = line break for lineno, line in enumerate(f): if len(line.rstrip('\n').rstrip('\r')) in [80, 79] and \ line[79] in ' 4\n': pickline += [line] for line in pickline: if line[18:28].strip() == '': # If line is empty miss it continue weight = line[14] if weight == '_': phase = line[10:17] weight = 0 polarity = '' else: phase = line[10:14].strip() polarity = line[16] if weight == ' ': weight = 0 polarity_maps = {"": "undecidable", "C": "positive", "D": "negative"} try: polarity = polarity_maps[polarity] except KeyError: polarity = "undecidable" # It is valid nordic for the origin to be hour 23 and picks to be hour # 00 or 24: this signifies a pick over a day boundary. if int(line[18:20]) == 0 and evtime.hour == 23: day_add = 86400 pick_hour = 0 elif int(line[18:20]) == 24: day_add = 86400 pick_hour = 0 else: day_add = 0 pick_hour = int(line[18:20]) try: time = UTCDateTime(evtime.year, evtime.month, evtime.day, pick_hour, int(line[20:22]), float(line[23:28])) + day_add except ValueError: time = UTCDateTime(evtime.year, evtime.month, evtime.day, int(line[18:20]), pick_hour, float("0." + line[23:38].split('.')[1])) +\ 60 + day_add # Add 60 seconds on to the time, this copes with s-file # preference to write seconds in 1-60 rather than 0-59 which # datetime objects accept if header[57:60] == 'AIN': ain = _float_conv(line[57:60]) warnings.warn('AIN: %s in header, currently unsupported' % ain) elif header[57:60] == 'SNR': snr = _float_conv(line[57:60]) else: warnings.warn('%s is not currently supported' % header[57:60]) # finalweight = _int_conv(line[68:70]) # Create a new obspy.event.Pick class for this pick _waveform_id = WaveformStreamID(station_code=line[1:6].strip(), channel_code=line[6:8].strip(), network_code='NA') pick = Pick(waveform_id=_waveform_id, phase_hint=phase, polarity=polarity, time=time) try: pick.onset = onsets[line[9]] except KeyError: pass if line[15] == 'A': pick.evaluation_mode = 'automatic' else: pick.evaluation_mode = 'manual' # Note these two are not always filled - velocity conversion not yet # implemented, needs to be converted from km/s to s/deg # if not velocity == 999.0: # new_event.picks[pick_index].horizontal_slowness = 1.0 / velocity if _float_conv(line[46:51]) is not None: pick.backazimuth = _float_conv(line[46:51]) # Create new obspy.event.Amplitude class which references above Pick # only if there is an amplitude picked. if _float_conv(line[33:40]) is not None: _amplitude = Amplitude(generic_amplitude=_float_conv(line[33:40]), period=_float_conv(line[41:45]), pick_id=pick.resource_id, waveform_id=pick.waveform_id) if pick.phase_hint == 'IAML': # Amplitude for local magnitude _amplitude.type = 'AML' # Set to be evaluating a point in the trace _amplitude.category = 'point' # Default AML unit in seisan is nm (Page 139 of seisan # documentation, version 10.0) _amplitude.generic_amplitude /= 1e9 _amplitude.unit = 'm' _amplitude.magnitude_hint = 'ML' else: # Generic amplitude type _amplitude.type = 'A' if snr: _amplitude.snr = snr new_event.amplitudes.append(_amplitude) elif _int_conv(line[28:33]) is not None: # Create an amplitude instance for code duration also _amplitude = Amplitude(generic_amplitude=_int_conv(line[28:33]), pick_id=pick.resource_id, waveform_id=pick.waveform_id) # Amplitude for coda magnitude _amplitude.type = 'END' # Set to be evaluating a point in the trace _amplitude.category = 'duration' _amplitude.unit = 's' _amplitude.magnitude_hint = 'Mc' if snr is not None: _amplitude.snr = snr new_event.amplitudes.append(_amplitude) # Create new obspy.event.Arrival class referencing above Pick if _float_conv(line[33:40]) is None: arrival = Arrival(phase=pick.phase_hint, pick_id=pick.resource_id) if weight is not None: arrival.time_weight = weight if _int_conv(line[60:63]) is not None: arrival.backazimuth_residual = _int_conv(line[60:63]) if _float_conv(line[63:68]) is not None: arrival.time_residual = _float_conv(line[63:68]) if _float_conv(line[70:75]) is not None: arrival.distance = kilometers2degrees(_float_conv(line[70:75])) if _int_conv(line[76:79]) is not None: arrival.azimuth = _int_conv(line[76:79]) new_event.origins[0].arrivals.append(arrival) new_event.picks.append(pick) return new_event
def _read_picks(f, new_event): """ Internal pick reader. Use read_nordic instead. :type f: file :param f: File open in read mode :type wav_names: list :param wav_names: List of waveform files in the sfile :type new_event: :class:`~obspy.core.event.event.Event` :param new_event: event to associate picks with. :returns: :class:`~obspy.core.event.event.Event` """ f.seek(0) evtime = new_event.origins[0].time pickline = [] # Set a default, ignored later unless overwritten snr = None for line in f: if line[79] == '7': header = line break for line in f: if len(line.rstrip('\n').rstrip('\r')) in [80, 79] and \ line[79] in ' 4\n': pickline += [line] for line in pickline: if line[18:28].strip() == '': # If line is empty miss it continue weight = line[14] if weight == '_': phase = line[10:17] weight = 0 polarity = '' else: phase = line[10:14].strip() polarity = line[16] if weight == ' ': weight = 0 polarity_maps = {"": "undecidable", "C": "positive", "D": "negative"} try: polarity = polarity_maps[polarity] except KeyError: polarity = "undecidable" # It is valid nordic for the origin to be hour 23 and picks to be hour # 00 or 24: this signifies a pick over a day boundary. if int(line[18:20]) == 0 and evtime.hour == 23: day_add = 86400 pick_hour = 0 elif int(line[18:20]) == 24: day_add = 86400 pick_hour = 0 else: day_add = 0 pick_hour = int(line[18:20]) try: time = UTCDateTime(evtime.year, evtime.month, evtime.day, pick_hour, int(line[20:22]), float(line[23:28])) + day_add except ValueError: time = UTCDateTime(evtime.year, evtime.month, evtime.day, int(line[18:20]), pick_hour, float("0." + line[23:38].split('.')[1])) +\ 60 + day_add # Add 60 seconds on to the time, this copes with s-file # preference to write seconds in 1-60 rather than 0-59 which # datetime objects accept if header[57:60] == 'AIN': ain = _float_conv(line[57:60]) warnings.warn('AIN: %s in header, currently unsupported' % ain) elif header[57:60] == 'SNR': snr = _float_conv(line[57:60]) else: warnings.warn('%s is not currently supported' % header[57:60]) # finalweight = _int_conv(line[68:70]) # Create a new obspy.event.Pick class for this pick _waveform_id = WaveformStreamID(station_code=line[1:6].strip(), channel_code=line[6:8].strip(), network_code='NA') pick = Pick(waveform_id=_waveform_id, phase_hint=phase, polarity=polarity, time=time) try: pick.onset = onsets[line[9]] except KeyError: pass if line[15] == 'A': pick.evaluation_mode = 'automatic' else: pick.evaluation_mode = 'manual' # Note these two are not always filled - velocity conversion not yet # implemented, needs to be converted from km/s to s/deg # if not velocity == 999.0: # new_event.picks[pick_index].horizontal_slowness = 1.0 / velocity if _float_conv(line[46:51]) is not None: pick.backazimuth = _float_conv(line[46:51]) # Create new obspy.event.Amplitude class which references above Pick # only if there is an amplitude picked. if _float_conv(line[33:40]) is not None: _amplitude = Amplitude(generic_amplitude=_float_conv(line[33:40]), period=_float_conv(line[41:45]), pick_id=pick.resource_id, waveform_id=pick.waveform_id) if pick.phase_hint == 'IAML': # Amplitude for local magnitude _amplitude.type = 'AML' # Set to be evaluating a point in the trace _amplitude.category = 'point' # Default AML unit in seisan is nm (Page 139 of seisan # documentation, version 10.0) _amplitude.generic_amplitude /= 1e9 _amplitude.unit = 'm' _amplitude.magnitude_hint = 'ML' else: # Generic amplitude type _amplitude.type = 'A' if snr: _amplitude.snr = snr new_event.amplitudes.append(_amplitude) elif _int_conv(line[28:33]) is not None: # Create an amplitude instance for code duration also _amplitude = Amplitude(generic_amplitude=_int_conv(line[28:33]), pick_id=pick.resource_id, waveform_id=pick.waveform_id) # Amplitude for coda magnitude _amplitude.type = 'END' # Set to be evaluating a point in the trace _amplitude.category = 'duration' _amplitude.unit = 's' _amplitude.magnitude_hint = 'Mc' if snr is not None: _amplitude.snr = snr new_event.amplitudes.append(_amplitude) # Create new obspy.event.Arrival class referencing above Pick if _float_conv(line[33:40]) is None: arrival = Arrival(phase=pick.phase_hint, pick_id=pick.resource_id) if weight is not None: arrival.time_weight = weight if _int_conv(line[60:63]) is not None: arrival.backazimuth_residual = _int_conv(line[60:63]) if _float_conv(line[63:68]) is not None: arrival.time_residual = _float_conv(line[63:68]) if _float_conv(line[70:75]) is not None: arrival.distance = kilometers2degrees(_float_conv(line[70:75])) if _int_conv(line[76:79]) is not None: arrival.azimuth = _int_conv(line[76:79]) new_event.origins[0].arrivals.append(arrival) new_event.picks.append(pick) return new_event