diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..ab44a73 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,53 @@ +# Simple workflow for deploying static content to GitHub Pages +name: docs + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + # Single deploy job since we're just deploying + deploy: + environment: + name: deploy-docs + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install template + run: pip install ".[dev]" + + - name: Build doc html + run: sphinx-build --keep-going docs/ docs/_build/html + + - name: Setup Pages + uses: actions/configure-pages@v2 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + # Upload entire repository + path: "./docs/_build/html" + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..cce4a4e --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,33 @@ +name: tests + +on: + push: + branches: ["main"] + paths-ignore: + - "docs/**" + - "*.md" + + workflow_dispatch: + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + python-version: ["3.11"] + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install python library + run: pip install "." + + - name: Test + run: pytest -m "not slow" -p "no:warnings" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..68bc17f --- /dev/null +++ b/.gitignore @@ -0,0 +1,160 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..e3c081f --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,20 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/psf/black + rev: 22.12.0 + hooks: + - id: black + - id: black-jupyter + - repo: https://github.com/pycqa/flake8 + rev: 6.0.0 + hooks: + - id: flake8 +# additional_dependencies: +# - flake8-bugbear +# - flake8-comprehensions +# - flake8-simplify diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d9e5e69 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 2024.02.23 + +- Features: Implements Dean article diff --git a/README.md b/README.md new file mode 100644 index 0000000..2555fc9 --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# IHSetDean + +Miller and Dean (2004) proposed a simple model for shoreline evolution using several field datasets. The model is developed based on the observation that shoreline positions change as a function of an equilibrium position. The model includes three adjustable parameters that represent the baseline conditions under which shoreline displacement is calculated to minimize the error. This model is very efficient because it only represents the shoreline response to the process and only requires input of readily available storm surge and water level data. + + +## Installation and use + +To install this module use: + +```sh +pip install https://github.com/IHCantabria/IHSetDean/archive/refs/tags/latest.zip +``` + +Run tests to validate: + +```sh +ihsetdean-tests +``` + +## Documentation + +Documentation is available at https://ihcantabria.github.io/IHSetDean + +## Credits + +Developed and maintained by Lim, Changbin @ IHCantabria. diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..41c270b --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/_static/images/Imagen1.png b/docs/_static/images/Imagen1.png new file mode 100755 index 0000000..2fc272a Binary files /dev/null and b/docs/_static/images/Imagen1.png differ diff --git a/docs/_static/images/add_images_here b/docs/_static/images/add_images_here new file mode 100644 index 0000000..e69de29 diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..890680f --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,52 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information +from IHSetDean.__init__ import __version__ + + +project = "IHSetDean" +copyright = "2024, Lim, Changbin" +author = "Lim, Changbin" +version = release = __version__ + +html_context = { + "display_github": True, # Integrate GitHub + "github_user": "ihcantabria", # Username + "github_repo": "IHSetDean", # Repo name + "github_version": "main", # Version + "conf_py_path": "/docs/", +} + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx_rtd_theme", + "myst_nb", + # 'sphinxcontrib.autodoc_pydantic', + "sphinx.ext.autosummary", +] +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "sphinx_rtd_theme" +html_theme_options = { + "display_version": True, + "style_external_links": False, +} +# html_theme = 'furo' +# html_theme = 'sphinx_book_theme' + +html_static_path = ["_static"] +html_logo = "" +html_title = " v" + release diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..aa80c82 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,32 @@ +# IHSetDean + +## Summary + +Miller and Dean (2004) proposed a simple model for shoreline evolution using several field datasets. The model is developed based on the observation that shoreline positions change as a function of an equilibrium position. The model includes three adjustable parameters that represent the baseline conditions under which shoreline displacement is calculated to minimize the error. This model is very efficient because it only represents the shoreline response to the process and only requires input of readily available storm surge and water level data. + +## Model formula + +Miller and Dean (2004) suggested a simple shoreline evolution model based on the imbalance of shoreline change between an equilibrium shoreline change and shoreline position as follows: + +```text +(∂S(t))/∂t=k(S_eq (t)-S(t)) + +S(t) : the shoreline position at time t +S_eq : the equilibrium shoreline position +k : the calibration parameter for the rate at which the shoreline approaches equilibrium (k; k=k_a H_b^2; k=k_a H_b^3; k=k_a Ω) +``` + +Miller and Dean (2004) proposed an equilibrium shoreline change owing to the change of sea level (Fig. 4 1): + +```text +S_eq=-W^* (t)((0.068H_b+S)/(B+1.28H_b )) + +H_b : the breaking wave height +S : the change in local water level +B : the berm wave height +W^* : the width of the active surf zone +``` + +![Definition sketch of shoreline evolution](_static/images/Imagen1.png) + +Fig. 4 1. Definition sketch of shoreline evolution according the change of water level owing to storm surge and wave setup (Miller and Dean, 2004). \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..b4f380c --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..1ea4c1e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,49 @@ +[build-system] +requires = ["flit_core >=3.2,<4"] +build-backend = "flit_core.buildapi" + + +[project] +name = "IHSetDean" +authors = [{ name = "Lim, Changbin", email = "changbin.lim@unican.es" }] +maintainers = [{ name = "Lim, Changbin", email = "changbin.lim@unican.es" }] +readme = "README.md" +requires-python = ">=3.9" +classifiers = [ + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Physics", + "Development Status :: 1 - Planning", + "Programming Language :: Python", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +] +dynamic = ["version", "description"] + +dependencies = ["numpy", "pytest >=7", "scipy"] + + +[project.optional-dependencies] +dev = ["flit", "black", "sphinx", "myst-nb", "sphinx_rtd_theme", "pre-commit"] + + +[project.urls] +documentation = "https://ihcantabria.github.io/IHSetDean/" +repository = "https://github.com/IHCantabria/IHSetDean" +changelog = "https://github.com/IHCantabria/IHSetDean/blob/main/CHANGELOG.md" + + +[project.scripts] +ihsetdean-tests = "IHSetDean.tests.__init__:run_tests" + + +[tool.pytest.ini_options] +addopts = "--durations=0 --durations-min=0.1" +testpaths = "src/tests" +markers = [ + "slow: marks tests as slow (deselect with '-m \"not slow\"')", + "serial", +] diff --git a/src/IHSetDean.ipynb b/src/IHSetDean.ipynb deleted file mode 100644 index 2945b7f..0000000 --- a/src/IHSetDean.ipynb +++ /dev/null @@ -1,108 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Main file to calibrate EBSM models for Tairua data" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "# Loading libraries\n", - "\n", - "import os\n", - "import scipy.io\n", - "import numpy as np\n", - "# import pandas as pd\n", - "# import scipy.optimize as opt\n", - "import matplotlib.pyplot as plt\n", - "# import matplotlib.dates as mdates\n", - "# from scipy.optimize import minimize\n", - "# import scipy.interpolate as interpolate\n", - "from scipy.interpolate import interp1d\n", - "from shapely.geometry import LineString\n", - "\n", - "os.chdir('..')\n", - "os.chdir('./modules')\n", - "from IHSetDean import *\n", - "os.chdir('..')\n", - "os.chdir('./src')\n", - "\n", - "plt.rcParams.update({'font.family': 'serif'})\n", - "plt.rcParams.update({'font.size': 7})\n", - "plt.rcParams.update({'font.weight': 'bold'})\n", - "font = {'family': 'serif',\n", - " 'weight': 'bold',\n", - " 'size': 8}" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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PpgEBARQqVIlzp07B2Ql1jp16tC1a1eDKys77rvvPoBc+/Dee+/F3t6e++67j0uXLpGenm7518D9999vWK224PLlywwdOpQNGzbw4YcfEhMTw9ChQ7Ufi2jbtm389ddfQNbCaFWqVOHChQs89NBDgPZjYYwfP56FCxfyxRdf0L17dwDeeecdnnzySUD7sLC2b9/OV199BUB8fDxXrlyhefPm+jtdTOr8CqxYsYIPP/yQDh06sGfPHj788EM6depkdFk2ac6cOfzyyy+sXLmSgIAAHnjgAUaNGsX777/Pli1b8PHx4fz583zxxRfUrFmTuLg4JkyYQGZmJgkJCdSvX58pU6ZU6CvPly5dyuDBg3ON+fn5ERwcrP1YBDt37uSVV16hY8eOnDx5ktOnT/N///d/PProo9qPRTRv3jw++OADjhw5wr///W/eeOMN5s+fr31YSEePHuWZZ56hY8eO7N27F5PJxGeffUazZs30/2IxKJiIiIiIzajwp3JERETEdiiYiIiIiM1QMBERERGboWAiIiIiNkPBRERERGyGgomIiIjYDAUTERERsRkKJiIiImIzFExERETEZiiYiIiIiM1QMBERERGb8f84JNmZJPD2oAAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "pt = r'D:\\[IH-SET]\\5_Models\\1_Static_equilibrium\\1_Beach_profile'\n", - "perfil = scipy.io.loadmat(pt + r'\\perfiles_cierre.mat')\n", - "\n", - "for p in range(1):\n", - " \n", - " d = perfil[\"perfil\"]['d'][0][p].flatten()\n", - " d = d - d[0]\n", - " z = perfil[\"perfil\"]['z'][0][p].flatten()\n", - " CM = perfil[\"perfil\"]['CM_95'][0][p].flatten()\n", - " z = z - CM\n", - " di = np.linspace(d[0], d[-1], 100)\n", - " z = interp1d(d, z, kind='linear', fill_value='extrapolate')(di)\n", - " d = di\n", - "\n", - " D50 = perfil[\"perfil\"]['D50'][0][p].flatten()\n", - "\n", - " # Assuming the 'ajuste_perfil' function is defined as in the previous code\n", - " pDeank, mDeank = Dean(d, z, D50)\n", - "\n", - " hk = []\n", - " hk.append(plt.plot(d, z - z[0], '--k')[0])\n", - " hk.append(plt.plot(mDeank['D'], mDeank['Z'], linewidth=2)[0])\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "PyJu", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.3" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/src/IHSetDean.py b/src/IHSetDean.py deleted file mode 100644 index d99d5b2..0000000 --- a/src/IHSetDean.py +++ /dev/null @@ -1,58 +0,0 @@ -import numpy as np -from scipy.interpolate import interp1d - -def caida_grano(D50): - ws = np.nan - if D50 < 0.1: - ws = 1.1e6 * (D50 * 0.001) ** 2 - elif 0.1 <= D50 <= 1: - ws = 273 * (D50 * 0.001) ** 1.1 - elif D50 > 1: - ws = 4.36 * D50 ** 0.5 - return ws - -def RMSEq(Y, Y2t): - return np.sqrt(np.mean((Y - Y2t) ** 2, axis=0)) - -def Dean(dp, zp, D50): - z = zp - zp[0] - d = dp - dp[0] - - # Profile with equidistant points - dp = np.linspace(0, dp[-1], 500).reshape(-1, 1) # 500 points - interp_func = interp1d(d, z, kind='linear', fill_value='extrapolate') - zp = interp_func(dp) - zp = zp[1:] - dp = dp[1:] - - ws = None - if D50 is not None: - ws = caida_grano(D50) - - Y = np.log(-zp) - Y2 = 2 / 3 * np.log(dp) - - fc = np.arange(-20, 20, 0.001) - Y2_grid, fc_grid = np.meshgrid(Y2, fc, indexing='ij') - Y2t = fc_grid + Y2_grid - - out = RMSEq(Y, Y2t) - I = np.argmin(out) - - A = np.exp(fc[I]) - kk = np.exp(fc[I] - np.log(ws**0.44)) if ws is not None else None - - hm = -A * dp ** (2 / 3) - err = RMSEq(zp, hm) - - Para = {'model': 'Dean'} - Para['formulation'] = ['h= Ax.^(2/3)', 'A=k ws^0.44'] - Para['name_coeffs'] = ['A', 'k'] - Para['coeffs'] = [A, kk] - Para['RMSE'] = err - - model = {'D': np.array([0] + list(dp.flatten())), - 'Z': np.array([0] + list(hm.flatten()))} - - return Para, model - \ No newline at end of file diff --git a/modules/IHSetDean.py b/src/IHSetDean/IHSetDean.py similarity index 63% rename from modules/IHSetDean.py rename to src/IHSetDean/IHSetDean.py index d99d5b2..bb681b5 100644 --- a/modules/IHSetDean.py +++ b/src/IHSetDean/IHSetDean.py @@ -1,5 +1,6 @@ import numpy as np -from scipy.interpolate import interp1d +from scipy.interpolate import interp1d + def caida_grano(D50): ws = np.nan @@ -8,34 +9,36 @@ def caida_grano(D50): elif 0.1 <= D50 <= 1: ws = 273 * (D50 * 0.001) ** 1.1 elif D50 > 1: - ws = 4.36 * D50 ** 0.5 + ws = 4.36 * D50**0.5 return ws + def RMSEq(Y, Y2t): return np.sqrt(np.mean((Y - Y2t) ** 2, axis=0)) + def Dean(dp, zp, D50): z = zp - zp[0] d = dp - dp[0] - + # Profile with equidistant points dp = np.linspace(0, dp[-1], 500).reshape(-1, 1) # 500 points - interp_func = interp1d(d, z, kind='linear', fill_value='extrapolate') + interp_func = interp1d(d, z, kind="linear", fill_value="extrapolate") zp = interp_func(dp) zp = zp[1:] dp = dp[1:] - + ws = None if D50 is not None: ws = caida_grano(D50) - + Y = np.log(-zp) Y2 = 2 / 3 * np.log(dp) - + fc = np.arange(-20, 20, 0.001) - Y2_grid, fc_grid = np.meshgrid(Y2, fc, indexing='ij') + Y2_grid, fc_grid = np.meshgrid(Y2, fc, indexing="ij") Y2t = fc_grid + Y2_grid - + out = RMSEq(Y, Y2t) I = np.argmin(out) @@ -45,14 +48,15 @@ def Dean(dp, zp, D50): hm = -A * dp ** (2 / 3) err = RMSEq(zp, hm) - Para = {'model': 'Dean'} - Para['formulation'] = ['h= Ax.^(2/3)', 'A=k ws^0.44'] - Para['name_coeffs'] = ['A', 'k'] - Para['coeffs'] = [A, kk] - Para['RMSE'] = err + Para = {"model": "Dean"} + Para["formulation"] = ["h= Ax.^(2/3)", "A=k ws^0.44"] + Para["name_coeffs"] = ["A", "k"] + Para["coeffs"] = [A, kk] + Para["RMSE"] = err + + model = { + "D": np.array([0] + list(dp.flatten())), + "Z": np.array([0] + list(hm.flatten())), + } - model = {'D': np.array([0] + list(dp.flatten())), - 'Z': np.array([0] + list(hm.flatten()))} - return Para, model - \ No newline at end of file diff --git a/src/IHSetDean/__init__.py b/src/IHSetDean/__init__.py new file mode 100644 index 0000000..8407dfe --- /dev/null +++ b/src/IHSetDean/__init__.py @@ -0,0 +1,3 @@ +""" Template """ + +__version__ = "0.1.0" diff --git a/src/IHSetDean/tests/__init__.py b/src/IHSetDean/tests/__init__.py new file mode 100644 index 0000000..98350d2 --- /dev/null +++ b/src/IHSetDean/tests/__init__.py @@ -0,0 +1,11 @@ +"""Testing subpackage""" + +from pathlib import Path +import pytest + + +def run_tests(): + """run all available tests""" + tests_path = Path(__file__).parent + print(f"Running tests from path: {tests_path}") + pytest.main(["-v", "-m", "not slow", "-p" "no:warnings", tests_path]) diff --git a/src/IHSetDean/tests/test_dean.py b/src/IHSetDean/tests/test_dean.py new file mode 100644 index 0000000..dc96f77 --- /dev/null +++ b/src/IHSetDean/tests/test_dean.py @@ -0,0 +1,24 @@ +from scipy import io +import numpy as np +from IHSetDean import IHSetDean +from scipy.interpolate import interp1d + + +def test_Dean(): + + perfil = io.loadmat("./data/perfiles_cierre.mat") + p = 0 + d = perfil["perfil"]["d"][0][p].flatten() + d = d - d[0] + z = perfil["perfil"]["z"][0][p].flatten() + CM = perfil["perfil"]["CM_95"][0][p].flatten() + z = z - CM + di = np.linspace(d[0], d[-1], 100) + z = interp1d(d, z, kind="linear", fill_value="extrapolate")(di) + d = di + + D50 = perfil["perfil"]["D50"][0][p].flatten() + + # Assuming the 'ajuste_perfil' function is defined as in the previous code + pDeank, mDeank = IHSetDean.Dean(d, z, D50) + assert pDeank["RMSE"][0] == 0.4840710371023019 diff --git a/src/main.py b/src/main.py deleted file mode 100644 index a23111d..0000000 --- a/src/main.py +++ /dev/null @@ -1,37 +0,0 @@ -import scipy.io -import numpy as np -import matplotlib.pyplot as plt -from scipy.interpolate import interp1d -from IHSetDean import * - -plt.rcParams.update({'font.family': 'serif'}) -plt.rcParams.update({'font.size': 7}) -plt.rcParams.update({'font.weight': 'bold'}) - -font = {'family': 'serif', - 'weight': 'bold', - 'size': 8} - -perfil = scipy.io.loadmat('./data/perfiles_cierre.mat') - -for p in range(1): - - d = perfil["perfil"]['d'][0][p].flatten() - d = d - d[0] - z = perfil["perfil"]['z'][0][p].flatten() - CM = perfil["perfil"]['CM_95'][0][p].flatten() - z = z - CM - di = np.linspace(d[0], d[-1], 100) - z = interp1d(d, z, kind='linear', fill_value='extrapolate')(di) - d = di - - D50 = perfil["perfil"]['D50'][0][p].flatten() - - # Assuming the 'ajuste_perfil' function is defined as in the previous code - pDeank, mDeank = Dean(d, z, D50) - - hk = [] - hk.append(plt.plot(d, z - z[0], '--k')[0]) - hk.append(plt.plot(mDeank['D'], mDeank['Z'], linewidth=2)[0]) - - plt.show() \ No newline at end of file