Skip to content

Commit cab3ca3

Browse files
authored
Merge pull request #145 from falconstryker/devel
bypass shtools for new tide decomp
2 parents e41cb27 + 1a74f98 commit cab3ca3

File tree

3 files changed

+65
-50
lines changed

3 files changed

+65
-50
lines changed

amescap/Spectral_utils.py

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -31,27 +31,40 @@
3131
# DEFINITIONS
3232
# ======================================================================
3333

34-
# Try to import pyshtools with proper error handling
35-
try:
36-
import pyshtools
37-
PYSHTOOLS_AVAILABLE = True
38-
except ImportError:
39-
PYSHTOOLS_AVAILABLE = False
40-
print(
41-
f"{Yellow}__________________\n"
42-
f"Tidal decomposition relies on the pyshtools library, "
43-
f"referenced at:\n\n"
44-
f"Mark A. Wieczorek and Matthias Meschede (2018). "
45-
f"SHTools - Tools for working with spherical harmonics,"
46-
f"Geochemistry, Geophysics, Geosystems, 2574-2592, "
47-
f"doi:10.1029/2018GC007529\n\nPlease consult pyshtools "
48-
f"documentation at:\n"
49-
f" {Cyan}https://pypi.org/project/pyshtools\n"
50-
f"{Yellow}And installation instructions for CAP with pyshtools:\n"
51-
f" {Cyan}https://amescap.readthedocs.io/en/latest/installation."
52-
f"html#_spectral_analysis{Yellow}\n"
53-
f"__________________{Nclr}\n\n"
54-
)
34+
def import_pyshtools():
35+
"""
36+
Attempt to import pyshtools and set the global variable
37+
PYSHTOOLS_AVAILABLE accordingly.
38+
Check if pyshtools is available and return its availability status
39+
40+
:return: True if pyshtools is available, False otherwise
41+
:rtype: bool
42+
"""
43+
44+
global PYSHTOOLS_AVAILABLE
45+
# Try to import pyshtools with proper error handling
46+
try:
47+
import pyshtools
48+
global pyshtools
49+
PYSHTOOLS_AVAILABLE = True
50+
except ImportError:
51+
PYSHTOOLS_AVAILABLE = False
52+
print(
53+
f"{Yellow}__________________\n"
54+
f"Tidal decomposition relies on the pyshtools library, "
55+
f"referenced at:\n"
56+
f"{Cyan}Mark A. Wieczorek and Matthias Meschede (2018). "
57+
f"SHTools - Tools for working with spherical harmonics, "
58+
f"Geochemistry, Geophysics, Geosystems, 2574-2592, "
59+
f"doi:10.1029/2018GC007529\n\n"
60+
f"Please consult pyshtools documentation at:\n"
61+
f"{Cyan}https://pypi.org/project/pyshtools\n\n"
62+
f"{Yellow}And installation instructions for CAP with pyshtools:\n"
63+
f"{Cyan}https://amescap.readthedocs.io/en/latest/installation."
64+
f"html#_spectral_analysis{Yellow}\n"
65+
f"__________________{Nclr}\n\n"
66+
)
67+
return PYSHTOOLS_AVAILABLE
5568

5669

