Skip to content

Commit 4adb93c

Browse files
authored
refactor: simplified file exports using wrappers in harmonics (#39)
fix: gfc format in `from_file` wrapper in harmonics
1 parent e81c3d3 commit 4adb93c

12 files changed

+162
-184
lines changed

doc/source/user_guide/grace_spatial_error.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Command Line Options
5959
* ``'SLF'``: Sutterley and Velicogna coefficients, Remote Sensing (2019)
6060
* ``'Swenson'``: GRACE-derived coefficients from Sean Swenson
6161
* ``'GFZ'``: GRACE/SLR derived coefficients from GFZ GravIS
62+
- ``--interpolate-geocenter``: Least-squares model missing Degree 1 coefficients
6263
- ``--slr-c20 X``: Replace *C*\ :sub:`20` coefficients with SLR values
6364

6465
* ``None``: use original values

doc/source/user_guide/grace_spatial_maps.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Command Line Options
7474
* ``'SLF'``: Sutterley and Velicogna coefficients, Remote Sensing (2019)
7575
* ``'Swenson'``: GRACE-derived coefficients from Sean Swenson
7676
* ``'GFZ'``: GRACE/SLR derived coefficients from GFZ GravIS
77+
- ``--interpolate-geocenter``: Least-squares model missing Degree 1 coefficients
7778
- ``--slr-c20 X``: Replace *C*\ :sub:`20` coefficients with SLR values
7879

7980
* ``None``: use original values

doc/source/user_guide/scale_grace_maps.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Command Line Options
7676
* ``'SLF'``: Sutterley and Velicogna coefficients, Remote Sensing (2019)
7777
* ``'Swenson'``: GRACE-derived coefficients from Sean Swenson
7878
* ``'GFZ'``: GRACE/SLR derived coefficients from GFZ GravIS
79+
- ``--interpolate-geocenter``: Least-squares model missing Degree 1 coefficients
7980
- ``--slr-c20 X``: Replace *C*\ :sub:`20` coefficients with SLR values
8081

8182
* ``None``: use original values

gravity_toolkit/harmonics.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
u"""
33
harmonics.py
4-
Written by Tyler Sutterley (05/2021)
4+
Written by Tyler Sutterley (07/2021)
55
66
Spherical harmonic data class for processing GRACE/GRACE-FO Level-2 data
77
@@ -26,6 +26,7 @@
2626
destripe_harmonics.py: filters spherical harmonics for correlated errors
2727
2828
UPDATE HISTORY:
29+
Updated 07/2021: fixed gfc format in from file wrapper
2930
Updated 05/2021: define int/float precision to prevent deprecation warning
3031
Updated 04/2021: add parser object for removing commented or empty lines
3132
use file not found exceptions in case insensitive filename
@@ -389,7 +390,7 @@ def from_file(self, filename, format=None, date=True, **kwargs):
389390
return harmonics().from_HDF5(filename, date=date, **kwargs)
390391
elif (format == 'gfc'):
391392
#-- ICGEM gravity model (.gfc)
392-
return harmonics().from_HDF5(filename, **kwargs)
393+
return harmonics().from_gfc(filename, **kwargs)
393394

394395
def from_dict(self, d):
395396
"""

scripts/calc_mascon.py

Lines changed: 35 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
u"""
33
calc_mascon.py
4-
Written by Tyler Sutterley (06/2021)
4+
Written by Tyler Sutterley (07/2021)
55
66
Calculates a time-series of regional mass anomalies through a least-squares
77
mascon procedure from GRACE/GRACE-FO time-variable gravity data
@@ -49,11 +49,28 @@
4949
--atm-correction: Apply atmospheric jump correction coefficients
5050
--pole-tide: Correct for pole tide drift
5151
--geocenter X: Update Degree 1 coefficients with SLR or derived values
52+
Tellus: GRACE/GRACE-FO TN-13 coefficients from PO.DAAC
53+
SLR: satellite laser ranging coefficients from CSR
54+
SLF: Sutterley and Velicogna coefficients, Remote Sensing (2019)
55+
Swenson: GRACE-derived coefficients from Sean Swenson
56+
GFZ: GRACE/GRACE-FO coefficients from GFZ GravIS
5257
--slr-c20 X: Replace C20 coefficients with SLR values
58+
CSR: use values from CSR (TN-07,TN-09,TN-11)
59+
GFZ: use values from GFZ
60+
GSFC: use values from GSFC (TN-14)
5361
--slr-21 X: Replace C21 and S21 coefficients with SLR values
62+
CSR: use values from CSR
63+
GFZ: use values from GFZ GravIS
64+
GSFC: use values from GSFC
5465
--slr-22 X: Replace C22 and S22 coefficients with SLR values
66+
CSR: use values from CSR
5567
--slr-c30 X: Replace C30 coefficients with SLR values
68+
CSR: use values from CSR (5x5 with 6,1)
69+
GFZ: use values from GFZ GravIS
70+
GSFC: use values from GSFC (TN-14)
5671
--slr-c50 X: Replace C50 coefficients with SLR values
72+
CSR: use values from CSR (5x5 with 6,1)
73+
GSFC: use values from GSFC
5774
--mean-file X: GRACE/GRACE-FO mean file to remove from the harmonic data
5875
--mean-format X: Input data format for GRACE/GRACE-FO mean file
5976
--mask X: Land-sea mask for redistributing mascon mass and land water flux
@@ -125,6 +142,7 @@
125142
https://doi.org/10.1029/2005GL025305
126143
127144
UPDATE HISTORY:
145+
Updated 07/2021: simplified file imports using wrappers in harmonics
128146
Updated 06/2021: switch from parameter files to argparse arguments
129147
Updated 05/2021: define int/float precision to prevent deprecation warning
130148
Updated 04/2021: include parameters for replacing C21/S21 and C22/S22
@@ -361,30 +379,22 @@ def calc_mascon(base_dir, PROC, DREL, DSET, LMAX, RAD,
361379
#-- not distributing uniformly over ocean
362380
ocean_str = ''
363381

364-
#-- input GRACE/GRACE-FO spherical harmonic datafiles
365-
#-- reading GRACE months for input range with grace_input_months.py
382+
#-- input GRACE/GRACE-FO spherical harmonic datafiles for date range
366383
#-- replacing low-degree harmonics with SLR values if specified
367384
#-- include degree 1 (geocenter) harmonics if specified
368385
#-- correcting for Pole-Tide and Atmospheric Jumps if specified
369386
Ylms = grace_input_months(base_dir, PROC, DREL, DSET, LMAX,
370387
START, END, MISSING, SLR_C20, DEG1, MMAX=MMAX,
371388
SLR_21=SLR_21, SLR_22=SLR_22, SLR_C30=SLR_C30, SLR_C50=SLR_C50,
372389
MODEL_DEG1=True, ATM=ATM, POLE_TIDE=POLE_TIDE)
373-
#-- full path to directory for specific GRACE/GRACE-FO product
374-
grace_dir = Ylms['directory']
375390
#-- create harmonics object from GRACE/GRACE-FO data
376391
GRACE_Ylms = harmonics().from_dict(Ylms)
392+
#-- full path to directory for specific GRACE/GRACE-FO product
393+
GRACE_Ylms.directory = Ylms['directory']
377394
#-- use a mean file for the static field to remove
378395
if MEAN_FILE:
379396
#-- read data form for input mean file (ascii, netCDF4, HDF5, gfc)
380-
if (MEANFORM == 'ascii'):
381-
mean_Ylms=harmonics().from_ascii(MEAN_FILE,date=False)
382-
elif (MEANFORM == 'netCDF4'):
383-
mean_Ylms=harmonics().from_netCDF4(MEAN_FILE,date=False)
384-
elif (MEANFORM == 'HDF5'):
385-
mean_Ylms=harmonics().from_HDF5(MEAN_FILE,date=False)
386-
elif (MEANFORM == 'gfc'):
387-
mean_Ylms=harmonics().from_gfc(MEAN_FILE)
397+
mean_Ylms = harmonics().from_file(MEAN_FILE,format=DATAFORM,date=False)
388398
#-- remove the input mean
389399
GRACE_Ylms.subtract(mean_Ylms)
390400
else:
@@ -425,18 +435,12 @@ def calc_mascon(base_dir, PROC, DREL, DSET, LMAX, RAD,
425435
REMOVE_FORMAT = REMOVE_FORMAT*len(REMOVE_FILES)
426436
#-- for each file to be removed
427437
for REMOVE_FILE,REMOVEFORM in zip(REMOVE_FILES,REMOVE_FORMAT):
428-
if (REMOVEFORM == 'ascii'):
429-
#-- ascii (.txt)
430-
Ylms = harmonics().from_ascii(REMOVE_FILE)
431-
elif (REMOVEFORM == 'netCDF4'):
432-
#-- netCDF4 (.nc)
433-
Ylms = harmonics().from_netCDF4(REMOVE_FILE)
434-
elif (REMOVEFORM == 'HDF5'):
435-
#-- HDF5 (.h5)
436-
Ylms = harmonics().from_HDF5(REMOVE_FILE)
437-
elif (REMOVEFORM == 'index'):
438+
if (REMOVEFORM == 'index'):
438439
#-- index containing files in data format
439440
Ylms = harmonics().from_index(REMOVE_FILE, DATAFORM)
441+
else:
442+
#-- individual file in ascii, netCDF4 or HDF5 formats
443+
Ylms = harmonics().from_file(REMOVE_FILE, format=DATAFORM)
440444
#-- reduce to GRACE/GRACE-FO months and truncate to degree and order
441445
Ylms = Ylms.subset(GRACE_Ylms.month).truncate(lmax=LMAX,mmax=MMAX)
442446
#-- distribute removed Ylms uniformly over the ocean
@@ -470,15 +474,7 @@ def calc_mascon(base_dir, PROC, DREL, DSET, LMAX, RAD,
470474
#-- for each valid file in the index (iterate over mascons)
471475
for reconstruct_file in file_list:
472476
#-- read reconstructed spherical harmonics
473-
if (DATAFORM == 'ascii'):
474-
#-- ascii (.txt)
475-
Ylms = harmonics().from_ascii(reconstruct_file)
476-
elif (DATAFORM == 'netCDF4'):
477-
#-- netcdf (.nc)
478-
Ylms = harmonics().from_netCDF4(reconstruct_file)
479-
elif (DATAFORM == 'HDF5'):
480-
#-- HDF5 (.H5)
481-
Ylms = harmonics().from_HDF5(reconstruct_file)
477+
Ylms = harmonics().from_file(reconstruct_file,format=DATAFORM)
482478
#-- truncate clm and slm matrices to LMAX/MMAX
483479
#-- add harmonics object to total
484480
construct_Ylms.add(Ylms.truncate(lmax=LMAX, mmax=MMAX))
@@ -504,15 +500,8 @@ def calc_mascon(base_dir, PROC, DREL, DSET, LMAX, RAD,
504500
mascon_list = []
505501
for k,fi in enumerate(mascon_files):
506502
#-- read mascon spherical harmonics
507-
if (DATAFORM == 'ascii'):
508-
#-- ascii (.txt)
509-
Ylms = harmonics().from_ascii(os.path.expanduser(fi),date=False)
510-
elif (DATAFORM == 'netCDF4'):
511-
#-- netcdf (.nc)
512-
Ylms = harmonics().from_netCDF4(os.path.expanduser(fi),date=False)
513-
elif (DATAFORM == 'HDF5'):
514-
#-- HDF5 (.H5)
515-
Ylms = harmonics().from_HDF5(os.path.expanduser(fi),date=False)
503+
Ylms = harmonics().from_file(os.path.expanduser(fi),
504+
format=DATAFORM, date=False)
516505
#-- Calculating the total mass of each mascon (1 cmwe uniform)
517506
total_area[k] = 4.0*np.pi*(rad_e**3)*rho_e*Ylms.clm[0,0]/3.0
518507
#-- distribute mascon mass uniformly over the ocean
@@ -544,13 +533,13 @@ def calc_mascon(base_dir, PROC, DREL, DSET, LMAX, RAD,
544533
args = (PROC,DREL,DSET,LMAX,order_str,ds_str,atm_str,GRACE_Ylms.month[0],
545534
GRACE_Ylms.month[-1], suffix[DATAFORM])
546535
delta_format = '{0}_{1}_{2}_DELTA_CLM_L{3:d}{4}{5}{6}_{7:03d}-{8:03d}.{9}'
547-
DELTA_FILE = delta_format.format(*args)
536+
DELTA_FILE = os.path.join(GRACE_Ylms.directory,delta_format.format(*args))
548537
#-- check full path of the GRACE directory for delta file
549538
#-- if file was previously calculated: will read file
550539
#-- else: will calculate the GRACE/GRACE-FO error
551-
if (not os.access(os.path.join(grace_dir, DELTA_FILE),os.F_OK)):
540+
if not os.access(DELTA_FILE, os.F_OK):
552541
#-- add output delta file to list object
553-
output_files.append(os.path.join(grace_dir,DELTA_FILE))
542+
output_files.append(DELTA_FILE)
554543

555544
#-- Delta coefficients of GRACE time series (Error components)
556545
delta_Ylms = harmonics(lmax=LMAX,mmax=MMAX)
@@ -584,26 +573,10 @@ def calc_mascon(base_dir, PROC, DREL, DSET, LMAX, RAD,
584573
#-- save GRACE/GRACE-FO delta harmonics to file
585574
delta_Ylms.time = np.copy(tsmth)
586575
delta_Ylms.month = np.int64(nsmth)
587-
if (DATAFORM == 'ascii'):
588-
#-- ascii (.txt)
589-
delta_Ylms.to_ascii(os.path.join(grace_dir,DELTA_FILE))
590-
elif (DATAFORM == 'netCDF4'):
591-
#-- netcdf (.nc)
592-
delta_Ylms.to_netCDF4(os.path.join(grace_dir,DELTA_FILE))
593-
elif (DATAFORM == 'HDF5'):
594-
#-- HDF5 (.H5)
595-
delta_Ylms.to_HDF5(os.path.join(grace_dir,DELTA_FILE))
576+
delta_Ylms.to_file(DELTA_FILE,format=DATAFORM)
596577
else:
597578
#-- read GRACE/GRACE-FO delta harmonics from file
598-
if (DATAFORM == 'ascii'):
599-
#-- ascii (.txt)
600-
delta_Ylms=harmonics().from_ascii(os.path.join(grace_dir,DELTA_FILE))
601-
elif (DATAFORM == 'netCDF4'):
602-
#-- netcdf (.nc)
603-
delta_Ylms=harmonics().from_netCDF4(os.path.join(grace_dir,DELTA_FILE))
604-
elif (DATAFORM == 'HDF5'):
605-
#-- HDF5 (.H5)
606-
delta_Ylms=harmonics().from_HDF5(os.path.join(grace_dir,DELTA_FILE))
579+
delta_Ylms = harmonics().from_file(DELTA_FILE,format=DATAFORM)
607580
#-- truncate GRACE/GRACE-FO delta clm and slm to d/o LMAX/MMAX
608581
delta_Ylms = delta_Ylms.truncate(lmax=LMAX, mmax=MMAX)
609582
tsmth = np.squeeze(delta_Ylms.time)

scripts/calc_sensitivity_kernel.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
u"""
33
calc_sensitivity_kernel.py
4-
Written by Tyler Sutterley (06/2021)
4+
Written by Tyler Sutterley (07/2021)
55
66
Calculates spatial sensitivity kernels through a least-squares mascon procedure
77
@@ -83,6 +83,7 @@
8383
https://doi.org/10.1029/2009GL039401
8484
8585
UPDATE HISTORY:
86+
Updated 07/2021: simplified file imports using wrappers in harmonics
8687
Updated 06/2021: switch from parameter files to argparse arguments
8788
Updated 05/2021: define int/float precision to prevent deprecation warning
8889
Updated 04/2021: add parser object for removing commented or empty lines
@@ -285,15 +286,8 @@ def calc_sensitivity_kernel(LMAX, RAD,
285286
mascon_list = []
286287
for k,fi in enumerate(mascon_files):
287288
#-- read mascon spherical harmonics
288-
if (DATAFORM == 'ascii'):
289-
#-- ascii (.txt)
290-
Ylms = harmonics().from_ascii(os.path.expanduser(fi),date=False)
291-
elif (DATAFORM == 'netCDF4'):
292-
#-- netcdf (.nc)
293-
Ylms = harmonics().from_netCDF4(os.path.expanduser(fi),date=False)
294-
elif (DATAFORM == 'HDF5'):
295-
#-- HDF5 (.H5)
296-
Ylms = harmonics().from_HDF5(os.path.expanduser(fi),date=False)
289+
Ylms = harmonics().from_file(os.path.expanduser(fi),
290+
format=DATAFORM, date=False)
297291
#-- Calculating the total mass of each mascon (1 cmwe uniform)
298292
total_area[k] = 4.0*np.pi*(rad_e**3)*rho_e*Ylms.clm[0,0]/3.0
299293
#-- distribute mascon mass uniformly over the ocean

scripts/combine_harmonics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ def main():
437437

438438
#-- run program with parameters
439439
try:
440-
info(args)
440+
info(args) if args.verbose else None
441441
combine_harmonics(args.infile, args.outfile,
442442
LMAX=args.lmax,
443443
MMAX=args.mmax,

scripts/convert_harmonics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ def main():
324324

325325
#-- run program with parameters
326326
try:
327-
info(args)
327+
info(args) if args.verbose else None
328328
convert_harmonics(args.infile, args.outfile,
329329
LMAX=args.lmax,
330330
MMAX=args.mmax,

scripts/grace_mean_harmonics.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
u"""
33
grace_mean_harmonics.py
4-
Written by Tyler Sutterley (06/2021)
4+
Written by Tyler Sutterley (07/2021)
55
66
Calculates the temporal mean of the GRACE/GRACE-FO spherical harmonics
77
for a given date range from a set of parameters
@@ -19,11 +19,28 @@
1919
--atm-correction: Apply atmospheric jump correction coefficients
2020
--pole-tide: Correct for pole tide drift
2121
--geocenter X: Update Degree 1 coefficients with SLR or derived values
22+
Tellus: GRACE/GRACE-FO TN-13 coefficients from PO.DAAC
23+
SLR: satellite laser ranging coefficients from CSR
24+
SLF: Sutterley and Velicogna coefficients, Remote Sensing (2019)
25+
Swenson: GRACE-derived coefficients from Sean Swenson
26+
GFZ: GRACE/GRACE-FO coefficients from GFZ GravIS
2227
--slr-c20 X: Replace C20 coefficients with SLR values
28+
CSR: use values from CSR (TN-07,TN-09,TN-11)
29+
GFZ: use values from GFZ
30+
GSFC: use values from GSFC (TN-14)
2331
--slr-21 X: Replace C21 and S21 coefficients with SLR values
32+
CSR: use values from CSR
33+
GFZ: use values from GFZ GravIS
34+
GSFC: use values from GSFC
2435
--slr-22 X: Replace C22 and S22 coefficients with SLR values
36+
CSR: use values from CSR
2537
--slr-c30 X: Replace C30 coefficients with SLR values
38+
CSR: use values from CSR (5x5 with 6,1)
39+
GFZ: use values from GFZ GravIS
40+
GSFC: use values from GSFC (TN-14)
2641
--slr-c50 X: Replace C50 coefficients with SLR values
42+
CSR: use values from CSR (5x5 with 6,1)
43+
GSFC: use values from GSFC
2744
--mean-file X: Output GRACE/GRACE-FO mean file
2845
--mean-format X: Output data format for GRACE/GRACE-FO mean file
2946
--log: Output a log file listing output files
@@ -52,6 +69,7 @@
5269
utilities.py: download and management utilities for files
5370
5471
UPDATE HISTORY:
72+
Updated 07/2021: simplified file exports using wrappers in harmonics
5573
Updated 06/2021: switch from parameter files to argparse arguments
5674
Updated 05/2021: define int/float precision to prevent deprecation warning
5775
Updated 04/2021: include parameters for replacing C21/S21 and C22/S22
@@ -124,7 +142,7 @@ def grace_mean_harmonics(base_dir, PROC, DREL, DSET, LMAX,
124142
#-- data formats for output: ascii, netCDF4, HDF5
125143
suffix = dict(ascii='txt', netCDF4='nc', HDF5='H5')[MEANFORM]
126144

127-
#-- reading GRACE months for input range with grace_input_months.py
145+
#-- reading GRACE months for input date range
128146
#-- replacing low-degree harmonics with SLR values if specified
129147
#-- include degree 1 (geocenter) harmonics if specified
130148
#-- correcting for Pole Tide Drift and Atmospheric Jumps if specified
@@ -153,15 +171,8 @@ def grace_mean_harmonics(base_dir, PROC, DREL, DSET, LMAX,
153171
os.makedirs(DIRECTORY, MODE)
154172

155173
#-- output spherical harmonics for the static field
156-
if (MEANFORM == 'ascii'):
157-
#-- output mean field to ascii
158-
mean_Ylms.to_ascii(MEAN_FILE,verbose=VERBOSE)
159-
elif (MEANFORM == 'netCDF4'):
160-
#-- output mean field to netCDF4
161-
mean_Ylms.to_netCDF4(MEAN_FILE,verbose=VERBOSE)
162-
elif (MEANFORM == 'HDF5'):
163-
#-- output mean field to HDF5
164-
mean_Ylms.to_HDF5(MEAN_FILE,verbose=VERBOSE)
174+
#-- output mean field to specified file format
175+
mean_Ylms.to_file(MEAN_FILE, format=MEANFORM, verbose=VERBOSE)
165176
#-- change the permissions mode
166177
os.chmod(MEAN_FILE, MODE)
167178

0 commit comments

Comments
 (0)