Skip to content

Commit

Permalink
Updates to CLI (#160)
Browse files Browse the repository at this point in the history
* include examples in distribution

* add command to copy examples via CLI

* remove conflicting settings in editable installation

* change title of tutorial

* move example dir to aeolis/

* delete examples dir from root of repo

* update readme files in examples

* include sand dune engine example

* upgrade to version 2.2.0

* simplify examples destination directory tree

* include Typer-based CLI

* change name of Typer CLI in toml

* remove parallet flag from example

* include dependency: typer

* delete document file for test coverage

* include note on how to set the examples

* fix missing run command testcase

* basic test for checking missing run command

* do assert operation inside context manager because calling function raises exception

* docstring typo

* typing.Annotated in console.py needs Python>=3.9

* strengthen unit test to check if the expected examples were unpacked properly. Assert outside context manager for missing run command testcase

* add steps to follow tutorial

* rephrase deprecation message. Try except block was for debug only. Remove output files from example. Disable the default creation of plots. Bump version via separate branch.

* use consistent naming scheme

* catch and report deprecated usage of aeolis-wind

* fix typo in comments

* Update sandmotor.rst

* Update 2D-parabolic.rst

---------

Co-authored-by: Niket <15953349+niketagrawal@users.noreply.github.com>
Co-authored-by: Sierd <sierd.devries@tudelft.nl>
  • Loading branch information
3 people committed Oct 11, 2023
1 parent f978950 commit 7285d07
Show file tree
Hide file tree
Showing 107 changed files with 355,678 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,27 @@ permissions:

jobs:
build:

runs-on: ubuntu-latest
timeout-minutes: 15

strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v3
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install -e .
pip install pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Test with pytest
run: |
pytest
pytest
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ https://github.com/openearth/aeolis-python/assets/14054272/128684d6-73ac-4a5f-a1

**Requirements:**

- Python 3.8 or newer
- Python 3.9 or newer
- pip 22.0 or newer
- netCDF4

### Installing from PyPI

On the comand line of your working environment (Bash/Shell, Conda, Mamba, or similar), run the following:
On the comand line of your working environment (Bash/Shell, Conda, Mamba, or similar), run the following:

```shell
pip install aeolis
Expand All @@ -46,7 +46,7 @@ pip install aeolis
```

3. AeoLiS users who intend to modify the sourcecode can install additional dependencies for test and documentation as follows. Go to root directory `aeolis-python/` and:

```shell
pip install -e .[dev]
```
Expand All @@ -56,9 +56,9 @@ pip install aeolis
Examples from command line:

```shell
aeolis params.txt
aeolis run <path/to/aeolis.txt/>
# or wind module
aeolis-wind wind.txt --mean=6 --duration=3600
aeolis wind <path/to/wind.txt> --mean=6 --duration=3600
```

## Documentation
Expand All @@ -74,16 +74,16 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) to know how you can help to
**Current Members:**

- [Bart van Westen](mailto:Bart.vanWesten@deltares.nl) at Deltares
- [Nick Cohn](mailto:nick.cohn@usace.army.mil) at U.S. Army Engineer Research and Development Center (ERDC)
- [Nick Cohn](mailto:nick.cohn@usace.army.mil) at U.S. Army Engineer Research and Development Center (ERDC)
- [Sierd de Vries](mailto:Sierd.deVries@tudelft.nl) (founder) at Delft University of Technology
- [Christa van IJzendoorn](mailto:C.O.vanIJzendoorn@tudelft.nl) at Delft University of Technology
- [Caroline Hallin](mailto:E.C.Hallin@tudelft.nl) at Delft University of Technology
- [Glenn Strypsteen](mailto:glenn.strypsteen@kuleuven.be) at Katholieke Universiteit Leuven
- [Janelle Skaden](mailto:Janelle.E.Skaden@usace.army.mil) at U.S. Army Engineer Research and Development Center (ERDC)

**Previous Members & Contributors:**
- [Bas Hoonhout](mailto:bas@hoonhout.com) (founder)
- Tom Pak
- [Bas Hoonhout](mailto:bas@hoonhout.com) (founder)
- Tom Pak
- Pieter Rauwoens
- Lisa Meijer

