Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 43 additions & 32 deletions amescap/Spectral_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,40 @@
# DEFINITIONS
# ======================================================================

# Try to import pyshtools with proper error handling
try:
import pyshtools
PYSHTOOLS_AVAILABLE = True
except ImportError:
PYSHTOOLS_AVAILABLE = False
print(
f"{Yellow}__________________\n"
f"Tidal decomposition relies on the pyshtools library, "
f"referenced at:\n\n"
f"Mark A. Wieczorek and Matthias Meschede (2018). "
f"SHTools - Tools for working with spherical harmonics,"
f"Geochemistry, Geophysics, Geosystems, 2574-2592, "
f"doi:10.1029/2018GC007529\n\nPlease consult pyshtools "
f"documentation at:\n"
f" {Cyan}https://pypi.org/project/pyshtools\n"
f"{Yellow}And installation instructions for CAP with pyshtools:\n"
f" {Cyan}https://amescap.readthedocs.io/en/latest/installation."
f"html#_spectral_analysis{Yellow}\n"
f"__________________{Nclr}\n\n"
)
def import_pyshtools():
"""
Attempt to import pyshtools and set the global variable
PYSHTOOLS_AVAILABLE accordingly.
Check if pyshtools is available and return its availability status

:return: True if pyshtools is available, False otherwise
:rtype: bool
"""

global PYSHTOOLS_AVAILABLE
# Try to import pyshtools with proper error handling
try:
import pyshtools
global pyshtools
PYSHTOOLS_AVAILABLE = True
except ImportError:
PYSHTOOLS_AVAILABLE = False
print(
f"{Yellow}__________________\n"
f"Tidal decomposition relies on the pyshtools library, "
f"referenced at:\n"
f"{Cyan}Mark A. Wieczorek and Matthias Meschede (2018). "
f"SHTools - Tools for working with spherical harmonics, "
f"Geochemistry, Geophysics, Geosystems, 2574-2592, "
f"doi:10.1029/2018GC007529\n\n"
f"Please consult pyshtools documentation at:\n"
f"{Cyan}https://pypi.org/project/pyshtools\n\n"
f"{Yellow}And installation instructions for CAP with pyshtools:\n"
f"{Cyan}https://amescap.readthedocs.io/en/latest/installation."
f"html#_spectral_analysis{Yellow}\n"
f"__________________{Nclr}\n\n"
)
return PYSHTOOLS_AVAILABLE


def diurn_extract(VAR, N, tod, lon):
Expand All @@ -74,7 +87,8 @@ def diurn_extract(VAR, N, tod, lon):
(e.g., size ``[Nh, time, lat, lon]``)
:rtype: ND arrays
"""

import_pyshtools()

dimsIN = VAR.shape
nsteps = len(tod)
period = 24
Expand Down Expand Up @@ -140,6 +154,7 @@ def diurn_extract(VAR, N, tod, lon):
# Return the phase and amplitude
return amp.reshape(dimsOUT), phas.reshape(dimsOUT)


def reconstruct_diurn(amp, phas, tod, lon, sumList=[]):
"""
Reconstructs a field wave based on its diurnal harmonics
Expand All @@ -162,7 +177,8 @@ def reconstruct_diurn(amp, phas, tod, lon, sumList=[]):
aggregated (i.e., size = ``[tod, time, lat, lon]``)
:rtype: _type_
"""

import_pyshtools()

dimsIN = amp.shape
N = dimsIN[0]
dimsSUM = np.append([len(tod)], dimsIN[1:])
Expand Down Expand Up @@ -207,6 +223,7 @@ def reconstruct_diurn(amp, phas, tod, lon, sumList=[]):
# Return harmonics separately
return varOUT


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

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

if not PYSHTOOLS_AVAILABLE:
raise ImportError(
Expand Down Expand Up @@ -440,6 +459,7 @@ def zonal_construct(COEFFS_flat, VAR_shape, btype=None, low_highcut=None):
print("(kmin,kmax) = ({kmin}, {kmax})
-> dx min = {L_min} km, dx max = {L_max} km")
"""
import_pyshtools()

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


def init_shtools():
"""
Check if pyshtools is available and return its availability status

:return: True if pyshtools is available, False otherwise
:rtype: bool
"""

