Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Deltares/Fm2Prof
Browse files Browse the repository at this point in the history
  • Loading branch information
kdberends committed Apr 24, 2024
2 parents d199874 + 5244565 commit 4f489b4
Show file tree
Hide file tree
Showing 14 changed files with 6,071 additions and 43 deletions.
2 changes: 1 addition & 1 deletion FM2PROF_WINDOWS.spec
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ exe = EXE(
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='docs/source/_static/favicon.ico'
icon='docs/figures/favicon.ico'
)
Binary file added docs/figures/favicon.ico
Binary file not shown.
27 changes: 27 additions & 0 deletions docs/markdown/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,31 @@ To check coverage:
`poetry run pytest --cov=fm2prof`


## Deploying

### Locally build executable

To build a local version of an FM2PROF executable, run:

`poetry run pyinstaller FM2PROF_WINDOWS.spec`

### Making a new release

After merging a PR, make a new tag. Using version `v2.3.0` as an example;

`git tag v2.3.0`

Use Github interface to draft a new release. Attach the executable. Then, update the documentation:

`poetry run mike deploy v2.3.0 latest -u`

Checkout the documentation branch

`git checkout gh-pages`

and push changes to github

`git push`



92 changes: 72 additions & 20 deletions docs/markdown/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,27 @@ This case is a simple 2D compound channel model.

To start a new project:

``` shell
FM2PROF create MyProject
```
=== "Python"

``` python
from fm2prof.IniFile import IniFile

inifile = IniFile().print_configuration()
ini_path = f"MyProject.ini"

with open(ini_path, "w") as f:
f.write(inifile)

```

=== "CLI"

``` bash
FM2PROF create MyProject
```

This will create a new directory \"MyProject\". In this directory you
will find [MyProject.ini]{.title-ref}. This is a valid configuration
file with all parameters set to their default values. You will also find
an [input]{.title-ref} and [output]{.title-ref} directory.

This will create a valid configuration file with all parameters set to their default values.

## Modify the input

Expand All @@ -50,9 +63,23 @@ CrossSectionLocationFile = # .csv or .txt file (, as delimiter) t

To be sure you used the correct data, run:

``` shell
FM2PROF check MyProject
```

=== "Python"

``` python
from fm2prof import Project

project = Project("MyProject.ini")

```

=== "CLI"

``` bash
FM2PROF check MyProject
```



Study the output. Errors indicate that something is wrong with your
input. In that case, you will need to correct the configurationfile.
Expand All @@ -64,18 +91,43 @@ settings that will be used and can be altered using a config file. The
configuration file does not need all parameters to be specified. If a
parameter is not in the configuration file, default values will be used.

To generate output, use:
The following examples run FM2PROF, overwrite any existing results and
produce figures of the generated cross-sections.

``` shell
FM2PROF run MyProject
```
=== "Python"

``` python
from fm2prof import Project
from fm2prof.utils import VisualiseOutput

# load project
project = Project("MyProject.ini")

# overwrite = True overwrites any existing output
project.run(overwrite=True)

# to visualize cross-sectino putput:
vis = VisualiseOutput(
project.get_output_directory(),
logger=project.get_logger()
)

All `outputFiles`{.interpreted-text role="ref"} are written to the
[output]{.title-ref} directory.
for css in vis.cross_sections:
vis.figure_cross_section(css)

```

## Inspect the results
=== "CLI"

``` bash
FM2PROF run MyProject -o -p
```



All `outputFiles` are written to the `output` directory specified in the FM2PROF configuration file.

After generating output it is important to check whether everything went
well. provides various tools and output files to do this. Go to
`diagnosis`{.interpreted-text role="ref"} and try to generate figures
with [fm2prof.utils]{.title-ref}.
well. See the following links to learn more about available tools:

- [Inspection cross-sections using a notebook](../../notebooks/cross_section_data)
49 changes: 33 additions & 16 deletions fm2prof/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1238,8 +1238,8 @@ class ModelOutputReader(FM2ProfBase):

def __init__(self,
logger=None,
start_time: datetime = None,
stop_time: datetime = None):
start_time: datetime | None = None,
stop_time: datetime | None = None):
super().__init__(logger=logger)

