Skip to main content
Geosciences LibreTexts

6.4: Earthquake Distance and Magnitude Jupyter Notebook

  • Page ID
    11990
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)

    Instructions

    • To use this page, read the text between each of the python code windows, then press RUN to execute the code in the box.
    • It is necessary to run each of the boxes in order.
    • Don't click restart in the cells unless you come back to the top of the page and start over.
    • If you modify the code, this modification will not remain after you leave or refresh this page.
    • You must run simulations/cells that require user input to completion. Make sure you see the Message informing you a cell is complete before continuing to the next cell. Here's why you must do this:
      • These cells may not be re-run until the simulation is completed, otherwise no output will be generated.
      • All following cells will not run until the user input cell is completed.
    • For Dropdown Menus: You do not need to rerun the cells with the menu to change your selection. However, you must rerun all of the following cells to implement the change.

    Be patient, some times it can take 1-2 minutes for the juypter kernel to start.

    An interactive example of calculating the distance from an earthquake from seismic wave arrivals and magnitude from the empirical formula for Richter Magnitude.

    Key Questions: Consider these as you work your way through this page.

    For Earthquake Distance:

    • Compare the distance predicted for the same ts-tp time for different rock types: which rock type gives the largest distance? Explain why.

    For Richter Magnitude:

    • As you increase the seismogram amplitude, does the magnitude increase, decrease, or stay the same?
    • Can you generate an unrealistic magnitude (M \(\geq\) 10)? If so, why? If not, which parameter value prevents this?

    First, we import the necessary libraries and create a dictionary containing p and s-wave velocities in different materials.

    import numpy as np
    from ipywidgets import interact, interactive, fixed, interact_manual
    import ipywidgets as widgets
    
    rock_types = {'shale':{'P':3000,'S':2600},'limestone':{'P':4250,'S':3100},'sandstone':{'P':2700,'S':2400},'alluvium':{'P':4000,'S':1900}}
    
    print('The libraries are imported and the dictionary is defined.')

    Earthquake Distance

    Now, let's learn about how we can determine how far away we are from an earthquake from a seismogram. The p and s-wave arrival times can be picked from a seismogram, and their difference between them is related to how far away the earthquake was. In this cell, you will be prompted to enter the difference in arrival times of the waves. That information will be used to calculate the distance between you and the earthquake assuming the waves are traveling through a layer of granite. The function distance_from_eq accomplishes this, and the formula is derived in 6.3: Location and Focal Mechanisms.

    print('Please enter the amount of time between the P-wave and S-wave arrivals between 1 and 60 s')
    arrival_diff = float(input())
    while arrival_diff < 1 or arrival_diff > 60:
        print('Invalid time difference: please enter a number between 1 and 120s')
        arrival_diff = float(input())
        
    def distance_from_eq(vp,vs,delta_t): 
        x = (-delta_t * vp * vs) / (vs - vp)
        return x
    
    vp = 4450 #m/s, granite ranges from about 3000 to 5900 m/s
    vs = 3500 #m/s, granite ranges from about 3400 to 3600 m/s
    
    x = distance_from_eq(vp,vs,arrival_diff)
    print('The p-wave velocity in granite is',vp,'m/s')
    print('The s-wave velocity in granite is',vs,'m/s')
    print('The distance from the earthquake is ' + '{:.2f}'.format(x/1000)+' km')
    print('The calculation is complete.')

    Now let's explore how different materials affect the results. Changing the material will change the p and s-wave velocities. This cell will prompt you to select a new arrival time difference and allow you to pick a material. Note: To change the material later on, you do not need to rerun this cell, simply change the dropdown menu selection. However, you will need to run all cells after this one.

    print('Please enter the amount of time between the P-wave and S-wave arrivals between 1 and 60 s') #Ask about Shale
    arrival_diff = float(input())
    while arrival_diff < 1 or arrival_diff > 60:
        print('Invalid time difference: please enter a number between 1 and 60s')
        arrival_diff = float(input())
    
    style = {'description_width': 'initial'}
    layout = {'width': '400px'}
    rock_dropdown = widgets.Dropdown(
        options=['shale', 'limestone', 'sandstone','alluvium'],
        value='shale',
        description='Select a material for your model',
        disabled=False,
        style = style,
        layout = layout
    )
    
    
    display(rock_dropdown)

    Now run the next cell to do the calculation, do this for all the materials and consider the key questions.

    rock = rock_dropdown.value
    print('Now plotting for',rock)
    
        
    
    vp = rock_types[rock]['P']
    vs = rock_types[rock]['S']
    
    
    x = distance_from_eq(vp,vs,arrival_diff)
    print('The p-wave velocity in',rock,'is',vp,'m/s.')
    print('The s-wave velocity in',rock,'is',vs,'m/s.') 
    print()
    print('The distance from the earthquake is ' + '{:.2f}'.format(x/1000)+' km.')
    print()
        
    
    print('Go up to the above cell, select a new rock type, and re-run this cell')
    print('Note: You do not need to re-run the cell with the dropdown menu')
    
    
    print('The calculation is complete.')

    Richter Magnitude

    Now let's take it a step further and calculate the Richter Magnitude. The Richter Magnitude depends on the amplitude on a Wood-Anderson Seismometer and the distance from the earthquake. This cell will prompt you to select an arrival time difference and a material type for this model.

    print('Please enter the amount of time between the P-wave and S-wave arrivals between 1 and 60 s') #Ask about Shale
    arrival_diff = float(input())
    while arrival_diff < 1 or arrival_diff > 60:
        print('Invalid time difference: please enter a number between 1 and 60s')
        arrival_diff = float(input())
        
    display(rock_dropdown)

    This cell will first calculate the distance from the earthquake just like before. However, to calculate magnitude we will also need the seismometer amplitude so you will be prompted to enter that here. To calculate the magnitude, the function richter_magnitude is defined. This formula is shown partially in 6.2: Earthquake Magnitude, however that version of the formula leaves \(A_0(\delta)\), where delta is the distance, as an unknown function. In this example, an empirical formula is used for \(A_0(\delta)\). Go ahead and run the cell, and see how the magnitude varies with different amplitudes.

    rock = rock_dropdown.value
    vp = rock_types[rock]['P']
    vs = rock_types[rock]['S']
    x = distance_from_eq(vp,vs,arrival_diff)
    print('The p-wave velocity in',rock,'is',vp,'m/s.')
    print('The s-wave velocity in',rock,'is',vs,'m/s.')
    print('The distance from the earthquake is ' + '{:.2f}'.format(x/1000)+' km')
    print()
    
    print('Enter an amplitude of shaking from a Wood Anderson Seismogram in mm:')
    print('The normal range of amplitudes is between 0.1 and 500 mm')
    A = float(input())
    
    
    def richter_magnitude(A,x):
        if x <= 200:
            M = (np.log10(A)  + 1.6*np.log10(x/1000) - 0.15)
        else:
            M = (np.log10(A)  + 3*np.log10(x/1000) - 3.38)
        return M
    
    while A > 0:
        print('Now calculating magnitude for an amplitude of',A,'mm')
        print()
        print('The Richter Magnitude of this earthquake is','{:.1f}'.format(richter_magnitude(A,x)))
        print()
        print('To exit the simulation, enter 0')
        print('Enter another amplitude of shaking from a Wood Anderson Seismogram in mm:')
        print('The normal range of amplitudes is between 0.1 and 500 mm')
        A = float(input())
    
    print('Feel free to try this again using a different ts-tp time or material')
    print('The simulation is complete, consider the key questions.')

    Key Questions: Consider these as you work your way through this page.

    For Earthquake Distance:

    • Compare the distance predicted for the same ts-tp time for different rock types: which rock type gives the largest distance? Explain why.

    For Richter Magnitude:

    • As you increase the seismogram amplitude, does the magnitude increase, decrease, or stay the same?
    • Can you generate an unrealistic magnitude (M \(\geq\) 10)? If so, why? If not, which parameter value prevents this?

    6.4: Earthquake Distance and Magnitude Jupyter Notebook is shared under a not declared license and was authored, remixed, and/or curated by LibreTexts.

    • Was this article helpful?