11#!/usr/bin/env python
22u"""
33calc_mascon.py
4- Written by Tyler Sutterley (06 /2021)
4+ Written by Tyler Sutterley (07 /2021)
55
66Calculates a time-series of regional mass anomalies through a least-squares
77 mascon procedure from GRACE/GRACE-FO time-variable gravity data
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
125142 https://doi.org/10.1029/2005GL025305
126143
127144UPDATE 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 )
0 commit comments