# http://pyrocko.org - GPLv3 # # The Pyrocko Developers, 21st Century # ---|P------/S----------~Lg----------
else: polarity_symbols = {1: '+', -1: '-', None: '', 0: '0'}
return None
return None
return int(s)
tt, ms = gmtime_x(timestamp) return mystrftime(None, tt, ms)
''' General purpose marker GUI element and base class for :py:class:`EventMarker` and :py:class:`PhaseMarker`.
:param nslc_ids: list of (network, station, location, channel) tuples (may contain wildcards) :param tmin: start time :param tmax: end time :param kind: (optional) integer to distinguish groups of markers (color-coded) '''
def from_string(line):
def fail(): raise MarkerParseError( 'Unable to create marker from string: "%s"' % line)
def parsedate(ymd, hms, sfs): return calendar.timegm( time.strptime(ymd+' '+hms, '%Y-%m-%d %H:%M:%S')) + float(sfs)
try: toks = line.split() if len(toks) in (4, 5): tmin = parsedate(*toks[:3]) tmax = tmin
elif len(toks) in (8, 9): tmin = parsedate(*toks[:3]) tmax = parsedate(*toks[3:6])
else: fail()
if len(toks) in (5, 9): kind = int(toks[-2]) else: kind = int(toks[-1])
nslc_ids = [] if len(toks) in (5, 9): for snslc in toks[-1].split(','): nslc = snslc.split('.') if len(nslc) != 4: fail()
nslc_ids.append(tuple(nslc))
except MarkerParseError: fail()
return Marker(nslc_ids, tmin, tmax, kind=kind)
'''Static method to write marker objects to file.
:param markers: list of :py:class:`Marker` objects :param fn: filename as string :param fdigits: number of decimal digits to use for sub-second time strings (default 3) ''' row.append('None') else:
def load_markers(fn): ''' Static method to load markers from file.
:param filename: filename as string :returns: list of :py:class:`Marker`, :py:class:`EventMarker` or :py:class:`PhaseMarker` objects ''' f.seek(0) for iline, line in enumerate(f): line = str(line.decode('ascii')) sline = line.strip() if not sline or sline.startswith('#'): continue try: m = Marker.from_string(sline) markers.append(m)
except MarkerParseError: logger.warning( 'Invalid marker definition in line %i of file "%s"' % (iline+1, fn))
f.close()
else:
else: logger.warning('Unsupported Markers File Version')
'aluminium4', 'aluminium5', 'aluminium6')]
'scarletred1', 'scarletred2', 'scarletred3', 'chameleon1', 'chameleon2', 'chameleon3', 'skyblue1', 'skyblue2', 'skyblue3', 'orange1', 'orange2', 'orange3', 'plum1', 'plum2', 'plum3', 'chocolate1', 'chocolate2', 'chocolate3')]
'''Set ``nslc_ids``, start time and end time of :py:class:`Marker`
:param nslc_ids: list or set of (network, station, location, channel) tuples :param tmin: start time :param tmax: end time '''
'''Set kind of :py:class:`Marker`
:param kind: (optional) integer to distinguish groups of markers (color-coded) '''
'''Get *start time* of :py:class:`Marker`'''
'''Get *end time* of :py:class:`Marker`'''
'''Get marker's network-station-location-channel pattern.
:returns: list or set of (network, station, location, channel) tuples
The network, station, location, or channel strings may contain wildcard expressions. ''' return self.nslc_ids
return self.alerted
self.alerted = state
'''See documentation of :py:func:`pyrocko.util.match_nslc`''' patterns = ['.'.join(x[:3]) for x in self.nslc_ids] return util.match_nslc(patterns, nsl)
'''See documentation of :py:func:`pyrocko.util.match_nslc`'''
'''If one *nslc_id* defines this marker return this id. If more than one *nslc_id* is defined in the :py:class:`Marker`s *nslc_ids* raise :py:exc:`MarkerOneNSLCRequired`.''' if len(self.nslc_ids) != 1: raise MarkerOneNSLCRequired()
return list(self.nslc_ids)[0]
return ''
''' Get a copy of this marker. ''' return copy.deepcopy(self)
def __str__(self): traces = ','.join(['.'.join(nslc_id) for nslc_id in self.nslc_ids]) st = myctime if self.tmin == self.tmax: return '%s %i %s' % (st(self.tmin), self.kind, traces) else: return '%s %s %g %i %s' % ( st(self.tmin), st(self.tmax), self.tmax-self.tmin, self.kind, traces)
t, format='%Y-%m-%d %H:%M:%S.'+'%iFRAC' % fdigits)
vals.extend(st(self.tmax).split()) vals.append(self.tmax-self.tmin)
ws.extend([10, 9+fdigits, 12])
def parse_attributes(vals): tmax = util.str_to_time(vals[2] + ' ' + vals[3]) i = 5
nslc_ids = [] else: [tuple(nslc_id.split('.')) for nslc_id in traces.split(',')])
def from_attributes(vals):
return cl(1)
self, p, time_projection, y_projection, draw_line=True, draw_triangle=False, **kwargs):
linepen.setColor(qg.QColor(150, 150, 150))
[-0.577*s, 0., 0.577*s], [0., 1.*s, 0.]) [-0.577*s, 0., 0.577*s], [0., -1.*s, 0.])
self, viewer, p, tr, time_projection, track_projection, gain, outline_label=False):
return
self.tmin, self.tmax, inplace=False, include_last=True, snap=(math.ceil, math.floor))
vdata = track_projection(gain*snippet.get_ydata()) udata_min = float( time_projection(snippet.tmin)) udata_max = float( time_projection(snippet.tmin+snippet.deltat*(vdata.size-1))) udata = num.linspace(udata_min, udata_max, vdata.size) qpoints = gui_util.make_QPolygonF(udata, vdata) pen.setWidth(1) p.setPen(pen) p.drawPolyline(qpoints) pen.setWidth(2) p.setPen(pen) drawpoint(*tr(self.tmin, clip=True, snap=math.ceil)) drawpoint(*tr(self.tmax, clip=True, snap=math.floor))
du = -7 else: p, u+du, v0, label, label_bg, 'TR', outline=outline_label)
except IndexError: pass
self, event=None, phasename=None, polarity=None, automatic=None, incidence_angle=None, takeoff_angle=None):
return
self._event_hash = event.get_hash() self._event_time = event.time else:
return
self.convert_to_marker()
""" An EventMarker is a GUI element representing a seismological event
:param event: A :py:class:`pyrocko.model.Event` object containing meta information of a seismological event :param kind: (optional) integer to distinguish groups of markers :param event_hash: (optional) hash code of event (see: :py:meth:`pyrocko.model.Event.get_hash`) """
else:
t.append('M%3.1f' % mag)
t.append(reg)
self, p, time_projection, y_projection, draw_line=False, draw_triangle=True)
p, u, v0-10., self.label(), label_bg, 'CB', outline=self._active)
'''Return an instance of the :py:class:`pyrocko.model.Event` associated to this :py:class:`EventMarker`'''
gain):
ev = self.get_event() evs = [] for k in 'magnitude lat lon depth name region catalog'.split(): if ev.__dict__[k] is not None and ev.__dict__[k] != '': if k == 'depth': sv = '%g km' % (ev.depth * 0.001) else: sv = '%s' % ev.__dict__[k] evs.append('%s = %s' % (k, sv))
return ', '.join(evs)
attributes = ['event:'] attributes.extend(Marker.get_attributes(self, fdigits=fdigits)) del attributes[-1] e = self._event attributes.extend([ e.get_hash(), e.lat, e.lon, e.depth, e.magnitude, e.catalog, e.name, e.region])
return attributes
ws = [6] ws.extend(Marker.get_attribute_widths(self, fdigits=fdigits)) del ws[-1] ws.extend([14, 12, 12, 12, 4, 5, 0, 0]) return ws
def from_attributes(vals):
vals[1:] + ['None']) str_to_float_or_none(x) for x in vals[5:9]] str_to_str_or_none(x) for x in vals[9:]] lat, lon, time=tmin, name=name, depth=depth, magnitude=magnitude, region=region, catalog=catalog) e, kind, event_hash=str_to_str_or_none(vals[4]))
''' A PhaseMarker is a GUI-element representing a seismological phase arrival
:param nslc_ids: list of (network, station, location, channel) tuples (may contain wildcards) :param tmin: start time :param tmax: end time :param kind: (optional) integer to distinguish groups of markers (color-coded) :param event: a :py:class:`pyrocko.model.Event` object containing meta information of a seismological event :param event_hash: (optional) hash code of event (see: :py:meth:`pyrocko.model.Event.get_hash`) :param event_time: (optional) time of the associated event :param phasename: (optional) name of the phase associated with the marker :param polarity: (optional) polarity of arriving phase :param automatic: (optional) :param incident_angle: (optional) incident angle of phase :param takeoff_angle: (optional) take off angle of phase ''' self, nslc_ids, tmin, tmax, kind=0, event=None, event_hash=None, event_time=None, phasename=None, polarity=None, automatic=None, incidence_angle=None, takeoff_angle=None):
gain):
self, viewer, p, tr, time_projection, track_projection, gain, outline_label=( self._event is not None and self._event == viewer.get_active_event()))
t.append(self.get_polarity_symbol())
t.append('@')
'''Return an instance of the :py:class:`pyrocko.model.Event` associated to this :py:class:`EventMarker`'''
else: if self._event is None: return None else: return self._event.get_hash()
return self._event.time else:
raise ValueError('polarity has to be 1, -1, 0 or None')
return polarity_symbols.get(self._polarity, '')
return self._polarity
toks = [] for k in 'incidence_angle takeoff_angle polarity'.split(): v = getattr(self, '_' + k) if v is not None: toks.append('%s = %s' % (k, v))
return ', '.join(toks)
attributes = ['phase:'] attributes.extend(Marker.get_attributes(self, fdigits=fdigits))
et = None, None if self._event: et = self._st(self._event.time, fdigits).split() elif self._event_time: et = self._st(self._event_time, fdigits).split()
attributes.extend([ self.get_event_hash(), et[0], et[1], self._phasename, self._polarity, self._automatic])
return attributes
return util.time_to_str( t, format='%Y-%m-%d %H:%M:%S.'+'%iFRAC' % fdigits)
ws = [6] ws.extend(Marker.get_attribute_widths(self, fdigits=fdigits)) ws.extend([14, 12, 12, 8, 4, 5]) return ws
def from_attributes(vals): nbasicvals = 7 else: vals[1:1+nbasicvals])
i = 11
else: event_time = None
event_hash=event_hash, event_time=event_time, phasename=phasename, polarity=polarity, automatic=automatic)
''' Load markers from file.
:param filename: filename as string :returns: list of :py:class:`Marker` Objects '''
''' Save markers to file.
:param markers: list of :py:class:`Marker` Objects :param filename: filename as string :param fdigits: number of decimal digits to use for sub-second time strings '''
return Marker.save_markers(markers, filename, fdigits=fdigits)
''' Reassociate phases to events after import from markers file. '''
marker.set_event(hash_to_events[h]) marker.set_event_hash(None) |