SourceParametersEstimation/tau_p_raytracing.py

93 lines
3.4 KiB
Python
Raw Normal View History

2024-10-09 11:24:44 +02:00
import os
import logging
import pandas as pd
import scipy.io
from obspy.geodetics import kilometer2degrees
from obspy.taup import TauPyModel
from obspy.taup.taup_create import build_taup_model
from obspy.taup.tau import TauModel
class CustomTauPyModel(TauPyModel):
"""
Custom TauPyModel for filepath modification.
"""
def __init__(self, filepath, model="iasp91", verbose=False, planet_flattening=0.0):
super().__init__(model, verbose, planet_flattening)
self.verbose = verbose
self.planet_flattening = planet_flattening
self.model = self.read_model(filepath)
@staticmethod
def read_model(path):
return TauModel.deserialize(path, cache=None)
class TauPRayTracer:
""" Class for raytracing seismic waves using TauP """
def __init__(self, velocity_mat_file):
logging.basicConfig(filename="application.log",
filemode='a',
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
datefmt='%H:%M:%S',
level=logging.INFO)
self.logger = logging.getLogger('converter')
self.path = "."
self.velocity_model = self._setup_velocity_model(velocity_mat_file)
def _setup_velocity_model(self, velocity_mat_file_name):
velocity_npz_file_path = f"{velocity_mat_file_name[:-3]}npz"
velocity_npz_file_name = velocity_npz_file_path.split('/')[-1]
nd_file = self._mat2nd(velocity_mat_file_name)
build_taup_model(nd_file, output_folder=f"{self.path}")
os.remove(nd_file)
try:
return CustomTauPyModel(filepath=f"{self.path}/{velocity_npz_file_name}")
except FileNotFoundError as er:
self.logger.warning(er)
@staticmethod
def _mat2nd(velocity_mat_file):
# Load the .mat file
mat_contents = scipy.io.loadmat(velocity_mat_file)
data = mat_contents["d"][0][0]
# Create DataFrame from the lists
data_dict = {
'depth': data[0].T[0],
'vp': data[1].T[0],
'vs': data[2].T[0],
'ro': data[3].T[0],
'qp': data[4].T[0],
'qs': data[5].T[0]
}
df = pd.DataFrame(data_dict)
# Adding two new rows to model file - required by TauP
# Get the last row of the DataFrame
last_row = df.iloc[-1].copy()
# Append the last row to the DataFrame
df = pd.concat([df, pd.DataFrame(last_row).T], ignore_index=True)
last_row['depth'] = 6178.1
# Append the modified last row to the DataFrame
df = pd.concat([df, pd.DataFrame(last_row).T], ignore_index=True)
# Specify the name of the text file to save
nd_filename = f'{velocity_mat_file[:-3]}nd'
# Save the DataFrame to a text file
df.to_csv(nd_filename, sep='\t', index=False, header=False)
return nd_filename
def calculate_arrival(self, distance_in_km, source_depth_in_km, receiver_depth_in_km, phase: str):
phase_list = [phase, phase.swapcase()]
return self.velocity_model.get_travel_times(source_depth_in_km=source_depth_in_km,
distance_in_degree=kilometer2degrees(distance_in_km),
receiver_depth_in_km=receiver_depth_in_km,
phase_list=phase_list
)[0]