Skip to content

Commit e06d95d

Browse files
committed
pylint
1 parent dd358d5 commit e06d95d

File tree

1 file changed

+93
-73
lines changed

1 file changed

+93
-73
lines changed

mhkit/river/resource.py

Lines changed: 93 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1+
"""
2+
The resource module provides functions for analyzing river and tidal energy resources.
3+
4+
This module includes utilities for:
5+
- Calculating flow characteristics (Froude number)
6+
- Computing exceedance probabilities
7+
- Fitting polynomial relationships between discharge, velocity, and power
8+
- Converting between different resource metrics (discharge to velocity, velocity to power)
9+
- Calculating energy production from power data
10+
11+
All functions include input validation and follow consistent unit conventions.
12+
"""
13+
114
import xarray as xr
215
import numpy as np
316
from scipy.stats import linregress as _linregress
417
from scipy.stats import rv_histogram as _rv_histogram
518
from mhkit.utils import convert_to_dataarray
619

720

8-
def Froude_number(v, h, g=9.80665):
21+
def froude_number(v, h, g=9.80665):
922
"""
1023
Calculate the Froude Number of the river, channel or duct flow,
1124
to check subcritical flow assumption (if Fr <1).
@@ -21,7 +34,7 @@ def Froude_number(v, h, g=9.80665):
2134
2235
Returns
2336
---------
24-
Fr : float
37+
froude_num : float
2538
Froude Number of the river [unitless].
2639
2740
"""
@@ -32,18 +45,18 @@ def Froude_number(v, h, g=9.80665):
3245
if not isinstance(g, (int, float)):
3346
raise TypeError(f"g must be of type int or float. Got: {type(g)}")
3447

35-
Fr = v / np.sqrt(g * h)
48+
froude_num = v / np.sqrt(g * h)
3649

37-
return Fr
50+
return froude_num
3851

3952

40-
def exceedance_probability(D, dimension="", to_pandas=True):
53+
def exceedance_probability(discharge, dimension="", to_pandas=True):
4154
"""
4255
Calculates the exceedance probability
4356
4457
Parameters
4558
----------
46-
D : pandas Series, pandas DataFrame, xarray DataArray, or xarray Dataset
59+
discharge : pandas Series, pandas DataFrame, xarray DataArray, or xarray Dataset
4760
Discharge indexed by time [datetime or s].
4861
4962
dimension: string (optional)
@@ -55,31 +68,31 @@ def exceedance_probability(D, dimension="", to_pandas=True):
5568
5669
Returns
5770
-------
58-
F : pandas DataFrame or xarray Dataset
71+
exceedance_prob : pandas DataFrame or xarray Dataset
5972
Exceedance probability [unitless] indexed by time [datetime or s]
6073
"""
6174
if not isinstance(dimension, str):
6275
raise TypeError(f"dimension must be of type str. Got: {type(dimension)}")
6376
if not isinstance(to_pandas, bool):
6477
raise TypeError(f"to_pandas must be of type bool. Got: {type(to_pandas)}")
6578

66-
D = convert_to_dataarray(D)
79+
discharge = convert_to_dataarray(discharge)
6780

6881
if dimension == "":
69-
dimension = list(D.coords)[0]
82+
dimension = list(discharge.coords)[0]
7083

71-
# Calculate exceedance probability (F)
72-
rank = D.rank(dim=dimension)
73-
rank = len(D[dimension]) - rank + 1 # convert to descending rank
74-
F = 100 * rank / (len(D[dimension]) + 1)
75-
F.name = "F"
84+
# Calculate exceedance probability
85+
rank = discharge.rank(dim=dimension)
86+
rank = len(discharge[dimension]) - rank + 1 # convert to descending rank
87+
exceedance_prob = 100 * rank / (len(discharge[dimension]) + 1)
88+
exceedance_prob.name = "exceedance_probability"
7689

77-
F = F.to_dataset() # for matlab
90+
exceedance_prob = exceedance_prob.to_dataset() # for matlab
7891

7992
if to_pandas:
80-
F = F.to_pandas()
93+
exceedance_prob = exceedance_prob.to_pandas()
8194

82-
return F
95+
return exceedance_prob
8396

8497

