18
18
def _refine_theo_pick_time (
19
19
trace , phase , theo_pick_time , s_minus_p , freqmin , debug = False ):
20
20
"""
21
- Refine theoretical pick time through the analysis of the smoothed envelope
22
- of the trace.
21
+ Refine theoretical pick time through the analysis of the smoothed
22
+ and contrasted envelope of the trace.
23
23
"""
24
24
tr = trace .copy ()
25
- # demean , highpass, normalize
25
+ # Demean , highpass, normalize
26
26
tr .detrend ('demean' )
27
27
tr .filter ('highpass' , freq = freqmin , corners = 2 )
28
28
tr .normalize ()
29
- # smoothed envelope
30
- tr_smooth = tr .copy ()
31
- tr_smooth .data = np .abs (tr_smooth .data )
29
+ # Build the envelope, smooth it and increase the contrast
30
+ tr_envelope = tr .copy ()
31
+ tr_envelope .data = np .abs (tr_envelope .data )
32
32
if phase == 'P' :
33
33
# Less smoothing for P phases
34
34
npts = int (0.02 * s_minus_p / tr .stats .delta )
35
35
else :
36
36
# More smoothing for S phases
37
- npts = int (0.1 * s_minus_p / tr .stats .delta )
37
+ npts = int (0.05 * s_minus_p / tr .stats .delta )
38
38
for _ in range (10 ):
39
- tr_smooth .data = smooth (tr_smooth .data , npts )
40
- tr_smooth .normalize ()
39
+ tr_envelope .data = smooth (tr_envelope .data , npts )
40
+ # Increase the contrast by rising to a certain power
41
+ power = 3 if phase == 'P' else 6
42
+ tr_envelope .data = tr_envelope .data ** power
43
+ tr_envelope .normalize ()
41
44
# Cut the trace around the theoretical pick time
42
- tr_cut = tr_smooth .copy ()
45
+ tr_cut = tr_envelope .copy ()
43
46
cut_t0 = theo_pick_time - 0.7 * s_minus_p
44
47
cut_t1 = theo_pick_time + 0.3 * s_minus_p
45
48
tr_cut .trim (cut_t0 , cut_t1 )
46
- # cut shift is used for debug plots
47
- cut_shift = tr_smooth .stats .starttime - tr_cut .stats .starttime
48
- # cut again up to the maximum amplitude
49
- max_time = tr_cut .stats .starttime + tr_cut .times ()[np .argmax (tr_cut .data )]
50
- tr_cut .trim (
51
- starttime = tr_cut .stats .starttime ,
52
- endtime = max_time )
49
+ # Threshold the cut trace, then cut it again up to its maximum
50
+ rms = np .sqrt (np .mean (tr_cut .data ** 2 ))
51
+ threshold = 0.1 if phase == 'P' else 0.8
52
+ threshold *= rms
53
+ # Loop to try to find a threshold that gives a cut trace
54
+ # with at least 5 samples
55
+ for _ in range (10 ):
56
+ _tmp_tr_cut = tr_cut .copy ()
57
+ _tmp_tr_cut .data [_tmp_tr_cut .data >= threshold ] = threshold
58
+ max_time = \
59
+ _tmp_tr_cut .stats .starttime + \
60
+ _tmp_tr_cut .times ()[np .argmax (_tmp_tr_cut .data )]
61
+ _tmp_tr_cut .trim (
62
+ starttime = tr_cut .stats .starttime ,
63
+ endtime = max_time )
64
+ if len (_tmp_tr_cut .data ) < 5 :
65
+ threshold *= 2
66
+ else :
67
+ tr_cut = _tmp_tr_cut .copy ()
68
+ break
53
69
# Remove a linear function defined by first/last sample of the trace
54
70
tr_cut_detrend = tr_cut .copy ()
55
71
tr_cut_detrend .detrend ('simple' )
@@ -76,7 +92,8 @@ def _refine_theo_pick_time(
76
92
_fig , ax = plt .subplots (figsize = (10 , 5 ))
77
93
ax .set_ylim (- 1.1 , 1.1 )
78
94
ax .plot (tr .times (), tr .data , 'k' , lw = 0.5 )
79
- ax .plot (tr .times (), tr_smooth .data , 'r' )
95
+ ax .plot (tr .times (), tr_envelope .data , 'r' )
96
+ cut_shift = tr_envelope .stats .starttime - tr_cut .stats .starttime
80
97
ax .plot (tr_cut .times ()- cut_shift , tr_cut .data , 'b' , lw = 2 )
81
98
ax .plot (
82
99
tr_cut_detrend .times ()- cut_shift , tr_cut_detrend .data , 'g' , lw = 4 )
@@ -105,7 +122,7 @@ def _refine_theo_pick_time(
105
122
def refine_trace_picks (trace , freqmin , debug = False ):
106
123
"""
107
124
Refine theoretical pick times through the analysis of the smoothed
108
- envelope of the trace.
125
+ and contrasted envelope of the trace.
109
126
"""
110
127
p_arrival_phase = trace .stats .arrivals ['P' ][0 ]
111
128
p_arrival_time = trace .stats .arrivals ['P' ][1 ]
0 commit comments