rashdf 0.7.2__py3-none-any.whl → 0.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cli.py CHANGED
@@ -21,6 +21,7 @@ COMMANDS = [
21
21
  "mesh_cell_faces",
22
22
  "refinement_regions",
23
23
  "bc_lines",
24
+ "ic_points",
24
25
  "breaklines",
25
26
  "reference_lines",
26
27
  "reference_points",
rashdf/geom.py CHANGED
@@ -41,6 +41,7 @@ class RasGeomHdf(RasHdf):
41
41
  GEOM_STRUCTURES_PATH = f"{GEOM_PATH}/Structures"
42
42
  FLOW_AREA_2D_PATH = f"{GEOM_PATH}/2D Flow Areas"
43
43
  BC_LINES_PATH = f"{GEOM_PATH}/Boundary Condition Lines"
44
+ IC_POINTS_PATH = f"{GEOM_PATH}/IC Points"
44
45
  BREAKLINES_PATH = f"{GEOM_PATH}/2D Flow Area Break Lines"
45
46
  REFERENCE_LINES_PATH = f"{GEOM_PATH}/Reference Lines"
46
47
  REFERENCE_POINTS_PATH = f"{GEOM_PATH}/Reference Points"
@@ -408,7 +409,10 @@ class RasGeomHdf(RasHdf):
408
409
  GeoDataFrame
409
410
  A GeoDataFrame containing the model structures if they exist.
410
411
  """
411
- if self.GEOM_STRUCTURES_PATH not in self:
412
+ if (
413
+ self.GEOM_STRUCTURES_PATH not in self
414
+ or f"{self.GEOM_STRUCTURES_PATH}/Attributes" not in self
415
+ ):
412
416
  return GeoDataFrame()
413
417
  struct_data = self[self.GEOM_STRUCTURES_PATH]
414
418
  v_conv_val = np.vectorize(convert_ras_hdf_value)
@@ -438,7 +442,32 @@ class RasGeomHdf(RasHdf):
438
442
  raise NotImplementedError
439
443
 
440
444
  def ic_points(self) -> GeoDataFrame: # noqa D102
441
- raise NotImplementedError
445
+ """Return initial conditions points.
446
+
447
+ Returns
448
+ -------
449
+ GeoDataFrame
450
+ A GeoDataFrame containing the initial condition points if they exist.
451
+ """
452
+ if self.IC_POINTS_PATH not in self:
453
+ return GeoDataFrame()
454
+ ic_data = self[self.IC_POINTS_PATH]
455
+ v_conv_str = np.vectorize(convert_ras_hdf_string)
456
+ names = v_conv_str(ic_data["Attributes"][()]["Name"])
457
+ mesh_names = v_conv_str(ic_data["Attributes"][()]["SA/2D"])
458
+ cell_ids = ic_data["Attributes"][()]["Cell Index"]
459
+ points = ic_data["Points"][()]
460
+ return GeoDataFrame(
461
+ {
462
+ "icpt_id": range(len(names)),
463
+ "icpt_name": names,
464
+ "mesh_name": mesh_names,
465
+ "cell_id": cell_ids,
466
+ "geometry": list(map(Point, points)),
467
+ },
468
+ geometry="geometry",
469
+ crs=self.projection(),
470
+ )
442
471
 
443
472
  def _reference_lines_points_names(
444
473
  self, reftype: str = "lines", mesh_name: Optional[str] = None
rashdf/plan.py CHANGED
@@ -168,6 +168,7 @@ class RasPlanHdf(RasGeomHdf):
168
168
  UNSTEADY_TIME_SERIES_PATH = f"{BASE_OUTPUT_PATH}/Unsteady Time Series"
169
169
  REFERENCE_LINES_OUTPUT_PATH = f"{UNSTEADY_TIME_SERIES_PATH}/Reference Lines"
170
170
  REFERENCE_POINTS_OUTPUT_PATH = f"{UNSTEADY_TIME_SERIES_PATH}/Reference Points"
171
+ BOUNDARY_CONDITIONS_OUTPUT_PATH = f"{UNSTEADY_TIME_SERIES_PATH}/Boundary Conditions"
171
172
  OBS_FLOW_OUTPUT_PATH = f"{OBS_DATA_PATH}/Flow"
172
173
  OBS_STAGE_OUTPUT_PATH = f"{OBS_DATA_PATH}/Stage"
173
174
 
@@ -1121,6 +1122,81 @@ class RasPlanHdf(RasGeomHdf):
1121
1122
  """
1122
1123
  return self.reference_timeseries_output(reftype="lines")
1123
1124
 
1125
+ def bc_line_timeseries_output(self, bc_line_name: str) -> xr.Dataset:
1126
+ """Return timeseries output data for a specific boundary condition line from a HEC-RAS HDF plan file.
1127
+
1128
+ Parameters
1129
+ ----------
1130
+ bc_line_name : str
1131
+ The name of the boundary condition line.
1132
+
1133
+ Returns
1134
+ -------
1135
+ xr.Dataset
1136
+ An xarray Dataset with timeseries output data for the specified boundary condition line.
1137
+ """
1138
+ path = f"{self.BOUNDARY_CONDITIONS_OUTPUT_PATH}/{bc_line_name}"
1139
+ dataset = self.get(path)
1140
+ if dataset is None:
1141
+ raise RasPlanHdfError(
1142
+ f"Could not find HDF group at path '{path}'."
1143
+ f" Does the Plan HDF file contain boundary condition output data for '{bc_line_name}'?"
1144
+ )
1145
+ columns = [c.decode("utf-8") for c in dataset.attrs["Columns"]]
1146
+ ds = xr.Dataset()
1147
+ try:
1148
+ import dask.array as da
1149
+
1150
+ # TODO: user-specified chunks?
1151
+ values = da.from_array(dataset, chunks=dataset.chunks)
1152
+ except ImportError:
1153
+ values = dataset[:]
1154
+ for i, col in enumerate(columns):
1155
+ units = dataset.attrs.get(col, None)
1156
+ if units is not None:
1157
+ units = units.decode("utf-8")
1158
+ da = xr.DataArray(
1159
+ values[:, i],
1160
+ name=col,
1161
+ dims=["time"],
1162
+ coords={
1163
+ "time": self.unsteady_datetimes(),
1164
+ },
1165
+ attrs={
1166
+ "units": units,
1167
+ "hdf_path": f"{path}",
1168
+ },
1169
+ )
1170
+ ds[col] = da
1171
+ return ds
1172
+
1173
+ def bc_lines_timeseries_output(self) -> xr.Dataset:
1174
+ """Return timeseries output data for boundary conditions lines from a HEC-RAS HDF plan file.
1175
+
1176
+ Returns
1177
+ -------
1178
+ xr.Dataset
1179
+ An xarray Dataset with timeseries output data for boundary conditions lines.
1180
+ """
1181
+ df_bc_lines = self.bc_lines()
1182
+ bc_lines_names = df_bc_lines["name"]
1183
+ datasets = []
1184
+ for bc_line_name in bc_lines_names:
1185
+ ds_bc_line = self.bc_line_timeseries_output(bc_line_name)
1186
+ datasets.append(ds_bc_line)
1187
+ bc_line_ids = df_bc_lines["bc_line_id"].values
1188
+ ds: xr.Dataset = xr.concat(
1189
+ datasets, dim=pd.Index(bc_line_ids, name="bc_line_id")
1190
+ )
1191
+ ds = ds.assign_coords(
1192
+ {
1193
+ "bc_line_name": ("bc_line_id", bc_lines_names),
1194
+ "bc_line_type": ("bc_line_id", df_bc_lines["type"]),
1195
+ "mesh_name": ("bc_line_id", df_bc_lines["mesh_name"]),
1196
+ }
1197
+ )
1198
+ return ds
1199
+
1124
1200
  def observed_timeseries_input(self, vartype: str = "Flow") -> xr.DataArray:
1125
1201
  """Return observed timeseries input data for reference lines and points from a HEC-RAS HDF plan file.
1126
1202
 
@@ -1381,10 +1457,49 @@ class RasPlanHdf(RasGeomHdf):
1381
1457
  """
1382
1458
  return self.get_attrs(self.VOLUME_ACCOUNTING_PATH)
1383
1459
 
1384
- def enroachment_points(self) -> GeoDataFrame: # noqa: D102
1385
- raise NotImplementedError
1460
+ def encroachment_points(self, profile_name: str) -> GeoDataFrame:
1461
+ """Return encroachment points from a HEC-RAS plan HDF file based on a user-specified flow profile.
1462
+
1463
+ Returns
1464
+ -------
1465
+ GeoDataframe
1466
+ A GeoDataFrame with cross-section encroachments represented as Point geometry features along with pertinent attributes.
1467
+ """
1468
+ cross_sections = self.cross_sections()
1469
+ cross_sections["Enc_Profile"] = profile_name
1470
+
1471
+ leftmost_sta = self.cross_sections_elevations()["elevation info"].apply(
1472
+ lambda x: x[0][0]
1473
+ )
1474
+ left_enc_sta = self.cross_sections_additional_enc_station_left()[profile_name]
1475
+ left_enc_points = GeoDataFrame(
1476
+ pd.concat(
1477
+ [
1478
+ cross_sections[["River", "Reach", "RS", "Enc_Profile"]],
1479
+ left_enc_sta.rename("Enc_Sta", inplace=False),
1480
+ ],
1481
+ axis=1,
1482
+ ),
1483
+ geometry=cross_sections.geometry.interpolate(left_enc_sta - leftmost_sta),
1484
+ )
1485
+ left_enc_points["Side"] = "Left"
1486
+
1487
+ right_enc_sta = self.cross_sections_additional_enc_station_right()[profile_name]
1488
+ right_enc_points = GeoDataFrame(
1489
+ pd.concat(
1490
+ [
1491
+ cross_sections[["River", "Reach", "RS", "Enc_Profile"]],
1492
+ right_enc_sta.rename("Enc_Sta", inplace=False),
1493
+ ],
1494
+ axis=1,
1495
+ ),
1496
+ geometry=cross_sections.geometry.interpolate(right_enc_sta - leftmost_sta),
1497
+ )
1498
+ right_enc_points["Side"] = "Right"
1499
+
1500
+ return GeoDataFrame(pd.concat([left_enc_points, right_enc_points]))
1386
1501
 
1387
- def steady_flow_names(self) -> list:
1502
+ def steady_flow_names(self) -> List[str]:
1388
1503
  """Return the profile information for each steady flow event.
1389
1504
 
1390
1505
  Returns
@@ -1393,7 +1508,7 @@ class RasPlanHdf(RasGeomHdf):
1393
1508
  A Dataframe containing the profile names for each event
1394
1509
  """
1395
1510
  if self.STEADY_PROFILES_PATH not in self:
1396
- return pd.DataFrame()
1511
+ return []
1397
1512
 
1398
1513
  profile_data = self[self.STEADY_PROFILES_PATH]
1399
1514
  profile_attrs = profile_data["Profile Names"][()]
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: rashdf
3
- Version: 0.7.2
3
+ Version: 0.8.0
4
4
  Summary: Read data from HEC-RAS HDF files.
5
5
  Project-URL: repository, https://github.com/fema-ffrd/rashdf
6
6
  Classifier: Development Status :: 4 - Beta
@@ -28,10 +28,12 @@ Requires-Dist: dask; extra == "dev"
28
28
  Requires-Dist: fsspec; extra == "dev"
29
29
  Requires-Dist: s3fs; extra == "dev"
30
30
  Requires-Dist: fiona==1.9.6; extra == "dev"
31
+ Requires-Dist: numcodecs<0.16; extra == "dev"
31
32
  Provides-Extra: docs
32
33
  Requires-Dist: sphinx; extra == "docs"
33
34
  Requires-Dist: numpydoc; extra == "docs"
34
35
  Requires-Dist: sphinx_rtd_theme; extra == "docs"
36
+ Dynamic: license-file
35
37
 
36
38
  # rashdf
37
39
  [![CI](https://github.com/fema-ffrd/rashdf/actions/workflows/continuous-integration.yml/badge.svg?branch=main)](https://github.com/fema-ffrd/rashdf/actions/workflows/continuous-integration.yml)
@@ -0,0 +1,12 @@
1
+ cli.py,sha256=HbyrdUVKfrmtU2T9ljKTPQ-ugomJqYbCA26ghGJDJh0,6588
2
+ rashdf/__init__.py,sha256=XXFtJDgLPCimqAhfsFz_pTWYECJiRT0i-Kb1uflXmVU,156
3
+ rashdf/base.py,sha256=cAQJX1aeBJKb3MJ06ltpbRTUaZX5NkuxpR1J4f7FyTU,2507
4
+ rashdf/geom.py,sha256=XAs6HQQaLkFlic60xUO0R2MuTi71H6f3WoEfNBlaxYU,27146
5
+ rashdf/plan.py,sha256=d8YhpC6cV8rhh3qf1o12TbhUvo_4pMh75vIdDkcAvjE,63971
6
+ rashdf/utils.py,sha256=Cba6sULF0m0jg6CQass4bPm2oxTd_avoe1pRQxq082c,10896
7
+ rashdf-0.8.0.dist-info/licenses/LICENSE,sha256=L_0QaLpQVHPcglVjiaJPnOocwzP8uXevDRjUPr9DL1Y,1065
8
+ rashdf-0.8.0.dist-info/METADATA,sha256=gw9owwT8skbZ7kupdYi8McfwMRXqk9PtXYWptJiTuQQ,6062
9
+ rashdf-0.8.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
+ rashdf-0.8.0.dist-info/entry_points.txt,sha256=LHHMR1lLy4wRyscMuW1RlYDXemtPgqQhNcILz0DtStY,36
11
+ rashdf-0.8.0.dist-info/top_level.txt,sha256=SrmLb6FFTJtM_t6O1v0M0JePshiQJMHr0yYVkHL7ztk,11
12
+ rashdf-0.8.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,12 +0,0 @@
1
- cli.py,sha256=yItWmCxnYLcuOpJVRpUsfv_NLS9IxLjojZB9GrxfKAU,6571
2
- rashdf/__init__.py,sha256=XXFtJDgLPCimqAhfsFz_pTWYECJiRT0i-Kb1uflXmVU,156
3
- rashdf/base.py,sha256=cAQJX1aeBJKb3MJ06ltpbRTUaZX5NkuxpR1J4f7FyTU,2507
4
- rashdf/geom.py,sha256=2aTfj6mqZGP6rysflQ5L8FeItlYJsknO00sKHo-yaTw,26090
5
- rashdf/plan.py,sha256=vGqxQssz6ObxIO48Vej-d7EtBJBZ90zCrt7gC5pHATE,59558
6
- rashdf/utils.py,sha256=Cba6sULF0m0jg6CQass4bPm2oxTd_avoe1pRQxq082c,10896
7
- rashdf-0.7.2.dist-info/LICENSE,sha256=L_0QaLpQVHPcglVjiaJPnOocwzP8uXevDRjUPr9DL1Y,1065
8
- rashdf-0.7.2.dist-info/METADATA,sha256=KkdJpptV8_IoCQwIa9ErfEGIJIz8rLMUvBZkdXuhDAQ,5994
9
- rashdf-0.7.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
10
- rashdf-0.7.2.dist-info/entry_points.txt,sha256=LHHMR1lLy4wRyscMuW1RlYDXemtPgqQhNcILz0DtStY,36
11
- rashdf-0.7.2.dist-info/top_level.txt,sha256=SrmLb6FFTJtM_t6O1v0M0JePshiQJMHr0yYVkHL7ztk,11
12
- rashdf-0.7.2.dist-info/RECORD,,