Skip to content

Commit bbd837f

Browse files
authored
feat: added notebook for visualizing harmonic errors (#74)
1 parent d87bc3e commit bbd837f

File tree

9 files changed

+570
-29
lines changed

9 files changed

+570
-29
lines changed

doc/source/user_guide/utilities.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ General Methods
5555

5656
.. autofunction:: gravity_toolkit.utilities.s3_client
5757

58+
.. autofunction:: gravity_toolkit.utilities.s3_bucket
59+
5860
.. autofunction:: gravity_toolkit.utilities.s3_key
5961

6062
.. autofunction:: gravity_toolkit.utilities.check_credentials

gravity_toolkit/degree_amplitude.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
u"""
33
degree_amplitude.py
4-
Written Tyler Sutterley (04/2022)
4+
Written Tyler Sutterley (05/2022)
55
66
Calculates the amplitude of each spherical harmonic degree
77
@@ -20,6 +20,7 @@
2020
numpy: Scientific Computing Tools For Python (https://numpy.org)
2121
2222
UPDATE HISTORY:
23+
Updated 05/2022: use numpy atleast_3d to add singleton dimensions
2324
Updated 04/2022: updated docstrings to numpy documentation format
2425
Updated 07/2020: added function docstrings
2526
Updated 05/2020: add singleton dimension to calculate time series amplitudes
@@ -49,9 +50,8 @@ def degree_amplitude(clm, slm, LMAX=None, MMAX=None):
4950
degree amplitude
5051
"""
5152
#-- add a singleton dimension to input harmonics
52-
if (np.ndim(clm) == 2):
53-
clm = np.copy(clm[:,:,None])
54-
slm = np.copy(slm[:,:,None])
53+
clm = np.atleast_3d(clm)
54+
slm = np.atleast_3d(slm)
5555
#-- check shape
5656
LMp1,MMp1,nt = np.shape(clm)
5757

@@ -64,8 +64,8 @@ def degree_amplitude(clm, slm, LMAX=None, MMAX=None):
6464

6565
#-- allocating for output array
6666
amp = np.zeros((LMAX+1,nt))
67-
for l in range(LMAX+1):#-- m:LMAX
68-
m = np.arange(l,MMAX+1)
67+
for l in range(LMAX+1):
68+
m = np.arange(0,MMAX+1)
6969
#-- degree amplitude of spherical harmonic degree
7070
amp[l,:] = np.sqrt(np.sum(clm[l,m,:]**2 + slm[l,m,:]**2,axis=0))
7171

gravity_toolkit/grace_months_index.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
4242
UPDATE HISTORY:
4343
Updated 05/2022: use argparse descriptions within documentation
44+
use new GSFC release 6 version 2 mascons as the default
4445
Updated 04/2022: updated docstrings to numpy documentation format
4546
Updated 09/2021: use functions for converting to and from GRACE months
4647
Updated 05/2021: define int/float precision to prevent deprecation warning
@@ -67,7 +68,7 @@
6768
import numpy as np
6869
from gravity_toolkit.time import grace_to_calendar
6970

70-
def grace_months_index(base_dir, DREL=['RL06','v02.4'], MODE=None):
71+
def grace_months_index(base_dir, DREL=['RL06','rl06v2.0'], MODE=None):
7172
"""
7273
Creates a file with the start and end days for each dataset
7374
@@ -206,7 +207,7 @@ def arguments():
206207
#-- GRACE/GRACE-FO data release
207208
parser.add_argument('--release','-r',
208209
metavar='DREL', type=str, nargs='+',
209-
default=['RL06','v02.4'],
210+
default=['RL06','rl06v2.0'],
210211
help='GRACE/GRACE-FO Data Release')
211212
#-- permissions mode of the local directories and files (number in octal)
212213
parser.add_argument('--mode','-M',

gravity_toolkit/read_GRACE_harmonics.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
u"""
33
read_GRACE_harmonics.py
4-
Written by Tyler Sutterley (04/2022)
4+
Written by Tyler Sutterley (05/2022)
55
Contributions by Hugo Lecomte
66
77
Reads GRACE files and extracts spherical harmonic data and drift rates (RL04)
@@ -42,6 +42,7 @@
4242
time.py: utilities for calculating time operations
4343
4444
UPDATE HISTORY:
45+
Updated 05/2022: updated comments
4546
Updated 04/2022: updated docstrings to numpy documentation format
4647
include utf-8 encoding in reads to be windows compliant
4748
check if GRACE/GRACE-FO data file is present in file-system
@@ -105,7 +106,7 @@ def read_GRACE_harmonics(input_file, LMAX, MMAX=None, POLE_TIDE=False):
105106
eslm: float
106107
sine spherical harmonic uncalibrated standard deviations
107108
header: str
108-
Header text from the GRACE file
109+
Header text from the GRACE/GRACE-FO file
109110
110111
References
111112
----------
@@ -118,9 +119,12 @@ def read_GRACE_harmonics(input_file, LMAX, MMAX=None, POLE_TIDE=False):
118119

119120
#-- parse filename
120121
PFX,SY,SD,EY,ED,N,PRC,F1,DRL,F2,SFX = parse_file(input_file)
121-
file_contents = extract_file(input_file, (SFX=='.gz'))
122+
#-- check if file is compressed
123+
compressed = (SFX == '.gz')
124+
#-- extract file contents
125+
file_contents = extract_file(input_file, compressed)
122126

123-
#-- JPL Mascon solutions
127+
#-- JPL mascon solutions in spherical harmonic form
124128
if PRC in ('JPLMSC',):
125129
DSET = 'GSM'
126130
DREL = np.int64(DRL)
@@ -134,18 +138,18 @@ def read_GRACE_harmonics(input_file, LMAX, MMAX=None, POLE_TIDE=False):
134138
#-- COST-G unfiltered combination solutions
135139
#-- https://doi.org/10.5880/ICGEM.COST-G.001
136140
elif PRC in ('COSTG',):
137-
DSET, = re.findall('GSM|GAC',PFX)
141+
DSET, = re.findall(r'GSM|GAC',PFX)
138142
DREL = np.int64(DRL)
139143
FLAG = r'gfc'
140-
#-- Standard GRACE solutions
144+
#-- Standard GRACE/GRACE-FO Level-2 solutions
141145
else:
142146
DSET = PFX
143147
DREL = np.int64(DRL)
144148
FLAG = r'GRCOF2'
145149

146-
#-- output python dictionary with GRACE data and date information
150+
#-- output python dictionary with GRACE/GRACE-FO data and metadata
147151
grace_L2_input = {}
148-
#-- extract GRACE date information from input file name
152+
#-- extract GRACE/GRACE-FO date information from input file name
149153
start_yr = np.float64(SY)
150154
end_yr = np.float64(EY)
151155
start_day = np.float64(SD)
@@ -230,10 +234,9 @@ def read_GRACE_harmonics(input_file, LMAX, MMAX=None, POLE_TIDE=False):
230234
#-- if drift rates exist at any time, will add to harmonics
231235
#-- Will convert the secular rates into a stokes contribution
232236
#-- Currently removes 2003.3 to get the temporal average close to 0.
233-
#-- note: += means grace_xlm = grace_xlm + drift_x
234237
if ((DREL == 4) and (DSET == 'GSM')):
235238
#-- time since 2003.3
236-
dt = (grace_L2_input['time']-2003.3)
239+
dt = (grace_L2_input['time'] - 2003.3)
237240
grace_L2_input['clm'][:,:] += dt*drift_c[:,:]
238241
grace_L2_input['slm'][:,:] += dt*drift_s[:,:]
239242

@@ -261,8 +264,7 @@ def read_GRACE_harmonics(input_file, LMAX, MMAX=None, POLE_TIDE=False):
261264
#-- before computing their harmonic solutions
262265
C21_PT = -1.551e-9*(m1 - 0.62e-3*dt) - 0.012e-9*(m2 + 3.48e-3*dt)
263266
S21_PT = 0.021e-9*(m1 - 0.62e-3*dt) - 1.505e-9*(m2 + 3.48e-3*dt)
264-
#-- correct GRACE spherical harmonics for pole tide
265-
#-- note: -= means grace_xlm = grace_xlm - PT
267+
#-- correct GRACE/GRACE-FO spherical harmonics for pole tide
266268
grace_L2_input['clm'][2,1] -= C21_PT
267269
grace_L2_input['slm'][2,1] -= S21_PT
268270
#-- GFZ Pole Tide Correction
@@ -271,13 +273,13 @@ def read_GRACE_harmonics(input_file, LMAX, MMAX=None, POLE_TIDE=False):
271273
#-- GFZ removes only a constant pole position
272274
C21_PT = -1.551e-9*(-0.62e-3*dt) - 0.012e-9*(3.48e-3*dt)
273275
S21_PT = 0.021e-9*(-0.62e-3*dt) - 1.505e-9*(3.48e-3*dt)
274-
#-- correct GRACE spherical harmonics for pole tide
275-
#-- note: -= means grace_xlm = grace_xlm - PT
276+
#-- correct GRACE/GRACE-FO spherical harmonics for pole tide
276277
grace_L2_input['clm'][2,1] -= C21_PT
277278
grace_L2_input['slm'][2,1] -= S21_PT
278279

279-
#-- return the GRACE data, GRACE date (mid-month in decimal), and the
280-
#-- start and end days as Julian dates
280+
#-- return the header data, GRACE/GRACE-FO data
281+
#-- GRACE/GRACE-FO date (mid-month in decimal)
282+
#-- and the start and end days as Julian dates
281283
return grace_L2_input
282284

283285
#-- PURPOSE: extract parameters from filename

gravity_toolkit/utilities.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
#!/usr/bin/env python
22
u"""
33
utilities.py
4-
Written by Tyler Sutterley (04/2022)
4+
Written by Tyler Sutterley (05/2022)
55
Download and management utilities for syncing time and auxiliary files
66
77
PYTHON DEPENDENCIES:
88
lxml: processing XML and HTML in Python
99
https://pypi.python.org/pypi/lxml
1010
1111
UPDATE HISTORY:
12+
Updated 05/2022: function for extracting bucket name from presigned url
1213
Updated 04/2022: updated docstrings to numpy documentation format
1314
update CMR queries to prepare for version 1 of RL06
1415
Updated 03/2022: add NASA Common Metadata Repository (CMR) queries
@@ -789,6 +790,25 @@ def s3_client(HOST=None, timeout=None, region_name='us-west-2'):
789790
#-- return the AWS client for region
790791
return client
791792

793+
#-- PURPOSE: get a s3 bucket name from a presigned url
794+
def s3_bucket(presigned_url):
795+
"""
796+
Get a s3 bucket name from a presigned url
797+
798+
Parameters
799+
----------
800+
presigned_url: str
801+
s3 presigned url
802+
803+
Returns
804+
-------
805+
bucket: str
806+
s3 bucket name
807+
"""
808+
host = url_split(presigned_url)
809+
bucket = re.sub(r's3:\/\/', r'', host[0], re.IGNORECASE)
810+
return bucket
811+
792812
#-- PURPOSE: get a s3 bucket key from a presigned url
793813
def s3_key(presigned_url):
794814
"""
@@ -798,9 +818,15 @@ def s3_key(presigned_url):
798818
----------
799819
presigned_url: str
800820
s3 presigned url
821+
822+
Returns
823+
-------
824+
key: str
825+
s3 bucket key for object
801826
"""
802827
host = url_split(presigned_url)
803-
return posixpath.join(*host[1:])
828+
key = posixpath.join(*host[1:])
829+
return key
804830

805831
#-- PURPOSE: check that entered NASA Earthdata credentials are valid
806832
def check_credentials(HOST='https://podaac-tools.jpl.nasa.gov/drive/files'):

0 commit comments

Comments
 (0)