Skip to content

Commit 24674f1

Browse files
authored
Merge pull request #337 from MHKiT-Software/develop
# MHKiT v0.8.1 MHKiT v0.8.1, includes bug fixes in the example notebooks and fixes the dependencies to requirements updates prior to Numpy 2.0.0. Fixes MHKIT v0.8.0 installation issues (#334) by fixing the dependencies. - #335 Fixes bugs in MHKiT example notebooks - #327
2 parents 83a9d6d + 089766b commit 24674f1

22 files changed

+387904
-388632
lines changed

environment.yml

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ channels:
33
- conda-forge
44
- defaults
55
dependencies:
6-
- python>=3.8
6+
- python>=3.8,<3.12
7+
- pip
78
- pandas>=1.0.0
8-
- numpy>=1.21.0
9-
- scipy
9+
- numpy>=1.21.0, <2.0.0
10+
- scipy<=1.13.1
1011
- matplotlib
1112
- requests
1213
- lxml
@@ -16,10 +17,11 @@ dependencies:
1617
- beautifulsoup4
1718
- xarray
1819
- h5py>=3.6.0
19-
- netcdf4>=1.5.8
20+
- netcdf4>=1.5.8, <=1.6.5
2021
- pip:
2122
- pecos>=0.3.0
2223
- fatpack
2324
- NREL-rex>=0.2.63
2425
- h5pyd>=0.7.0
2526
- six>=1.13.0
27+
- notebook

examples/ADCP_Delft3D_TRTS_example.ipynb

+447-434
Large diffs are not rendered by default.

examples/PacWave_resource_characterization_example.ipynb

+94-100
Large diffs are not rendered by default.

examples/cdip_example.ipynb

+129-160
Large diffs are not rendered by default.

examples/metocean_example.ipynb

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"cell_type": "markdown",
4141
"metadata": {},
4242
"source": [
43-
"# 1. Request Continuous Wind Data from NDBC\n",
43+
"## 1. Request Continuous Wind Data from NDBC\n",
4444
" \n",
4545
"MHKiT can be used to request historical data from the National Data Buoy Center ([NDBC](https://www.ndbc.noaa.gov/)). This process is split into the following steps:\n",
4646
"\n",
@@ -1098,7 +1098,7 @@
10981098
"name": "python",
10991099
"nbconvert_exporter": "python",
11001100
"pygments_lexer": "ipython3",
1101-
"version": "3.9.12"
1101+
"version": "3.9.17"
11021102
}
11031103
},
11041104
"nbformat": 4,

examples/mooring_example.ipynb

+387,153-387,839
Large diffs are not rendered by default.

examples/tidal_example.ipynb

+27-60
Large diffs are not rendered by default.

mhkit/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# Ignore future warnings
1818
_warn.simplefilter(action="ignore", category=FutureWarning)
1919

20-
__version__ = "v0.8.0"
20+
__version__ = "v0.8.1"
2121

2222
__copyright__ = """
2323
Copyright 2019, Alliance for Sustainable Energy, LLC under the terms of

mhkit/loads/extreme/extremes.py

+1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ def short_term_extreme(
241241
short_term_extreme_dist = fit_maxima(maxima)
242242
else:
243243
print("Passed `method` not found.")
244+
short_term_extreme_dist = None
244245
return short_term_extreme_dist
245246

246247

mhkit/mooring/io.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
"""
2-
io.py
3-
42
This module provides functions to read and parse MoorDyn output files.
53
64
The main function read_moordyn takes as input the path to a MoorDyn output file and optionally

