Converting Between Moment Magnitude and Seismic Moment with Python

Introduction

The historical tradition of using magnitude to communicate the size of an earthquake is deeply entrenched both within seismology and throughout the public. So it makes sense to have a way of mapping seismic moment into a magnitude. Kanamori (1977) developed just such a conversion, which we call moment magnitude and represent as \(M_W\). The relationship was defined in CGS units as:

$$M_w=\frac{2}{3} \log _{10}\left(M_0\right)-10.7~,$$

where \(M_0\) is the moment in dyne-cm. To convert a moment from dyne-cm to N-m (newton meters), divide by \(10^7\). We can invert the equation to convert \(M_W\) to seismic moment:

$$M_0=10^{1.5 \left(M_w+10.7\right)}~.$$

Converting back and forth from the two measures is a common task, and long ago I wrote a simple command-line driven fortran code to perform the conversion. In this note I describe two python scripts that will do the job. Like the original Fortran, both use command-line arguments, and part of the reason for this note is to provide an example of using command-line arguments in python. I use the convenient argparse package to handle all the details.

Python Code

The first version uses two command line arguments -mw and -m0 to indicate whether you want to go from \(M_W\) to \(M_0\) or from \(M_0\) to \(M_W\). Here is the code:

#!/usr/local/anaconda/bin/python
#
#====================================================================
#   MAIN PROGRAM
#====================================================================
if __name__ == '__main__':
    #
    import argparse, math
    #
    parser = argparse.ArgumentParser( \
        description='Convert between seismic moment and moment magnitude.')
    #
    parser.add_argument('floats', metavar='Value', type=float, nargs='+',\
        help='A seismic moment in dyne cm or an Mw value.')
    #
    args = parser.parse_args()
    #
    for value in args.floats:
        if value <= 12:
            print "Mw = %.2f, M0 = %9.3e dyne cm" % (value,math.pow(10,1.5*(value+10.7)))
        else:
            print "M0 = %9.3e dyne cm, Mw = %.2f" % (value,0.66667*math.log10(value)-10.7)
#

Example Usage

Three example executions of the script are shown below. The first asks for help, the next two convert from \(M_W\) to \(M_0\) and \(M_0\)  to \(M_W\) respectively. I used mwmo as the name because I find it easier to type an “o” than a “0”.

unix > mwmo -h
usage: mwmo [-h] [-m0 M0] [-mw MW]

Convert between seismic moment and moment magnitude.

optional arguments:
  -h, --help  show this help message and exit
  -m0 M0      Seismic moment in dyne cm
  -mw MW      Moment magnitude.
unix > mwmo -mw 6
Mw = 6.00, M0 = 1.122e+25 dyne cm
unix > mwmo -m0 1.122e+25
M0 = 1.122e+25 dyne cm, Mw = 6.00

A problem with this version is that typing -mw or -m0 is annoying and unnecessary. Because the size of magnitudes is so different, we can tell which type of value is input simply by checking the size. For example, if the value is less than 12, we know it’s a magnitude value, not a seismic moment. This leads to a simpler-to-use script that interprets the input correctly and performs the conversion. It also lets us handle multiple values at time.

Python Code

#!/usr/local/anaconda/bin/python
#
#====================================================================
#   MAIN PROGRAM
#====================================================================
if __name__ == '__main__':
    #
    import argparse, math
    #
    parser = argparse.ArgumentParser( \
        description='Convert between seismic moment and moment magnitude.')
    #
    parser.add_argument('floats', metavar='Value', type=float, nargs='+',\
        help='A seismic moment in dyne cm or and Mw value.')
    #
    args = parser.parse_args()
    #
    for value in args.floats:
        if value <= 12:
            print "Mw = %.2f, M0 = %9.3e dyne cm" % (value,math.pow(10,1.5*(value+10.7)))
        else:
            print "M0 = %9.3e dyne cm, Mw = %.2f" % (value,0.66667*math.log10(value)-10.7)
#

Example Usage

Here are three example executions of the new version of the script:

unix > mwmo -h
usage: mwmo [-h] Value [Value ...]

Convert between seismic moment and moment magnitude.

positional arguments:
  Value       A seismic moment in dyne cm or and Mw value.

optional arguments:
  -h, --help  show this help message and exit
unix > mwmo 6.0
Mw = 6.00, M0 = 1.122e+25 dyne cm
unix > mwmo 1.12e25
M0 = 1.120e+25 dyne cm, Mw = 6.00

Here’s an example requesting conversion of multiple \(M_W\) values

unix > mwmo 0 1 2 3 4 5 6 7 8 9
Mw = 0.00, M0 = 1.122e+16 dyne cm
Mw = 1.00, M0 = 3.548e+17 dyne cm
Mw = 2.00, M0 = 1.122e+19 dyne cm
Mw = 3.00, M0 = 3.548e+20 dyne cm
Mw = 4.00, M0 = 1.122e+22 dyne cm
Mw = 5.00, M0 = 3.548e+23 dyne cm
Mw = 6.00, M0 = 1.122e+25 dyne cm
Mw = 7.00, M0 = 3.548e+26 dyne cm
Mw = 8.00, M0 = 1.122e+28 dyne cm
Mw = 9.00, M0 = 3.548e+29 dyne cm

I installed the script in my python bin directory and use it from the Terminal App often.