-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding PreProcessing and DeepDenoiser
- Loading branch information
Marius Isken
committed
Feb 5, 2024
1 parent
4fbeeaf
commit 6d1ffe2
Showing
17 changed files
with
483 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
from __future__ import annotations | ||
|
||
from typing import TYPE_CHECKING, Literal | ||
|
||
from pydantic import BaseModel, Field, field_validator | ||
|
||
from qseek.utils import NSL | ||
|
||
if TYPE_CHECKING: | ||
from pyrocko.trace import Trace | ||
|
||
from qseek.waveforms.base import WaveformBatch | ||
|
||
|
||
class BatchPreProcessing(BaseModel): | ||
process: Literal["BasePreProcessing"] = "BasePreProcessing" | ||
|
||
stations: set[NSL] = Field( | ||
default=set(), | ||
description="List of station codes to process. E.g. ['6E.BFO', '6E.BHZ']. " | ||
"If empty, all stations are processed.", | ||
) | ||
|
||
@field_validator("stations") | ||
@classmethod | ||
def validate_stations(cls, v) -> set[NSL]: | ||
stations = set() | ||
for station in v: | ||
stations.add(NSL.parse(station)) | ||
return stations | ||
|
||
@classmethod | ||
def get_subclasses(cls) -> tuple[type[BatchPreProcessing], ...]: | ||
""" | ||
Returns a tuple of all the subclasses of BasePreProcessing. | ||
""" | ||
return tuple(cls.__subclasses__()) | ||
|
||
def select_traces(self, batch: WaveformBatch) -> list[Trace]: | ||
""" | ||
Selects traces from the given list based on the stations specified. | ||
Args: | ||
traces (list[Trace]): The list of traces to select from. | ||
Returns: | ||
list[Trace]: The selected traces. | ||
""" | ||
if not self.stations: | ||
return batch.traces | ||
return [ | ||
trace | ||
for trace in batch.traces | ||
if NSL.parse(trace.nslc_id).station in self.stations | ||
] | ||
|
||
async def prepare(self) -> None: | ||
""" | ||
Prepare the pre-processing module. | ||
""" | ||
pass | ||
|
||
async def process_batch(self, batch: WaveformBatch) -> WaveformBatch: | ||
""" | ||
Process a list of traces. | ||
Args: | ||
traces (list[Trace]): The list of traces to be processed. | ||
Returns: | ||
list[Trace]: The processed list of traces. | ||
""" | ||
raise NotImplementedError |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
from __future__ import annotations | ||
|
||
import asyncio | ||
import logging | ||
from typing import TYPE_CHECKING, Literal | ||
|
||
from obspy import Stream | ||
from pydantic import Field, PrivateAttr | ||
from pyrocko import obspy_compat | ||
|
||
from qseek.pre_processing.base import BatchPreProcessing | ||
|
||
if TYPE_CHECKING: | ||
from seisbench.models import DeepDenoiser as SeisBenchDeepDenoiser | ||
|
||
from qseek.waveforms.base import WaveformBatch | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
DenoiserModels = Literal["original", "instance"] | ||
obspy_compat.plant() | ||
|
||
|
||
class DeepDenoiser(BatchPreProcessing): | ||
"""De-noise the traces using the DeepDenoiser neural network (Zhu et al., 2019).""" | ||
|
||
process: Literal["deep-denoiser"] = "deep-denoiser" | ||
|
||
model: DenoiserModels = Field( | ||
"original", | ||
description="The model to use for denoising.", | ||
) | ||
torch_use_cuda: bool | str = Field( | ||
False, | ||
description="Whether to use CUDA for the PyTorch model." | ||
"A string can be used to specify the device.", | ||
) | ||
|
||
_denoiser: SeisBenchDeepDenoiser = PrivateAttr() | ||
|
||
async def prepare(self) -> None: | ||
import torch | ||
from seisbench.models import DeepDenoiser as SeisBenchDeepDenoiser | ||
|
||
self._denoiser = SeisBenchDeepDenoiser.from_pretrained(self.model) | ||
if self.torch_use_cuda: | ||
if isinstance(self.torch_use_cuda, bool): | ||
self._denoiser.cuda() | ||
else: | ||
self._denoiser.cuda(self.torch_use_cuda) | ||
|
||
self._denoiser.eval() | ||
try: | ||
logger.info("compiling DeepDenoiser model...") | ||
self._denoiser = torch.compile(self._denoiser, mode="max-autotune") | ||
except RuntimeError as exc: | ||
logger.warning( | ||
"failed to compile PhaseNet model, using uncompiled model.", | ||
exc_info=exc, | ||
) | ||
|
||
async def process_batch(self, batch: WaveformBatch) -> WaveformBatch: | ||
if self._denoiser is None: | ||
raise RuntimeError("DeepDenoiser model not initialized.") | ||
|
||
stream = Stream(tr.to_obspy_trace() for tr in self.select_traces(batch)) | ||
stream = await asyncio.to_thread(self._denoiser.annotate, stream) | ||
|
||
denoised_traces = [tr.to_pyrocko_trace() for tr in stream] | ||
for tr in denoised_traces: | ||
tr.channel = tr.channel.replace("DeepDenoiser_", "") | ||
|
||
return batch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from __future__ import annotations | ||
|
||
import asyncio | ||
from typing import TYPE_CHECKING, Literal | ||
|
||
from pydantic import Field, PositiveFloat | ||
|
||
from qseek.pre_processing.base import BatchPreProcessing | ||
|
||
if TYPE_CHECKING: | ||
from qseek.waveforms.base import WaveformBatch | ||
|
||
|
||
class Downsample(BatchPreProcessing): | ||
"""Downsample the traces to a new sampling frequency.""" | ||
|
||
process: Literal["downsample"] = "downsample" | ||
sampling_frequency: PositiveFloat = Field( | ||
100.0, | ||
description="The new sampling frequency in Hz.", | ||
) | ||
|
||
async def process_batch(self, batch: WaveformBatch) -> WaveformBatch: | ||
desired_deltat = 1 / self.sampling_frequency | ||
|
||
def worker() -> None: | ||
for trace in self.select_traces(batch): | ||
if trace.deltat < desired_deltat: | ||
trace.downsample_to(deltat=desired_deltat, allow_upsample_max=3) | ||
|
||
await asyncio.to_thread(worker) | ||
return batch |
Oops, something went wrong.