shipgrav 1.0.3__tar.gz → 1.0.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. {shipgrav-1.0.3 → shipgrav-1.0.5}/.github/test_conda_env.yml +1 -0
  2. {shipgrav-1.0.3 → shipgrav-1.0.5}/.github/workflows/test.yml +3 -2
  3. {shipgrav-1.0.3 → shipgrav-1.0.5}/CHANGELOG +34 -0
  4. {shipgrav-1.0.3 → shipgrav-1.0.5}/PKG-INFO +9 -4
  5. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/requirements.txt +2 -0
  6. {shipgrav-1.0.3 → shipgrav-1.0.5}/example-scripts/RMBA_calc.py +69 -38
  7. {shipgrav-1.0.3 → shipgrav-1.0.5}/example-scripts/dgs_bgm_comp.py +65 -27
  8. {shipgrav-1.0.3 → shipgrav-1.0.5}/example-scripts/dgs_ccp_calc.py +42 -19
  9. {shipgrav-1.0.3 → shipgrav-1.0.5}/example-scripts/dgs_raw_comp.py +91 -38
  10. {shipgrav-1.0.3 → shipgrav-1.0.5}/example-scripts/interactive_line_pick.py +29 -17
  11. {shipgrav-1.0.3 → shipgrav-1.0.5}/example-scripts/mru_coherence.py +75 -36
  12. {shipgrav-1.0.3 → shipgrav-1.0.5}/joss/paper.md +1 -1
  13. {shipgrav-1.0.3 → shipgrav-1.0.5}/pyproject.toml +4 -3
  14. {shipgrav-1.0.3 → shipgrav-1.0.5}/readme.md +4 -2
  15. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/__init__.py +13 -7
  16. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/database.toml +1 -0
  17. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/grav.py +6 -13
  18. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/io.py +42 -25
  19. shipgrav-1.0.5/shipgrav/tests/ex_files/AT01_bgm.BGM +4 -0
  20. shipgrav-1.0.5/shipgrav/tests/ex_files/AT01_nav.gps +8 -0
  21. shipgrav-1.0.5/shipgrav/tests/ex_files/MGL2003_bgm.y2020d244 +4 -0
  22. shipgrav-1.0.5/shipgrav/tests/ex_files/MGL2003_nav.y2020d244 +12 -0
  23. shipgrav-1.0.5/shipgrav/tests/ex_files/NBP_2301_nav.d013 +22 -0
  24. shipgrav-1.0.5/shipgrav/tests/ex_files/RR2212_bgm.txt +6 -0
  25. shipgrav-1.0.5/shipgrav/tests/ex_files/RR2212_nav.txt +19 -0
  26. shipgrav-1.0.5/shipgrav/tests/ex_files/SR2302_nav.raw +36 -0
  27. shipgrav-1.0.5/shipgrav/tests/ex_files/TN400_dgs_proc.Raw +2 -0
  28. shipgrav-1.0.5/shipgrav/tests/ex_files/TN400_dgs_raw.Raw +0 -0
  29. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/test_grav_data.py +8 -2
  30. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/test_grav_nodata.py +19 -1
  31. shipgrav-1.0.5/shipgrav/tests/test_io.py +128 -0
  32. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/test_nav.py +2 -1
  33. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/test_utils.py +2 -1
  34. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/utils.py +12 -9
  35. shipgrav-1.0.3/example-scripts/download_data.sh +0 -79
  36. shipgrav-1.0.3/shipgrav/tests/test_io.py +0 -55
  37. {shipgrav-1.0.3 → shipgrav-1.0.5}/.github/workflows/draft-pdf.yml +0 -0
  38. {shipgrav-1.0.3 → shipgrav-1.0.5}/.github/workflows/release-publish.yml +0 -0
  39. {shipgrav-1.0.3 → shipgrav-1.0.5}/.gitignore +0 -0
  40. {shipgrav-1.0.3 → shipgrav-1.0.5}/.readthedocs.yml +0 -0
  41. {shipgrav-1.0.3 → shipgrav-1.0.5}/CONTRIBUTORS.md +0 -0
  42. {shipgrav-1.0.3 → shipgrav-1.0.5}/LICENSE +0 -0
  43. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/Makefile +0 -0
  44. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/_static/SR2312_serial_laptop.png +0 -0
  45. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/_static/TN400_FAA.png +0 -0
  46. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/_static/TN400_ccp.png +0 -0
  47. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/_static/cursor.png +0 -0
  48. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/_static/rmba.png +0 -0
  49. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/_static/roll_coherence.png +0 -0
  50. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/_templates/mynavigation.html +0 -0
  51. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/conf.py +0 -0
  52. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/index.rst +0 -0
  53. {shipgrav-1.0.3 → shipgrav-1.0.5}/docs/make.bat +0 -0
  54. {shipgrav-1.0.3 → shipgrav-1.0.5}/joss/paper.bib +0 -0
  55. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/nav.py +0 -0
  56. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/__init__.py +1 -1
  57. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/__main__.py +0 -0
  58. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/ex_files/AT05_01_bgm.RGS +0 -0
  59. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/ex_files/DGStest_laptop.dat +0 -0
  60. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/ex_files/IXBlue.yaml +0 -0
  61. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/ex_files/SR2312_dgs_raw.txt +0 -0
  62. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/ex_files/SR2312_mru.txt +0 -0
  63. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/ex_files/TN400_bgm.Raw +0 -0
  64. {shipgrav-1.0.3 → shipgrav-1.0.5}/shipgrav/tests/ex_files/TN400_nav.Raw +0 -0
