-
Notifications
You must be signed in to change notification settings - Fork 5
Waves: add accessor for waves #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
735a62a
1d: convert to 2d
gauteh 10295f0
example: add example for interpolating to IMU observations
gauteh c4ba1af
waves: add waves accessor
gauteh 22f3768
WIP; fix axis overwriting
jerabaul29 e29c6ba
WIP; fix axis overwriting
jerabaul29 3e5308a
do not use exception to pop / generate ax
jerabaul29 98f011a
Fix doc generation requirement
jerabaul29 9cfade0
Update example, clean up, add labels etc
jerabaul29 fa4d346
Add handle to pcolor, update example
jerabaul29 4bee16e
Remove broken unused import
jerabaul29 d48427a
Remove old spectra plot test
jerabaul29 9ef2168
Hand edit doc api to pass CICD
jerabaul29 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
""" | ||
Finding the closeset or interpolated positions at given times (e.g. wave observations). | ||
======================================================================================= | ||
""" | ||
|
||
from pathlib import Path | ||
from trajan.readers.omb import read_omb_csv | ||
import xarray as xr | ||
import coloredlogs | ||
|
||
coloredlogs.install(level='debug') | ||
|
||
#%% | ||
# Read the data | ||
data = Path.cwd().parent / "tests" / "test_data" / "csv" / "omb3.csv" | ||
ds = read_omb_csv(data) | ||
print(ds) | ||
|
||
#%% | ||
# The wave data in the variable `pHs0` is given along a different observation dimension. | ||
# Because it is also a observation, i.e. in the style of 2D trajectory | ||
# datasets, we need to iterate over the trajectories: | ||
|
||
|
||
def gridwaves(tds): | ||
t = tds[['lat', 'lon', | ||
'time']].traj.gridtime(tds['time_waves_imu'].squeeze()) | ||
return t.traj.to_2d(obsdim='obs_waves_imu') | ||
|
||
|
||
dsw = ds.groupby('trajectory').map(gridwaves) | ||
|
||
print(dsw) | ||
|
||
#%% | ||
# We now have the positions interpolated to the IMU (wave) observations. We | ||
# could also merge these together to one dataset again: | ||
|
||
ds = xr.merge((ds, dsw.rename({ | ||
'lon': 'lon_waves', | ||
'lat': 'lat_waves' | ||
}).drop('time'))) | ||
print(ds) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
""" | ||
Plotting wave spectra data, using the accessor syntax | ||
================================================ | ||
""" | ||
|
||
# %% | ||
|
||
exit() | ||
|
||
# %% | ||
|
||
ipython3 | ||
|
||
# %% | ||
|
||
from pathlib import Path | ||
from trajan.readers.omb import read_omb_csv | ||
from trajan.plot.spectra import plot_trajan_spectra | ||
import coloredlogs | ||
import datetime | ||
import matplotlib.pyplot as plt | ||
|
||
# adjust the level of information printed | ||
# coloredlogs.install(level='error') | ||
coloredlogs.install(level='debug') | ||
|
||
# %% | ||
|
||
# load the data from an example file with several buoys and a bit of wave spectra data | ||
path_to_test_data = Path.cwd().parent / "tests" / "test_data" / "csv" / "omb3.csv" | ||
xr_data = read_omb_csv(path_to_test_data) | ||
|
||
# %% | ||
|
||
# if no axis is provided, an axis will be generated automatically | ||
|
||
xr_data.isel(trajectory=0).processed_elevation_energy_spectrum.wave.plot( | ||
xr_data.isel(trajectory=0).time_waves_imu.squeeze(), | ||
) | ||
|
||
plt.show() | ||
|
||
# %% | ||
|
||
# it is also possible to provide an axis on which to plot | ||
|
||
# a plot with 3 lines, 2 columns | ||
fig, ax = plt.subplots(3, 2) | ||
|
||
ax_out = xr_data.isel(trajectory=0).processed_elevation_energy_spectrum.wave.plot( | ||
xr_data.isel(trajectory=0).time_waves_imu.squeeze(), | ||
# plot on the second line, first column | ||
ax=ax[1, 0] | ||
) | ||
|
||
plt.show() | ||
|
||
# %% |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from numpy.testing import assert_almost_equal | ||
import numpy as np | ||
import trajan as ta | ||
import xarray as xr | ||
import pandas as pd | ||
|
||
def test_to2d(barents): | ||
# print(barents) | ||
gr = barents.traj.gridtime('1H') | ||
# print(gr) | ||
|
||
assert gr.traj.is_1d() | ||
|
||
b2d = gr.traj.to_2d() | ||
assert b2d.traj.is_2d() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import xarray as xr | ||
import logging | ||
import numpy as np | ||
|
||
from .plot import Plot | ||
|
||
# recommended by cf-xarray | ||
xr.set_options(keep_attrs=True) | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
@xr.register_dataarray_accessor('wave') | ||
class Wave: | ||
def __init__(self, ds): | ||
self.ds = ds | ||
self.__plot__ = None | ||
|
||
@property | ||
def plot(self) -> Plot: | ||
""" | ||
See :class:`trajan.waves.Plot`. | ||
""" | ||
if self.__plot__ is None: | ||
logger.debug(f'Setting up new plot object.') | ||
self.__plot__ = Plot(self.ds) | ||
|
||
return self.__plot__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import logging | ||
import matplotlib.pyplot as plt | ||
import cartopy.crs as ccrs | ||
import numpy as np | ||
import xarray as xr | ||
import cf_xarray as _ | ||
|
||
from trajan.accessor import detect_time_dim | ||
|
||
logger = logging.getLogger(__name__) | ||
logging.getLogger('matplotlib.font_manager').disabled = True | ||
|
||
|
||
class Plot: | ||
ds: xr.Dataset | ||
|
||
# A lon-lat projection with the currently used globe. | ||
gcrs = None | ||
|
||
DEFAULT_LINE_COLOR = 'gray' | ||
|
||
def __init__(self, ds): | ||
self.ds = ds | ||
|
||
def __call__(self, *args, **kwargs): | ||
if self.ds.attrs['standard_name'] == 'sea_surface_wave_variance_spectral_density': | ||
return self.spectra(*args, **kwargs) | ||
else: | ||
raise ValueError('Unknown wave variable') | ||
|
||
def spectra(self, time, *args, **kwargs): | ||
""" | ||
Plot the wave spectra information from a trajan compatible xarray. | ||
|
||
Args: | ||
|
||
time: DataArray with times. | ||
|
||
vrange: can be either: | ||
- None to use the default log range [-3.0, 1.0] | ||
- a tuple of float to set the log range explicitely | ||
|
||
`nseconds_gap`: float | ||
Number of seconds between 2 consecutive | ||
spectra for one instrument above which we consider that there is a | ||
data loss that should be filled with NaN. This is to avoid "stretching" | ||
neighboring spectra over long times if an instrument gets offline. | ||
|
||
Returns: | ||
|
||
ax: plt.Axes | ||
""" | ||
vrange = kwargs.pop('vrange', None) | ||
nseconds_gap = kwargs.pop('nseconds_gap', 6 * 3600) | ||
try: | ||
ax = kwargs.pop('ax') | ||
except: | ||
ax = plt.axes() | ||
jerabaul29 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if vrange is None: | ||
vmin_pcolor = -3.0 | ||
vmax_pcolor = 1.0 | ||
else: | ||
vmin_pcolor = vrange[0] | ||
vmax_pcolor = vrange[1] | ||
|
||
spectra_frequencies = self.ds.cf['wave_frequency'] | ||
|
||
crrt_spectra = self.ds.to_numpy() | ||
# crrt_spectra_times = detect_time_dim(self.ds, 'obs_waves_imu').to_numpy() | ||
crrt_spectra_times = time.to_numpy() | ||
|
||
list_datetimes = [] | ||
list_spectra = [] | ||
|
||
# avoid streching at the left | ||
list_datetimes.append( | ||
crrt_spectra_times[0] - np.timedelta64(2, 'm')) | ||
list_spectra.append(np.full(len(spectra_frequencies), np.nan)) | ||
|
||
for crrt_spectra_ind in range(1, crrt_spectra.shape[0], 1): | ||
if np.isnan(crrt_spectra_times[crrt_spectra_ind]): | ||
continue | ||
|
||
# if a gap with more than nseconds_gap seconds, fill with NaNs | ||
# to avoid stretching neighbors over missing data | ||
seconds_after_previous = float( | ||
crrt_spectra_times[crrt_spectra_ind] - crrt_spectra_times[crrt_spectra_ind-1]) / 1e9 | ||
if seconds_after_previous > nseconds_gap: | ||
logger.debug( | ||
f"spectrum index {crrt_spectra_ind} is {seconds_after_previous} seconds \ | ||
after the previous one; insert nan spectra in between to avoid stretching") | ||
list_datetimes.append( | ||
crrt_spectra_times[crrt_spectra_ind-1] + np.timedelta64(2, 'h')) | ||
list_spectra.append( | ||
np.full(len(spectra_frequencies), np.nan)) | ||
list_datetimes.append( | ||
crrt_spectra_times[crrt_spectra_ind] - np.timedelta64(2, 'h')) | ||
list_spectra.append( | ||
np.full(len(spectra_frequencies), np.nan)) | ||
|
||
list_spectra.append(crrt_spectra[crrt_spectra_ind, :]) | ||
list_datetimes.append(crrt_spectra_times[crrt_spectra_ind]) | ||
|
||
# avoid stretching at the right | ||
last_datetime = list_datetimes[-1] | ||
list_datetimes.append(last_datetime + np.timedelta64(2, 'm')) | ||
list_spectra.append(np.full(len(spectra_frequencies), np.nan)) | ||
|
||
pclr = ax.pcolor(list_datetimes, spectra_frequencies, np.log10( | ||
np.transpose(np.array(list_spectra))), vmin=vmin_pcolor, vmax=vmax_pcolor) | ||
|
||
return ax | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.