5770
def diurn_extract(VAR, N, tod, lon):
@@ -74,7 +87,8 @@ def diurn_extract(VAR, N, tod, lon):
7487
(e.g., size ``[Nh, time, lat, lon]``)
7588
:rtype: ND arrays
7689
"""
77-
90+
import_pyshtools()
91+
7892
dimsIN = VAR.shape
7993
nsteps = len(tod)
8094
period = 24
@@ -140,6 +154,7 @@ def diurn_extract(VAR, N, tod, lon):
140154
# Return the phase and amplitude
141155
return amp.reshape(dimsOUT), phas.reshape(dimsOUT)
142156

157+
143158
def reconstruct_diurn(amp, phas, tod, lon, sumList=[]):
144159
"""
145160
Reconstructs a field wave based on its diurnal harmonics
@@ -162,7 +177,8 @@ def reconstruct_diurn(amp, phas, tod, lon, sumList=[]):
162177
aggregated (i.e., size = ``[tod, time, lat, lon]``)
163178
:rtype: _type_
164179
"""
165-
180+
import_pyshtools()
181+
166182
dimsIN = amp.shape
167183
N = dimsIN[0]
168184
dimsSUM = np.append([len(tod)], dimsIN[1:])
@@ -207,6 +223,7 @@ def reconstruct_diurn(amp, phas, tod, lon, sumList=[]):
207223
# Return harmonics separately
208224
return varOUT
209225

226+
210227
def extract_diurnal_harmonics(kmx, tmx, varIN, tod, lon):
211228
"""
212229
Obtain west and east propagating waves. This is a Python
@@ -344,6 +361,7 @@ def zeroPhi_filter(VAR, btype, low_highcut, fs, axis=0, order=4,
344361
.. note:: ``Wn=[low, high]`` are expressed as a function of the
345362
Nyquist frequency
346363
"""
364+
import_pyshtools()
347365

348366
# Create the filter
349367
low_highcut = np.array(low_highcut)
@@ -381,6 +399,7 @@ def zonal_decomposition(VAR):
381399
.. note:: Output size is (``[...,lat/2, lat/2]``) as lat is the
382400
smallest dimension. This matches the Nyquist frequency.
383401
"""
402+
import_pyshtools()
384403

385404
if not PYSHTOOLS_AVAILABLE:
386405
raise ImportError(
@@ -440,6 +459,7 @@ def zonal_construct(COEFFS_flat, VAR_shape, btype=None, low_highcut=None):
440459
print("(kmin,kmax) = ({kmin}, {kmax})
441460
-> dx min = {L_min} km, dx max = {L_max} km")
442461
"""
462+
import_pyshtools()
443463

444464
if not PYSHTOOLS_AVAILABLE:
445465
raise ImportError(
@@ -472,12 +492,3 @@ def zonal_construct(COEFFS_flat, VAR_shape, btype=None, low_highcut=None):
472492
return VAR.reshape(VAR_shape)
473493

474494

475-
def init_shtools():
476-
"""
477-
Check if pyshtools is available and return its availability status
478-
479-
:return: True if pyshtools is available, False otherwise
480-
:rtype: bool
481-
"""
482-
483-
return PYSHTOOLS_AVAILABLE

bin/MarsFiles.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ def wrapper(*args, **kwargs):
444444
f"in Sols.\n"
445445
f"{Yellow}Generates a new file ending in ``_hps.nc``\n"
446446
f"{Green}Example:\n"
447-
f"> MarsFiles 01336.atmos_daily.nc -hps 10 -add_trend\n"
447+
f"> MarsFiles 01336.atmos_daily.nc -hps 10\n"
448448
f"{Nclr}\n\n"
449449
)
450450
)
@@ -464,7 +464,7 @@ def wrapper(*args, **kwargs):
464464
f"cutoff frequency in Sols.\n"
465465
f"{Yellow}Generates a new file ending in ``_lps.nc``\n"
466466
f"{Green}Example:\n"
467-
f"> MarsFiles 01336.atmos_daily.nc -lps 20 -add_trend\n"
467+
f"> MarsFiles 01336.atmos_daily.nc -lps 20\n"
468468
f"{Nclr}\n\n"
469469
)
470470
)
@@ -484,7 +484,7 @@ def wrapper(*args, **kwargs):
484484
f"cutoff frequency in Sols.\nData detrended before filtering.\n"
485485
f"{Yellow}Generates a new file ending in ``_bps.nc``\n"
486486
f"{Green}Example:\n"
487-
f"> MarsFiles 01336.atmos_daily.nc -bps 10 20 -add_trend\n"
487+
f"> MarsFiles 01336.atmos_daily.nc -bps 10 20\n"
488488
f"{Nclr}\n\n"
489489
)
490490
)
@@ -539,21 +539,25 @@ def wrapper(*args, **kwargs):
539539
parser=parser,
540540
nargs=2, type=int,
541541
help=(
542-
f"{Yellow}This is separate from -tide and does not provide "
543-
f"total amplitude and phase. It does not work with the options "
544-
f"normalize and reconstruct.\n"
542+
f"{Yellow}This function is separate distinct from [-tide "
543+
f"--tide_decomp] and therefore does not return total amplitude \n"
544+
f"and phase nor does it work with [-norm --normalize] or [-recon "
545+
f"--reconstruct].\n"
546+
f"For 'diurn' files only.\n"
545547
f"{Nclr}\n"
546-
f"Use fourier decomposition to break down the signal into kmx longitudinal harmonics "
547-
f"and tmx diurnal harmonics.\nOnly works with 'diurn' files.\nReturns the normalized phases "
548-
f"and amplitudes (not percent) of the propagating tides for the variables.\n"
549-
f"kmx = 1 wavenumber 1, kmx = 2 wavenumber 2, etc.\n"
550-
f"tmx = 1 diurnal tide, tmx = 2 semi-diurnal, etc.\n"
551-
f"Works on 'diurn' files only.\n"
552-
f"{Yellow}Generates a new file ending in ``_prop_tides.nc``\n"
548+
f"Use fourier decomposition to break down a variable into `kmx` "
549+
f"longitudinal (spatial) harmonics and `tmx` \n"
550+
f"diurnal (time) harmonics. This returns the normalized phases and "
551+
f"amplitudes (not percent) of the \n"
552+
f"propagating tides for a variable.\n"
553+
f"{Yellow}Generates a new file ending in ``_prop_tides.nc``{Nclr}\n"
554+
f"`kmx = 1` for wavenumber 1, `kmx = 2` for wavenumber 2, etc.\n"
555+
f"`tmx = 1` for diurnal tide, `tmx = 2` for semi-diurnal tide, etc.\n"
553556
f"{Green}Example:\n"
557+
f"> MarsFiles 01336.atmos_diurn.nc -prop kmx tmx -incl ps temp\n"
554558
f"> MarsFiles 01336.atmos_diurn.nc -prop 2 2 -incl ps temp\n"
555-
f"{Blue}(extracts eastward and westward tide components of ps and\ntemp "
556-
f"variables up to semi-dirunal wavenumber 2)"
559+
f"{Blue}(extracts the eastward and westward tide components of ps and"
560+
f"temp up to semi-diurnal wavenumber 2)"
557561
f"{Nclr}\n\n"
558562
)
559563
)
@@ -1795,9 +1799,9 @@ def main():
17951799
args.band_pass_spatial):
17961800
from amescap.Spectral_utils import (zonal_decomposition,
17971801
zonal_construct,
1798-
init_shtools)
1802+
import_pyshtools)
17991803
# Load the module
1800-
init_shtools()
1804+
import_pyshtools()
18011805
if args.high_pass_spatial:
18021806
btype = "high"
18031807
nk = np.asarray(args.high_pass_spatial).astype(int)

docs/source/installation.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ The pip installation method is less recommended as it requires manual installati
469469
# Activate your virtual environment
470470
471471
# Install CAP with spectral analysis support
472-
pip install "amescap[spectral] @ git+https://github.com/NASA-Planetary-Science/AmesCAP.git@pyshtools"
472+
pip install "amescap[spectral] @ git+https://github.com/NASA-Planetary-Science/AmesCAP.git"
473473
474474
# Don't forget to copy the profile file to your home directory
475475
cp amescap/mars_templates/amescap_profile ~/.amescap_profile

0 commit comments

Comments
 (0)