> For the complete documentation index, see [llms.txt](https://jonas.gitbook.io/seismo_rain/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jonas.gitbook.io/seismo_rain/seismic-data/extracting-seismic-data.md).

# Extracting seismic data

To match the specific characteristics of the chosen rainfall event, we selected four seismic stations (2A.1517, 2A.199, 2A.465, 2A.763) positioned along the same latitude, spanning west to east and approximately 7 km apart from each other. The decision to limit the number of seismic stations for analysis to four was based on time constraints related to loading seismic waveform data.

<figure><img src="/files/K2pMyct9Ze44oK68j7IW" alt=""><figcaption><p>Four selected seismic station (2A.1517, 2A.199, 2A.465, 2A.763) for this study (edited from Hua et al., 2023)</p></figcaption></figure>

## ObsPy library to import seismic data from a data centre using the FDSN client interface

Obspy is a Python framework for processing seismological data (Beyreuther et al., 2010), you can access its detailed documentation via this [link](https://docs.obspy.org/index.html#).

```python
import obspy
from obspy.clients.fdsn import Client

# The 2A network seismic data is saved at the IRIS PH5 repository
IRISPH5 = Client('IRISPH5',timeout=3600) 
```

## Extract the waveforms from all four seismic stations

```python
# Print the wall time of this cell (It might take up to 20 mins to run)
%%time

# FDSN seismic network code
net = "2A" 

# Select the seismic station of interest
station = "1517,199,465,763"

# Select the location code within the seismic station (use "*" to select all)
location = "*"

# Select the channel ("*Z": only select the vertical channel)
channel = "*Z"

# Select the time range of the seismic waveform
# obspy.UTCDateTime is in the order: year, month, day, hour, minute, second, microsecond
starttime = obspy.UTCDateTime(2016,4,19,22)
endtime = obspy.UTCDateTime(2016,4,20,2) 

# Saving the waveforms as a stream (st)
st = IRISPH5.get_waveforms(net,station,location,channel,starttime,endtime)

# Backing up "st"
st.bak = st.copy()

# Print the stream
print(st)
```

The output from `print(st)` reveals that within the stream, each waveform is designated as an individual trace.

```
4 Trace(s) in Stream:
2A.1517..DPZ | 2016-04-19T22:00:00.000000Z - 2016-04-20T01:59:59.998000Z | 500.0 Hz, 7200000 samples
2A.199..DPZ  | 2016-04-19T22:00:00.000000Z - 2016-04-20T01:59:59.998000Z | 500.0 Hz, 7200000 samples
2A.465..DPZ  | 2016-04-19T22:00:00.000000Z - 2016-04-20T01:59:59.998000Z | 500.0 Hz, 7200000 samples
2A.763..DPZ  | 2016-04-19T22:00:00.000000Z - 2016-04-20T01:59:59.998000Z | 500.0 Hz, 7200000 samples
CPU times: user 2.52 s, sys: 1.57 s, total: 4.08 s
Wall time: 17min 36s
```

If you're interested in understanding how the channel codes are composed, you can explore the documentation via this [link](https://docs.fdsn.org/projects/source-identifiers/en/latest/channel-codes.html) (FDSN, 2020).

## Plotting the waveform

```python
import matplotlib.pyplot as plt

# Plotting waveforms
st.plot()

# Close a figure window
plt.close()
```

<figure><img src="/files/2kIFdFVerZR7OJHEcBzL" alt=""><figcaption><p><strong>The unprocessed waveform of the four selected seismic stations</strong> </p></figcaption></figure>

## Applying a bandpass filter to all the waveforms

As mentioned in [Frequency of interest](/seismo_rain/seismic-data/frequency-of-interest.md), we will be applying a bandpass filter of 80 Hz to 150 Hz to all the waveforms.&#x20;

```python
st.filter('bandpass',freqmin=80,freqmax=150)
st.plot()
plt.close()
```

<figure><img src="/files/mvUdzk4SqIB9S5jrdZRR" alt=""><figcaption><p><strong>Bandpass filter of 80-150 Hz is applied to all waveforms</strong></p></figcaption></figure>

## Converting the waveforms to the magnitude of displacement of the seismic sensor

We now need to convert the "count value" displayed on the y-axis of the waveforms to a meaningful metric representing displacement in meters.&#x20;

Before proceeding, it is important to remove all instrumental responses from the seismic sensor data. These responses are known to be frequency-dependent ([Wilson et al., 2013](https://ui.adsabs.harvard.edu/abs/2013AGUFM.S42A..04W/abstract#:~:text=Neglecting%20to%20remove%20the%20frequency,typically%20presumed%20to%20be%20flat.)) and neglecting this step may result in significant errors in both amplitude and phase.

The instrument response of each station can be accessed by the `IRISPH5.get_stations` where `level="response"` returns the full response information for the requested channels.

```python
# Extracting instrument response from each channel  
inv = IRISPH5.get_stations(network="2A",station="1517,199,465,763",level='response',channel='DPZ')

# Plotting the displacement (m) amplitude of the seismic sensor 
st.remove_response(inv,output='DISP')
st.plot()
plt.close()
```

<figure><img src="/files/4QEadPXTm5B93MnrAh7W" alt=""><figcaption><p><strong>The displacement amplitude (in meters) of all four seismic stations</strong></p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://jonas.gitbook.io/seismo_rain/seismic-data/extracting-seismic-data.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
