Skip to content

Commit 2d1e8dd

Browse files
authored
Merge pull request #79 from ESMValGroup/development
Release v2.0.0a1
2 parents 307faac + 125931c commit 2d1e8dd

File tree

27 files changed

+794
-451
lines changed

27 files changed

+794
-451
lines changed

README.md

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,68 @@
11
# ESMValTool Core package
2+
23
[![Documentation Status](https://readthedocs.org/projects/esmvaltool/badge/?version=version2_development)](https://esmvaltool.readthedocs.io/en/version2_development/?badge=version2_development)
34
[![DOIBadge](https://img.shields.io/badge/DOI-10.17874%2Fac8548f0315-blue.svg)](https://doi.org/10.17874/ac8548f0315)
45
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ESMValGroup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
56
[![CircleCI](https://circleci.com/gh/ESMValGroup/ESMValCore.svg?style=svg)](https://circleci.com/gh/ESMValGroup/ESMValCore)
6-
[![Codacy Coverage Badge](https://api.codacy.com/project/badge/Coverage/79bf6932c2e844eea15d0fb1ed7e415c)](https://www.codacy.com/app/ESMValGroup/ESMValCore?utm_source=github.com&utm_medium=referral&utm_content=ESMValGroup/ESMValCore&utm_campaign=Badge_Coverage)
7-
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/79bf6932c2e844eea15d0fb1ed7e415c)](https://www.codacy.com/app/ESMValGroup/ESMValTool?utm_source=github.com&utm_medium=referral&utm_content=ESMValGroup/ESMValTool&utm_campaign=Badge_Grade)
7+
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/5d496dea9ef64ec68e448a6df5a65783)](https://www.codacy.com/app/ESMValGroup/ESMValCore?utm_source=github.com&utm_medium=referral&utm_content=ESMValGroup/ESMValCore&utm_campaign=Badge_Coverage)
8+
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5d496dea9ef64ec68e448a6df5a65783)](https://www.codacy.com/app/ESMValGroup/ESMValCore?utm_source=github.com&utm_medium=referral&utm_content=ESMValGroup/ESMValCore&utm_campaign=Badge_Grade)
89
[![Docker Build Status](https://img.shields.io/docker/build/esmvalgroup/esmvaltool.svg)](https://hub.docker.com/r/esmvalgroup/esmvaltool/)
910
[![Anaconda-Server Badge](https://anaconda.org/esmvalgroup/esmvalcore/badges/installer/conda.svg)](https://conda.anaconda.org/esmvalgroup)
1011

11-
12-
ESMValTool Core: core functionalities for the ESMValTool, a community diagnostic and performance metrics tool for routine evaluation of Earth system models in CMIP
12+
ESMValTool Core: core functionalities for the ESMValTool, a community
13+
diagnostic and performance metrics tool for routine evaluation of Earth System
14+
Models in CMIP.
1315

1416
# Getting started
15-
This is the development branch for ESMValTool Core. ESMValTool version 2 is under rapid development, an installation from source is recommended at the moment.
16-
17-
## Installing from source [recommended]
18-
Please see [CONTRIBUTING.md](https://github.com/ESMValGroup/ESMValCore/blob/development/CONTRIBUTING.md) for instructions on installing ESMValTool from source.
1917

2018
## Installing from Anaconda
19+
2120
The Anaconda package can be found on [ESMValGroup Anaconda Channel.](https://anaconda.org/ESMValGroup)
2221

23-
If you already installed Anaconda, you can install ESMValTool by running:
24-
```
25-
conda install -c esmvalgroup -c conda-forge esmvalcore
26-
```
22+
If you already have
23+
[Anaconda installed](https://conda.io/projects/conda/en/latest/user-guide/install/index.html),
24+
you can install ESMValTool Core by running:
25+
26+
conda install -c esmvalgroup -c conda-forge esmvalcore
27+
28+
## Installing from source
29+
30+
If you need the very latest features, please see
31+
[CONTRIBUTING.md](https://github.com/ESMValGroup/ESMValCore/blob/development/CONTRIBUTING.md)
32+
for instructions on installing ESMValTool Core from source.
33+
34+
## Using ESMValTool Core as a Python library
35+
36+
The ESMValTool Core package provides various functions for:
37+
38+
- Finding data in a directory structure typically used for CMIP data
39+
40+
- Reading CMOR tables and using those to check model and observational data.
41+
42+
- ESMValTool preprocessor functions based on
43+
[iris](https://scitools.org.uk/iris/docs/latest/) for e.g. regridding,
44+
vertical interpolation, statistics, correcting (meta)data errors, extracting
45+
a time range, etcetera.
2746

2847
## Running ESMValTool
29-
- Review `config-user.yml`. To customize for your system, create a copy, edit and use the command line option `-c` to instruct `esmvaltool` to use your custom configuration.
30-
- Optionally install the ESMValTool recipes and diagnostics
31-
- Run e.g. `esmvaltool -c ~/config-user.yml examples/recipe_python.yml
48+
49+
- Review `config-user.yml`. To customize for your system, create a copy, edit
50+
and use the command line option `-c` to instruct `esmvaltool` to use your
51+
custom configuration file.
52+
53+
- Install the [ESMValTool](https://github.com/ESMValGroup/ESMValTool)
54+
to run [ESMValTool recipes and diagnostics](https://esmvaltool.readthedocs.io/en/latest/recipes/index.html)
55+
56+
- Run e.g. `esmvaltool -c ~/config-user.yml examples/recipe_python.yml` after
57+
downloading the necessary data.
3258

3359
## Getting help
34-
The easiest way to get help if you cannot find the answer in the documentation on [readthedocs](https://esmvaltool.readthedocs.io), is to open an [issue on GitHub](https://github.com/ESMValGroup/ESMValCore/issues).
60+
61+
The easiest way to get help if you cannot find the answer in the documentation
62+
on [readthedocs](https://esmvaltool.readthedocs.io), is to open an
63+
[issue on GitHub](https://github.com/ESMValGroup/ESMValCore/issues).
3564

3665
## Contributing
37-
If you would like to contribute a new diagnostic or feature, please have a look at [CONTRIBUTING.md](https://github.com/ESMValGroup/ESMValCore/blob/development/CONTRIBUTING.md).
3866

67+
If you would like to contribute a new feature, please have a
68+
look at [CONTRIBUTING.md](https://github.com/ESMValGroup/ESMValCore/blob/development/CONTRIBUTING.md).

doc/sphinx/source/esmvalcore/preprocessor.inc

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ The _area.py module contains the following preprocessor functions:
131131

132132
* extract_region: Extract a region from a cube based on lat/lon corners.
133133
* zonal_means: Calculates the zonal or meridional means.
134-
* average_region: Calculates the average value over a region.
134+
* area_statistics: Calculates the average value over a region.
135135
* extract_named_regions: Extract a specific region from in the region cooordinate.
136136

137137

@@ -166,26 +166,24 @@ This function takes two arguments:
166166
See also :func:`esmvalcore.preprocessor.zonal_means`.
167167

168168

169-
3. average_region
169+
3. area_statistics
170170
-----------------
171171

172172
This function calculates the average value over a region - weighted by the
173173
cell areas of the region.
174174

175-
This function takes three arguments:
176-
coord1: the name of the coordinate in the first direction.
177-
coord2: the name of the coordinate in the second dimension.
178-
operator: the name of the operation to apply (default: mean).
175+
This function takes the argument,
176+
operator: the name of the operation to apply.
179177

180-
While this function is named `average_region`, it can be used to apply several
178+
This function can be used to apply several
181179
different operations in the horizonal plane: mean, standard deviation, median
182180
variance, minimum and maximum.
183181

184182
Note that this function is applied over the entire dataset. If only a specific
185183
region, depth layer or time period is required, then those regions need to be
186184
removed using other preprocessor operations in advance.
187185

188-
See also :func:`esmvalcore.preprocessor.average_region`.
186+
See also :func:`esmvalcore.preprocessor.area_statistics`.
189187

190188

191189
4. extract_named_regions
@@ -205,7 +203,7 @@ Volume manipulation
205203
The _volume.py module contains the following preprocessor functions:
206204

207205
* extract_volume: Extract a specific depth range from a cube.
208-
* average_volume: Calculate the volume-weighted average.
206+
* volume_statistics: Calculate the volume-weighted average.
209207
* depth_integration: Integrate over the depth dimension.
210208
* extract_transect: Extract data along a line of constant latitude or longitude.
211209
* extract_trajectory: Extract data along a specified trajectory.
@@ -225,19 +223,19 @@ negative, then z_min and z_max need to be negative numbers.
225223
See also :func:`esmvalcore.preprocessor.extract_volume`.
226224

227225

228-
2. average_volume
226+
2. volume_statistics
229227
-----------------
230228

231229
This function calculates the volume-weighted average across three dimensions,
232230
but maintains the time dimension. The following arguments are required:
233231

234-
coord1: the name of the coordinate in the first direction.
235-
coord2: the name of the coordinate in the second dimension.
232+
This function takes the argument: operator, which defines the
233+
operation to apply over the volume.
236234

237235
No depth coordinate is required as this is determined by iris. This
238236
function works best when the fx_files provide the cell volume.
239237

240-
See also :func:`esmvalcore.preprocessor.average_volume`.
238+
See also :func:`esmvalcore.preprocessor.volume_statistics`.
241239

242240

243241
3. depth_integration
@@ -294,15 +292,21 @@ Vertical interpolation
294292
======================
295293
Documentation of _regrid.py (part 1)
296294

297-
Land/Sea/Ice Masking
298-
====================
295+
Masking
296+
=======
299297
Documentation of _mask.py (part 1)
300298

299+
1. Introduction to masking
300+
---------------------------
301+
301302
Certain metrics and diagnostics need to be computed and performed on restricted regions of the Globe; ESMValTool supports subsetting the input data on land mass, oceans and seas, ice. This is achived by masking the model data and keeping only the values associated with grid points that correspond to e.g. land mass
302303
or oceans and seas; masking is done either by using standard mask files that have the same grid resolution as the model data (these files are usually produced
303304
at the same time with the model data and are called fx files) or, in the absence of these files, by using Natural Earth masks. Natural Earth masks, even if they are not model-specific, represent a good approximation since their grid resolution is almost always much higher than the model data, and they are constantly updated with changing
304305
geographical features.
305306

307+
2. Land-sea masking
308+
-------------------
309+
306310
In ESMValTool v2 land-seas-ice masking can be done in two places: in the preprocessor, to apply a mask on the data before any subsequent preprocessing step, and before
307311
running the diagnostic, or in the disgnostic phase. We present both these implementations below.
308312

@@ -321,6 +325,9 @@ kept in the data after applying the mask; conversely, it will retrieve the `fx:
321325
type of files; observational data is missing them altogether), then the tool attempts to mask using Natural Earth mask files (that are vectorized rasters).
322326
Note that the resolutions for the Natural Earth masks are much higher than any usual CMIP model: 10m for land and 50m for ocean masks.
323327

328+
3. Ice masking
329+
---------------
330+
324331
Note that for masking out ice the preprocessor is using a different function, this so that both land and sea or ice can be masked out without
325332
losing generality. To mask ice out one needs to add the preprocessing step much as above:
326333

@@ -334,6 +341,9 @@ losing generality. To mask ice out one needs to add the preprocessing step much
334341
To keep only the ice, one needs to mask out landsea, so use that as value for mask_out. As in the case of mask_landsea, the tool will automatically
335342
retrieve the `fx: sftgif` file corresponding the the used variable and extract the ice mask from it.
336343

344+
4. mask files
345+
--------------
346+
337347
At the core of the land/sea/ice masking in the preprocessor are the mask files (whether it be fx type or Natural Earth type of files); these files (bar Natural Earth)
338348
can be retrived and used in the diagnostic phase as well or solely. By specifying the `fx_files:` key in the variable in diagnostic in the recipe, and populating it
339349
with a list of desired files e.g.:
@@ -356,6 +366,42 @@ the 'config' diagnostic variable items e.g.:
356366
sftlf_file = attributes['fx_files']['sftlf']
357367
areacello_file = attributes['fx_files']['areacello']
358368

369+
5. Missing values masks
370+
-----------------------
371+
372+
Missing (masked) values can be a nuisance especially when dealing with multimodel ensembles and having to compute
373+
multimodel statistics; different numbers of missing data from dataset to datest may introduce biases and artifically
374+
assign more weight to the datasets that have less missing data. This is handled in ESMValTool via the missing values
375+
masks: two types of such masks are available: one for the multimodel case and another for the single model case.
376+
377+
The multimodel missing values mask (mask_fillvalues) is a preprocessor step that usually comes after all the single-model
378+
steps (regridding, area selection etc) have been performed; in a nutshell, it combines missing values masks from individual
379+
models into a multimodel missing values mask; the individual model masks are built according to common criteria:
380+
the user chooses a time window in which missing data points are counted, and if the number of missing data points relative
381+
to the number of total data points in a window is less than a chosen fractional theshold, the window is discarded i.e.
382+
all the points in the window are masked (set to missing).
383+
384+
.. code-block:: bash
385+
386+
preprocessors:
387+
missing_values_preprocessor:
388+
mask_fillvalues:
389+
threshold_fraction: 0.95
390+
min_value: 19.0
391+
time_window: 10.0
392+
393+
In the example above, the fractional threshold for missing data vs. total data is set to 95% and the time window is set to
394+
10.0 (units of the time coordinate units). Optionally, a minimum value threshold can be applied, in this case it is set
395+
to 19.0 (in units of the variable units).
396+
397+
A similar preprocessor step exists for the single-dataset: mask_window_threshold (with the same arguments as mask_fillvalues).
398+
399+
6. Min, max and interval masking
400+
--------------------------------
401+
402+
Thresholding on minimum and maximum accepted data values can also be performed: masks are constructed based on the
403+
results of thresholding; inside and outside interval thresholding and masking can also be performed. These functions
404+
are mask_above_threshold, mask_below_threshold, mask_inside_range, and mask_outside_range.
359405

360406
Horizontal regridding
361407
=====================

doc/sphinx/source/recipes/recipe_oceans.rst

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -488,9 +488,8 @@ An appropriate preprocessor for a 3D+time field would be:
488488
lat2: 30.
489489
z_min: 0.
490490
z_max: 3000.
491-
average_region:
492-
coord1: longitude
493-
coord2: latitude
491+
area_statistics:
492+
operator: mean
494493

495494

496495

@@ -524,18 +523,15 @@ For a global area-weighted average 2D field:
524523

525524
.. code-block:: yaml
526525
527-
average_area:
528-
coord1: longitude
529-
coord2: latitude
526+
area_statistics:
527+
operator: mean
530528

531529
For a global volume-weighted average 3D field:
532530

533531
.. code-block:: yaml
534532
535-
average_volume:
536-
coord1: longitude
537-
coord2: latitude
538-
coordz: depth
533+
volume_statistics:
534+
operator: mean
539535

540536
For a global area-weighted surface of a 3D field:
541537

@@ -544,9 +540,8 @@ For a global area-weighted surface of a 3D field:
544540
extract_levels:
545541
levels: [0., ]
546542
scheme: linear_horizontal_extrapolate_vertical
547-
average_area:
548-
coord1: longitude
549-
coord2: latitude
543+
area_statistics:
544+
operator: mean
550545

551546

552547
An example of the multi-model time series plots can seen here:

doc/sphinx/source/requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ prov[dot]
1010
psutil
1111
pyyaml
1212
shapely
13-
six
1413
xarray
1514
yamale
1615
sklearn

esmvalcore/_config.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
import logging.config
55
import os
66
import time
7-
from distutils.version import LooseVersion
87

9-
import iris
108
import yaml
119

1210
from .cmor.table import read_cmor_tables
@@ -29,11 +27,6 @@ def find_diagnostics():
2927
DIAGNOSTICS_PATH = find_diagnostics()
3028

3129

32-
def use_legacy_iris():
33-
"""Return True if legacy iris is used."""
34-
return LooseVersion(iris.__version__) < LooseVersion("2.0.0")
35-
36-
3730
def read_config_user_file(config_file, recipe_name):
3831
"""Read config user file and store settings in a dictionary."""
3932
with open(config_file, 'r') as file:

esmvalcore/_data_finder.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
import os
1010
import re
1111

12-
import six
13-
1412
from ._config import get_project_config, replace_mip_fx
1513
from .cmor.table import CMOR_TABLES
1614

@@ -177,7 +175,7 @@ def _select_drs(input_type, drs, project):
177175
"""Select the directory structure of input path."""
178176
cfg = get_project_config(project)
179177
input_path = cfg[input_type]
180-
if isinstance(input_path, six.string_types):
178+
if isinstance(input_path, str):
181179
return input_path
182180

183181
structure = drs.get(project, 'default')

esmvalcore/_recipe.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ def _update_fx_settings(settings, variable, config_user):
413413
settings['mask_landseaice']['fx_files'].append(
414414
fx_files_dict['sftgif'])
415415

416-
for step in ('average_region', 'average_volume'):
416+
for step in ('area_statistics', 'volume_statistics'):
417417
if settings.get(step, {}).get('fx_files'):
418418
settings[step]['fx_files'] = get_input_fx_filelist(
419419
variable=variable,
@@ -431,7 +431,7 @@ def _read_attributes(filename):
431431

432432
with Dataset(filename, 'r') as dataset:
433433
for attr in dataset.ncattrs():
434-
attributes[attr] = getattr(dataset, attr)
434+
attributes[attr] = dataset.getncattr(attr)
435435
return attributes
436436

437437

esmvalcore/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""ESMValCore version."""
2-
__version__ = '2.0.0a0'
2+
__version__ = '2.0.0a1'

esmvalcore/cmor/check.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ def __init__(self,
7070
self.automatic_fixes = automatic_fixes
7171

7272
def check_metadata(self, logger=None):
73-
"""Check the cube metadata.
73+
"""
74+
Check the cube metadata.
7475
7576
Perform all the tests that do not require to have the data in memory.
7677

0 commit comments

Comments
 (0)