138 lines
4.9 KiB
Python
138 lines
4.9 KiB
Python
import logging
|
|
|
|
from obspy import read, read_events, read_inventory
|
|
|
|
from SpectralAnalysis import SpectralAnalysis
|
|
|
|
|
|
def count_matching_stations(stream, inventory):
|
|
"""
|
|
Count how many stations from the given stream are present in the inventory.
|
|
|
|
Parameters:
|
|
- stream: ObsPy Stream object containing seismic data.
|
|
- inventory: ObsPy Inventory object containing network and station metadata.
|
|
|
|
Returns:
|
|
- count: Number of stations from the stream found in the inventory.
|
|
"""
|
|
# Extract unique station codes from the stream
|
|
stream_stations = set([trace.stats.station for trace in stream])
|
|
|
|
# Extract unique station codes from the inventory
|
|
inventory_stations = set([station.code for network in inventory for station in network.stations])
|
|
|
|
# Count how many stations from the stream are in the inventory
|
|
count = len(stream_stations.intersection(inventory_stations))
|
|
|
|
return count, len(stream_stations)
|
|
|
|
|
|
def main(waveforms, network_inventory, picks_qml, event_latitude, event_longitude, event_depth, vp, vs, density, taper_type, taper_len,
|
|
window_len, freq_min, freq_max, min_sn_ratio=1, min_energy_ratio=1, p_wave_analysis=True, s_wave_analysis=True,
|
|
raytracing=True, allow_station_elevations=False,
|
|
source_model="Madariaga", sp_fit_model="FBoatwright", norm="L2", z_threshold=6,
|
|
q_min=1, q_max=400, velocity_model=None):
|
|
"""
|
|
Main function for application: SPECTRALPARAMETERS
|
|
Arguments:
|
|
waveforms: path to input file of type 'seismogram'
|
|
Velocity model: path to input file of type 'velocity_model'
|
|
network_inventory: path to input file of type 'inventory'
|
|
event_qml: path to input file of type 'quakeml_seismogram_picks'
|
|
raytracing: parameter of type 'BOOLEAN'
|
|
save plots: parameter of type 'BOOLEAN'
|
|
Returns:
|
|
File(s) named 'Katalog sejsmiczny' of type 'quakeml_seismogram_picks' and format 'XML' from working directory
|
|
:param event_qml:
|
|
"""
|
|
|
|
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)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
config = {
|
|
# filenames
|
|
"P_WAVE_SP_FITTING_RESULTS_JSON": "P_wave_analysis_sp_fit_solutions.json",
|
|
"S_WAVE_SP_FITTING_RESULTS_JSON": "S_wave_analysis_sp_fit_solutions.json",
|
|
"P_WAVE_JK_RESULTS": "P_wave_analysis_JK_solutions.csv",
|
|
"S_WAVE_JK_RESULTS": "S_wave_analysis_JK_solutions.csv",
|
|
"P_WAVE_SP_FITTING_RESULTS": "P_wave_analysis_sp_fit_solutions.csv",
|
|
"S_WAVE_SP_FITTING_RESULTS": "S_wave_analysis_sp_fit_solutions.csv",
|
|
"EVENT_RESULTS": "results.csv",
|
|
"velocity_mat_file": velocity_model,
|
|
# app options
|
|
"P_wave_analysis": p_wave_analysis,
|
|
"S_wave_analysis": s_wave_analysis,
|
|
"raytrace": raytracing,
|
|
"allow_station_elev": allow_station_elevations,
|
|
|
|
#event location
|
|
"longitude": event_longitude,
|
|
"latitude": event_latitude,
|
|
"depth": event_depth, # in meters
|
|
|
|
# phase hints
|
|
"p_phase_hint": ["P", "Pg"],
|
|
"s_phase_hint": ["S", "Sg"],
|
|
|
|
# source parameters
|
|
"vp": vp,
|
|
"vs": vs,
|
|
"density": density,
|
|
|
|
# window parameters
|
|
"taper_len": taper_len,
|
|
"window_len": window_len,
|
|
"taper_type": taper_type,
|
|
# filter parameters
|
|
"freq_min": freq_min,
|
|
"freq_max": freq_max,
|
|
# frequency signal-to-noise ratio
|
|
"min_sn_ratio": min_sn_ratio,
|
|
# if station signal-to-noise ratio
|
|
"min_energy_ratio": min_energy_ratio,
|
|
|
|
# L1 / L2
|
|
"norm": norm,
|
|
# Spectrum fitting model: FBrune / FBoatwright
|
|
"sp_fit_model": sp_fit_model,
|
|
# Source model: Madariaga / Brune
|
|
"sp_source_model": source_model,
|
|
|
|
# outliers detection
|
|
"z_threshold": z_threshold,
|
|
|
|
# q - damping limits
|
|
"q_min": q_min,
|
|
"q_max": q_max,
|
|
|
|
}
|
|
|
|
# reading files
|
|
stream = read(waveforms)
|
|
inv = read_inventory(network_inventory)
|
|
|
|
qml = read_events(picks_qml).events[0]
|
|
|
|
if not stream:
|
|
msg = "MSEED file is empty"
|
|
logger.error(msg)
|
|
raise Exception(msg)
|
|
if not inv or len(inv) == 0:
|
|
msg = "Inventory file is empty"
|
|
logger.error(msg)
|
|
raise Exception(msg)
|
|
else:
|
|
count, total = count_matching_stations(stream, inv)
|
|
logger.info(f"{count} out of {total} stations in stream are in the inventory")
|
|
if count == 0:
|
|
msg = "No stations from MSEED in the Network Inventory"
|
|
logger.error(msg)
|
|
raise Exception(msg)
|
|
else:
|
|
sa = SpectralAnalysis(stream=stream, event=qml, inventory=inv, config=config, logger=logger)
|
|
sa.run() |