Expand All @@ -98,4 +98,4 @@ Please, cite this software as follows:
- AeoLiS is supported by the [Digital Competence Centre](https://dcc.tudelft.nl), Delft University of Technology.
- The contributing guidelines for AeoLiS are derived from the [NLeSC/python-template](https://github.com/NLeSC/python-template) and [numpy contributing guide](https://numpy.org/devdocs/dev/index.html#development-process-summary)

&copy; (2023) AeoLiS Development Team, Delft, The Netherlands.
&copy; (2023) AeoLiS Development Team, Delft, The Netherlands.
228 changes: 146 additions & 82 deletions aeolis/console.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''This file is part of AeoLiS.
"""This file is part of AeoLiS.
AeoLiS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -13,110 +13,174 @@
You should have received a copy of the GNU General Public License
along with AeoLiS. If not, see <http://www.gnu.org/licenses/>.
AeoLiS Copyright (C) 2015 Bas Hoonhout
AeoLiS Copyright (C) 2023 AeoLiS Development Team
bas.hoonhout@deltares.nl b.m.hoonhout@tudelft.nl
Deltares Delft University of Technology
Unit of Hydraulic Engineering Faculty of Civil Engineering and Geosciences
Boussinesqweg 1 Stevinweg 1
2629 HVDelft 2628CN Delft
The Netherlands The Netherlands
'''
Delft University of Technology
Faculty of Civil Engineering and Geosciences
Stevinweg 1
2628CN Delft
The Netherlands
"""

from __future__ import absolute_import, division

import os
import docopt
import sys
import logging
import numpy as np
from aeolis.model import AeoLiSRunner, WindGenerator


#class StreamFormatter(logging.Formatter):
#
# def format(self, record):
# if record.levelname == 'INFO':
# return record.getMessage()
# else:
# return '%s: %s' % (record.levelname, record.getMessage())

import shutil

def aeolis():
'''aeolis : a process-based model for simulating supply-limited aeolian sediment transport
Usage:
aeolis <config> [options]
Positional arguments:
config configuration file
import numpy as np
import typer
from typing import Annotated, Optional

Options:
-h, --help show this help message and exit
--callback=FUNC reference to callback function (e.g. example/callback.py:callback)
--restart=FILE model restart file
--verbose=LEVEL logging verbosity [default: 20]
--debug write debug logs
import aeolis as aeolis_pkg
from aeolis.model import AeoLiSRunner, WindGenerator

'''

aeolis_app = typer.Typer(
add_completion=False,
pretty_exceptions_enable=True,
help=(
"AeoLiS, a process-based model for simulating supply-limited aeolian"
" sediment transport"
),
)


@aeolis_app.command(
help="runs model for simulating supply-limited aeolian sediment transport."
)
def run(
config: Annotated[str, typer.Argument(help="configuration file")],
callback: Annotated[
Optional[str],
typer.Option(
help=(
"reference to callback function (e.g."
" example/callback.py:callback)"
)
),
] = None,
restart: Annotated[
Optional[str], typer.Option(help="model restart file")
] = None,
verbose: Annotated[
Optional[int], typer.Option(help="logging verbosity")
] = 20,
debug: Annotated[
bool,
typer.Option(
"--debug",
help="write debug logs",
),
] = False,
):
print_license()

arguments = docopt.docopt(aeolis.__doc__)

logger = logging.getLogger('aeolis')
logger = logging.getLogger("aeolis")

# start model
model = AeoLiSRunner(configfile=arguments['<config>'])
model.run(callback=arguments['--callback'],
restartfile=arguments['--restart'])


def wind():
'''aeolis-wind : a wind time series generation tool for the aeolis model
Usage:
aeolis-wind <file> [--mean=MEAN] [--max=MAX] [--duration=DURATION] [--timestep=TIMESTEP]
Positional arguments:
file output file
model = AeoLiSRunner(configfile=config)
model.run(callback=callback, restartfile=restart)


@aeolis_app.command(
name="wind", help="A wind time series generation tool for the aeolis model."
)
def wind(
file: Annotated[str, typer.Argument(help="output file")],
mean: Annotated[float, typer.Option(help="mean wind speed")] = 10,
max: Annotated[float, typer.Option(help="maximum wind speed")] = 30,
duration: Annotated[
int, typer.Option(help="duration of time series")
] = 3600,
timestep: Annotated[int, typer.Option(help="timestep of time series")] = 60,
):
print_license()

Options:
-h, --help show this help message and exit
--mean=MEAN mean wind speed [default: 10]
--max=MAX maximum wind speed [default: 30]
--duration=DURATION duration of time series [default: 3600]
--timestep=TIMESTEP timestep of time series [default: 60]
# create random wind time series
generator = WindGenerator(mean_speed=mean, max_speed=max, dt=timestep)
generator.generate(duration=duration)
generator.write_time_series(file)

'''
u = generator.get_time_series()[1]

fmt = "%-4s : %6.3f m/s"
print(fmt % ("min", np.min(u)))
print(fmt % ("mean", np.mean(u)))
print(fmt % ("max", np.max(u)))


@aeolis_app.command(name="examples", help="sets up some examples for AeoLiS.")
def examples(
dir: Annotated[
str,
typer.Argument(
help=(
"directory for the examples' data. It will be created if it"
" does not exist."
)
),
]
):
print_license()

arguments = docopt.docopt(wind.__doc__)
current_path = os.getcwd()
destination_path = os.path.join(current_path, dir)

# create random wind time series
generator = WindGenerator(mean_speed=float(arguments['--mean']),
max_speed=float(arguments['--max']),
dt=float(arguments['--timestep']))
generator.generate(duration=float(arguments['--duration']))
generator.write_time_series(arguments['<file>'])
destination_path = os.path.join(dir, "aeolis-examples")
# Path to examples in installed aeolis package directory
source_path = os.path.join(os.path.dirname(aeolis_pkg.__file__), "examples")

u = generator.get_time_series()[1]
# Examples that will be included in destination path
# Key: path where the example is located in the installed aeolis package directory
# Value: path where the example will be copied to
_examples = {
"2D/Parabolic_dune": "Parabolic_dune",
"sandengine_small_grids": "sandengine_small_grids",
}
# Copy examples to target path. Creates destination path if it does not exist.
for source, target in _examples.items():
example_path = os.path.join(source_path, source)
target_path = os.path.join(destination_path, target)
shutil.copytree(example_path, target_path)

fmt = '%-4s : %6.3f m/s'
print(fmt % ('min', np.min(u)))
print(fmt % ('mean', np.mean(u)))
print(fmt % ('max', np.max(u)))
print("Done. Examples copied to: \n %s" % destination_path)


def print_license():
print('AeoLiS Copyright (C) 2015 Bas Hoonhout')
print('This program comes with ABSOLUTELY NO WARRANTY.')
print('This is free software, and you are welcome to redistribute it')
print('under certain conditions; See LICENSE.txt for details.')
print('')


if __name__ == '__main__':
aeolis()
print("AeoLiS Copyright (c) 2023 AeoLiS Development Team")
print("This program comes with ABSOLUTELY NO WARRANTY.")
print("This is free software, and you are welcome to redistribute it")
print("under certain conditions; See LICENSE.txt for details.")
print("")


def start_aeolis_app():
if len(sys.argv) == 2 and os.path.isfile(sys.argv[1]):
print(
"Usage of the command line syntax `aeolis <path_to_aeolis.txt>` has"
" been deprecated from v3.0.0 onwards.\n\n"
"To run a model, use the syntax `aeolis run <path_to_aeolis.txt>`\n"
)
sys.exit(1)
else:
aeolis_app()


def start_aeolis_wind_app():
"""
This function serves the purpose of catching the deprecated command line syntx `aeolis-wind <path_to_wind.txt>` and pritning a message on the console instructing the user to use `aeolis wind <path_to_wind.txt>` instead.
"""
print(
"Usage of the command line syntax `aeolis-wind <path_to_wind.txt>` has"
" been deprecated from v3.0.0 onwards.\n\nTo run the wind module, use"
" the syntax `aeolis wind <path_to_wind.txt>`\n"
)
sys.exit(1)


if __name__ == "__main__":
start_aeolis_app()
start_aeolis_wind_app()
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions aeolis/examples/1D/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 1 Dimensional Examples

This is wehere we put our 1D examples.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions aeolis/examples/2D/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 2 Dimensional Examples

This is wehere we put our 2D examples. Some of these examples are included in the distribution package.

0 comments on commit 7285d07

Please sign in to comment.