A Step-by-Step Guide to Converting Kinemetrics EVT Files to SAC Format using ObsPy
Working with seismic data has probably exposed you to Kinemetrics EVT files. These files are commonly used for recording seismic data; however, to perform in-depth analysis or work with specific tools, you may need to convert them to the SAC (Seismic Analysis Code) format.
In this article, I’ll walk you through the process of converting Kinemetrics EVT files to SAC using Python and the ObsPy library.
Whether you’re a seismologist, a researcher, or simply interested in the fascinating world of earthquakes, this step-by-step guide will help you unlock valuable insights from your EVT data. Let’s dive in!
Prerequisites :
- Python3 and ObsPy: Make sure you have Python installed on your system and the ObsPy library. You can install ObsPy using pip:
pip install obspy
Or if you use Conda:
conda install -c conda-forge obspy
- Kinemetrics EVT Files: Ensure that your EVT files are in the same directory as this script or in its subdirectories.
Now that we have all that we need, we can finally start writing code.
Step 1: Introduction
- Start by importing the required libraries, ObsPy, and the “os” module.
The “os” library in Python, short for “operating system,” provides a way to interact with the underlying operating system on which your Python program is running. It is a standard Python library, so you don’t need to install it separately.
from obspy import read
import os
- This is entirely optional, but if you’re like me and you want to create a visually appealing header when starting your program or providing usage guidelines, you can achieve this using the
print
method."
print("*" * len("Welcome to the Evt_SAC converter"))
print("Welcome to the Evt_SAC converter")
print("*" * len("Welcome to the Evt_SAC converter"))
print(
"\n Before we begin, make sure your data is in the same folder (or one of its subfolders) as the program."
)
Step 2: Input EVT File
- Prompt the user to provide the name of the EVT file they want to convert using the
input
method. The script that we will be creating accepts as input either the file name or the full path to the file, including the file name.
event_name = input("\nEnter the name of the file to convert: ").replace(" ", "")
- The script checks whether the specified file exists in the current directory. If it’s not found, the script conducts a search in all subdirectories. At the end of the search, if the file is not found, a warning message is displayed.
if not os.path.exists(event_name):
start_directory = os.getcwd() # Get the current working directory's path
# Search for the file in all subdirectories
for root, _, files in os.walk(start_directory):
if event_name in files:
event_name = os.path.join(root, event_name)
event_not_found = False
break
else:
event_not_found = True
if event_not_found:
print(f"WARNING: '{event_name}' does not exist in '{start_directory}' or its subdirectories.")
Since what we’re doing is basically an interaction between the program and the operating system (looking through folders), as you can see, this above section relies heavily on the “os” library, which is why we imported it in Step 1.
Step 3: Read and Convert the EVT File to SAC
Now that we’ve sorted the boring stuff we can finally start converting. Let the fun begin!
if os.path.exists(event_name):
st = read(event_name, format="kinemetrics_evt").detrend()
for tr in st:
tr.data = tr.data * tr.stats.calib * 100 # Data conversion
tr.stats.network = "..." # Replace as you please
tr.stats.station = tr.stats.kinemetrics_evt.stnid
tr.stats.location = "..." # Replace as you please
tr.stats.channel = tr.stats.kinemetrics_evt.chan_id
- If the EVT file exists, the script reads the recording using ObsPy’s
read
function, specifying the file format as "kinemetrics_evt." It also applies detrending to the data. - We continue by iterating through each trace (‘tr’ which represents different channels) in the stream (‘st’) and perform data conversion from ‘Counts’ to the physical unit by multiplying it by the trace’s calibration factor (‘tr.stats.calib’). The final data unit can vary depending on the type of the sensor. In my case, it’s acceleration, and I want it to be in cm/s² or cm.s−2 that’s why I've scaled it by 100.
- From this point on, the rest of the above script is optional. What it does is that it extracts information from the file name and assigns it to the corresponding attributes in the ObsPy Trace objects. This includes setting the network, station, location, and channel. You can customize these values according to your specific requirements. I’ve explained this part in more detail in my article “Reading, Modifying, and Converting Seismic Event Data Using ObsPy”.
Step 4: Create a Directory for Converted Files
directory_name = "Converted_event_to_SAC"
if not os.path.exists(directory_name):
os.mkdir(directory_name)
path_to_directory = os.path.abspath(directory_name)
- In this step, we go back to using the “os” library to create a directory named “Converted_event_to_SAC” if it doesn’t already exist. This directory will be beneficial for storing the converted SAC files.
- Then, we get the absolute path to the newly created directory.
Step 5: Write SAC Files
event_name= os.path.basename(event_name)
for i, tr in enumerate(st):
output_file_name = f"{event_name[:-4]}_{tr.stats.channel}.sac"
output_file_path = os.path.join(path_to_directory, output_file_name)
tr.write(output_file_path, format="SAC")
print("**** Operation completed successfully ****")
- If you want to keep the same name format for the resulting SAC files (I’m using the plural form because each channel component will be stored in a separate file) as the EVT file we use the
os.path.basename()
function to extract the filename from the full path of theevent_name
variable. It is a common practice to do this to obtain just the file's name, excluding the directory path. - This
for
loop iterates through the Trace objects ‘tr’ in the ‘st’ variable. Each Trace object represents a channel of seismic data, and the loop allows you to process each channel individually. - We create unique file names for each SAC file. Here, the
output_file_name
is generated as follows:
{event_name[:-4]}
: This extracts the first part of the event_name
, excluding the last four characters. The [:-4]
slice is used to remove the file extension (e.g., ".evt"). This part of the name typically represents the event or station name.
_{tr.stats.channel}.sac
: This part adds the channel name to the output file name, separated by an underscore, and appends the ".sac" file extension. The tr.stats.channel
represents the channel name associated with the current Trace object, if you chose to skip the optional part in step 3 you may need to change this to _{tr.stats.kinemetrics_evt.chan_id}.sac
- We use
os.path.join()
to combine thepath_to_directory
(the directory where the SAC files will be saved) and theoutput_file_name
to create the full file path for the current channel. - We write the current channel’s data to the specified output file path (“Converted_event_to_SAC” directory) in the SAC format. It uses the
tr.write()
function from ObsPy with the format set to "SAC." - Finally, a success message is printed to indicate that the operation is completed.
Conclusion:
This article has provided a fundamental understanding of converting Kinemetrics EVT files to SAC format, empowering you to leverage seismic data for analysis and research. The beauty of structured data is in its potential, and this conversion is your key to unlocking insights from the Earth’s dynamic movements.
For the complete Python code used in this tutorial, you can find it in my GitHub repository EVT_to_SAC. Feel free to explore and adapt it to your specific needs.
I would like to acknowledge the invaluable contribution of the ObsPy library, a powerful and versatile tool for working with seismic data.
Happy converting, and may your discoveries be as profound as the Earth’s movements.
Beyreuther, M., Barsch, R., Krischer, L., Megies, T., Behr, Y., & Wassermann, J. (2010). ObsPy: A Python toolbox for seismology. Seismological Research Letters, 81(3), 530–533.