diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..92eaf0b --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,12 @@ +include README.md +include License.md +include CONTRIBUTING.md +include CHANGES_SUMMARY.md +include TESTING.md +include requirements.txt +include pytest.ini +recursive-include examples *.ipynb +recursive-include tests *.py +global-exclude __pycache__ +global-exclude *.py[co] +global-exclude .DS_Store diff --git a/README.md b/README.md index ca20ac7..d132d0a 100644 --- a/README.md +++ b/README.md @@ -16,20 +16,20 @@ Converted from: https://github.com/metocean/diwasp ## Installation -### Basic Installation +### From Source ```bash # Clone the repository git clone https://github.com/SBFRF/pyDIWASP.git cd pyDIWASP -# Install dependencies -pip install numpy scipy matplotlib +# Install the package +pip install -e . ``` ### Requirements -- Python 3.6+ +- Python 3.8+ - NumPy - SciPy - Matplotlib @@ -38,7 +38,7 @@ pip install numpy scipy matplotlib ```python import numpy as np -from dirspec import dirspec +from pydiwasp import dirspec # Define instrument data structure ID = { diff --git a/examples/pyDIWASP_example.ipynb b/examples/pyDIWASP_example.ipynb index 4b372e3..c422bf5 100644 --- a/examples/pyDIWASP_example.ipynb +++ b/examples/pyDIWASP_example.ipynb @@ -45,17 +45,9 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "# Add pyDIWASP to Python path\n", - "# This assumes you're running the notebook from the examples/ directory\n", - "# The parent directory (..) contains the pyDIWASP modules\n", - "if os.getcwd().endswith('examples'):\n", - " sys.path.insert(0, '..')\n", - "elif os.path.basename(os.getcwd()) != 'pyDIWASP':\n", - " print('Warning: Notebook should be run from examples/ directory or repo root')\n", - "\n", - "from dirspec import dirspec\n", - "from infospec import infospec\n", - "from plotspec import plotspec\n", + "# Import pyDIWASP functions\n", + "# If the package is installed (pip install -e .), you can import directly\n", + "from pydiwasp import dirspec, infospec, plotspec\n", "\n", "# Set random seed for reproducibility\n", "np.random.seed(42)\n", diff --git a/pydiwasp/__init__.py b/pydiwasp/__init__.py new file mode 100644 index 0000000..729f369 --- /dev/null +++ b/pydiwasp/__init__.py @@ -0,0 +1,30 @@ +""" +pyDIWASP - DIrectional WAve SPectrum analysis in Python + +Python conversion of the DIWASP package (DIrectional WAve SPectrum analysis Version 1.4) + +Main Functions: +- dirspec: Main directional wave spectrum estimation +- infospec: Calculate wave statistics from spectrum +- plotspec: Plot directional spectrum +- interpspec: Interpolate spectrum to different grid +- writespec: Write spectrum to file +""" + +__version__ = "0.1.0" + +# Import main API functions +from .dirspec import dirspec +from .infospec import infospec, compangle +from .plotspec import plotspec +from .interpspec import interpspec +from .writespec import writespec + +__all__ = [ + 'dirspec', + 'infospec', + 'compangle', + 'plotspec', + 'interpspec', + 'writespec', +] diff --git a/dirspec.py b/pydiwasp/dirspec.py similarity index 91% rename from dirspec.py rename to pydiwasp/dirspec.py index feb302e..d9bad60 100644 --- a/dirspec.py +++ b/pydiwasp/dirspec.py @@ -2,22 +2,22 @@ import numpy as np import matplotlib.pyplot as plt from scipy.signal import detrend -from interpspec import interpspec -from infospec import infospec -from writespec import writespec -from plotspec import plotspec -from private.velx import velx -from private.vely import vely -from private.pres import pres -from private.elev import elev -from private.vels import vels -from private.accs import accs, accz -from private.wavenumber import wavenumber -from private.IMLM import IMLM -from private.EMEP import EMEP -from private.smoothspec import smoothspec -from private.diwasp_csd import diwasp_csd -from private.check_data import check_data +from .interpspec import interpspec +from .infospec import infospec +from .writespec import writespec +from .plotspec import plotspec +from .private.velx import velx +from .private.vely import vely +from .private.pres import pres +from .private.elev import elev +from .private.vels import vels +from .private.accs import accs, accz +from .private.wavenumber import wavenumber +from .private.IMLM import IMLM +from .private.EMEP import EMEP +from .private.smoothspec import smoothspec +from .private.diwasp_csd import diwasp_csd +from .private.check_data import check_data def dirspec(ID, SM, EP, Options_=None): """ diff --git a/infospec.py b/pydiwasp/infospec.py similarity index 98% rename from infospec.py rename to pydiwasp/infospec.py index d665973..6cdd515 100644 --- a/infospec.py +++ b/pydiwasp/infospec.py @@ -1,5 +1,5 @@ import numpy as np -from private.hsig import hsig +from .private.hsig import hsig def infospec(SM): """ diff --git a/interpspec.py b/pydiwasp/interpspec.py similarity index 95% rename from interpspec.py rename to pydiwasp/interpspec.py index 51b9e1c..b229b58 100644 --- a/interpspec.py +++ b/pydiwasp/interpspec.py @@ -1,8 +1,8 @@ import numpy as np from warnings import warn from scipy.interpolate import griddata -from private.hsig import hsig -from private.spectobasis import spectobasis +from .private.hsig import hsig +from .private.spectobasis import spectobasis def interpspec(SMin, SMout, method='linear'): """ diff --git a/plotspec.py b/pydiwasp/plotspec.py similarity index 98% rename from plotspec.py rename to pydiwasp/plotspec.py index af968e0..1adb393 100644 --- a/plotspec.py +++ b/pydiwasp/plotspec.py @@ -1,6 +1,6 @@ import matplotlib.pyplot as plt import numpy as np -from private.spectobasis import spectobasis +from .private.spectobasis import spectobasis def plotspec(SM, ptype): """ diff --git a/private/BDM.py b/pydiwasp/private/BDM.py similarity index 100% rename from private/BDM.py rename to pydiwasp/private/BDM.py diff --git a/private/DFTM.py b/pydiwasp/private/DFTM.py similarity index 100% rename from private/DFTM.py rename to pydiwasp/private/DFTM.py diff --git a/private/EMEP.py b/pydiwasp/private/EMEP.py similarity index 100% rename from private/EMEP.py rename to pydiwasp/private/EMEP.py diff --git a/private/EMLM.py b/pydiwasp/private/EMLM.py similarity index 100% rename from private/EMLM.py rename to pydiwasp/private/EMLM.py diff --git a/private/IMLM.py b/pydiwasp/private/IMLM.py similarity index 100% rename from private/IMLM.py rename to pydiwasp/private/IMLM.py diff --git a/pydiwasp/private/__init__.py b/pydiwasp/private/__init__.py new file mode 100644 index 0000000..93843a4 --- /dev/null +++ b/pydiwasp/private/__init__.py @@ -0,0 +1,6 @@ +""" +Private internal functions for pyDIWASP. + +This module contains internal functions used by the main analysis routines. +These are not part of the public API and may change without notice. +""" diff --git a/private/accs.py b/pydiwasp/private/accs.py similarity index 100% rename from private/accs.py rename to pydiwasp/private/accs.py diff --git a/private/check_data.py b/pydiwasp/private/check_data.py similarity index 100% rename from private/check_data.py rename to pydiwasp/private/check_data.py diff --git a/private/diwasp_csd.py b/pydiwasp/private/diwasp_csd.py similarity index 100% rename from private/diwasp_csd.py rename to pydiwasp/private/diwasp_csd.py diff --git a/private/elev.py b/pydiwasp/private/elev.py similarity index 100% rename from private/elev.py rename to pydiwasp/private/elev.py diff --git a/private/hsig.py b/pydiwasp/private/hsig.py similarity index 100% rename from private/hsig.py rename to pydiwasp/private/hsig.py diff --git a/private/pres.py b/pydiwasp/private/pres.py similarity index 100% rename from private/pres.py rename to pydiwasp/private/pres.py diff --git a/private/slpx.py b/pydiwasp/private/slpx.py similarity index 100% rename from private/slpx.py rename to pydiwasp/private/slpx.py diff --git a/private/slpy.py b/pydiwasp/private/slpy.py similarity index 100% rename from private/slpy.py rename to pydiwasp/private/slpy.py diff --git a/private/smoothspec.py b/pydiwasp/private/smoothspec.py similarity index 100% rename from private/smoothspec.py rename to pydiwasp/private/smoothspec.py diff --git a/private/spectobasis.py b/pydiwasp/private/spectobasis.py similarity index 100% rename from private/spectobasis.py rename to pydiwasp/private/spectobasis.py diff --git a/private/vels.py b/pydiwasp/private/vels.py similarity index 95% rename from private/vels.py rename to pydiwasp/private/vels.py index b9acd4e..c58ab24 100644 --- a/private/vels.py +++ b/pydiwasp/private/vels.py @@ -1,4 +1,4 @@ -from private.velz import velz +from .velz import velz def vels(ffreqs, dirs, wns, z, depth): """ diff --git a/private/velx.py b/pydiwasp/private/velx.py similarity index 100% rename from private/velx.py rename to pydiwasp/private/velx.py diff --git a/private/vely.py b/pydiwasp/private/vely.py similarity index 100% rename from private/vely.py rename to pydiwasp/private/vely.py diff --git a/private/velz.py b/pydiwasp/private/velz.py similarity index 100% rename from private/velz.py rename to pydiwasp/private/velz.py diff --git a/private/wavenumber.py b/pydiwasp/private/wavenumber.py similarity index 100% rename from private/wavenumber.py rename to pydiwasp/private/wavenumber.py diff --git a/writespec.py b/pydiwasp/writespec.py similarity index 100% rename from writespec.py rename to pydiwasp/writespec.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..f26c9b4 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,38 @@ +[build-system] +requires = ["setuptools>=45", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "pyDIWASP" +version = "0.1.0" +description = "Python conversion of DIWASP: DIrectional WAve SPectrum analysis" +readme = "README.md" +authors = [ + {name = "SBFRF", email = "support@sbfrf.org"} +] +license = {text = "GPL-3.0"} +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Physics", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +requires-python = ">=3.8" +dependencies = [ + "numpy>=1.20.0,<2.0", + "scipy>=1.7.0,<2.0", + "matplotlib>=3.3.0,<4.0", +] + +[project.urls] +Homepage = "https://github.com/SBFRF/pyDIWASP" +Repository = "https://github.com/SBFRF/pyDIWASP" + +[tool.setuptools.packages.find] +include = ["pydiwasp*"] diff --git a/setup.py b/setup.py index 778d5d4..dfadfab 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/SBFRF/pyDIWASP", - packages=find_packages(), + packages=find_packages(include=['pydiwasp', 'pydiwasp.*']), classifiers=[ "Development Status :: 3 - Alpha", "Intended Audience :: Science/Research", diff --git a/tests/test_api.py b/tests/test_api.py index 27256d4..5d1b015 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -10,9 +10,7 @@ import os from contextlib import redirect_stdout -from infospec import infospec -from interpspec import interpspec -from writespec import writespec +from pydiwasp import infospec, interpspec, writespec class TestInfospec: @@ -106,7 +104,7 @@ def test_interpspec_basic(self): def test_interpspec_preserves_energy(self): """Test that interpolation approximately preserves energy.""" - from private.hsig import hsig + from pydiwasp.private.hsig import hsig # Create a peaked spectrum freqs_in = np.linspace(0.05, 0.5, 15) diff --git a/tests/test_core.py b/tests/test_core.py index 0a45595..a2e77ba 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -7,18 +7,15 @@ import unittest -import numpy as np -from infospec import compangle -from private.hsig import hsig -from private.check_data import check_data - import numpy as np import pytest +from pydiwasp.infospec import compangle + try: - from private.wavenumber import wavenumber - from private.hsig import hsig - from private.check_data import check_data + from pydiwasp.private.wavenumber import wavenumber + from pydiwasp.private.hsig import hsig + from pydiwasp.private.check_data import check_data except ImportError as exc: raise ImportError( "Could not import pyDIWASP modules. Ensure the package is installed, " @@ -182,7 +179,7 @@ class TestTransferFunctions: def test_elev_transfer_function(self): """Test elevation transfer function.""" - from private.elev import elev + from pydiwasp.private.elev import elev # Test parameters w = 2 * np.pi * np.array([0.1, 0.2]) # Angular frequencies @@ -198,7 +195,7 @@ def test_elev_transfer_function(self): def test_pres_transfer_function(self): """Test pressure transfer function.""" - from private.pres import pres + from pydiwasp.private.pres import pres w = 2 * np.pi * np.array([0.1, 0.2]) dirs = np.array([0, np.pi/4, np.pi/2]) diff --git a/tests/test_integration.py b/tests/test_integration.py index b96d5ce..7803f86 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -10,7 +10,7 @@ import os from contextlib import redirect_stdout -from dirspec import dirspec +from pydiwasp import dirspec class TestDirspecIntegration: