Skip to content
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

Refactor time operations #87

Merged
merged 36 commits into from
Sep 9, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
269a2f9
Add operator support to time preproc
Jun 13, 2019
33506ee
Refactored time
Jun 17, 2019
52e6802
Fix codacy issues
Jun 17, 2019
e08a3a5
Add guess bounds and rename clim
Jun 17, 2019
3856d21
Fix climate statistics
Jun 18, 2019
449d2bc
Fix documentation and tests
Jun 18, 2019
15ae7c7
Fix missing doc
Jun 18, 2019
31226e4
Fix format
Jun 18, 2019
5d35366
Update esmvalcore/preprocessor/_time.py
Jun 19, 2019
0bc255b
Update esmvalcore/preprocessor/_time.py
Jun 19, 2019
5e79de7
Update esmvalcore/preprocessor/_time.py
Jun 19, 2019
90e3d9a
Update esmvalcore/preprocessor/_time.py
Jun 19, 2019
4ccb505
Update esmvalcore/preprocessor/_time.py
Jun 19, 2019
6240469
Update esmvalcore/preprocessor/_time.py
Jun 19, 2019
c7da35b
Merge branch 'development' of https://github.com/ESMValGroup/ESMValCo…
Jun 19, 2019
72c7c4c
Merge branch 'development' of https://github.com/ESMValGroup/ESMValCo…
Jul 2, 2019
2997c62
Updated doc
Jul 2, 2019
af87ec3
Fix lint
Jul 2, 2019
cf7a2a7
Update time functions references
Jul 2, 2019
cd62cd1
Address bouwe comments
Jul 4, 2019
e1769ff
Merge branch 'development' of https://github.com/ESMValGroup/ESMValCo…
Aug 8, 2019
530e111
Add new doc
Aug 8, 2019
8dc7ae5
Fix doc error
Aug 8, 2019
a358175
Small doc change
Aug 12, 2019
bfe1456
Add anomalies computation
Aug 20, 2019
22c7597
Add anomalies doc
Aug 20, 2019
20d3673
Fix some broadcasting problems
Aug 20, 2019
c4344d2
use dask
Aug 22, 2019
ed28733
Add anomalies
Aug 23, 2019
26329be
Address comments
Aug 23, 2019
9c9935b
Apply suggestions from code review
Aug 23, 2019
33eaa4f
Merge branch 'development' of https://github.com/ESMValGroup/ESMValCo…
Aug 27, 2019
d388a4b
Fix flake 8 error
Aug 27, 2019
ddc1137
Apply suggestions from code review
Aug 28, 2019
95ac988
Remove variance
Aug 29, 2019
84cc65f
Fix error
Aug 29, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions esmvalcore/preprocessor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
from ._reformat import (cmor_check_data, cmor_check_metadata, fix_data,
fix_file, fix_metadata)
from ._regrid import extract_levels, regrid
from ._time import (annual_mean, extract_month, extract_season, extract_time,
regrid_time, seasonal_mean, time_average)
from ._time import (extract_month, extract_season, extract_time, regrid_time,
daily_statistics, monthly_statistics, seasonal_statistics,
annual_statistics, decadal_statistics,
climate_statistics)
from ._volume import (volume_statistics, depth_integration, extract_trajectory,
extract_transect, extract_volume)

Expand Down Expand Up @@ -77,9 +79,12 @@
# 'annual_cycle': annual_cycle,
# 'diurnal_cycle': diurnal_cycle,
'zonal_means',
'annual_mean',
'seasonal_mean',
'time_average',
'daily_statistics',
'monthly_statistics',
'seasonal_statistics',
'annual_statistics',
'decadal_statistics',
'climate_statistics',
'regrid_time',
'cmor_check_data',
# Save to file
Expand Down
44 changes: 2 additions & 42 deletions esmvalcore/preprocessor/_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,11 @@

import iris
from dask import array as da
from ._shared import guess_bounds, get_iris_analysis_operation

logger = logging.getLogger(__name__)


# guess bounds tool
def _guess_bounds(cube, coords):
"""Guess bounds of a cube, or not."""
# check for bounds just in case
for coord in coords:
if not cube.coord(coord).has_bounds():
cube.coord(coord).guess_bounds()
return cube


# slice cube over a restricted area (box)
def extract_region(cube, start_longitude, end_longitude, start_latitude,
end_latitude):
Expand Down Expand Up @@ -72,37 +63,6 @@ def extract_region(cube, start_longitude, end_longitude, start_latitude,
return cube.copy(data)


def get_iris_analysis_operation(operator):
"""
Determine the iris analysis operator from a string.

Map string to functional operator.

Parameters
----------
operator: str
A named operator.

Returns
-------
function: A function from iris.analysis

Raises
------
ValueError
operator not in allowed operators list.
allowed operators: mean, median, std_dev, variance, min, max
"""
operators = ['mean', 'median', 'std_dev', 'variance', 'min', 'max']
operator = operator.lower()
if operator not in operators:
raise ValueError("operator {} not recognised. "
"Accepted values are: {}."
"".format(operator, ', '.join(operators)))
operation = getattr(iris.analysis, operator.upper())
return operation


def zonal_means(cube, coordinate, mean_type):
"""
Get zonal means.
Expand Down Expand Up @@ -230,7 +190,7 @@ def area_statistics(cube, operator, fx_files=None):

coord_names = ['longitude', 'latitude']
if grid_areas is None or not grid_areas.any():
cube = _guess_bounds(cube, coord_names)
cube = guess_bounds(cube, coord_names)
grid_areas = iris.analysis.cartography.area_weights(cube)
logger.info('Calculated grid area shape: %s', grid_areas.shape)

Expand Down
71 changes: 71 additions & 0 deletions esmvalcore/preprocessor/_shared.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""
Shared functions for preprocessor.

Utility functions that can be used for multiple preprocessor steps
"""
import logging

import iris
import iris.analysis

logger = logging.getLogger(__name__)


# guess bounds tool
def guess_bounds(cube, coords):
"""Guess bounds of a cube, or not."""
# check for bounds just in case
for coord in coords:
if not cube.coord(coord).has_bounds():
cube.coord(coord).guess_bounds()
return cube


def get_iris_analysis_operation(operator):
"""
Determine the iris analysis operator from a string.

Map string to functional operator.

Parameters
----------
operator: str
A named operator.

Returns
-------
function: A function from iris.analysis

Raises
------
ValueError
operator not in allowed operators list.
allowed operators: mean, median, std_dev, variance, min, max
"""
operators = ['mean', 'median', 'std_dev', 'variance', 'min', 'max']
operator = operator.lower()
if operator not in operators:
raise ValueError("operator {} not recognised. "
"Accepted values are: {}."
"".format(operator, ', '.join(operators)))
operation = getattr(iris.analysis, operator.upper())
return operation


def operator_accept_weights(operator):
"""
Get if operator support weights.

Parameters
----------
operator: str
A named operator.

Returns
-------
bool: True if operator support weights, False otherwise

"""
if operator.lower() in ('mean',):
return True
return False
Loading