Skip to content

Commit

Permalink
Merge pull request #59 from kthyng/more_general
Browse files Browse the repository at this point in the history
Making the codebase more general
  • Loading branch information
kthyng authored Sep 11, 2023
2 parents 894e95c + c12c07e commit 7750997
Show file tree
Hide file tree
Showing 21 changed files with 2,194 additions and 448 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ repos:
rev: v0.982
hooks:
- id: mypy
additional_dependencies: [types-setuptools, types-PyYAML, types-requests]
additional_dependencies: [types-setuptools, types-PyYAML, types-requests, types-DateTimeRange]
exclude: docs/source/conf.py
args: [--ignore-missing-imports]

Expand Down
3 changes: 3 additions & 0 deletions ci/environment-py3.10.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ dependencies:
############## These will have to be adjusted to your specific project
# - cf_pandas
- cf_xarray
- cmocean
- datetimerange
- extract_model
# - intake
# - intake-axds
# - intake-erddap
- matplotlib-base
- numpy
- pandas
- pyproj
- scipy
- xarray
##############
Expand Down
3 changes: 3 additions & 0 deletions ci/environment-py3.8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ dependencies:
############## These will have to be adjusted to your specific project
# - cf_pandas
- cf_xarray
- cmocean
- datetimerange
- extract_model
# - intake
# - intake-axds
# - intake-erddap
- matplotlib-base
- numpy
- pandas
- pyproj
- scipy
- xarray
##############
Expand Down
3 changes: 3 additions & 0 deletions ci/environment-py3.9.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ dependencies:
############## These will have to be adjusted to your specific project
# - cf_pandas
- cf_xarray
- cmocean
- datetimerange
- extract_model
# - intake
# - intake-axds
# - intake-erddap
- matplotlib-base
- numpy
- pandas
- pyproj
- scipy
- xarray
##############
Expand Down
3 changes: 3 additions & 0 deletions docs/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ dependencies:
- cartopy
# - cf_pandas
- cf_xarray
- cmocean
- datetimerange
- extract_model
- intake
# - intake-axds
Expand All @@ -20,6 +22,7 @@ dependencies:
# These are needed for the docs themselves
- jupytext
- numpydoc
- pyproj
- requests
- sphinx
- sphinx-markdown-tables
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ To install from PyPI:
:caption: For contributors

developer.md
whats_new
GitHub repository <https://github.com/axiom-data-science/ocean-model-skill-assessor>


Expand Down
5 changes: 5 additions & 0 deletions docs/whats_new.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# What's New

## unreleased version

