Spaces:
Sleeping
Sleeping
File size: 6,059 Bytes
448e634 b359d50 4fcf8ef ff71114 4fcf8ef b359d50 4fcf8ef b359d50 4fcf8ef 2eccf6c 4fcf8ef 2eccf6c b359d50 4fcf8ef 2eccf6c b359d50 2eccf6c 4fcf8ef 2eccf6c 4fcf8ef 2eccf6c 4fcf8ef 2eccf6c 4fcf8ef 86764f2 2eccf6c 6becbe6 4fcf8ef 2eccf6c 6becbe6 4fcf8ef 2eccf6c 4fcf8ef 86764f2 4fcf8ef 2eccf6c 4fcf8ef 2eccf6c 4fcf8ef 2eccf6c 4fcf8ef 86764f2 2eccf6c 4fcf8ef 2013310 4fcf8ef 2eccf6c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
import streamlit as st
import pandas as pd
from obspy import UTCDateTime
from obspy.clients.fdsn import Client
import matplotlib.pyplot as plt
# --- App Configuration ---
st.set_page_config(
page_title="Taiwan Earthquake Explorer πΉπΌ",
page_icon="π",
layout="wide"
)
# --- FDSN Client & Caching ---
client = Client("IRIS")
# CORRECTED FUNCTION
@st.cache_data
def search_earthquakes(start_time_str, end_time_str, min_mag, min_lat, max_lat, min_lon, max_lon):
"""
Searches for earthquake events using the ObsPy client.
Accepts time as strings to enable caching.
"""
try:
# Convert string arguments back to UTCDateTime objects inside the function
start_time = UTCDateTime(start_time_str)
end_time = UTCDateTime(end_time_str)
catalog = client.get_events(
starttime=start_time,
endtime=end_time,
minlatitude=min_lat,
maxlatitude=max_lat,
minlongitude=min_lon,
maxlongitude=max_lon,
minmagnitude=min_mag,
orderby="time-asc"
)
return catalog
except Exception as e:
st.error(f"Could not retrieve event data: {e}")
return None
@st.cache_data
def get_waveforms_for_event(_event):
"""
Retrieves and processes seismic waveforms for a given event.
_event is a tuple of event properties to make it hashable for caching.
"""
event_time_str, _, _, _ = _event
event_time = UTCDateTime(event_time_str)
t_start = event_time - 30
t_end = event_time + 5 * 60
try:
stream = client.get_waveforms(
network="TW", station="*", location="*", channel="BH*",
starttime=t_start, endtime=t_end, attach_response=True
)
if len(stream) > 0:
stream.detrend("linear")
stream.taper(max_percentage=0.05, type="cosine")
stream.remove_response(output="VEL")
return stream
else:
return None
except Exception:
return None
# --- Streamlit User Interface ---
st.title("π Taiwan Earthquake Explorer")
st.markdown("Search, map, and visualize seismic data from the TW network via IRIS FDSN.")
st.sidebar.header("π Search Parameters")
# --- Sidebar Controls ---
default_start = UTCDateTime("2024-04-02T23:00:00")
default_end = UTCDateTime("2024-04-03T01:00:00")
start_date = st.sidebar.date_input("Start Date", value=default_start.date)
start_time_str = st.sidebar.text_input("Start Time (UTC)", value=default_start.strftime("%H:%M:%S"))
end_date = st.sidebar.date_input("End Date", value=default_end.date)
end_time_str = st.sidebar.text_input("End Time (UTC)", value=default_end.strftime("%H:%M:%S"))
start_utc = UTCDateTime(f"{start_date}T{start_time_str}")
end_utc = UTCDateTime(f"{end_date}T{end_time_str}")
st.sidebar.markdown("---")
min_mag = st.sidebar.slider("Minimum Magnitude", 2.0, 8.0, 5.5)
st.sidebar.markdown("---")
st.sidebar.subheader("Geographical Region (Taiwan)")
min_lat = st.sidebar.number_input("Min Latitude", value=21.5, format="%.2f")
max_lat = st.sidebar.number_input("Max Latitude", value=25.5, format="%.2f")
min_lon = st.sidebar.number_input("Min Longitude", value=120.0, format="%.2f")
max_lon = st.sidebar.number_input("Max Longitude", value=122.5, format="%.2f")
# --- Main App Logic ---
if st.sidebar.button("Search for Earthquakes", type="primary"):
# CORRECTED FUNCTION CALL: Pass times as ISO strings
catalog = search_earthquakes(start_utc.isoformat(), end_utc.isoformat(), min_mag, min_lat, max_lat, min_lon, max_lon)
if catalog and len(catalog) > 0:
st.success(f"β
Found {len(catalog)} earthquake(s).")
event_data = [{
"Time (UTC)": (event.preferred_origin() or event.origins[0]).time.strftime('%Y-%m-%d %H:%M:%S'),
"Latitude": (event.preferred_origin() or event.origins[0]).latitude,
"Longitude": (event.preferred_origin() or event.origins[0]).longitude,
"Depth (km)": (event.preferred_origin() or event.origins[0]).depth / 1000.0,
"Magnitude": (event.preferred_magnitude() or event.magnitudes[0]).mag,
"Mag Type": (event.preferred_magnitude() or event.magnitudes[0]).magnitude_type
} for event in catalog]
event_df = pd.DataFrame(event_data)
st.subheader("πΊοΈ Earthquake Map")
st.map(event_df, latitude='Latitude', longitude='Longitude', size='Magnitude', zoom=6)
st.subheader("π Earthquake Catalog Table")
st.dataframe(event_df)
st.markdown("---")
st.subheader(" seismograph Seismic Waveform Viewer")
event_options = {f"{row['Time (UTC)']} - Mag: {row['Magnitude']:.1f}": index for index, row in event_df.iterrows()}
selected_event_str = st.selectbox("Select an event to view waveforms:", options=event_options.keys())
if selected_event_str:
selected_index = event_options[selected_event_str]
selected_event = catalog[selected_index]
origin = selected_event.preferred_origin() or selected_event.origins[0]
event_tuple = (str(origin.time), origin.latitude, origin.longitude, origin.depth)
with st.spinner("Fetching waveforms from TW network... This may take a moment."):
waveforms = get_waveforms_for_event(event_tuple)
if waveforms and len(waveforms) > 0:
st.success(f"π Found and processed {len(waveforms)} waveform traces.")
fig, ax = plt.subplots(figsize=(12, len(waveforms) * 1.5))
waveforms.plot(fig=fig, handle=True)
ax.set_title(f"Seismic Waveforms for Event: {selected_event_str}")
st.pyplot(fig)
else:
st.warning("Could not retrieve any waveform data for the selected event from the TW network.")
else:
st.warning("No earthquakes found matching your criteria. Try expanding the search window or lowering the magnitude.")
|