@@ -9,3 +9,4 @@ dependencies:
9
9
  - tomli
10
10
  - pyyaml
11
11
  - coverage
12
+ - tqdm
@@ -1,11 +1,12 @@
1
1
  name: tests
2
2
  on:
3
3
  push:
4
+ branches:
5
+ - main
4
6
  #workflow_dispatch:
5
7
  pull_request:
6
8
  branches:
7
- # only branches from forks which have the form 'user:branch-name'
8
- - '**:**'
9
+ - main
9
10
  schedule:
10
11
  - cron: '42 0 * * 6'
11
12
  jobs:
@@ -1,3 +1,29 @@
1
+ v1.0.5
2
+
3
+ 2024-11-20 Hannah F Mark <hmark@whoi.edu>
4
+
5
+ * corrections to dependencies lists in docs
6
+ * bug fixes for example scripts
7
+
8
+ v1.0.4
9
+
10
+ 2024-11-01 Hannah F Mark <hmark@whoi.edu>
11
+
12
+ * update dependencies and docs
13
+ * add a flag to turn progress bars on/off so tests are cleaner
14
+ * add more tests for better coverage, fix bugs discovered by tests
15
+ * format example scripts for jupytext, update docs and optional dependencies
16
+ * update example scripts to use pooch for download, delete data_download script
17
+ * add progress bars for things (mostly file reads) and tqdm dependency
18
+
19
+ 2024-10-29 Hannah F Mark <hmark@whoi.edu>
20
+
21
+ * clean/format code with isort and flake8
22
+ * update triggers for test workflow: run on push and on PR
23
+ * use abs path for example files so tests can be run from outside tests/ dir
24
+
25
+ v1.0.3
26
+
1
27
  2024-10-25 Hannah F Mark <hmark@whoi.edu>
2
28
 
3
29
  * update pkg_resources (deprecated from 3.13) to importlib.resources for test suite
@@ -13,6 +39,14 @@
13
39
  * fix indexing in one part of RMBA example script for future deprecation of chained assignment
14
40
  * add detail to contributor guidelines
15
41
 
42
+ v1.0.2
43
+
44
+ 2024-09-17 Hannah F Mark <hmark@whoi.edu>
45
+
46
+ * update docs and optional dependencies
47
+
48
+ v1.0.1
49
+
16
50
  2024-07-15 Hannah F Mark <hmark@whoi.edu>
17
51
 
18
52
  * PEP8 reformat, typos
@@ -1,10 +1,9 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: shipgrav
3
- Version: 1.0.3
3
+ Version: 1.0.5
4
4
  Summary: Functions for marine gravity data processing and reduction
5
5
  Author-email: "Hannah F. Mark" <hmark@whoi.edu>
6
6
  Maintainer-email: "Hannah F. Mark" <hmark@whoi.edu>
7
- License-File: LICENSE
8
7
  Keywords: UNOLS,gravimetry,marine gravity
9
8
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
10
9
  Classifier: Operating System :: OS Independent
@@ -15,13 +14,18 @@ Requires-Dist: pyyaml
15
14
  Requires-Dist: scipy
16
15
  Requires-Dist: statsmodels
17
16
  Requires-Dist: tomli
17
+ Requires-Dist: tqdm
18
18
  Provides-Extra: examples
19
19
  Requires-Dist: geographiclib; extra == 'examples'
20
+ Requires-Dist: jupyterlab; extra == 'examples'
21
+ Requires-Dist: jupytext; extra == 'examples'
20
22
  Requires-Dist: matplotlib; extra == 'examples'
23
+ Requires-Dist: pooch; extra == 'examples'
21
24
  Description-Content-Type: text/markdown
22
25
 
23
26
  # shipgrav