return PYSHTOOLS_AVAILABLE
38 changes: 21 additions & 17 deletions bin/MarsFiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ def wrapper(*args, **kwargs):
f"in Sols.\n"
f"{Yellow}Generates a new file ending in ``_hps.nc``\n"
f"{Green}Example:\n"
f"> MarsFiles 01336.atmos_daily.nc -hps 10 -add_trend\n"
f"> MarsFiles 01336.atmos_daily.nc -hps 10\n"
f"{Nclr}\n\n"
)
)
Expand All @@ -464,7 +464,7 @@ def wrapper(*args, **kwargs):
f"cutoff frequency in Sols.\n"
f"{Yellow}Generates a new file ending in ``_lps.nc``\n"
f"{Green}Example:\n"
f"> MarsFiles 01336.atmos_daily.nc -lps 20 -add_trend\n"
f"> MarsFiles 01336.atmos_daily.nc -lps 20\n"
f"{Nclr}\n\n"
)
)
Expand All @@ -484,7 +484,7 @@ def wrapper(*args, **kwargs):
f"cutoff frequency in Sols.\nData detrended before filtering.\n"
f"{Yellow}Generates a new file ending in ``_bps.nc``\n"
f"{Green}Example:\n"
f"> MarsFiles 01336.atmos_daily.nc -bps 10 20 -add_trend\n"
f"> MarsFiles 01336.atmos_daily.nc -bps 10 20\n"
f"{Nclr}\n\n"
)
)
Expand Down Expand Up @@ -539,21 +539,25 @@ def wrapper(*args, **kwargs):
parser=parser,
nargs=2, type=int,
help=(
f"{Yellow}This is separate from -tide and does not provide "
f"total amplitude and phase. It does not work with the options "
f"normalize and reconstruct.\n"
f"{Yellow}This function is separate distinct from [-tide "
f"--tide_decomp] and therefore does not return total amplitude \n"
f"and phase nor does it work with [-norm --normalize] or [-recon "
f"--reconstruct].\n"
f"For 'diurn' files only.\n"
f"{Nclr}\n"
f"Use fourier decomposition to break down the signal into kmx longitudinal harmonics "
f"and tmx diurnal harmonics.\nOnly works with 'diurn' files.\nReturns the normalized phases "
f"and amplitudes (not percent) of the propagating tides for the variables.\n"
f"kmx = 1 wavenumber 1, kmx = 2 wavenumber 2, etc.\n"
f"tmx = 1 diurnal tide, tmx = 2 semi-diurnal, etc.\n"
f"Works on 'diurn' files only.\n"
f"{Yellow}Generates a new file ending in ``_prop_tides.nc``\n"
f"Use fourier decomposition to break down a variable into `kmx` "
f"longitudinal (spatial) harmonics and `tmx` \n"
f"diurnal (time) harmonics. This returns the normalized phases and "
f"amplitudes (not percent) of the \n"
f"propagating tides for a variable.\n"
f"{Yellow}Generates a new file ending in ``_prop_tides.nc``{Nclr}\n"
f"`kmx = 1` for wavenumber 1, `kmx = 2` for wavenumber 2, etc.\n"
f"`tmx = 1` for diurnal tide, `tmx = 2` for semi-diurnal tide, etc.\n"
f"{Green}Example:\n"
f"> MarsFiles 01336.atmos_diurn.nc -prop kmx tmx -incl ps temp\n"
f"> MarsFiles 01336.atmos_diurn.nc -prop 2 2 -incl ps temp\n"
f"{Blue}(extracts eastward and westward tide components of ps and\ntemp "
f"variables up to semi-dirunal wavenumber 2)"
f"{Blue}(extracts the eastward and westward tide components of ps and"
f"temp up to semi-diurnal wavenumber 2)"
f"{Nclr}\n\n"
)
)
Expand Down Expand Up @@ -1795,9 +1799,9 @@ def main():
args.band_pass_spatial):
from amescap.Spectral_utils import (zonal_decomposition,
zonal_construct,
init_shtools)
import_pyshtools)
# Load the module
init_shtools()
import_pyshtools()
if args.high_pass_spatial:
btype = "high"
nk = np.asarray(args.high_pass_spatial).astype(int)
Expand Down
2 changes: 1 addition & 1 deletion docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ The pip installation method is less recommended as it requires manual installati
# Activate your virtual environment

# Install CAP with spectral analysis support
pip install "amescap[spectral] @ git+https://github.com/NASA-Planetary-Science/AmesCAP.git@pyshtools"
pip install "amescap[spectral] @ git+https://github.com/NASA-Planetary-Science/AmesCAP.git"

# Don't forget to copy the profile file to your home directory
cp amescap/mars_templates/amescap_profile ~/.amescap_profile
Expand Down