self._path_out: Path = Path(".")
Expand All @@ -1249,8 +1249,8 @@ def __init__(self,
self._data_1D_Q: pd.DataFrame = None
self._time_offset_1d: int = 0

self._start_time: Union[datetime, type(None)] = start_time
self._stop_time: Union[datetime, type(None)] = stop_time
self._start_time: datetime | None = start_time
self._stop_time: datetime | None = stop_time

@property
def start_time(self) -> Union[datetime, None]:
Expand Down Expand Up @@ -1307,13 +1307,13 @@ def load_flow1d_data(self):
self.file_1D_Q,
index_col=0,
parse_dates=True,
date_parser=self._dateparser,
date_format=self._time_fmt,
)
self._data_1D_H = pd.read_csv(
self.file_1D_H,
index_col=0,
parse_dates=True,
date_parser=self._dateparser,
date_format=self._time_fmt,
)
self.set_logger_message("Using existing flow1d csv files")
else:
Expand All @@ -1338,13 +1338,13 @@ def load_flow2d_data(self):
self.file_2D_Q,
index_col=0,
parse_dates=True,
date_parser=self._dateparser,
date_format=self._time_fmt,
)
self._data_2D_H = pd.read_csv(
self.file_2D_H,
index_col=0,
parse_dates=True,
date_parser=self._dateparser,
date_format=self._time_fmt,
)
self.set_logger_message("Using existing flow2d csv files")
else:
Expand All @@ -1356,13 +1356,13 @@ def load_flow2d_data(self):
self.file_2D_Q,
index_col=0,
parse_dates=True,
date_parser=self._dateparser,
date_format=self._time_fmt,
)
self._data_2D_H = pd.read_csv(
self.file_2D_H,
index_col=0,
parse_dates=True,
date_parser=self._dateparser,
date_format=self._time_fmt,
)

def get_1d2d_map(self):
Expand All @@ -1380,6 +1380,7 @@ def read_all_data(self) -> None:
self.load_flow2d_data()

def _dateparser(self, t):
#DEPRECATED
return datetime.strptime(t, self._time_fmt)

@property
Expand Down Expand Up @@ -1439,7 +1440,14 @@ def time_offset_1d(self, seconds: int = 0):
self._time_offset_1d = seconds

def _apply_startstop_time(self, data: pd.DataFrame) -> pd.DataFrame:
""" Applies stop/start time to data """
"""
Applies stop/start time to data
"""
if self.stop_time is None:
self.stop_time = data.index[-1]
if self.start_time is None:
self.start_time = data.index[0]

if self.start_time >= self.stop_time:
self.set_logger_message("Stop time ({self.stop_time}) should be later than start time ({self.start_time})", "error")
raise ValueError
Expand Down Expand Up @@ -1604,8 +1612,8 @@ class Compare1D2D(ModelOutputReader):
def __init__(
self,
project: Project,
path_1d: Union[Path, str],
path_2d: Union[Path, str],
path_1d: Union[Path, str] | None,
path_2d: Union[Path, str] | None,
routes: List[List[str]],
start_time: Union[None, datetime] = None,
stop_time: Union[None, datetime] = None,
Expand All @@ -1616,11 +1624,11 @@ def __init__(
else:
super().__init__()

if isinstance(path_1d, (Path, str)) & Path(path_1d).is_file():
if isinstance(path_1d, (Path, str)) and Path(path_1d).is_file():
self.path_flow1d = path_1d
else:
self.set_logger_message(f'1D netCDF file does not exist or is not provided. Input provided: {path_1d}.', 'debug')
if isinstance(path_1d, (Path, str)) & Path(path_2d).is_file():
if isinstance(path_1d, (Path, str)) and Path(path_2d).is_file():
self.path_flow2d = path_2d
else:
self.set_logger_message(f'2D netCDF file does not exist or is not provided. Input provided: {path_2d}.', 'debug')
Expand Down Expand Up @@ -1911,7 +1919,16 @@ def _style_error_axes(self, ax, ylim: List[float] = [-0.5, 0.5]):
ax.tick_params(axis="y", colors=self._color_error)
ax.grid(False)

def _compute_statistics(self):
def _compute_statistics(self) -> pd.DataFrame:
"""
Computes statistics for the difference between 1D and 2D water levels
Returns DataFrame with
columns: rkm, branch, is_lmw, bias, std, mae
rows: observation stations
"""

diff = self.data_1D_H - self.data_2D_H
station_names = diff.columns
rkms = self._names_to_rkms(station_names)
Expand Down
Loading

0 comments on commit 4f489b4

Please sign in to comment.