* `omsa.run` now saves the polygon found for the input model into the project directory.
4 changes: 4 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ dependencies:
- aiohttp
# - cf_pandas
- cf_xarray
- cmocean
- datetimerange
- extract_model
- intake
# - intake-axds
# - intake-erddap
- intake-xarray
- matplotlib-base
- oceans
- pandas
- pip
- pyproj
- requests
- scipy
- xarray
Expand Down
150 changes: 138 additions & 12 deletions ocean_model_skill_assessor/accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,168 @@
Class to facilitate some functions directly on DataFrames.
"""

from pandas import DatetimeIndex
import pandas as pd
import xarray as xr

# from pandas import DatetimeIndex
from pandas.api.extensions import register_dataframe_accessor

from ocean_model_skill_assessor.plot import time_series
from ocean_model_skill_assessor.plot import line, scatter, surface

from .stats import compute_stats


@register_dataframe_accessor("omsa")
@xr.register_dataset_accessor("omsa")
class SkillAssessorAccessor:
"""Class to facilitate some functions directly on DataFrames."""

def __init__(self, df):
def __init__(self, dd):
"""
don't validate with this because might not be time series
Parameters
----------
pandas_obj: DataFrame
Should be observations, could be unloaded dask dataframe
obj: DataFrame or Dataset.
Should be observations and model, could be unloaded dask dataframe
"""
self._validate(df)
self.df = df
# if isinstance(dd, pd.DataFrame):
# self._validate(dd)
self.dd = dd

@staticmethod
def _validate(df):
def _validate(dd):
"""DataFrame must have datetimes as index."""
if not isinstance(df.index, DatetimeIndex):
if not isinstance(dd.index, pd.DatetimeIndex):
raise TypeError("DataFrame index must be datetimes")

@property
def compute_stats(self):
"""Run `compute_stats` on DataFrame."""
if not hasattr(self, "_compute_stats"):
stats = compute_stats(self.df["obs"], self.df["model"])
stats = compute_stats(self.dd["obs"], self.dd["model"])
self._compute_stats = stats
return self._compute_stats

def plot(self, **kwargs):
def plot(self, featuretype=None, key_variable=None, **kwargs):
"""Plot."""
time_series.plot(self.df["obs"], self.df["model"], **kwargs)
# import pdb; pdb.set_trace()
import xcmocean

# cmap and cmapdiff
da = xr.DataArray(name=key_variable)

# use featuretype to determine plot type, otherwise assume time series
with xr.set_options(cmap_sequential=da.cmo.seq, cmap_divergent=da.cmo.div):
if featuretype is not None:
if featuretype == "timeSeries":
xname, yname, zname = (
self.dd.index.name or "index",
["obs", "model"],
None,
)
xlabel, ylabel = "", key_variable
# xname, yname, zname = self.dd.cf["T"].name, ["obs","model"], None
# import pdb; pdb.set_trace()
line.plot(
self.dd.reset_index(),
xname,
yname,
xlabel=xlabel,
ylabel=ylabel,
figsize=(15, 5),
**kwargs
)
elif featuretype == "trajectoryProfile":
xname, yname, zname = "distance", "Z", ["obs", "model"]
surface.plot(
self.dd.reset_index(),
xname,
yname,
zname,
kind="scatter",
**kwargs
)
# surface.plot(xname, yname, self.dd["obs"], self.dd["model"], kind="scatter", **kwargs)
# scatter.plot(self.dd["obs"], self.dd["model"], **kwargs)
elif featuretype == "timeSeriesProfile":
xname, yname, zname = "T", "Z", ["obs", "model"]
surface.plot(
self.dd.reset_index(),
xname,
yname,
zname,
kind="pcolormesh",
**kwargs
)
# surface.plot(xname, yname, self.dd["obs"].squeeze(), self.dd["model"].squeeze(), **kwargs)
elif featuretype == "profile":
# use transpose so that index depth is plotted on y axis instead of x axis
# import pdb; pdb.set_trace()
xname, yname, zname = (
["obs", "model"],
self.dd.index.name or "index",
None,
)
# import pdb; pdb.set_trace()
xlabel, ylabel = key_variable, yname
# xname, yname, zname = ["obs","model"], self.dd.cf["Z"].name, None
line.plot(
self.dd.reset_index(),
xname,
yname,
xlabel=xlabel,
ylabel=ylabel,
figsize=(4, 8),
**kwargs
)
else:
xname, yname, zname = "index", ["obs", "model"], None
line.plot(
self.dd.reset_index(), xname, yname, figsize=(15, 5), **kwargs
)
# time_series.plot(self.dd["obs"], self.dd["model"], **kwargs)


# @xr.register_dataset_accessor("omsa")
# class SkillAssessorAccessor:
# """Class to facilitate some functions directly on Datasets."""

# def __init__(self, ds):
# """
# Parameters
# ----------
# xarray_obj: Dataset
# Should be observations and model, could be unloaded dask dataframe
# """
# self._validate(ds)
# self.df = ds

# # @staticmethod
# # def _validate(df):
# # """DataFrame must have datetimes as index."""
# # if not isinstance(df.index, DatetimeIndex):
# # raise TypeError("DataFrame index must be datetimes")

# @property
# def compute_stats(self):
# """Run `compute_stats` on Dataset"""
# if not hasattr(self, "_compute_stats"):
# stats = compute_stats(self.ds["obs"], self.ds["model"])
# self._compute_stats = stats
# return self._compute_stats

# def plot(self, featuretype=None, **kwargs):
# """Plot."""

# # use featuretype to determine plot type, otherwise assume time series
# if featuretype is not None:
# if featuretype == "timeSeries":
# time_series.plot(self.df["obs"], self.df["model"], **kwargs)
# elif featuretype == "trajectoryProfile":
# scatter.plot(self.df["obs"], self.df["model"], **kwargs)
# elif featuretype == "timeSeriesProfile":
# surface.plot(self.df["obs"], self.df["model"], **kwargs)
# else:
# time_series.plot(self.df["obs"], self.df["model"], **kwargs)
Loading

0 comments on commit 7750997

Please sign in to comment.