mhkit/power/quality.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ def harmonics(
107107
hertz = np.arange(0, 3060, 5)
108108
elif grid_freq == 50:
109109
hertz = np.arange(0, 2570, 5)
110+
else:
111+
raise ValueError(f"grid_freq must be either 50 or 60. Got {grid_freq}")
110112

111113
harmonic_amplitudes = harmonic_amplitudes.reindex(
112114
{"frequency": hertz}, method="nearest"
@@ -322,7 +324,11 @@ def interharmonics(
322324
+ f"xr.DataArray, or xr.Dataset. Got {type(harmonic_amplitudes)}"
323325
)
324326

325-
if grid_freq not in [50, 60]:
327+
if grid_freq == 60:
328+
hertz = np.arange(0, 3060, 60)
329+
elif grid_freq == 50:
330+
hertz = np.arange(0, 2550, 50)
331+
else:
326332
raise ValueError(f"grid_freq must be either 50 or 60. Got {grid_freq}")
327333

328334
if not isinstance(to_pandas, bool):
@@ -340,11 +346,6 @@ def interharmonics(
340346
+ f"of harmonic_amplitudes. Got {frequency_dimension}"
341347
)
342348

343-
if grid_freq == 60:
344-
hertz = np.arange(0, 3060, 60)
345-
elif grid_freq == 50:
346-
hertz = np.arange(0, 2550, 50)
347-
348349
# Sort input data index
349350
if frequency_dimension == "":
350351
frequency_dimension = list(harmonic_amplitudes.dims)[0]

mhkit/tests/mooring/test_mooring.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def test_animate_2d_update(self):
8686
y_data = self.dsani[nodes_y[0]].isel(Time=frame).values
8787

8888
# Manually set the data for the line object
89-
line.set_data(x_data, y_data)
89+
line.set_data([x_data], [y_data])
9090

9191
# Extract updated data from the line object
9292
updated_x, updated_y = line.get_data()
@@ -126,7 +126,7 @@ def test_animate_3d_update(self):
126126
z_data = self.dsani[nodes_z[0]].isel(Time=frame).values
127127

128128
# Manually set the data for the line object
129-
line.set_data(x_data, y_data)
129+
line.set_data([x_data], [y_data])
130130
line.set_3d_properties(z_data)
131131

132132
# Extract updated data from the line object

mhkit/tests/tidal/test_io.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ def test_load_noaa_data_xarray(self):
5959
"""
6060
file_name = join(datadir, "s08010.json")
6161
data = tidal.io.noaa.read_noaa_json(file_name, to_pandas=False)
62-
self.assertTrue(np.all(list(data.variables) == ["index", "s", "d", "b"]))
62+
# Check if the variable sets are equal
63+
data_variables = list(data.variables)
64+
required_variables = ["index", "s", "d", "b"]
65+
data_variables_set = set(data_variables)
66+
required_variables_set = set(required_variables)
67+
self.assertTrue(data_variables_set == required_variables_set)
6368
self.assertEqual(len(data["index"]), 18890)
6469
self.assertEqual(data.attrs["id"], "s08010")
6570

@@ -96,7 +101,12 @@ def test_request_noaa_data_basic_xarray(self):
96101
write_json=None,
97102
to_pandas=False,
98103
)
99-
self.assertTrue(np.all(list(data.variables) == ["index", "s", "d", "b"]))
104+
# Check if the variable sets are equal
105+
data_variables = list(data.variables)
106+
required_variables = ["index", "s", "d", "b"]
107+
data_variables_set = set(data_variables)
108+
required_variables_set = set(required_variables)
109+
self.assertTrue(data_variables_set == required_variables_set)
100110
self.assertEqual(len(data["index"]), 183)
101111
self.assertEqual(data.attrs["id"], "s08010")
102112

mhkit/tests/wave/io/hindcast/test_hindcast.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ def setUpClass(cls):
7171
cls.mp = pd.read_csv(
7272
join(datadir, "hindcast/multiparm.csv"),
7373
index_col="time_index",
74-
names=["time_index", "energy_period_87", "mean_zero-crossing_period_87"],
74+
names=["time_index", "energy_period_0", "mean_zero-crossing_period_0"],
7575
header=0,
7676
dtype={
77-
"energy_period_87": "float32",
78-
"mean_zero-crossing_period_87": "float32",
77+
"energy_period_0": "float32",
78+
"mean_zero-crossing_period_0": "float32",
7979
},
8080
)
8181
cls.mp.index = pd.to_datetime(cls.mp.index)

mhkit/tidal/graphics.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ def plot_current_timeseries(
331331

332332
if not isinstance(principal_direction, (int, float)):
333333
raise TypeError("principal_direction must be of type int or float")
334-
if (principal_direction < 0) and (principal_direction > 360):
334+
if (principal_direction < 0) or (principal_direction > 360):
335335
raise ValueError("principal_direction must be between 0 and 360 degrees")
336336

337337
# Rotate coordinate system by supplied principal_direction

mhkit/tidal/io/noaa.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
This module provides functions to fetch, process, and read NOAA (National
55
Oceanic and Atmospheric Administration) current data directly from the
6-
NOAA Tides and Currents API (https://tidesandcurrents.noaa.gov/api/). It
6+
NOAA Tides and Currents API (https://api.tidesandcurrents.noaa.gov/api/prod/). It
77
supports loading data into a pandas DataFrame, handling data in XML and
88
JSON formats, and writing data to a JSON file.
99
@@ -46,9 +46,9 @@ def request_noaa_data(
4646
to_pandas=True,
4747
):
4848
"""
49-
Loads NOAA current data directly from https://tidesandcurrents.noaa.gov/api/
49+
Loads NOAA current data directly from https://api.tidesandcurrents.noaa.gov/api/prod/
5050
into a pandas DataFrame. NOAA sets max of 31 days between start and end date.
51-
See https://co-ops.nos.noaa.gov/api/ for options. All times are reported as
51+
See https://api.tidesandcurrents.noaa.gov/api/prod/ for options. All times are reported as
5252
GMT and metric units are returned for data. Uses cached data if available.
5353
5454
The request URL prints to the screen.

mhkit/utils/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .time_utils import matlab_to_datetime, excel_to_datetime
1+
from .time_utils import matlab_to_datetime, excel_to_datetime, index_to_datetime
22
from .stat_utils import (
33
get_statistics,
44
vector_statistics,

mhkit/utils/time_utils.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import datetime as dt
22
import pandas as pd
33
import numpy as np
4+
from pecos.utils import index_to_datetime
45

56

67
def matlab_to_datetime(matlab_datenum):

mhkit/wave/io/hindcast/hindcast.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def request_wpto_point_data(
239239
gid = rex_waves.lat_lon_gid(lat_lon)
240240
cols = temp_data.columns[:]
241241
for i, col in zip(range(len(cols)), cols):
242-
temp = f"{param}_{gid}"
242+
temp = f"{param}_{i}"
243243
temp_data = temp_data.rename(columns={col: temp})
244244

245245
data_list.append(temp_data)
@@ -263,7 +263,7 @@ def request_wpto_point_data(
263263
data["time_index"] = pd.to_datetime(data.time_index)
264264

265265
if isinstance(parameter, list):
266-
param_coords = [f"{param}_{gid}" for param in parameter]
266+
param_coords = [f"{param}_{i}" for param in parameter]
267267
data.coords["parameter"] = xr.DataArray(
268268
param_coords, dims="parameter"
269269
)
@@ -433,7 +433,7 @@ def request_wpto_directional_spectrum(
433433
else:
434434
break
435435

436-
ax1 = np.product(data_array.shape[:3])
436+
ax1 = np.prod(data_array.shape[:3])
437437
ax2 = data_array.shape[-1] if len(data_array.shape) == 4 else 1
438438
datas[i] = pd.DataFrame(
439439
data_array.reshape(ax1, ax2), columns=columns, index=idx

mhkit/wave/performance.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def capture_length_matrix(Hm0, Te, L, statistic, Hm0_bins, Te_bins, to_pandas=Tr
167167
Te = convert_to_dataarray(Te)
168168
L = convert_to_dataarray(L)
169169

170-
if not isinstance(statistic, (str, types.FunctionType)):
170+
if not (isinstance(statistic, str) or callable(statistic)):
171171
raise TypeError(
172172
f"statistic must be of type str or callable. Got: {type(statistic)}"
173173
)
@@ -219,7 +219,8 @@ def wave_energy_flux_matrix(Hm0, Te, J, statistic, Hm0_bins, Te_bins, to_pandas=
219219
Hm0 = convert_to_dataarray(Hm0)
220220
Te = convert_to_dataarray(Te)
221221
J = convert_to_dataarray(J)
222-
if not isinstance(statistic, (str, callable)):
222+
223+
if not (isinstance(statistic, str) or callable(statistic)):
223224
raise TypeError(
224225
f"statistic must be of type str or callable. Got: {type(statistic)}"
225226
)

requirements.txt

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pandas>=1.0.0
2-
numpy>=1.21.0
3-
scipy
2+
numpy>=1.21.0, <2.0.0
3+
scipy<=1.13.1
44
matplotlib
55
requests
66
pecos>=0.3.0
@@ -11,8 +11,9 @@ NREL-rex>=0.2.63
1111
six>=1.13.0
1212
h5py>=3.6.0
1313
h5pyd>=0.7.0
14-
netCDF4>=1.5.8
14+
netCDF4>=1.5.8, <=1.6.5
1515
xarray
1616
statsmodels
1717
bottleneck
1818
beautifulsoup4
19+
notebook

setup.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
]
2020
DEPENDENCIES = [
2121
"pandas>=1.0.0",
22-
"numpy>=1.21.0",
23-
"scipy",
22+
"numpy>=1.21.0, <2.0.0",
23+
"scipy<=1.13.1",
2424
"matplotlib",
2525
"requests",
2626
"pecos>=0.3.0",
@@ -31,7 +31,7 @@
3131
"six>=1.13.0",
3232
"h5py>=3.6.0",
3333
"h5pyd >=0.7.0",
34-
"netCDF4",
34+
"netCDF4>=1.5.8, <=1.6.5",
3535
"xarray",
3636
"statsmodels",
3737
"pytz",
@@ -57,7 +57,7 @@
5757
5858
Installation
5959
------------------------
60-
MHKiT-Python requires Python (3.7, 3.8, or 3.9) along with several Python
60+
MHKiT-Python requires Python (3.8, 3.9, 3.10, or 3.11) along with several Python
6161
package dependencies. MHKiT-Python can be installed from PyPI using the command ``pip install mhkit``.
6262
See [installation instructions](https://mhkit-software.github.io/MHKiT/installation.html) for more information.
6363

0 commit comments

Comments
 (0)