24
27
  [![build status](https://github.com/PFPE/shipgrav/workflows/tests/badge.svg)](https://github.com/PFPE/shipgrav/actions)
28
+ [![codecov](https://codecov.io/gh/PFPE/shipgrav/branch/main/graph/badge.svg)](https://codecov.io/gh/PFPE/shipgrav)
25
29
 
26
30
  shipgrav is a Python package designed for reading, processing, and reducing marine gravity data from UNOLS ships. It is created and maintained by PFPE for the marine gravimetry community. The shipgrav repository also contains scripts with example workflows for gravity data processing and reduction.
27
31
 
@@ -32,9 +36,10 @@ scipy\
32
36
  pandas 2.0+\
33
37
  statsmodels\
34
38
  tomli\
35
- pyyaml
39
+ pyyaml\
40
+ tqdm
36
41
 
37
- To run the example scripts, you will also need matplotlib.
42
+ To run the example scripts, you will also need matplotlib, geographiclib, and pooch. To run the example scripts in jupyter, you will also need jupyterlab and jupytext.
38
43
 
39
44
  ## Installation
40
45
  shipgrav can be installed from PyPI using `pip`. Detailed instructions are in the [documentation](https://shipgrav.readthedocs.io/).
@@ -8,3 +8,5 @@ scipy
8
8
  tomli
9
9
  statsmodels
10
10
  pyyaml
11
+ tqdm
12
+ pooch
@@ -1,26 +1,13 @@
1
- import numpy as np
2
- from pandas import read_csv
3
- import shipgrav.grav as sgg
4
- import matplotlib.pyplot as plt
5
- from geographiclib.geodesic import Geodesic
6
- from scipy.signal import firwin, filtfilt
7
- from scipy.interpolate import interp1d
8
- from glob import glob
9
- import os
10
- import sys
11
-
12
- ########################################################################
13
- # Example script for calculating the mantle Bouger anomaly (MBA) and
14
- # residual MBA (RMBA), and estimating crustal thickness variations, using
15
- # data from a Ride transit.
16
-
1
+ # %% [markdown]
2
+ # ### Example script for calculating the mantle Bouger anomaly (MBA) and residual MBA (RMBA), and estimating crustal thickness variations, using data from a Ride transit.
3
+ #
17
4
  # This script works with a file from the interactive line picker script
18
- # that is located in
19
- # data/Ride/SR2312/gravimeter/DGS/line-segments/
20
-
5
+ # that is provided in a zenodo repository at https://doi.org/10.5281/zenodo.12733929
6
+ # The file is automatically downloaded by this script using pooch
7
+ #
21
8
  # It is hard-coded to run on a specific example file but could be
22
9
  # adjusted (see below)
23
-
10
+ #
24
11
  # Tthe RMBA thermal correction is highly sensitive to edge effects,
25
12
  # Here we will demo the process of embedding the line segment
26
13
  # in a longer line pulled from global grids: FAA, bathymetry,
@@ -28,50 +15,74 @@ import sys
28
15
  # For a cruise with multibeam and magnetics (for bathymetry and age)
29
16
  # both of those could be embedded alongside FAA. For this cruise,
30
17
  # everything but the FAA is entirely pulled from global grids.
31
-
18
+ #
32
19
  # Since this is an example running on a known input file, we have pre-
33
20
  # tracked the coordinates in the following global grids:
34
- # Bathymetry:
21
+ #
22
+ # #### Bathymetry:
23
+ #
35
24
  # The GEBCO_2014 Grid, version 20141103, http://www.gebco.net
36
- # FAA:
25
+ #
26
+ # #### FAA:
27
+ #
37
28
  # Sandwell, D. T., R. D. Müller, W. H. F. Smith, E. Garcia, R. Francis (2014).
38
29
  # New global marine gravity model from CryoSat-2 and Jason-1 reveals buried
39
30
  # tectonic structure, Science 346(6205), pp. 65-67,
40
31
  # doi: 10.1126/science.1258213
41
- # Sediment thickness:
32
+ #
33
+ # #### Sediment thickness:
34
+ #
42
35
  # Divins, D.L. (2003). Total Sediment Thickness of the World's Oceans &
43
36
  # Marginal Seas, NOAA National Geophysical Data Center, Boulder, CO.
44
- # Plate age:
37
+ #
38
+ # #### Plate age:
39
+ #
45
40
  # Seton, M., Müller, R. D., Zahirovic, S., Williams, S., Wright, N., Cannon, J.,
46
41
  # Whittaker, J., Matthews, K., McGirr, R., (2020). A global dataset of
47
42
  # present-day oceanic crustal age and seafloor spreading parameters,
48
43
  # Geochemistry, Geophysics, Geosystems, doi: 10.1029/2020GC009214
44
+ #
49
45
  # and
46
+ #
50
47
  # Müller, R. D., Zahirovic, S., Williams, S. E., Cannon, J., Seton, M.,
51
48
  # Bower, D. J., Tetley, M. G., Heine, C., Le Breton, E., Liu, S., Russell, S. H. J.,
52
49
  # Yang, T., Leonard, J., and Gurnis, M. (2019). A global plate model
53
50
  # including lithospheric deformation along major rifts and orogens since the
54
51
  # Triassic. Tectonics, 38, doi: 10.1029/2018TC005462
55
52
  # (age grids accessed from earthbyte.org)
56
-
53
+ #
57
54
  # To run this example using a different input file, you will need
58
55
  # to supply paths to grids of bathymetry, FAA, sediment thickness,
59
56
  # and plate age; and make sure that units match what the script expects.
60
- ########################################################################
61
57
 
58
+ # %%
59
+ import os
60
+
61
+ import matplotlib.pyplot as plt
62
+ import numpy as np
63
+ import pooch
64
+ import shipgrav.grav as sgg
65
+ from geographiclib.geodesic import Geodesic
66
+ from pandas import read_csv
67
+ from scipy.interpolate import interp1d
68
+ from scipy.signal import filtfilt, firwin
69
+ from tqdm import tqdm
70
+
71
+ # %%
72
+ # read the data
62
73
  ship = 'Ride'
63
74
  cruise = 'SR2312'
64
- root = 'data/'
65
- seg_path = os.path.join(root, ship, cruise, 'gravimeter/DGS/line-segments')
66
- # seg_files = np.sort(glob(os.path.join(seg_path,'segment*.dat')))
67
- # we want to use one particular file that is saved here, which is:
68
- seg_file = os.path.join(seg_path, 'example_segment_s3_330234-428488.dat')
69
75
 
70
- # read the data
71
- data = read_csv(seg_file, parse_dates=[16,]) # fully offshore Newport, OR
76
+ seg_file = dgs_files = pooch.retrieve(url="https://zenodo.org/records/12733929/files/data.zip",
77
+ known_hash="md5:83b0411926c0fef9d7ccb2515bb27cc0", progressbar=True,
78
+ processor=pooch.Unzip(
79
+ members=['data/Ride/SR2312/gravimeter/DGS/line-segments/example_segment_s3_330234-428488.dat']))
80
+
81
+ data = read_csv(seg_file[0], parse_dates=[16,]) # fully offshore Newport, OR
72
82
  # this segment is a straight-ish line; it has a lot of stations along it
73
83
  # where the ship was more or less stationary but that's ok
74
84
 
85
+ # %%
75
86
  # set up coordinates for extending the ends of the line
76
87
  wgs = Geodesic.WGS84 # object for calculating line extensions etc
77
88
  faz01 = wgs.Inverse(data.iloc[0]['lat_new'], data.iloc[0]['lon_new'],
@@ -86,16 +97,17 @@ if l_seg < l_ext: # but if it's a short segment, just use the segment length on
86
97
  l_ext = l_seg
87
98
  # calculate distances btwn points to get avg spacing for extensions
88
99
  xrng = np.zeros(len(data))
89
- for i in range(1, len(data)):
100
+ for i in tqdm(range(1, len(data)),desc='calculating ranges'):
90
101
  xrng[i] = wgs.Inverse(data.iloc[0]['lat_new'], data.iloc[0]['lon_new'],
91
102
  data.iloc[i]['lat_new'], data.iloc[i]['lon_new'])['s12']
92
103
  dx_avg = np.mean(np.diff(xrng))
93
104
  n_ext = int(l_ext/dx_avg)
94
105
 
106
+ # %%
95
107
  # get the actual coordinate points for each extended side
96
108
  frnt_ext = np.zeros((n_ext, 2))
97
109
  back_ext = np.zeros((n_ext, 2))
98
- for i in range(n_ext):
110
+ for i in tqdm(range(n_ext),desc='calculating extensions'):
99
111
  frnt_pt = wgs.Direct(data.iloc[0]['lat_new'],
100
112
  data.iloc[0]['lon_new'], faz10, dx_avg*(i+1))
101
113
  back_pt = wgs.Direct(data.iloc[-1]['lat_new'],
@@ -110,6 +122,8 @@ a_lon = np.hstack(
110
122
  [frnt_ext[:, 0][::-1], data['lon_new'].values, back_ext[:, 0]])
111
123
  a_lat = np.hstack(
112
124
  [frnt_ext[:, 1][::-1], data['lat_new'].values, back_ext[:, 1]])
125
+
126
+ # %%
113
127
  ########################################################################
114
128
  # this would be the point where you would track through gridfiles
115
129
  # if using a different line than the example file.
@@ -125,13 +139,21 @@ a_lat = np.hstack(
125
139
  # age_grd = os.path.expanduser('~/Data/Muller_agegrids/age.2020.1.GeeK2007.1m.nc')
126
140
  # os.system('gmt grdtrack temp.ll -G%s -G%s -G%s -G%s > tracked.llm' % (dep_grd, faa_grd, sed_grd, age_grd))
127
141
  ########################################################################
142
+
143
+ # %%
128
144
  # since we've already pre-tracked the example line, we'll just load in the
129
145
  # info here
130
- track = read_csv(os.path.join(seg_path, 'tracked.llm'), sep='\t',
146
+
147
+ track_file = dgs_files = pooch.retrieve(url="https://zenodo.org/records/12733929/files/data.zip",
148
+ known_hash="md5:83b0411926c0fef9d7ccb2515bb27cc0", progressbar=True,
149
+ processor=pooch.Unzip(
150
+ members=['data/Ride/SR2312/gravimeter/DGS/line-segments/tracked.llm']))
151
+ track = read_csv(track_file[0], sep='\t',
131
152
  names=['lon', 'lat', 'dep', 'faa', 'sed', 'age'])
132
153
  # NOTE that if you are working with data from near a coast, line extensions
133
154
  # might end up on land. Check for NaN values in your tracked file.
134
155
 
156
+ # %%
135
157
  # filter FAA from the segment since Sandwell grid is very long-wavelength
136
158
  sampling = 1
137
159
  taps = 2*240
@@ -141,6 +163,7 @@ wn = freq/nyquist
141
163
  B = firwin(taps, wn, window='blackman') # approx equivalent to matlab fir1
142
164
  ffaa = filtfilt(B, 1, data['faa'])
143
165
 
166
+ # %%
144
167
  # embed our FAA in the tracked line (everything else remains tracked)
145
168
  track.loc[n_ext+taps:n_ext+taps+len(ffaa[taps:-taps])-1,'faa'] = ffaa[taps:-taps]
146
169
  # NOTE you may want to check your embedded FAA for large jumps at the ends
@@ -148,9 +171,10 @@ track.loc[n_ext+taps:n_ext+taps+len(ffaa[taps:-taps])-1,'faa'] = ffaa[taps:-taps
148
171
  # the jumps aren't *too* big* and also we don't care that much about the
149
172
  # results of this example, but for real analyses, you should care!
150
173
 
174
+ # %%
151
175
  # interpolate everything to an even X spacing (after recalculating total distance)
152
176
  xpts_line = np.zeros(len(track))
153
- for i in range(1, len(track)):
177
+ for i in tqdm(range(1, len(track)),desc='interpolating to even spacing'):
154
178
  xpts_line[i] = wgs.Inverse(track.iloc[0]['lat'], track.iloc[0]['lon'],
155
179
  track.iloc[i]['lat'], track.iloc[i]['lon'])['s12']
156
180
  # NOTE be careful with the number of points here
@@ -169,6 +193,7 @@ age_int = fage(xobs)
169
193
  fsed = interp1d(xpts_line, track['sed'].values)
170
194
  sed_int = fsed(xobs)
171
195
 
196
+ # %%
172
197
  # calculate topography, sediment, and crust corrections (for MBA)
173
198
  # and thermal correction (for RMBA)
174
199
  # sed density approx based on Hamilton 1978, doi: 10.1121/1.381747
@@ -189,6 +214,7 @@ anom_c = sgg.grav1d_padded(xobs, dep_int-sed_int-dz_c, 0, drho[2]) # crust
189
214
 
190
215
  MBA = FAA_int - anom_w - anom_s - anom_c # mantle Bouger anomaly
191
216
 
217
+ # %%
192
218
  # correct for plate cooling (RMBA)
193
219
  corrs = np.zeros((len(temps)-1, len(xobs))) # calculate gravity due to temps
194
220
  for i in range(len(temps)-1): # loop over a set of isotherms defined above
@@ -196,9 +222,11 @@ for i in range(len(temps)-1): # loop over a set of isotherms defined above
196
222
  corrs[i, :] = sgg.grav1d_padded(
197
223
  xobs, dep_int-sed_int-ziso-dz_c, 0, drho[i+3])
198
224
 
225
+ # %%
199
226
  # RMBA is MBA minus summed thermal correction
200
227
  RMBA = MBA - np.sum(corrs, axis=0)
201
228
 
229
+ # %%
202
230
  # estimate crustal thickness
203
231
  nx = len(xobs)
204
232
  ny = 1 # we're only working with a line, but the function works for a 2D region
@@ -215,6 +243,7 @@ wsmall = 5
215
243
  cthick, rev_grav = sgg.crustal_thickness_2D(RMBA, nx=nx, ny=ny, dx=dx, dy=dy,
216
244
  zdown=zdown, rho=rho, wlarge=wlarge, wsmall=wsmall, back=True)
217
245
 
246
+ # %%
218
247
  # make some plots to see what we got out of this
219
248
  plt.figure()
220
249
  plt.plot(xobs/1e3, np.real(rev_grav), label='recovered RMBA')
@@ -230,3 +259,5 @@ plt.xlabel('distance along line [km]')
230
259
  plt.ylabel('crustal thickness variation [km]')
231
260
 
232
261
  plt.show()
262
+
263
+ # %%
@@ -1,33 +1,44 @@
1
- import numpy as np
2
- import shipgrav.grav as sgg
3
- import shipgrav.nav as sgn
4
- import shipgrav.io as sgi
5
- import tomli as tm
6
- from glob import glob
7
- from scipy.interpolate import interp1d
8
- from scipy.signal import firwin, filtfilt
9
- import matplotlib.pyplot as plt
10
- import os
11
- import sys
12
-
13
- ########################################################################
14
- # Example script for reading and lightly processing DGS laptop data
15
- # from a Thompson cruise, and comparing to BGM serial files.
1
+ # %% [markdown]
2
+ # ### Example script for reading and lightly processing DGS laptop data from a Thompson cruise, and comparing to BGM serial files.
3
+ #
4
+ # Data files are downloaded by the script using pooch
16
5
  #
17
6
  # Read DGS and navigation files
7
+ #
18
8
  # Read BGM files
9
+ #
19
10
  # Correct for meter bias with info from shipgrav
11
+ #
20
12
  # Compare BGM and DGS outputs
13
+ #
21
14
  # Use timestamps to sync more accurate nav with the gravity data.
15
+ #
22
16
  # Calculate FAA (free air anomaly)
17
+ #
23
18
  # Plot
19
+ #
24
20
  # satellite data tracked from v32.1 Global Gravity grid, which
25
21
  # includes data from SIO, NOAA, and NGA.
22
+ #
26
23
  # Reference: Sandwell et al. (2014) New global marine gravity model
27
24
  # from CryoSat-2 and Jason-1 reveals buried tectonic struture.
28
25
  # Science 346(6205), DOI: 10.1126/science.1258213
29
- ########################################################################
30
26
 
27
+ # %%
28
+ import os
29
+ from glob import glob
30
+
31
+ import matplotlib.pyplot as plt
32
+ import numpy as np
33
+ import pooch
34
+ import shipgrav.grav as sgg
35
+ import shipgrav.io as sgi
36
+ import tomli as tm
37
+ from scipy.interpolate import interp1d
38
+ from scipy.signal import filtfilt, firwin
39
+
40
+
41
+ # %%
31
42
  # set some general metadata
32
43
  ship = 'Thompson'
33
44
  cruise = 'TN400' # this is used for filepaths
@@ -39,26 +50,39 @@ with open('../shipgrav/database.toml', 'rb') as f:
39
50
  nav_tag = info['nav-talkers'][ship]
40
51
  biases = info['bias-values'][ship]
41
52
 
42
- # set up file paths, get lists of input files
43
- root = 'data/'
44
- dgs_path = os.path.join(root, ship, cruise, 'gravimeter/DGS')
45
- # we only have serial BGM
46
- bgm_path = os.path.join(root, ship, cruise, 'gravimeter/BGM3/serial')
47
- nav_path = os.path.join(root, ship, cruise, 'NAV')
48
- dgs_files = np.sort(glob(os.path.join(dgs_path, 'AT1M-Grav-PROC_*.Raw')))
49
- bgm_files = np.sort(glob(os.path.join(bgm_path, 'BGM3-GRAV-RAW*.Raw')))
50
- nav_files = np.sort(glob(os.path.join(nav_path, 'POSMV*%s*.Raw' % nav_tag)))
51
-
53
+ # %%
54
+ # get files: DGS laptop from zenodo, BGM serial and nav from R2R
55
+ dgs_files = pooch.retrieve(url="https://zenodo.org/records/12733929/files/data.zip",
56
+ known_hash="md5:83b0411926c0fef9d7ccb2515bb27cc0", progressbar=True,
57
+ processor=pooch.Unzip(
58
+ members=['data/Thompson/TN400/gravimeter/DGS/AT1M-Grav-PROC_20220314-000001.Raw',
59
+ 'data/Thompson/TN400/gravimeter/DGS/AT1M-Grav-PROC_20220313-000001.Raw']))
60
+
61
+ bgm_files = pooch.retrieve(url="https://service.rvdata.us/data/cruise/TN400/fileset/151470",
62
+ known_hash='b0ccc52e60334284dd79573e27e050eead77f5ac1d59f510385c7e05a8474bcf',progressbar=True,
63
+ processor=pooch.Untar(
64
+ members=['TN400/151470/data/BGM3-GRAV-RAW_20220313-000001.Raw',
65
+ 'TN400/151470/data/BGM3-GRAV-RAW_20220314-000001.Raw']))
66
+
67
+ nav_files = pooch.retrieve(url="https://service.rvdata.us/data/cruise/TN400/fileset/151457",
68
+ known_hash="76e66365c41d393510bb7ab9637305296282e9041415c1343faa171af28abf85",progressbar=True,
69
+ processor=pooch.Untar(
70
+ members=['TN400/151457/data/POSMV-V5-INGGA-RAW_20220313-000001.Raw',
71
+ 'TN400/151457/data/POSMV-V5-INGGA-RAW_20220314-000001.Raw']))
72
+
73
+ # %%
52
74
  # read and sort the nav data
53
75
  gps_nav = sgi.read_nav(ship, nav_files)
54
76
  gps_nav.sort_values('time_sec', inplace=True)
55
77
  gps_nav.reset_index(inplace=True, drop=True)
56
78
 
79
+ # %%
57
80
  # we happen to know that there are some weird nav dropouts in this dataset
58
81
  # so clean them up here
59
82
  bad_inds = np.where(np.diff(gps_nav['lon']) > 1)[0]
60
83
  gps_nav.drop(bad_inds, axis=0, inplace=True)
61
84
 
85
+ # %%
62
86
  # read and sort the DGS laptop data
63
87
  dgs_data = sgi.read_dgs_laptop(dgs_files, ship)
64
88
  dgs_data.sort_values('date_time', inplace=True)
@@ -67,11 +91,15 @@ dgs_data['tsec'] = [e.timestamp()
67
91
  for e in dgs_data['date_time']] # get posix timestamps
68
92
  dgs_data['grav'] = dgs_data['rgrav'] + biases['dgs']
69
93
 
94
+ # %%
70
95
  # read and sort the BGM data
71
96
  bgm_data = sgi.read_bgm_raw(bgm_files, ship)
97
+ bgm_data.sort_values('date_time', inplace=True)
98
+ bgm_data.reset_index(inplace=True, drop=True)
72
99
  bgm_data['tsec'] = [e.timestamp() for e in bgm_data['date_time']]
73
100
  bgm_data['grav'] = bgm_data['rgrav'] + biases['bgm']
74
101
 
102
+ # %%
75
103
  # sync data geographic coordinates to nav by interpolating with timestamps
76
104
  # (interpolators use posix timestamps, not datetimes)
77
105
  gps_lon_int = interp1d(gps_nav['time_sec'].values, gps_nav['lon'].values,
@@ -84,6 +112,7 @@ dgs_data['lat_new'] = gps_lat_int(dgs_data['tsec'].values)
84
112
  bgm_data['lon_new'] = gps_lon_int(bgm_data['tsec'].values)
85
113
  bgm_data['lat_new'] = gps_lat_int(bgm_data['tsec'].values)
86
114
 
115
+ # %%
87
116
  # calculate corrections for FAA for DGS and BGM
88
117
  for df in [dgs_data, bgm_data]:
89
118
  ellipsoid_ht = np.zeros(len(df)) # we are working at sea level
@@ -97,6 +126,7 @@ for df in [dgs_data, bgm_data]:
97
126
  df['faa'] = df['grav'] - lat_corr + eotvos_corr + tide_corr
98
127
  df['full_field'] = df['grav'] + eotvos_corr + tide_corr
99
128
 
129
+ # %%
100
130
  # apply a lowpass filter
101
131
  taps = 2*240
102
132
  freq = 1./240
@@ -108,10 +138,16 @@ B = firwin(taps, wn, window='blackman') # approx equivalent to matlab fir1
108
138
  dfaa = filtfilt(B, 1, dgs_data['faa'])
109
139
  bfaa = filtfilt(B, 1, bgm_data['faa'])
110
140
 
141
+ # %%
111
142
  # load satellite data for comparison
112
- sat_grav = np.loadtxt(os.path.join(root, ship, cruise, 'sandwell_tracked.llg'), usecols=(3,),
143
+ sat_path = pooch.retrieve(url="https://zenodo.org/records/12733929/files/data.zip",
144
+ known_hash="md5:83b0411926c0fef9d7ccb2515bb27cc0", progressbar=True,
145
+ processor=pooch.Unzip(
146
+ members=['data/Thompson/TN400/sandwell_tracked.llg']))
147
+ sat_grav = np.loadtxt(sat_path[0], usecols=(3,),
113
148
  delimiter=',', skiprows=1)
114
149
 
150
+ # %%
115
151
  # plot this data and satellite data (trim edge effects from filtering)
116
152
  plt.figure(figsize=(11, 4.8))
117
153
  plt.plot(dgs_data.iloc[taps:-taps//2]['date_time'],
@@ -125,3 +161,5 @@ plt.ylabel('Free air anomaly [mGal]')
125
161
  plt.legend(fontsize=8)
126
162
  plt.tight_layout()
127
163
  plt.show()
164
+
165
+ # %%
@@ -1,27 +1,35 @@
1
- import numpy as np
2
- import shipgrav.io as sgi
3
- import shipgrav.grav as sgg
4
- import shipgrav.nav as sgn
5
- import tomli as tm
6
- from scipy.signal import firwin, filtfilt
7
- import matplotlib.pyplot as plt
8
- from glob import glob
9
- import os
10
- import sys
11
-
12
- ########################################################################
13
- # Example script using data from TN400 to illustrate how cross-
14
- # coupling coefficients are calculated and applied.
1
+ # %% [markdown]
2
+ # ### Example script using data from TN400 to illustrate how cross-coupling coefficients are calculated and applied.
3
+ #
4
+ # Data files are downloaded by the script using pooch
15
5
  #
16
6
  # Read DGS data files
17
7
  # (not bothering with navigation syncing; see dgs_bgm_comp.py)
8
+ #
18
9
  # Calculate FAA
10
+ #
19
11
  # Calculate various kinematic parameters
12
+ #
20
13
  # Fit for cross-coupling coefficients
14
+ #
21
15
  # Correct for cross-coupling
16
+ #
22
17
  # Plot with and without corrections
23
- ########################################################################
24
18
 
19
+ # %%
20
+ import os
21
+ from glob import glob
22
+
23
+ import matplotlib.pyplot as plt
24
+ import numpy as np
25
+ import pooch
26
+ import shipgrav.grav as sgg
27
+ import shipgrav.io as sgi
28
+ import shipgrav.nav as sgn
29
+ import tomli as tm
30
+ from scipy.signal import filtfilt, firwin
31
+
32
+ # %%
25
33
  # set some general metadata
26
34
  ship = 'Thompson'
27
35
  cruise = 'TN400'
@@ -32,11 +40,16 @@ with open('../shipgrav/database.toml', 'rb') as f:
32
40
  # nav_tag = info['nav-talkers'][ship] # could use this for nav file read
33
41
  bias_dgs = info['bias-values'][ship]['dgs']
34
42
 
35
- # set up file paths, get lists of input files
36
- root = 'data/'
37
- dgs_path = os.path.join(root, ship, cruise, 'gravimeter/DGS')
38
- dgs_files = np.sort(glob(os.path.join(dgs_path, 'AT1M*.Raw')))
43
+ # %%
44
+ # get the files from Zenodo: TN400 DGS laptop data
45
+ # the archive download includes some things not used for this example; those are not unpacked
46
+ dgs_files = pooch.retrieve(url="https://zenodo.org/records/12733929/files/data.zip",
47
+ known_hash="md5:83b0411926c0fef9d7ccb2515bb27cc0", progressbar=True,
48
+ processor=pooch.Unzip(
49
+ members=['data/Thompson/TN400/gravimeter/DGS/AT1M-Grav-PROC_20220314-000001.Raw',
50
+ 'data/Thompson/TN400/gravimeter/DGS/AT1M-Grav-PROC_20220313-000001.Raw']))
39
51
 
52
+ # %%
40
53
  # read and sort the gravimeter data
41
54
  dgs_data = sgi.read_dgs_laptop(dgs_files, ship)
42
55
  dgs_data.sort_values('date_time', inplace=True)
@@ -45,9 +58,11 @@ dgs_data['tsec'] = [e.timestamp()
45
58
  for e in dgs_data['date_time']] # get posix timestamps
46
59
  dgs_data['grav'] = dgs_data['rgrav'] + bias_dgs
47
60
 
61
+ # %%
48
62
  # trim some bits that we happen to know are bad
49
63
  dgs_data = dgs_data.iloc[1000:]
50
64
 
65
+ # %%
51
66
  # calculate corrections for FAA
52
67
  ellipsoid_ht = np.zeros(len(dgs_data)) # we are working at sea level
53
68
  lat_corr = sgg.wgs_grav(dgs_data['lat']) + \
@@ -60,6 +75,7 @@ tide_corr = sgg.longman_tide_prediction(
60
75
  dgs_data['faa'] = dgs_data['grav'] - lat_corr + eotvos_corr + tide_corr
61
76
  dgs_data['full_field'] = dgs_data['grav'] + eotvos_corr + tide_corr
62
77
 
78
+ # %%
63
79
  # calculate kinematic variables and corrections for tilt correction
64
80
  # (maybe not strictly necessary? depends who you ask)
65
81
  gps_vn, gps_ve = sgn.latlon_to_EN(
@@ -77,6 +93,7 @@ vel[np.isnan(vel)] = 0
77
93
  acc_cross, acc_long = sgn.rotate_acceleration_EN_to_cl(
78
94
  crse, gps_eacc, gps_nacc) # gps-derived cross and long accel
79
95
 
96
+ # %%
80
97
  # tilt correction
81
98
  up_vecs = sgg.up_vecs(1/sampling, lat_corr, acc_cross,
82
99
  acc_long, 0, 240, 0.7071, 240, 0.7071)
@@ -85,6 +102,7 @@ cross_in_plat = acc_cross*up_vecs[1, :]
85
102
  long_in_plat = acc_long*up_vecs[0, :]
86
103
  level_error = lat_corr - igf_in_plat - long_in_plat + cross_in_plat
87
104
 
105
+ # %%
88
106
  # calculate cross-coupling coefficients
89
107
  _, model = sgg.calc_cross_coupling_coefficients(dgs_data['faa'].values, dgs_data['vcc'].values, dgs_data['ve'].values,
90
108
  dgs_data['al'].values, dgs_data['ax'].values, level_error.values)
@@ -93,6 +111,7 @@ print('cross coupling parameters from fit:')
93
111
  print('ve %.3f, vcc %.3f, al %.3f, ax %.3f, lev %.3f' % (model.params.ve,
94
112
  model.params.vcc, model.params.al, model.params.ax, model.params.lev))
95
113
 
114
+ # %%
96
115
  # apply cross-coupling correction and plot the (filtered) FAA
97
116
  dgs_data['faa_ccp'] = dgs_data['faa'] + model.params.ve*dgs_data['ve'] + \
98
117
  model.params.vcc*dgs_data['vcc'] + \
@@ -108,6 +127,8 @@ B = firwin(taps, wn, window='blackman') # approx equivalent to matlab fir1
108
127
 
109
128
  ffaa = filtfilt(B, 1, dgs_data['faa'])
110
129
  cfaa = filtfilt(B, 1, dgs_data['faa_ccp'])
130
+
131
+ # %%
111
132
  plt.figure(figsize=(11, 4.8))
112
133
  plt.plot(dgs_data.iloc[taps:-taps//2]['date_time'],
113
134
  ffaa[taps:-taps//2], label='no ccp')
@@ -118,3 +139,5 @@ plt.ylabel('Free air anomaly [mGal]')
118
139
  plt.legend(fontsize=8)
119
140
  plt.tight_layout()
120
141
  plt.show()
142
+
143
+ # %%