From cbed33369fb885855ab13ee5c15c9d2295bf552d Mon Sep 17 00:00:00 2001 From: Thomas Williams Date: Thu, 2 May 2024 09:29:24 -0400 Subject: [PATCH 1/3] refactor some tests --- pyproject.toml | 2 +- tests/__init__.py | 10 ++++++ tests/test_geom.py | 48 +++++++++++----------------- tests/test_plan.py | 80 +++++++++++++++++----------------------------- 4 files changed, 59 insertions(+), 81 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bd64e0d..6c286a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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] diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..37546a3 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -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 diff --git a/tests/test_geom.py b/tests/test_geom.py index 204d60d..fca3427 100644 --- a/tests/test_geom.py +++ b/tests/test_geom.py @@ -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]]' @@ -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 diff --git a/tests/test_plan.py b/tests/test_plan.py index fe98f21..e48b42a 100644 --- a/tests/test_plan.py +++ b/tests/test_plan.py @@ -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 From e44b740441d00e29e106b42c5db99236c533bb45 Mon Sep 17 00:00:00 2001 From: Thomas Williams Date: Thu, 2 May 2024 09:31:37 -0400 Subject: [PATCH 2/3] removed unused 'notebooks' dir --- notebooks/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 notebooks/.gitkeep diff --git a/notebooks/.gitkeep b/notebooks/.gitkeep deleted file mode 100644 index e69de29..0000000 From 70a5382121b229ed85a87ffe15f8377d7a6c0161 Mon Sep 17 00:00:00 2001 From: Thomas Williams Date: Thu, 2 May 2024 09:54:18 -0400 Subject: [PATCH 3/3] README updates for 0.1.0 release --- README.md | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ab02cf7..81962f7 100644 --- a/README.md +++ b/README.md @@ -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: ```