Skip to content

Commit

Permalink
Merge pull request #27 from fema-ffrd/release/0.1.0
Browse files Browse the repository at this point in the history
Release/0.1.0
  • Loading branch information
thwllms authored May 2, 2024
2 parents 1ff1c97 + 70a5382 commit 852c4ac
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 83 deletions.
41 changes: 39 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,48 @@ Read data from [HEC-RAS](https://www.hec.usace.army.mil/software/hec-ras/) [HDF]
*Pronunciation: `raz·aitch·dee·eff`*

## Install
A prerelease version of `rashdf` is available from PyPI:
```bash
$ pip install rashdf=0.1.0b1
$ pip install rashdf
```

## Usage
`RasGeomHdf` and `RasPlanHdf` are extensions of
[h5py.File](https://docs.h5py.org/en/stable/high/file.html#h5py.File). They contain
methods to export HEC-RAS model geometry as
[GeoDataFrame](https://geopandas.org/en/stable/docs/reference/geodataframe.html)
objects.
```python
>>> from rashdf import RasGeomHdf
>>> geom_hdf = RasGeomHdf("path/to/rasmodel/Muncie.g04.hdf")
>>> mesh_cells = geom_hdf.mesh_cell_polygons() # export a GeoDataFrame
>>> mesh_cells
mesh_name cell_id geometry
0 2D Interior Area 0 POLYGON ((406025.000 1805015.237, 406025.000 1...
1 2D Interior Area 1 POLYGON ((406075.000 1805018.545, 406075.000 1...
2 2D Interior Area 2 POLYGON ((406075.000 1804975.000, 406075.000 1...
3 2D Interior Area 3 POLYGON ((406125.000 1804975.000, 406125.000 1...
4 2D Interior Area 4 POLYGON ((406175.000 1804975.000, 406175.000 1...
... ... ... ...
5386 2D Interior Area 5386 POLYGON ((409163.402 1802463.621, 409175.000 1...
5387 2D Interior Area 5387 POLYGON ((409160.953 1802374.120, 409125.000 1...
5388 2D Interior Area 5388 POLYGON ((409163.402 1802463.621, 409161.906 1...
5389 2D Interior Area 5389 POLYGON ((409112.480 1802410.114, 409112.046 1...
5390 2D Interior Area 5390 POLYGON ((409112.480 1802410.114, 409063.039 1...
>>> mesh_cells.to_file("mucie-mesh-cell-polygons.shp")
```

Also, methods to extract certain HDF group attributes as dictionaries:
```python
>>> from rashdf import RasPlanHdf
>>> with RasPlanHdf("path/to/rasmodel/Muncie.p04.hdf") as plan_hdf:
>>> results_unsteady_summary = plan_hdf.get_results_unsteady_summary()
>>> results_unsteady_summary
{'Computation Time DSS': '00:00:00', 'Computation Time Total': '00:00:23', 'Maximum WSEL Error': 0.0099277812987566, 'Maximum number of cores': 6, 'Run Time Window': [datetime.datetime(2024, 3, 27, 9, 31, 52), datetime.datetime(2024, 3, 27, 9, 32, 15)], 'Solution': 'Unsteady Finished Successfully', 'Time Solution Went Unstable': None, 'Time Stamp Solution Went Unstable': 'Not Applicable'}
```

## Documentation
Coming soon.

## Developer Setup
Create a virtual environment in the project directory:
```
Expand Down
Empty file removed notebooks/.gitkeep
Empty file.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
version = "0.1.0-beta.1"
version = "0.1.0"
dependencies = ["h5py", "geopandas"]

[project.optional-dependencies]
Expand Down
10 changes: 10 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import h5py

from pathlib import Path


def _create_hdf_with_group_attrs(path: Path, group_path: str, attrs: dict):
with h5py.File(path, "w") as f:
group = f.create_group(group_path)
for key, value in attrs.items():
group.attrs[key] = value
48 changes: 18 additions & 30 deletions tests/test_geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
from pyproj import CRS
from pathlib import Path

from . import _create_hdf_with_group_attrs

TEST_DATA = Path("./tests/data")
MUNCIE_G05 = TEST_DATA / "ras/Muncie.g05.hdf"
TEST_JSON = TEST_DATA / "json"

TEST_ATTRS = {"test_attribute1": "test_str1", "test_attribute2": 500}


def test_projection(tmp_path):
wkt = 'PROJCS["Albers_Conic_Equal_Area",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["false_easting",0.0],PARAMETER["false_northing",0.0],PARAMETER["central_meridian",-96.0],PARAMETER["standard_parallel_1",29.5],PARAMETER["standard_parallel_2",45.5],PARAMETER["latitude_of_origin",37.5],UNIT["Foot_US",0.3048006096012192]]'
Expand Down Expand Up @@ -74,39 +78,23 @@ def test_refinement_regions():


def test_get_geom_attrs(tmp_path):
attrs_to_set = {"test_attribute1": "test_str1", "test_attribute2": 500}

with h5py.File(tmp_path / "test.hdf", "w") as f:
geom_group = f.create_group(RasGeomHdf.GEOM_PATH)
for key, value in attrs_to_set.items():
geom_group.attrs[key] = value

ras_hdf = RasGeomHdf(tmp_path / "test.hdf")

assert ras_hdf.get_geom_attrs() == attrs_to_set
test_hdf = tmp_path / "test.hdf"
_create_hdf_with_group_attrs(test_hdf, RasGeomHdf.GEOM_PATH, TEST_ATTRS)
ras_hdf = RasGeomHdf(test_hdf)
assert ras_hdf.get_geom_attrs() == TEST_ATTRS


def test_get_geom_structures_attrs(tmp_path):
attrs_to_set = {"test_attribute1": "test_str1", "test_attribute2": 500}

with h5py.File(tmp_path / "test.hdf", "w") as f:
structures_group = f.create_group(RasGeomHdf.GEOM_STRUCTURES_PATH)
for key, value in attrs_to_set.items():
structures_group.attrs[key] = value

ras_hdf = RasGeomHdf(tmp_path / "test.hdf")

assert ras_hdf.get_geom_structures_attrs() == attrs_to_set
test_hdf = tmp_path / "test.hdf"
_create_hdf_with_group_attrs(test_hdf, RasGeomHdf.GEOM_STRUCTURES_PATH, TEST_ATTRS)
ras_hdf = RasGeomHdf(test_hdf)
assert ras_hdf.get_geom_structures_attrs() == TEST_ATTRS


def test_get_geom_2d_flow_area_attrs(tmp_path):
attrs_to_set = {"test_attribute1": "test_str1", "test_attribute2": 500}

with h5py.File(tmp_path / "test.hdf", "w") as f:
flow_area_group = f.create_group(f"{RasGeomHdf.FLOW_AREA_2D_PATH}/group")
for key, value in attrs_to_set.items():
flow_area_group.attrs[key] = value

ras_hdf = RasGeomHdf(tmp_path / "test.hdf")

assert ras_hdf.get_geom_2d_flow_area_attrs() == attrs_to_set
test_hdf = tmp_path / "test.hdf"
_create_hdf_with_group_attrs(
test_hdf, f"{RasGeomHdf.FLOW_AREA_2D_PATH}/group", TEST_ATTRS
)
ras_hdf = RasGeomHdf(test_hdf)
assert ras_hdf.get_geom_2d_flow_area_attrs() == TEST_ATTRS
80 changes: 30 additions & 50 deletions tests/test_plan.py
Original file line number Diff line number Diff line change
@@ -1,71 +1,51 @@
from src.rashdf import RasPlanHdf

import h5py
from . import _create_hdf_with_group_attrs

attrs_to_set = {"test_attribute1": "test_str1", "test_attribute2": 500}
TEST_ATTRS = {"test_attribute1": "test_str1", "test_attribute2": 500}


def test_get_plan_info_attrs(tmp_path):
with h5py.File(tmp_path / "test.hdf", "w") as f:
group = f.create_group(RasPlanHdf.PLAN_INFO_PATH)
for key, value in attrs_to_set.items():
group.attrs[key] = value

ras_plan_hdf = RasPlanHdf(tmp_path / "test.hdf")

assert ras_plan_hdf.get_plan_info_attrs() == attrs_to_set
test_hdf = tmp_path / "test.hdf"
_create_hdf_with_group_attrs(test_hdf, RasPlanHdf.PLAN_INFO_PATH, TEST_ATTRS)
ras_plan_hdf = RasPlanHdf(test_hdf)
assert ras_plan_hdf.get_plan_info_attrs() == TEST_ATTRS


def test_get_plan_param_attrs(tmp_path):
with h5py.File(tmp_path / "test.hdf", "w") as f:
group = f.create_group(RasPlanHdf.PLAN_PARAMS_PATH)
for key, value in attrs_to_set.items():
group.attrs[key] = value

ras_plan_hdf = RasPlanHdf(tmp_path / "test.hdf")

assert ras_plan_hdf.get_plan_param_attrs() == attrs_to_set
test_hdf = tmp_path / "test.hdf"
_create_hdf_with_group_attrs(test_hdf, RasPlanHdf.PLAN_PARAMS_PATH, TEST_ATTRS)
ras_plan_hdf = RasPlanHdf(test_hdf)
assert ras_plan_hdf.get_plan_param_attrs() == TEST_ATTRS


def test_get_meteorology_precip_attrs(tmp_path):
with h5py.File(tmp_path / "test.hdf", "w") as f:
group = f.create_group(RasPlanHdf.PRECIP_PATH)
for key, value in attrs_to_set.items():
group.attrs[key] = value

ras_plan_hdf = RasPlanHdf(tmp_path / "test.hdf")

assert ras_plan_hdf.get_meteorology_precip_attrs() == attrs_to_set
test_hdf = tmp_path / "test.hdf"
_create_hdf_with_group_attrs(test_hdf, RasPlanHdf.PRECIP_PATH, TEST_ATTRS)
ras_plan_hdf = RasPlanHdf(test_hdf)
assert ras_plan_hdf.get_meteorology_precip_attrs() == TEST_ATTRS


def test_get_results_unsteady_attrs(tmp_path):
with h5py.File(tmp_path / "test.hdf", "w") as f:
group = f.create_group(RasPlanHdf.RESULTS_UNSTEADY_PATH)
for key, value in attrs_to_set.items():
group.attrs[key] = value

ras_plan_hdf = RasPlanHdf(tmp_path / "test.hdf")

assert ras_plan_hdf.get_results_unsteady_attrs() == attrs_to_set
test_hdf = tmp_path / "test.hdf"
_create_hdf_with_group_attrs(test_hdf, RasPlanHdf.RESULTS_UNSTEADY_PATH, TEST_ATTRS)
ras_plan_hdf = RasPlanHdf(test_hdf)
assert ras_plan_hdf.get_results_unsteady_attrs() == TEST_ATTRS


def test_get_results_unsteady_summary_attrs(tmp_path):
with h5py.File(tmp_path / "test.hdf", "w") as f:
group = f.create_group(RasPlanHdf.RESULTS_UNSTEADY_SUMMARY_PATH)
for key, value in attrs_to_set.items():
group.attrs[key] = value

ras_plan_hdf = RasPlanHdf(tmp_path / "test.hdf")

assert ras_plan_hdf.get_results_unsteady_summary_attrs() == attrs_to_set
test_hdf = tmp_path / "test.hdf"
_create_hdf_with_group_attrs(
test_hdf, RasPlanHdf.RESULTS_UNSTEADY_SUMMARY_PATH, TEST_ATTRS
)
ras_plan_hdf = RasPlanHdf(test_hdf)
assert ras_plan_hdf.get_results_unsteady_summary_attrs() == TEST_ATTRS


def test_get_results_volume_accounting_attrs(tmp_path):
with h5py.File(tmp_path / "test.hdf", "w") as f:
group = f.create_group(RasPlanHdf.VOLUME_ACCOUNTING_PATH)
for key, value in attrs_to_set.items():
group.attrs[key] = value

ras_plan_hdf = RasPlanHdf(tmp_path / "test.hdf")

assert ras_plan_hdf.get_results_volume_accounting_attrs() == attrs_to_set
test_hdf = tmp_path / "test.hdf"
_create_hdf_with_group_attrs(
test_hdf, RasPlanHdf.VOLUME_ACCOUNTING_PATH, TEST_ATTRS
)
ras_plan_hdf = RasPlanHdf(test_hdf)
assert ras_plan_hdf.get_results_volume_accounting_attrs() == TEST_ATTRS

0 comments on commit 852c4ac

Please sign in to comment.