From 838f1242c2657b5f026dd1160abfa4b7dcb1fb53 Mon Sep 17 00:00:00 2001 From: Felipe Maza Date: Fri, 23 Feb 2024 13:52:19 +0100 Subject: [PATCH] adapts the module to a pip package --- .github/workflows/docs.yml | 53 ++++++++ .github/workflows/tests.yml | 33 +++++ .gitignore | 160 ++++++++++++++++++++++++ .pre-commit-config.yaml | 20 +++ CHANGELOG.md | 3 + README.md | 26 ++++ docs/Makefile | 20 +++ docs/_static/images/Imagen1.png | Bin 0 -> 52375 bytes docs/_static/images/add_images_here | 0 docs/conf.py | 52 ++++++++ docs/index.md | 32 +++++ docs/make.bat | 35 ++++++ pyproject.toml | 49 ++++++++ src/IHSetDean.ipynb | 108 ---------------- src/IHSetDean.py | 58 --------- {modules => src/IHSetDean}/IHSetDean.py | 40 +++--- src/IHSetDean/__init__.py | 3 + src/IHSetDean/tests/__init__.py | 11 ++ src/IHSetDean/tests/test_dean.py | 24 ++++ src/main.py | 37 ------ 20 files changed, 543 insertions(+), 221 deletions(-) create mode 100644 .github/workflows/docs.yml create mode 100644 .github/workflows/tests.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 docs/Makefile create mode 100755 docs/_static/images/Imagen1.png create mode 100644 docs/_static/images/add_images_here create mode 100644 docs/conf.py create mode 100644 docs/index.md create mode 100644 docs/make.bat create mode 100644 pyproject.toml delete mode 100644 src/IHSetDean.ipynb delete mode 100644 src/IHSetDean.py rename {modules => src/IHSetDean}/IHSetDean.py (63%) create mode 100644 src/IHSetDean/__init__.py create mode 100644 src/IHSetDean/tests/__init__.py create mode 100644 src/IHSetDean/tests/test_dean.py delete mode 100644 src/main.py 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 0000000000000000000000000000000000000000..2fc272abd0513fa351a5c583b64c13f23d38a7eb GIT binary patch literal 52375 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 W_L^Q9W@ZA=$L^5x!MgpFNUL 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