Skip to content

Commit 2420620

Browse files
authored
Lint river module (#389)
This PR adds pylint enforcement to the MHKiT river module. Additionally this PR adds type hints to the river module functions. Part of #275
1 parent f6f7301 commit 2420620

File tree

18 files changed

+688
-442
lines changed

18 files changed

+688
-442
lines changed

.github/workflows/pylint.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ jobs:
3737
run: |
3838
pylint mhkit/acoustics/
3939
40-
- name: Run Pylint on mhkit/tidal
40+
- name: Run Pylint on mhkit/tidal/
4141
run: |
4242
pylint mhkit/tidal/
43+
44+
- name: Run Pylint on mhkit/river/
45+
run: |
46+
pylint --extension-pkg-allow-list=netCDF4 mhkit/river/

examples/ADCP_Delft3D_TRTS_example.ipynb

Lines changed: 105 additions & 110 deletions
Large diffs are not rendered by default.

examples/river_example.ipynb

Lines changed: 28 additions & 29 deletions
Large diffs are not rendered by default.

mhkit/river/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""
2+
The river module provides tools and utilities for analyzing river energy resources.
3+
4+
"""
5+
16
from mhkit.river import performance
27
from mhkit.river import graphics
38
from mhkit.river import resource

mhkit/river/graphics.py

Lines changed: 100 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
1+
"""
2+
The graphics module provides plotting utilities for river energy resource data.
3+
4+
"""
5+
6+
from typing import Union, Optional
17
import numpy as np
28
import xarray as xr
39
import matplotlib.pyplot as plt
10+
from matplotlib.axes import Axes
11+
from numpy.typing import ArrayLike
412
from mhkit.utils import convert_to_dataarray
513

614

7-
def _xy_plot(x, y, fmt=".", label=None, xlabel=None, ylabel=None, title=None, ax=None):
15+
# pylint: disable=too-many-arguments
16+
# pylint: disable=too-many-positional-arguments
17+
def _xy_plot(
18+
x: ArrayLike,
19+
y: ArrayLike,
20+
fmt: str = ".",
21+
label: Optional[str] = None,
22+
xlabel: Optional[str] = None,
23+
ylabel: Optional[str] = None,
24+
title: Optional[str] = None,
25+
ax: Optional[Axes] = None,
26+
) -> Axes:
827
"""
928
Base function to plot any x vs y data
1029
@@ -50,16 +69,21 @@ def _xy_plot(x, y, fmt=".", label=None, xlabel=None, ylabel=None, title=None, ax
5069
return ax
5170

5271

53-
def plot_flow_duration_curve(D, F, label=None, ax=None):
72+
def plot_flow_duration_curve(
73+
discharge: Union[ArrayLike, xr.DataArray],
74+
exceedance_prob: Union[ArrayLike, xr.DataArray],
75+
label: Optional[str] = None,
76+
ax: Optional[Axes] = None,
77+
) -> Axes:
5478
"""
5579
Plots discharge vs exceedance probability as a Flow Duration Curve (FDC)
5680
5781
Parameters
5882
------------
59-
D: array-like
60-
Discharge [m/s] indexed by time
83+
discharge: array-like
84+
Discharge [m3/s] indexed by time
6185
62-
F: array-like
86+
exceedance_prob: array-like
6387
Exceedance probability [unitless] indexed by time
6488
6589
label: string
@@ -74,13 +98,15 @@ def plot_flow_duration_curve(D, F, label=None, ax=None):
7498
ax : matplotlib pyplot axes
7599
76100
"""
77-
# Sort by F
78-
temp = xr.Dataset(data_vars={"D": D, "F": F})
79-
temp = temp.sortby("F", ascending=False)
101+
# Sort by exceedance_prob
102+
temp = xr.Dataset(
103+
data_vars={"discharge": discharge, "exceedance_prob": exceedance_prob}
104+
)
105+
temp = temp.sortby("exceedance_prob", ascending=False)
80106

81107
ax = _xy_plot(
82-
temp["D"],
83-
temp["F"],
108+
temp["discharge"],
109+
temp["exceedance_prob"],
84110
fmt="-",
85111
label=label,
86112
xlabel="Discharge [$m^3/s$]",
@@ -92,16 +118,21 @@ def plot_flow_duration_curve(D, F, label=None, ax=None):
92118
return ax
93119

94120

95-
def plot_velocity_duration_curve(V, F, label=None, ax=None):
121+
def plot_velocity_duration_curve(
122+
velocity: Union[ArrayLike, xr.DataArray],
123+
exceedance_prob: Union[ArrayLike, xr.DataArray],
124+
label: Optional[str] = None,
125+
ax: Optional[Axes] = None,
126+
) -> Axes:
96127
"""
97128
Plots velocity vs exceedance probability as a Velocity Duration Curve (VDC)
98129
99130
Parameters
100131
------------
101-
V: array-like
132+
velocity: array-like
102133
Velocity [m/s] indexed by time
103134
104-
F: array-like
135+
exceedance_prob: array-like
105136
Exceedance probability [unitless] indexed by time
106137
107138
label: string
@@ -116,13 +147,15 @@ def plot_velocity_duration_curve(V, F, label=None, ax=None):
116147
ax : matplotlib pyplot axes
117148
118149
"""
119-
# Sort by F
120-
temp = xr.Dataset(data_vars={"V": V, "F": F})
121-
temp = temp.sortby("F", ascending=False)
150+
# Sort by exceedance_prob
151+
temp = xr.Dataset(
152+
data_vars={"velocity": velocity, "exceedance_prob": exceedance_prob}
153+
)
154+
temp = temp.sortby("exceedance_prob", ascending=False)
122155

123156
ax = _xy_plot(
124-
temp["V"],
125-
temp["F"],
157+
temp["velocity"],
158+
temp["exceedance_prob"],
126159
fmt="-",
127160
label=label,
128161
xlabel="Velocity [$m/s$]",
@@ -133,16 +166,21 @@ def plot_velocity_duration_curve(V, F, label=None, ax=None):
133166
return ax
134167

135168

136-
def plot_power_duration_curve(P, F, label=None, ax=None):
169+
def plot_power_duration_curve(
170+
power: Union[ArrayLike, xr.DataArray],
171+
exceedance_prob: Union[ArrayLike, xr.DataArray],
172+
label: Optional[str] = None,
173+
ax: Optional[Axes] = None,
174+
) -> Axes:
137175
"""
138176
Plots power vs exceedance probability as a Power Duration Curve (PDC)
139177
140178
Parameters
141179
------------
142-
P: array-like
180+
power: array-like
143181
Power [W] indexed by time
144182
145-
F: array-like
183+
exceedance_prob: array-like
146184
Exceedance probability [unitless] indexed by time
147185
148186
label: string
@@ -157,13 +195,13 @@ def plot_power_duration_curve(P, F, label=None, ax=None):
157195
ax : matplotlib pyplot axes
158196
159197
"""
160-
# Sort by F
161-
temp = xr.Dataset(data_vars={"P": P, "F": F})
162-
temp.sortby("F", ascending=False)
198+
# Sort by exceedance_prob
199+
temp = xr.Dataset(data_vars={"power": power, "exceedance_prob": exceedance_prob})
200+
temp.sortby("exceedance_prob", ascending=False)
163201

164202
ax = _xy_plot(
165-
temp["P"],
166-
temp["F"],
203+
temp["power"],
204+
temp["exceedance_prob"],
167205
fmt="-",
168206
label=label,
169207
xlabel="Power [W]",
@@ -174,13 +212,18 @@ def plot_power_duration_curve(P, F, label=None, ax=None):
174212
return ax
175213

176214

177-
def plot_discharge_timeseries(Q, time_dimension="", label=None, ax=None):
215+
def plot_discharge_timeseries(
216+
discharge: Union[ArrayLike, xr.DataArray],
217+
time_dimension: str = "",
218+
label: Optional[str] = None,
219+
ax: Optional[Axes] = None,
220+
) -> Axes:
178221
"""
179222
Plots discharge time-series
180223
181224
Parameters
182225
------------
183-
Q: array-like
226+
discharge: array-like
184227
Discharge [m3/s] indexed by time
185228
186229
time_dimension: string (optional)
@@ -199,14 +242,14 @@ def plot_discharge_timeseries(Q, time_dimension="", label=None, ax=None):
199242
ax : matplotlib pyplot axes
200243
201244
"""
202-
Q = convert_to_dataarray(Q)
245+
discharge = convert_to_dataarray(discharge)
203246

204247
if time_dimension == "":
205-
time_dimension = list(Q.coords)[0]
248+
time_dimension = list(discharge.coords)[0]
206249

207250
ax = _xy_plot(
208-
Q.coords[time_dimension].values,
209-
Q,
251+
discharge.coords[time_dimension].values,
252+
discharge,
210253
fmt="-",
211254
label=label,
212255
xlabel="Time",
@@ -217,16 +260,22 @@ def plot_discharge_timeseries(Q, time_dimension="", label=None, ax=None):
217260
return ax
218261

219262

220-
def plot_discharge_vs_velocity(D, V, polynomial_coeff=None, label=None, ax=None):
263+
def plot_discharge_vs_velocity(
264+
discharge: Union[ArrayLike, xr.DataArray],
265+
velocity: Union[ArrayLike, xr.DataArray],
266+
polynomial_coeff: Optional[np.poly1d] = None,
267+
label: Optional[str] = None,
268+
ax: Optional[Axes] = None,
269+
) -> Axes:
221270
"""
222271
Plots discharge vs velocity data along with the polynomial fit
223272
224273
Parameters
225274
------------
226-
D : array-like
227-
Discharge [m/s] indexed by time
275+
discharge : array-like
276+
Discharge [m3/s] indexed by time
228277
229-
V : array-like
278+
velocity : array-like
230279
Velocity [m/s] indexed by time
231280
232281
polynomial_coeff: numpy polynomial
@@ -244,16 +293,16 @@ def plot_discharge_vs_velocity(D, V, polynomial_coeff=None, label=None, ax=None)
244293
245294
"""
246295
ax = _xy_plot(
247-
D,
248-
V,
296+
discharge,
297+
velocity,
249298
fmt=".",
250299
label=label,
251300
xlabel="Discharge [$m^3/s$]",
252301
ylabel="Velocity [$m/s$]",
253302
ax=ax,
254303
)
255304
if polynomial_coeff:
256-
x = np.linspace(D.min(), D.max())
305+
x = np.linspace(discharge.min(), discharge.max())
257306
ax = _xy_plot(
258307
x,
259308
polynomial_coeff(x),
@@ -267,16 +316,22 @@ def plot_discharge_vs_velocity(D, V, polynomial_coeff=None, label=None, ax=None)
267316
return ax
268317

269318

270-
def plot_velocity_vs_power(V, P, polynomial_coeff=None, label=None, ax=None):
319+
def plot_velocity_vs_power(
320+
velocity: Union[ArrayLike, xr.DataArray],
321+
power: Union[ArrayLike, xr.DataArray],
322+
polynomial_coeff: Optional[np.poly1d] = None,
323+
label: Optional[str] = None,
324+
ax: Optional[Axes] = None,
325+
) -> Axes:
271326
"""
272327
Plots velocity vs power data along with the polynomial fit
273328
274329
Parameters
275330
------------
276-
V : array-like
331+
velocity : array-like
277332
Velocity [m/s] indexed by time
278333
279-
P: array-like
334+
power: array-like
280335
Power [W] indexed by time
281336
282337
polynomial_coeff: numpy polynomial
@@ -294,16 +349,16 @@ def plot_velocity_vs_power(V, P, polynomial_coeff=None, label=None, ax=None):
294349
295350
"""
296351
ax = _xy_plot(
297-
V,
298-
P,
352+
velocity,
353+
power,
299354
fmt=".",
300355
label=label,
301356
xlabel="Velocity [$m/s$]",
302357
ylabel="Power [$W$]",
303358
ax=ax,
304359
)
305360
if polynomial_coeff:
306-
x = np.linspace(V.min(), V.max())
361+
x = np.linspace(velocity.min(), velocity.max())
307362
ax = _xy_plot(
308363
x,
309364
polynomial_coeff(x),

mhkit/river/io/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1+
"""
2+
This module provides input/output functionality for river energy related data in MHKiT.
3+
4+
"""
5+
16
from mhkit.river.io import usgs
27
from mhkit.river.io import d3d

0 commit comments

Comments
 (0)