Skip to content

Commit 89ffa82

Browse files
committed
fixes phase follow
1 parent de21a19 commit 89ffa82

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

lightguide/blast.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from __future__ import annotations
2+
from collections import deque
23

34
import logging
45
from copy import deepcopy
@@ -330,6 +331,8 @@ def follow_phase(
330331
window_size: int | tuple[int, int] = 50,
331332
threshold: float = 5e-1,
332333
max_shift: int = 20,
334+
stack: bool = False,
335+
no_of_stacks: int = 5,
333336
) -> tuple[np.ndarray, list[datetime], np.ndarray]:
334337
"""Follow a phase pick through a Blast.
335338
@@ -340,7 +343,7 @@ def follow_phase(
340343
2. Calculate normalized cross correlate with downwards neighbor.
341344
3. Evaluate maximum x-correlation in allowed window (max_shift).
342345
4. Update template trace and go to 2.
343-
346+
4a. if stack=True: stack templates for correlation to stabilize
344347
5. Repeat for upward neighbors.
345348
346349
Args:
@@ -353,6 +356,12 @@ def follow_phase(
353356
Defaults to 5e-1.
354357
max_shift (int, optional): Maximum allowed shift in samples for
355358
neighboring picks. Defaults to 20.
359+
stack (bool): If True - (a default number of 5) templates will be stacked and used
360+
as correlation template. Stacking close to the initial template is limited to
361+
the distance to the initial tamplate. I.e. the correlation of a trace 3 traces
362+
next to the initial template will only use a stacked template of 3 traces
363+
(initial trace an trace 1 and 2 next to it), altough the no_of_stacks is set higher.
364+
no_of_stacks (int): Numbers of traces to stack to define the template.
356365
357366
Returns:
358367
tuple[np.ndarray, list[datetime], np.ndarray]: Tuple of channel number,
@@ -375,12 +384,21 @@ def follow_phase(
375384
def prepare_template(data: np.ndarray) -> np.ndarray:
376385
return data * template_taper
377386

387+
# def stack_n_straces(data: np.ndarray,stack_traces) -> np.ndarray:
388+
389+
# return stacked_data
390+
378391
def correlate(data: np.ndarray, direction: Literal[1, -1] = 1) -> None:
379392
template = root_template.copy()
380-
index = root_idx
393+
template_deque = deque([np.array(template)])
381394

395+
index = root_idx
382396
for ichannel, trace in enumerate(data):
383397
template = prepare_template(template)
398+
# check if stacking is activated
399+
if stack and len(template_deque) > 2:
400+
template = prepare_template(template_stack)
401+
384402
norm = np.sqrt(np.sum(template**2)) * np.sqrt(np.sum(trace**2))
385403
correlation = np.correlate(trace, template, mode="same")
386404
correlation = np.abs(correlation / norm)
@@ -395,7 +413,7 @@ def correlate(data: np.ndarray, direction: Literal[1, -1] = 1) -> None:
395413
phase_correlation = correlation[phase_idx]
396414
phase_time = self._sample_to_time(int(phase_idx))
397415

398-
if phase_correlation < threshold:
416+
if phase_correlation > threshold:
399417
continue
400418

401419
# Avoid the edges
@@ -409,14 +427,21 @@ def correlate(data: np.ndarray, direction: Literal[1, -1] = 1) -> None:
409427
template = trace[
410428
phase_idx - window_size[0] : phase_idx + window_size[1] + 1
411429
].copy()
430+
431+
# stacking
432+
if len(template_deque) <= no_of_stacks:
433+
template_deque.append(template)
434+
if len(template_deque) == no_of_stacks + 1:
435+
template_deque.popleft()
436+
template_stack = np.sum(template_deque, axis=0) / len(template_deque)
437+
412438
index = phase_idx
413439

414440
correlate(self.data[pick_channel:])
415441
correlate(self.data[: pick_channel - 1][::-1], direction=-1)
416442

417443
pick_channels = np.array(pick_channels) + self.start_channel
418444
pick_correlations = np.array(pick_correlations)
419-
420445
return pick_channels, pick_times, pick_correlations
421446

422447
def taper(self, alpha: float = 0.05) -> None:

0 commit comments

Comments
 (0)