Skip to content

Commit 4f36c35

Browse files
committed
speed up updating of network magnitude
..by finding out which already existing station magnitudes can be reused. It was taking ages with many stations because even unchanged stations were recalculated when picking magnitudes on one station.
1 parent 2a47bca commit 4f36c35

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

CHANGELOG.txt

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ master
1919
temporary directory for easy reuse (see #79)
2020
- taper settings (applied before any filtering) can now be controlled via
2121
config file (see #80)
22+
- speed up magnitude calculation by reusing unchanged station magnitudes when
23+
updating the network magnitude while changing magnitude picks on one station
24+
(see #88)
2225

2326
0.5.1
2427
- fix getting metadata via arclink (see #65)

obspyck/event_helper.py

+10
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ def __init__(self, *args, **kwargs):
7474

7575

7676
class StationMagnitude(obspy.core.event.StationMagnitude, CommonEventHelper):
77+
# we use _amplitude_ids to store amplitude IDS of used Amplitudes, since
78+
# QuakeML only has room to store a single Amplitude for a StationMagnitude
79+
# unfortunately
80+
do_not_warn_on = ['extra', '_amplitude_ids']
81+
7782
def __init__(self, *args, **kwargs):
7883
super(StationMagnitude, self).__init__()
7984
self.used = True
@@ -168,6 +173,11 @@ def __init__(self, origin=None, pick=None, *args, **kwargs):
168173

169174

170175
class Amplitude(obspy.core.event.Amplitude, CommonEventHelper):
176+
# we use _station_magnitude_id to store ID of derived StationMagnitude,
177+
# since QuakeML does not link back and this makes it easier to find the
178+
# correct one
179+
do_not_warn_on = ['extra', '_station_magnitude_id']
180+
171181
def __init__(self, seed_string=None, *args, **kwargs):
172182
super(Amplitude, self).__init__()
173183
if seed_string:

obspyck/obspyck.py

+29-3
Original file line numberDiff line numberDiff line change
@@ -2998,7 +2998,7 @@ def hypoDist(self, coords):
29982998
def calculateStationMagnitudes(self):
29992999
event = self.catalog[0]
30003000
origin = event.origins[0]
3001-
event.station_magnitudes = []
3001+
station_magnitudes = []
30023002

30033003
netstaloc = set([(amp.waveform_id.network_code,
30043004
amp.waveform_id.station_code,
@@ -3011,7 +3011,22 @@ def calculateStationMagnitudes(self):
30113011
pazs = []
30123012
channels = []
30133013
p2ps = []
3014-
for amplitude in self.getAmplitudes(net, sta, loc):
3014+
amplitudes_ = self.getAmplitudes(net, sta, loc)
3015+
3016+
# check if we can reuse an existing StationMagnitude
3017+
amp_ids = set(str(amp.resource_id) for amp in amplitudes_)
3018+
for sm in event.station_magnitudes:
3019+
if sm.get('_amplitude_ids') == amp_ids:
3020+
break
3021+
else:
3022+
sm = None
3023+
if sm is not None:
3024+
station_magnitudes.append(sm)
3025+
self.critical('reusing existing magnitude for %s: %0.2f' % (
3026+
sta, sm.mag))
3027+
continue
3028+
3029+
for amplitude in amplitudes_:
30153030
self.debug(str(amplitude))
30163031
timedelta = amplitude.get_timedelta()
30173032
self.debug("Timedelta: " + str(timedelta))
@@ -3046,7 +3061,10 @@ def calculateStationMagnitudes(self):
30463061
dist = self.hypoDist(tr.stats.coordinates)
30473062
mag = estimate_magnitude(pazs, p2ps, timedeltas, dist)
30483063
sm = StationMagnitude()
3049-
event.station_magnitudes.append(sm)
3064+
# store ids of used amplitudes, so we're able to tell when a
3065+
# station magnitude needs to be updated
3066+
sm._amplitude_ids = amp_ids
3067+
station_magnitudes.append(sm)
30503068
sm.origin_id = origin.resource_id
30513069
sm.method_id = "/".join(
30523070
[ID_ROOT, "station_magnitude_method", "obspyck", "2"])
@@ -3062,8 +3080,16 @@ def calculateStationMagnitudes(self):
30623080
extra.amplitudeIDs = {'value': ",".join([str(a.resource_id)
30633081
for a in amplitudes]),
30643082
'namespace': NAMESPACE}
3083+
# need to do this at the very end when StationMagnitude is not
3084+
# changed anymore, and we need to avoid setting a new random ID
3085+
# automatically (in event_helper.py)
3086+
for amplitude in amplitudes:
3087+
super(Amplitude, amplitude).__setattr__(
3088+
'_station_magnitude_id', str(sm.resource_id))
30653089
self.critical('calculated new magnitude for %s: %0.2f (channels: %s)' % (
30663090
sta, mag, ",".join(channels)))
3091+
# finally switch out station magnitudes
3092+
event.station_magnitudes = station_magnitudes
30673093

30683094
#see http://www.scipy.org/Cookbook/LinearRegression for alternative routine
30693095
#XXX replace with drawWadati()

0 commit comments

Comments
 (0)