8598
def polynomial_fit(x, y, n):
@@ -100,45 +113,48 @@ def polynomial_fit(x, y, n):
100113
----------
101114
polynomial_coefficients : numpy polynomial
102115
List of polynomial coefficients
103-
R2 : float
104-
Polynomical fit coeffcient of determination
116+
r_squared : float
117+
Polynomial fit coefficient of determination
105118
106119
"""
107120
try:
108121
x = np.array(x)
109-
except:
110-
pass
122+
except (ValueError, TypeError) as exc:
123+
raise TypeError("x must be convertible to np.ndarray") from exc
111124
try:
112125
y = np.array(y)
113-
except:
114-
pass
126+
except (ValueError, TypeError) as exc:
127+
raise TypeError("y must be convertible to np.ndarray") from exc
128+
115129
if not isinstance(x, np.ndarray):
116130
raise TypeError(f"x must be of type np.ndarray. Got: {type(x)}")
117131
if not isinstance(y, np.ndarray):
118132
raise TypeError(f"y must be of type np.ndarray. Got: {type(y)}")
119133
if not isinstance(n, int):
120134
raise TypeError(f"n must be of type int. Got: {type(n)}")
121135

122-
# Get coeffcients of polynomial of order n
136+
# Get coefficients of polynomial of order n
123137
polynomial_coefficients = np.poly1d(np.polyfit(x, y, n))
124138

125-
# Calculate the coeffcient of determination
126-
slope, intercept, r_value, p_value, std_err = _linregress(
127-
y, polynomial_coefficients(x)
128-
)
129-
R2 = r_value**2
139+
# Calculate the coefficient of determination
140+
_, _, r_value, _, _ = _linregress(y, polynomial_coefficients(x))
141+
r_squared = r_value**2
130142

131-
return polynomial_coefficients, R2
143+
return polynomial_coefficients, r_squared
132144

133145

134-
def discharge_to_velocity(D, polynomial_coefficients, dimension="", to_pandas=True):
146+
# pylint: disable=too-many-arguments
147+
# pylint: disable=too-many-positional-arguments
148+
def discharge_to_velocity(
149+
discharge, polynomial_coefficients, dimension="", to_pandas=True
150+
):
135151
"""
136152
Calculates velocity given discharge data and the relationship between
137153
discharge and velocity at an individual turbine
138154
139155
Parameters
140156
------------
141-
D : numpy ndarray, pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
157+
discharge : numpy ndarray, pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
142158
Discharge data [m3/s] indexed by time [datetime or s]
143159
polynomial_coefficients : numpy polynomial
144160
List of polynomial coefficients that describe the relationship between
@@ -151,57 +167,58 @@ def discharge_to_velocity(D, polynomial_coefficients, dimension="", to_pandas=Tr
151167
152168
Returns
153169
------------
154-
V: pandas DataFrame or xarray Dataset
170+
velocity: pandas DataFrame or xarray Dataset
155171
Velocity [m/s] indexed by time [datetime or s]
156172
"""
157173
if not isinstance(polynomial_coefficients, np.poly1d):
158174
raise TypeError(
159-
f"polynomial_coefficients must be of type np.poly1d. Got: {type(polynomial_coefficients)}"
175+
"polynomial_coefficients must be of "
176+
f"type np.poly1d. Got: {type(polynomial_coefficients)}"
160177
)
161178
if not isinstance(dimension, str):
162179
raise TypeError(f"dimension must be of type str. Got: {type(dimension)}")
163180
if not isinstance(to_pandas, bool):
164181
raise TypeError(f"to_pandas must be of type str. Got: {type(to_pandas)}")
165182

166-
D = convert_to_dataarray(D)
183+
discharge = convert_to_dataarray(discharge)
167184

168185
if dimension == "":
169-
dimension = list(D.coords)[0]
186+
dimension = list(discharge.coords)[0]
170187

171188
# Calculate velocity using polynomial
172-
V = xr.DataArray(
173-
data=polynomial_coefficients(D),
189+
velocity = xr.DataArray(
190+
data=polynomial_coefficients(discharge),
174191
dims=dimension,
175-
coords={dimension: D[dimension]},
192+
coords={dimension: discharge[dimension]},
176193
)
177-
V.name = "V"
194+
velocity.name = "velocity"
178195

179-
V = V.to_dataset() # for matlab
196+
velocity = velocity.to_dataset() # for matlab
180197

181198
if to_pandas:
182-
V = V.to_pandas()
199+
velocity = velocity.to_pandas()
183200

184-
return V
201+
return velocity
185202

186203

187204
def velocity_to_power(
188-
V, polynomial_coefficients, cut_in, cut_out, dimension="", to_pandas=True
205+
velocity, polynomial_coefficients, cut_in, cut_out, dimension="", to_pandas=True
189206
):
190207
"""
191208
Calculates power given velocity data and the relationship
192209
between velocity and power from an individual turbine
193210
194211
Parameters
195212
----------
196-
V : numpy ndarray, pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
213+
velocity : numpy ndarray, pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
197214
Velocity [m/s] indexed by time [datetime or s]
198215
polynomial_coefficients : numpy polynomial
199216
List of polynomial coefficients that describe the relationship between
200217
velocity and power at an individual turbine
201218
cut_in: int/float
202-
Velocity values below cut_in are not used to compute P
219+
Velocity values below cut_in are not used to compute power
203220
cut_out: int/float
204-
Velocity values above cut_out are not used to compute P
221+
Velocity values above cut_out are not used to compute power
205222
dimension: string (optional)
206223
Name of the relevant xarray dimension. If not supplied,
207224
defaults to the first dimension. Does not affect pandas input.
@@ -210,12 +227,13 @@ def velocity_to_power(
210227
211228
Returns
212229
-------
213-
P : pandas DataFrame or xarray Dataset
230+
power : pandas DataFrame or xarray Dataset
214231
Power [W] indexed by time [datetime or s]
215232
"""
216233
if not isinstance(polynomial_coefficients, np.poly1d):
217234
raise TypeError(
218-
f"polynomial_coefficients must be of type np.poly1d. Got: {type(polynomial_coefficients)}"
235+
"polynomial_coefficients must be"
236+
f"of type np.poly1d. Got: {type(polynomial_coefficients)}"
219237
)
220238
if not isinstance(cut_in, (int, float)):
221239
raise TypeError(f"cut_in must be of type int or float. Got: {type(cut_in)}")
@@ -224,64 +242,66 @@ def velocity_to_power(
224242
if not isinstance(dimension, str):
225243
raise TypeError(f"dimension must be of type str. Got: {type(dimension)}")
226244
if not isinstance(to_pandas, bool):
227-
raise TypeError(f"to_pandas must be of type str. Got: {type(to_pandas)}")
245+
raise TypeError(f"to_pandas must be of type bool. Got: {type(to_pandas)}")
228246

229-
V = convert_to_dataarray(V)
247+
velocity = convert_to_dataarray(velocity)
230248

231249
if dimension == "":
232-
dimension = list(V.coords)[0]
250+
dimension = list(velocity.coords)[0]
233251

234-
# Calculate velocity using polynomial
235-
power = polynomial_coefficients(V)
252+
# Calculate power using polynomial
253+
power_values = polynomial_coefficients(velocity)
236254

237255
# Power for velocity values outside lower and upper bounds Turbine produces 0 power
238-
power[V < cut_in] = 0.0
239-
power[V > cut_out] = 0.0
256+
power_values[velocity < cut_in] = 0.0
257+
power_values[velocity > cut_out] = 0.0
240258

241-
P = xr.DataArray(data=power, dims=dimension, coords={dimension: V[dimension]})
242-
P.name = "P"
259+
power = xr.DataArray(
260+
data=power_values, dims=dimension, coords={dimension: velocity[dimension]}
261+
)
262+
power.name = "power"
243263

244-
P = P.to_dataset()
264+
power = power.to_dataset()
245265

246266
if to_pandas:
247-
P = P.to_pandas()
267+
power = power.to_pandas()
248268

249-
return P
269+
return power
250270

251271

252-
def energy_produced(P, seconds):
272+
def energy_produced(power_data, seconds):
253273
"""
254274
Returns the energy produced for a given time period provided
255275
exceedance probability and power.
256276
257277
Parameters
258278
----------
259-
P : numpy ndarray, pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
279+
power_data : numpy ndarray, pandas DataFrame, pandas Series, xarray DataArray, or xarray Dataset
260280
Power [W] indexed by time [datetime or s]
261281
seconds: int or float
262282
Seconds in the time period of interest
263283
264284
Returns
265285
-------
266-
E : float
286+
energy : float
267287
Energy [J] produced in the given length of time
268288
"""
269289
if not isinstance(seconds, (int, float)):
270290
raise TypeError(f"seconds must be of type int or float. Got: {type(seconds)}")
271291

272-
P = convert_to_dataarray(P)
292+
power_data = convert_to_dataarray(power_data)
273293

274-
# Calculate Histogram of power
275-
H, edges = np.histogram(P, 100)
294+
# Calculate histogram of power
295+
hist_values, edges = np.histogram(power_data, 100)
276296
# Create a distribution
277-
hist_dist = _rv_histogram([H, edges])
297+
hist_dist = _rv_histogram([hist_values, edges])
278298
# Sample range for pdf
279299
x = np.linspace(edges.min(), edges.max(), 1000)
280-
# Calculate the expected value of Power
281-
expected_val_of_power = np.trapz(x * hist_dist.pdf(x), x=x)
300+
# Calculate the expected value of power
301+
expected_power = np.trapz(x * hist_dist.pdf(x), x=x)
282302
# Note: Built-in Expected Value method often throws warning
283303
# EV = hist_dist.expect(lb=edges.min(), ub=edges.max())
284-
# Energy
285-
E = seconds * expected_val_of_power
304+
# Calculate energy
305+
energy = seconds * expected_power
286306

287-
return E
307+
return energy

0 commit comments

Comments
 (0)