MHKiT-Software / MHKiT-Python

MHKiT-Python provides the marine renewable energy (MRE) community tools for data processing, visualization, quality control, resource assessment, and device performance.
https://mhkit-software.github.io/MHKiT/
BSD 3-Clause "New" or "Revised" License
47 stars 45 forks source link

NOAA: Wave Watch 3 #233

Closed ssolson closed 7 months ago

ssolson commented 1 year ago

NOAA offers Wave Watch 3 data here: https://pae-paha.pacioos.hawaii.edu/erddap/griddap/ww3_global.html

This PR will address the request made by @ryancoe to add NOAA: Wave Watch 3 data requests by building off Ryan's ww3 feature-branch (https://github.com/ryancoe/MHKiT-Python/tree/getWW3) in the superceeded PR #65 .

Additoinal discussion has taken place on the CLC Generator Tool: https://github.com/SNL-WaterPower/DLCgenerator/issues/10

ssolson commented 1 year ago

Accessing and Visualizing WW3 Data Using erddap-python and xarray

In my research, I found that there are a few Python packages specifically designed for handling ERDDAP data. One such package is erddap-python, which seems straightforward to use.

Here's an example of how to access and visualize WW3 data using erddap-python:

Step 1: Install erddap-python

pip install erddap-python

Step 2: Search for "WW3" on the ERDDAP server

from erddapClient import ERDDAP_Server

remote = ERDDAP_Server('https://coastwatch.pfeg.noaa.gov/erddap')
searchResults = remote.search(searchFor="WW3")
ww3 = searchResults[0]

print("Search results:", searchResults)
print(ww3)

Search results: Results: 1 [ 0 - NWW3_Global_Best , "WaveWatch III (WW3) Global Wave Model" ]

Title: WaveWatch III (WW3) Global Wave Model Server URL: https://coastwatch.pfeg.noaa.gov/erddap Dataset ID: NWW3_Global_Best Dimensions: ... ...

The selected values from the print statement are shown below. We get 1 search result. This gives us a single search result of type Griddap, with the Dataset ID NWW3_Global_Best. Note: I have found it best to request a netcdf. Store it locally and then open that data using xarray.

Step 3: Access the WW3 dataset and save it as a NetCDF file

import xarray as xr
from erddapClient import ERDDAP_Griddap

remote = ERDDAP_Griddap('https://coastwatch.pfeg.noaa.gov/erddap', 'NWW3_Global_Best')

ds = (
    remote.setResultVariables(['Tper']).setSubset(
        time=slice('2011-01-01','2011-01-02'),
        depth=0,
        latitude=slice(-77.5,77.5),
        longitude=slice(0, 359.5)
    )
    .getData(filetype='nc')
)

print("Writing to file" )
with open(path,'wb') as fb:
    fb.write(ds)

ds = xr.open_dataset('ww3.nc')

Step 4: Plot the mean Tper

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 2.5))
mean_Tper = ds['Tper'].mean('time')
mean_Tper = mean_Tper.transpose('latitude', 'longitude')
mean_Tper = mean_Tper.isel(depth=0)
mean_Tper.plot.contourf(x='longitude', y='latitude')
plt.show()

image

Additional information

The following print statements provide more information about the dataset, dimensions, and variables which were used to form the setSubset in the original ds request.

from erddapClient import ERDDAP_Griddap

remote = ERDDAP_Griddap('https://coastwatch.pfeg.noaa.gov/erddap', 'NWW3_Global_Best')
print("remote", remote)
print(remote.dimensions)
print(remote.dimensions['depth'].data)
print("variables:", remote.variables.keys())
print("summary:", remote.info['summary'])
print("start:", remote.getAttribute('time_coverage_start'))

I encountered issues using the .getxArray() method, so I recommend using .getData(filetype='nc') as shown above.

@ryancoe, have you tried this package? What are your thoughts on the example provided here, and how MHKiT could better serve this data to the Marine Energy industry?

ryancoe commented 1 year ago

@ssolson - I haven't tried that. Very cool!

Graham-EGI commented 1 year ago

@ssolson this looks very useful!

My feedback in how it could relate to the DLC tool:

  1. Would it be possible to have a function that doesn't write the file to disk? Potentially using io.BytesIO() to read the stream into a file-like object and then read that into xarray from the .nc file response? Xarray may need an engine argument to open_dataset. See notes under filename_or_obj here.
  2. Is there a unique identifier in the data that can be used to collect all years of data for a specific grid point? I believe I recall this to be a grid of hindcast points. For example, DOE WPTO 32-year hindcast data has a GID for each grid point that is unique for each region that data is available for. Or would it just need to be the lat/lon coordinates of a given grid point?
ssolson commented 1 year ago

@Graham-EGI Yes you can request an array object although as mentioned in my post above I was having some trouble working with the data when returned that way. The API documentation for the tool I used is here: https://hmedrano.github.io/erddap-python/#ERDDAP_Griddap

Looking at my example above you simply change: .getData(filetype='nc') to .getxArray()

I would have done more testing however the WW3 data is down today. I might have additionally tested https://github.com/ioos/erddapy to see if I had better luck with that tool.

The ERDDAP grid data is accessed by unique lat and long Looking at the NOAA frontend: https://coastwatch.pfeg.noaa.gov/erddap/griddap/NWW3_Global_Best.html We can see the reported spacing of 0.5 image

ssolson commented 7 months ago

Closing for now. Will reopen if there is interest.