This documentation is not for the latest stable Salvus version.
MIN_PERIOD = 70.0
MAX_PERIOD = 120.0
SIMULATION_TIME_IN_SECONDS = 1200.0
SALVUS_FLOW_SITE_NAME = "local"
RANKS_PER_JOB = 8
PROJECT_DIR = "project_dir_central_europe"
period_band_name = f"{int(MIN_PERIOD)}_{int(MAX_PERIOD)}_seconds"
import pathlib
from salvus import namespace as sn
Common moment magnitude vs fault length relations, constants taken from Leonard, M. (2014). Self-Consistent Earthquake Fault-Scaling Relations: Update and Extension to Stable Continental Strike-Slip Faults. Bulletin of the Seismological Society of America, 104(6), 2953–2965. doi:10.1785/0120140087
Screenshot from the EFEHR Hazard Map Portal, CC BY-SA 3.0 (unported).
Project
around it. Domain
objects can be visualized so it is easy to try a few values until the desired result is achieved. This will be the inversion domain so the goal here is to get as close to the desired region as possible as it cannot be changed after a project has been created. The map projections between the above image and the domain plot are different but they show a very similar region.lat_center, lon_center = 48.0, 10.0
lat_extent, lon_extent = 25.0, 25.0
domain = sn.domain.dim3.SphericalChunkDomain(
lat_center=lat_center,
lat_extent=lat_extent,
lon_center=lon_center,
lon_extent=lon_extent,
radius_in_meter=6371e3,
)
domain.plot()
p = sn.Project.from_domain(
path=pathlib.Path(PROJECT_DIR), domain=domain, load_if_exists=True
)
if not p.events.list():
for file in sorted(pathlib.Path("data").glob("*.h5")):
print(f"Adding external data from `{file}`")
p.actions.seismology.add_asdf_file(
filename=file,
data_name="raw_data",
receiver_fields=["displacement"],
)
Adding external data from `data/event_CRETE_GREECE_Mag_6.15_2015-04-16-18-07.h5` Adding external data from `data/event_ICELAND_REGION_Mag_5.75_2020-06-20-19-26.h5` Adding external data from `data/event_STRAIT_OF_GIBRALTAR_Mag_6.38_2016-01-25-04-22.h5`
if not p.events.list():
p += p.actions.seismology.get_events_from_csv_catalog_file(
filename="./data/gcmt_catalog.csv.bz2",
max_count=30,
min_moment_magnitude=5.75,
max_moment_magnitude=6.5,
min_distance_in_meters=500e3,
min_year=2010,
max_year=2020,
random_seed=123456,
)
for event in p.events.list():
if p.waveforms.has_data("EXTERNAL_DATA:raw_data", event=event):
continue
p.actions.seismology.download_data_for_event(
data_name="raw_data",
event=event,
# If you leave this empty all providers will be queried.
download_providers=["IRIS"],
add_receivers_to_project_event=True,
receiver_fields=["displacement"],
seconds_before_event=240.0,
seconds_after_event=1.2 * SIMULATION_TIME_IN_SECONDS,
)
p.viz.nb.domain()
p.viz.nb.waveforms(
data="EXTERNAL_DATA:raw_data", receiver_field="displacement"
)
EXTERNAL_DATA:raw_data
data name. SalvusProject refers to waveform data by data type (or namespace if you will) and name within that data type. Everything before the colon is the data type, everything after the name. If no data type is given it will default to SYNTHETIC_DATA
. SalvusProject distinguishes three data types:SYNTHETIC_DATA
: Synthetically computed waveforms. These are always computed within the project structure.EXTERNAL_DATA
: Observed or externally computed waveform data.PROCESSED_DATA
: Any processed data. The data can originate from synthetic, external or even other processed data but a function sits in between that processed the data in some fashion.FilteredHeaviside
source time function. This will become crucial at later stages because it saves us from having to process the synthetics (and account for that in the adjoint source computation).from salvus.project.tools.processing.seismology import (
get_remove_response_and_bandpass_filter_processing_function,
)
processing_function = (
get_remove_response_and_bandpass_filter_processing_function(
min_frequency_in_hertz=1.0 / MAX_PERIOD,
max_frequency_in_hertz=1.0 / MIN_PERIOD,
highpass_corners=3,
lowpass_corners=3,
zerophase=False,
)
)
p.add_to_project(
sn.processing.seismology.SeismologyProcessingConfiguration(
name=period_band_name,
data_source_name="EXTERNAL_DATA:raw_data",
processing_function=processing_function,
),
overwrite=True,
)
p.viz.nb.waveforms(
[f"PROCESSED_DATA:{period_band_name}"],
receiver_field="displacement",
)