-
Notifications
You must be signed in to change notification settings - Fork 245
Wrap meca #516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrap meca #516
Changes from 75 commits
e26ecd3
0232450
922af45
28efc2d
2fe87af
cff30cc
b6339a1
1239366
ffff36d
d9407e9
8536864
ed383d0
f9ac410
5f3bfae
910e0f3
29c0738
ae84de1
78cde02
598efb6
cfef2d5
31a0973
100d4f1
52cd24f
97697aa
cfd1c21
da20e4f
6dfcbe6
de80acc
acc6bf6
8040b34
5352f9c
5782ee8
393d1c8
f57ff25
4314417
1d89c6f
cd3ebca
45b01de
deaa1aa
ff164e6
64fa78c
641dd02
a44e36a
d666290
916269b
9a5c390
9d0cb4a
790864a
b7a85bd
770e6b6
f94c04e
ed83d01
5ea36ce
c35bbbc
355379d
dbd936f
8defa26
80af68a
eb3ce79
69f3919
0b8fdfe
6545cb1
e48c945
6b83b16
2cad4a7
7548740
b5ab932
f44bc5d
3946493
08830e9
a4c65ac
50f582c
b173b49
b388ab2
bf47d8b
6c3af68
53424e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| """ | ||
| Focal mechanisms | ||
| ---------------- | ||
|
|
||
| The :meth:`pygmt.Figure.meca` method can plot focal mechanisms, or beachballs. | ||
| We can specify the focal mechanism nodal planes or moment tensor components as | ||
| a dict using the ``spec`` argument (or they can be specified as a 1d or 2d array, | ||
| or within a specified file). The size of plotted beachballs can be specified | ||
| using the ``scale`` argument. | ||
| """ | ||
|
|
||
| import pygmt | ||
|
|
||
| fig = pygmt.Figure() | ||
|
|
||
| # generate a basemap near Washington state showing coastlines, land, and water | ||
| fig.coast( | ||
| region=[-125, -122, 47, 49], | ||
| projection="M6c", | ||
| land="grey", | ||
| water="lightblue", | ||
| shorelines=True, | ||
| resolution="f", | ||
| frame="a", | ||
| ) | ||
|
|
||
| # store focal mechanisms parameters in a dict | ||
| focal_mechanism = dict(strike=330, dip=30, rake=90, magnitude=3) | ||
|
|
||
| # pass the focal mechanism data to meca in addition to the scale and event location | ||
| fig.meca(focal_mechanism, scale="1c", longitude=-124.3, latitude=48.1, depth=12.0) | ||
|
|
||
| fig.show() |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,241 @@ | ||||
| """ | ||||
| Tests for meca | ||||
| """ | ||||
| import os | ||||
| import pandas as pd | ||||
| import numpy as np | ||||
| import pytest | ||||
|
|
||||
| from .. import Figure | ||||
|
|
||||
|
|
||||
| TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data") | ||||
|
|
||||
|
|
||||
| @pytest.mark.mpl_image_compare | ||||
| def test_meca_spec_dictionary(): | ||||
| """ | ||||
| Test supplying a dictionary containing a single focal mechanism to the | ||||
| `spec` argument. | ||||
| """ | ||||
|
|
||||
| fig = Figure() | ||||
|
|
||||
| # Right lateral strike slip focal mechanism | ||||
| fig.meca( | ||||
| dict(strike=0, dip=90, rake=0, magnitude=5), | ||||
| longitude=0, | ||||
| latitude=5, | ||||
| depth=0, | ||||
| scale="2.5c", | ||||
| region=[-1, 1, 4, 6], | ||||
| projection="M14c", | ||||
| frame=2, | ||||
| ) | ||||
|
|
||||
| return fig | ||||
|
|
||||
|
|
||||
| @pytest.mark.mpl_image_compare | ||||
| def test_meca_spec_dict_list(): | ||||
| """ | ||||
| Test supplying a dictionary containing a list of focal mechanism to the | ||||
| `spec` argument. | ||||
| """ | ||||
|
|
||||
| fig = Figure() | ||||
|
|
||||
| # supply focal mechanisms as a dict of lists | ||||
| focal_mechanisms = dict( | ||||
| strike=[330, 350], dip=[30, 50], rake=[90, 90], magnitude=[3, 2] | ||||
| ) | ||||
|
|
||||
| fig.meca( | ||||
| focal_mechanisms, | ||||
| longitude=[-124.3, -124.4], | ||||
| latitude=[48.1, 48.2], | ||||
| depth=[12.0, 11.0], | ||||
| region=[-125, -122, 47, 49], | ||||
| scale="2c", | ||||
| projection="M14c", | ||||
| ) | ||||
|
|
||||
| return fig | ||||
|
|
||||
|
|
||||
| @pytest.mark.mpl_image_compare | ||||
| def test_meca_spec_dataframe(): | ||||
| """ | ||||
| Test supplying a pandas DataFrame containing focal mechanisms and | ||||
| locations to the `spec` argument. | ||||
| """ | ||||
|
|
||||
| fig = Figure() | ||||
|
|
||||
| # supply focal mechanisms to meca as a dataframe | ||||
| focal_mechanisms = dict( | ||||
| strike=[324, 353], | ||||
| dip=[20.6, 40], | ||||
| rake=[83, 90], | ||||
| magnitude=[3.4, 2.9], | ||||
| longitude=[-124, -124.4], | ||||
| latitude=[48.1, 48.2], | ||||
| depth=[12, 11.0], | ||||
| ) | ||||
| spec_dataframe = pd.DataFrame(data=focal_mechanisms) | ||||
|
|
||||
| fig.meca(spec_dataframe, region=[-125, -122, 47, 49], scale="2c", projection="M14c") | ||||
|
|
||||
| return fig | ||||
|
|
||||
|
|
||||
| @pytest.mark.mpl_image_compare | ||||
| def test_meca_spec_1d_array(): | ||||
| """ | ||||
| Test supplying a 1D numpy array containing focal mechanisms and | ||||
| locations to the `spec` argument. | ||||
| """ | ||||
|
|
||||
| fig = Figure() | ||||
|
|
||||
| # supply focal mechanisms to meca as a 1D numpy array, here we are using | ||||
| # the Harvard CMT zero trace convention but the focal mechanism | ||||
| # parameters may be specified any of the available conventions. Since we | ||||
| # are not using a dict or dataframe the convention and component should | ||||
| # be specified. | ||||
| focal_mechanism = [ | ||||
| -127.40, # longitude | ||||
| 40.87, # latitude | ||||
| 12, # depth | ||||
| -3.19, # mrr | ||||
| 0.16, # mtt | ||||
| 3.03, # mff | ||||
| -1.02, # mrt | ||||
| -3.93, # mrf | ||||
| -0.02, # mtf | ||||
| 23, # exponent | ||||
| 0, # plot_lon, 0 to plot at event location | ||||
| 0, # plot_lat, 0 to plot at event location | ||||
| ] | ||||
| focal_mech_array = np.asarray(focal_mechanism) | ||||
|
|
||||
| fig.meca( | ||||
| focal_mech_array, | ||||
| convention="mt", | ||||
| component="full", | ||||
| region=[-128, -127, 40, 41], | ||||
| scale="2c", | ||||
| projection="M14c", | ||||
| ) | ||||
|
|
||||
| return fig | ||||
|
|
||||
|
|
||||
| @pytest.mark.mpl_image_compare | ||||
| def test_meca_spec_2d_array(): | ||||
| """ | ||||
| Test supplying a 2D numpy array containing focal mechanisms and | ||||
| locations to the `spec` argument. | ||||
| """ | ||||
|
|
||||
| fig = Figure() | ||||
|
|
||||
| # supply focal mechanisms to meca as a 2D numpy array, here we are using | ||||
| # the GCMT convention but the focal mechanism parameters may be | ||||
| # specified any of the available conventions. Since we are not using a | ||||
| # dict or dataframe the convention and component should be specified. | ||||
| focal_mechanisms = [ | ||||
| [ | ||||
| -127.40, # longitude | ||||
| 40.87, # latitude | ||||
| 12, # depth | ||||
| 170, # strike1 | ||||
| 20, # dip1 | ||||
| -110, # rake1 | ||||
| 11, # strike2 | ||||
| 71, # dip2 | ||||
| -83, # rake2 | ||||
| 5.1, # mantissa | ||||
| 23, # exponent | ||||
| 0, # plot_lon, 0 means we want to plot at the event location | ||||
| 0, # plot_lat | ||||
| ], | ||||
| [-127.50, 40.88, 12.0, 168, 40, -115, 20, 54, -70, 4.0, 23, 0, 0], | ||||
| ] | ||||
| focal_mechs_array = np.asarray(focal_mechanisms) | ||||
|
|
||||
| fig.meca( | ||||
| focal_mechs_array, | ||||
| convention="gcmt", | ||||
| region=[-128, -127, 40, 41], | ||||
| scale="2c", | ||||
| projection="M14c", | ||||
| ) | ||||
|
|
||||
| return fig | ||||
|
|
||||
|
|
||||
| @pytest.mark.mpl_image_compare | ||||
| def test_meca_spec_file(): | ||||
| """ | ||||
| Test supplying a file containing focal mechanisms and locations to the | ||||
| `spec` argument. | ||||
| """ | ||||
|
|
||||
| fig = Figure() | ||||
|
|
||||
| focal_mechanism = [-127.43, 40.81, 12, -3.19, 1.16, 3.93, -1.02, -3.93, -1.02, 23] | ||||
|
|
||||
| # writes temp file to pass to gmt | ||||
| with open(os.path.join(TEST_DATA_DIR, "temp.test"), mode="w") as temp_file: | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is a really good application for the GMTTempFile, docstring w/ usage example below: pygmt/pygmt/helpers/tempfile.py Line 27 in 2884fd0
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the usage example would be: from pygmt.helpers import GMTTempFile
with GMTTempFile() as temp:
with open(temp.name, mode="w") as temp_file:
temp_file.write(...)
some_gmt_module(temp.name, ...)Then you don't need to use the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oooo thanks Liam, that's clever! Testing this test is a little slow on my end because
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Finally passed after a restart but the grdview tests are very slow now. Looks like test_meca is passing now.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry about the slow test (we'll need to streamline this somehow at some point). A workaround is to only run the meca tests locally. Use
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
After using
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, so the temp.file object needed to be passed to meca rather than a temporary file name string. Should be fixed now.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I think this PR is good to merge. Thanks for your contribution!
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks @liamtoney I apparently need some rest |
||||
| temp_file.write(" ".join([str(x) for x in focal_mechanism])) | ||||
|
|
||||
| # supply focal mechanisms to meca as a file | ||||
| fig.meca( | ||||
| os.path.join(TEST_DATA_DIR, "temp.test"), | ||||
| convention="mt", | ||||
| component="full", | ||||
| region=[-128, -127, 40, 41], | ||||
| scale="2c", | ||||
| projection="M14c", | ||||
| ) | ||||
|
|
||||
| # remove the temporary file | ||||
| os.remove("temp.test") | ||||
|
|
||||
| return fig | ||||
|
|
||||
|
|
||||
| @pytest.mark.mpl_image_compare | ||||
| def test_meca_loc_array(): | ||||
| """ | ||||
| Test supplying lists and np.ndarrays as the event location (longitude, | ||||
| latitude, and depth). | ||||
| """ | ||||
|
|
||||
| fig = Figure() | ||||
|
|
||||
| # specify focal mechanisms | ||||
| focal_mechanisms = dict( | ||||
| strike=[327, 350], dip=[41, 50], rake=[68, 90], magnitude=[3, 2] | ||||
| ) | ||||
|
|
||||
| # longitude, latitude, and depth may be specified as an int, float, | ||||
| # list, or 1d numpy array | ||||
| longitude = np.array([-123.3, -124.4]) | ||||
| latitude = np.array([48.4, 48.2]) | ||||
| depth = [12.0, 11.0] # to test mixed data types as inputs | ||||
|
|
||||
| scale = "2c" | ||||
|
|
||||
| fig.meca( | ||||
| focal_mechanisms, | ||||
| scale, | ||||
| longitude, | ||||
| latitude, | ||||
| depth, | ||||
| region=[-125, -122, 47, 49], | ||||
| projection="M14c", | ||||
| ) | ||||
|
|
||||
| return fig | ||||
Uh oh!
There was an error while loading. Please reload this page.