From 918971294241efa98a9f7dbca48cf5698c5bff94 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 12 Mar 2020 17:24:43 +0100 Subject: [PATCH 001/647] change the titles of each section --- _episodes/03-configuration.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 8ba2ebb9..0ae07627 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -24,26 +24,29 @@ Make a copy and rename it to ``config-user.yml``: {: .source} This file contains the information for: - * Rootpaths to the data from different projects - * Directory structure for input data + * Directory structure for the data from different projects + * Rootpaths to input data * Number of available CPUs * Destination directory * Auxiliary data directory * Output settings -## Rootpaths to input data +## Directory structure for the data from different projects ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source, like CMIP for dataset from climate model intercomparison project, and OBS for observational dataset that adhere to (CMOR standard)[https://cmor.llnl.gov/]. For each category, you can define either one path or several pathes as a list. + +## Rootpaths to input data In this lesson, you work with data from (CMIP5)[https://esgf-node.llnl.gov/projects/cmip5/]. Add the root path of the folder where you downloaded the data during the (Setup)[https://escience-academy.github.io/lesson-esmvaltool/setup.html]. ~~~ rootpath: ... - CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2, ~/escience-academy/test_data] + CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2, ~/tutorial/test_data] ~~~ {: .source} +## Number of available CPUs ## Auxiliary data directory (used for some additional datasets) auxiliary_data_dir: ~/auxiliary_data From ba968d999654d05b5dffdd44c28be9f4356a3c52 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 11:05:55 +0100 Subject: [PATCH 002/647] update information about directory structure --- _episodes/03-configuration.md | 36 ++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 0ae07627..65d323fb 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -3,7 +3,7 @@ title: "Configuration" teaching: 0 exercises: 0 questions: -- "What is user configuration file and how can I use it?" +- "What is the user configuration file and how can I use it?" objectives: - "Understand the data directories structure" - "Configure ESMValTool to ignore some settings" @@ -25,19 +25,40 @@ Make a copy and rename it to ``config-user.yml``: This file contains the information for: * Directory structure for the data from different projects - * Rootpaths to input data + * Rootpath to input data * Number of available CPUs * Destination directory * Auxiliary data directory * Output settings ## Directory structure for the data from different projects -ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source, like CMIP for dataset from climate model intercomparison project, and OBS for observational dataset that adhere to (CMOR standard)[https://cmor.llnl.gov/]. -For each category, you can define either one path or several pathes as a list. +Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. +The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from the climate model intercomparison project whereas OBS for an observational dataset. For each category, you can define either one path or several pathes as a list. + +~~~ +rootpath: + CMIP3: [~/cmip3_inputpath1, ~/cmip3_inputpath2] + CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2] + CMIP6: [~/cmip6_inputpath1, ~/cmip6_inputpath2] + OBS: ~/obs_inputpath + OBS6: ~/obs6_inputpath + obs4mips: ~/obs4mips_inputpath + ana4mips: ~/ana4mips_inputpath + native6: ~/native6_inputpath + RAWOBS: ~/rawobs_inputpath + default: ~/default_inputpath +~~~ +{: .source} + +> ## Attention +> +> * For more information about data from different projects, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/inputdata.html). +{: .callout} ## Rootpaths to input data +The ``rootpath`` specifies the directories where ESMValTool will look for input data. In this lesson, you work with data from (CMIP5)[https://esgf-node.llnl.gov/projects/cmip5/]. -Add the root path of the folder where you downloaded the data during the (Setup)[https://escience-academy.github.io/lesson-esmvaltool/setup.html]. +Add the root path of the folder where you downloaded the data during the (Setup)[https://esmvalgroup.github.io/tutorial/setup.html]. ~~~ rootpath: @@ -46,6 +67,11 @@ Add the root path of the folder where you downloaded the data during the (Setup) ~~~ {: .source} +> ## Attention +> +> * For more information about setting the correct rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). +{: .callout} + ## Number of available CPUs ## Auxiliary data directory (used for some additional datasets) auxiliary_data_dir: ~/auxiliary_data From 71bf19e7ca63f25eecd43e7dd20c65f242366475 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 11:09:06 +0100 Subject: [PATCH 003/647] fix hyperlinks --- _episodes/03-configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 65d323fb..cf04896c 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -57,8 +57,8 @@ rootpath: ## Rootpaths to input data The ``rootpath`` specifies the directories where ESMValTool will look for input data. -In this lesson, you work with data from (CMIP5)[https://esgf-node.llnl.gov/projects/cmip5/]. -Add the root path of the folder where you downloaded the data during the (Setup)[https://esmvalgroup.github.io/tutorial/setup.html]. +In this lesson, you work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). +Add the root path of the folder where you downloaded the data during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). ~~~ rootpath: From f58ac76f8af991f71af617f08567dfd9bc2f2b61 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 11:30:06 +0100 Subject: [PATCH 004/647] reorder the sections according to config file --- _episodes/03-configuration.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index cf04896c..dcd0f958 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -24,16 +24,16 @@ Make a copy and rename it to ``config-user.yml``: {: .source} This file contains the information for: - * Directory structure for the data from different projects * Rootpath to input data + * Directory structure for the data from different projects * Number of available CPUs * Destination directory * Auxiliary data directory * Output settings -## Directory structure for the data from different projects -Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. -The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from the climate model intercomparison project whereas OBS for an observational dataset. For each category, you can define either one path or several pathes as a list. +## Rootpaths to input data +ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. +The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from the climate model intercomparison project whereas OBS for an observational dataset. The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. ~~~ rootpath: @@ -50,13 +50,6 @@ rootpath: ~~~ {: .source} -> ## Attention -> -> * For more information about data from different projects, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/inputdata.html). -{: .callout} - -## Rootpaths to input data -The ``rootpath`` specifies the directories where ESMValTool will look for input data. In this lesson, you work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). Add the root path of the folder where you downloaded the data during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). @@ -72,6 +65,16 @@ Add the root path of the folder where you downloaded the data during the [Setup] > * For more information about setting the correct rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} +## Directory structure for the data from different projects +Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). + + + +> ## Attention +> +> * For more information about data from different projects, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/inputdata.html). +{: .callout} + ## Number of available CPUs ## Auxiliary data directory (used for some additional datasets) auxiliary_data_dir: ~/auxiliary_data From fc2fd93f63f02161e0e592c79c935cc2477dbc5b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 13:50:24 +0100 Subject: [PATCH 005/647] add more explanations about config file at the top --- _episodes/03-configuration.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index dcd0f958..f5f17325 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -16,10 +16,12 @@ keypoints: The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. This is an (YAML file) [https://yaml.org/spec/1.2/spec.html]. An example configuration file can be found in the root directory of the ESMValTool repository. -Make a copy and rename it to ``config-user.yml``: +Let's change our working directory to ESMValTool, then make a copy of the file and rename it to ``config-user.yml``, then run a text editor called Nano to open it: ~~~ + cd ESMValTool cp config-user-example.yml config-user.yml + nano config-user.yml ~~~ {: .source} @@ -31,6 +33,11 @@ This file contains the information for: * Auxiliary data directory * Output settings +> ## Which text editor +> +> No matter what editor you use, you will need to know where it searches for and saves files. If you start it from the shell, it will (probably) use your current working directory as its default location. We use ``nano`` in examples because it is one of the least complex text editors. Press ctrl + O to save the file, and then ctrl + X to exit nano. +{: .callout} + ## Rootpaths to input data ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from the climate model intercomparison project whereas OBS for an observational dataset. The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. From 74a806cb9243910dbf6cec07b75141060374ed54 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 13:59:19 +0100 Subject: [PATCH 006/647] add info about drs --- _episodes/03-configuration.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index f5f17325..9ff9a27a 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -67,19 +67,23 @@ Add the root path of the folder where you downloaded the data during the [Setup] ~~~ {: .source} -> ## Attention +> ## Setting the correct rootpath > -> * For more information about setting the correct rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). +> * For more information about setting the rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} ## Directory structure for the data from different projects -Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). - +Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). To set a directory, you can use one of the values of ``default``, ``BADC``, ``DKRZ``, ``ETHZ``, ... . Let's use ``default`` in our example: +~~~ +drs: + CMIP5: default +~~~ +{: .source} -> ## Attention +> ## Available drs > -> * For more information about data from different projects, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/inputdata.html). +> * For more information about directories, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/config.html#developer-configuration-file). {: .callout} ## Number of available CPUs From 7acb55dbbe7ce6f6f381a924861d707bce847975 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 14:15:07 +0100 Subject: [PATCH 007/647] update info about number of tasks --- _episodes/03-configuration.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 9ff9a27a..0be4e614 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -28,7 +28,7 @@ Let's change our working directory to ESMValTool, then make a copy of the file a This file contains the information for: * Rootpath to input data * Directory structure for the data from different projects - * Number of available CPUs + * Number of parallel tasks * Destination directory * Auxiliary data directory * Output settings @@ -69,7 +69,7 @@ Add the root path of the folder where you downloaded the data during the [Setup] > ## Setting the correct rootpath > -> * For more information about setting the rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). +> For more information about setting the rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} ## Directory structure for the data from different projects @@ -83,10 +83,22 @@ drs: > ## Available drs > -> * For more information about directories, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/config.html#developer-configuration-file). +> For more information about directories, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/config.html#developer-configuration-file). +{: .callout} + +## Number of parallel tasks +This option enables you to perform parallel processing. You can choose the number of tasks in parallel as 1/2/3/4/... or you can set it to ``null`` that tells ESMValTool to use the number of available CPUs: + +~~~ +max_parallel_tasks: null +~~~ +{: .source} + +> ## Set the number of tasks +> +> If you run out of memory, try setting ``max_parallel_tasks`` to 1. Then, check the amount of memory you need for that by inspecting the file ``run/resource_usage.txt`` in the output directory. Using the number there you can increase the number of parallel tasks again to a reasonable number for the amount of memory available in your system. {: .callout} -## Number of available CPUs ## Auxiliary data directory (used for some additional datasets) auxiliary_data_dir: ~/auxiliary_data From dfbb8694ac87628b806a8e35dcd667bef6c4b0bc Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 14:43:42 +0100 Subject: [PATCH 008/647] add info about destination dir --- _episodes/03-configuration.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 0be4e614..f41c00ef 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -99,6 +99,27 @@ max_parallel_tasks: null > If you run out of memory, try setting ``max_parallel_tasks`` to 1. Then, check the amount of memory you need for that by inspecting the file ``run/resource_usage.txt`` in the output directory. Using the number there you can increase the number of parallel tasks again to a reasonable number for the amount of memory available in your system. {: .callout} +## Destination directory +The destination directory is the rootpath where ESMValTool will store its output, i.e. figures, data, logs, etc. With every run, ESMValTool automatically generates a new output folder determined by the recipe name, and date and time using the format: YYYYMMDD_HHMMSS. This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. + +Let's name our destination directory as ``esmvaltool_output`` in the working directory: + +~~~ +output_dir: ./esmvaltool_output +~~~ +{: .source} + +> ## Content of subfolders +> +> * ``plots``: the location for all plots, split by individual diagnostics and fields. +> * ``preproc``: this folder contains all the preprocessed data and metadata.yml interface files. Note that by default this directory will be deleted after each run because most users will only need the results from the diagnostic scripts. +> * ``run``: this folder includes all log files, a copy of the recipe, a summary of the resource usage, and the settings.yml interface files, resource_usage.txt and temporary files created by the diagnostic scripts. +> * ``work``: a place for any diagnostic script results that are not plots, e.g. files in NetCDF format (depends on the diagnostic script). +> +> We explain more about output in the next [lesson](https://esmvalgroup.github.io/tutorial/04-toy-example/index.html) +{: .callout} + + ## Auxiliary data directory (used for some additional datasets) auxiliary_data_dir: ~/auxiliary_data From 4502a827c747793fc6fbb9cc17459ad2e1fe3f54 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 14:58:04 +0100 Subject: [PATCH 009/647] run a mardownlinter and fix the errors --- _episodes/03-configuration.md | 48 +++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index f41c00ef..ee6ad8d1 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -15,23 +15,25 @@ keypoints: ## The configuration file The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. -This is an (YAML file) [https://yaml.org/spec/1.2/spec.html]. An example configuration file can be found in the root directory of the ESMValTool repository. +This is an [YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be found in the root directory of the ESMValTool repository. Let's change our working directory to ESMValTool, then make a copy of the file and rename it to ``config-user.yml``, then run a text editor called Nano to open it: -~~~ +~~~bash cd ESMValTool cp config-user-example.yml config-user.yml nano config-user.yml ~~~ + {: .source} This file contains the information for: - * Rootpath to input data - * Directory structure for the data from different projects - * Number of parallel tasks - * Destination directory - * Auxiliary data directory - * Output settings + +* Rootpath to input data +* Directory structure for the data from different projects +* Number of parallel tasks +* Destination directory +* Auxiliary data directory +* Output settings > ## Which text editor > @@ -39,10 +41,11 @@ This file contains the information for: {: .callout} ## Rootpaths to input data + ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from the climate model intercomparison project whereas OBS for an observational dataset. The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. -~~~ +~~~YAML rootpath: CMIP3: [~/cmip3_inputpath1, ~/cmip3_inputpath2] CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2] @@ -55,16 +58,18 @@ rootpath: RAWOBS: ~/rawobs_inputpath default: ~/default_inputpath ~~~ + {: .source} In this lesson, you work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). Add the root path of the folder where you downloaded the data during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). -~~~ +~~~YAML rootpath: ... CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2, ~/tutorial/test_data] ~~~ + {: .source} > ## Setting the correct rootpath @@ -73,12 +78,14 @@ Add the root path of the folder where you downloaded the data during the [Setup] {: .callout} ## Directory structure for the data from different projects + Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). To set a directory, you can use one of the values of ``default``, ``BADC``, ``DKRZ``, ``ETHZ``, ... . Let's use ``default`` in our example: -~~~ +~~~YAML drs: CMIP5: default ~~~ + {: .source} > ## Available drs @@ -87,11 +94,14 @@ drs: {: .callout} ## Number of parallel tasks + This option enables you to perform parallel processing. You can choose the number of tasks in parallel as 1/2/3/4/... or you can set it to ``null`` that tells ESMValTool to use the number of available CPUs: -~~~ +~~~YAML + max_parallel_tasks: null ~~~ + {: .source} > ## Set the number of tasks @@ -100,13 +110,15 @@ max_parallel_tasks: null {: .callout} ## Destination directory + The destination directory is the rootpath where ESMValTool will store its output, i.e. figures, data, logs, etc. With every run, ESMValTool automatically generates a new output folder determined by the recipe name, and date and time using the format: YYYYMMDD_HHMMSS. This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. Let's name our destination directory as ``esmvaltool_output`` in the working directory: -~~~ +~~~YAML output_dir: ./esmvaltool_output ~~~ + {: .source} > ## Content of subfolders @@ -119,9 +131,7 @@ output_dir: ./esmvaltool_output > We explain more about output in the next [lesson](https://esmvalgroup.github.io/tutorial/04-toy-example/index.html) {: .callout} - -## Auxiliary data directory (used for some additional datasets) - auxiliary_data_dir: ~/auxiliary_data +## Auxiliary data directory The ``auxiliary_data_dir`` setting is the path to place any required additional auxiliary data files. This method was necessary because certain @@ -133,6 +143,12 @@ files if they can not be downloaded at runtime. To reiterate, this setting is not for model or observational datasets, rather it is for data files used in plotting such as coastline descriptions and so on. +~~~YAML +auxiliary_data_dir: ~/auxiliary_data +~~~ + +{: .source} + ## Output settings From 2e037f1080dd4db0a1fc0bd60e6fd6fc9d7d849d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 15:04:01 +0100 Subject: [PATCH 010/647] remove {source} after code block --- _episodes/03-configuration.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index ee6ad8d1..8e778f9b 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -24,8 +24,6 @@ Let's change our working directory to ESMValTool, then make a copy of the file a nano config-user.yml ~~~ -{: .source} - This file contains the information for: * Rootpath to input data @@ -59,8 +57,6 @@ rootpath: default: ~/default_inputpath ~~~ -{: .source} - In this lesson, you work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). Add the root path of the folder where you downloaded the data during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). @@ -70,8 +66,6 @@ Add the root path of the folder where you downloaded the data during the [Setup] CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2, ~/tutorial/test_data] ~~~ -{: .source} - > ## Setting the correct rootpath > > For more information about setting the rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). @@ -86,8 +80,6 @@ drs: CMIP5: default ~~~ -{: .source} - > ## Available drs > > For more information about directories, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/config.html#developer-configuration-file). @@ -102,8 +94,6 @@ This option enables you to perform parallel processing. You can choose the numbe max_parallel_tasks: null ~~~ -{: .source} - > ## Set the number of tasks > > If you run out of memory, try setting ``max_parallel_tasks`` to 1. Then, check the amount of memory you need for that by inspecting the file ``run/resource_usage.txt`` in the output directory. Using the number there you can increase the number of parallel tasks again to a reasonable number for the amount of memory available in your system. @@ -119,8 +109,6 @@ Let's name our destination directory as ``esmvaltool_output`` in the working dir output_dir: ./esmvaltool_output ~~~ -{: .source} - > ## Content of subfolders > > * ``plots``: the location for all plots, split by individual diagnostics and fields. @@ -147,8 +135,6 @@ plotting such as coastline descriptions and so on. auxiliary_data_dir: ~/auxiliary_data ~~~ -{: .source} - ## Output settings From feace8b94ccc9fd8701aaeb7b524bbd2d76c443c Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 15:33:03 +0100 Subject: [PATCH 011/647] update info about output settings --- _episodes/03-configuration.md | 66 ++++++++++++++--------------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 8e778f9b..ec9c88a0 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -73,7 +73,7 @@ Add the root path of the folder where you downloaded the data during the [Setup] ## Directory structure for the data from different projects -Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). To set a directory, you can use one of the values of ``default``, ``BADC``, ``DKRZ``, ``ETHZ``, ... . Let's use ``default`` in our example: +Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). To set a directory, you can use one of the values of ``default``, ``BADC``, ``DKRZ``, ``ETHZ``, .... Let's use ``default`` in our example: ~~~YAML drs: @@ -121,51 +121,39 @@ output_dir: ./esmvaltool_output ## Auxiliary data directory -The ``auxiliary_data_dir`` setting is the path to place any required -additional auxiliary data files. This method was necessary because certain -Python toolkits such as cartopy will attempt to download data files at run -time, typically geographic data files such as coastlines or land surface maps. -This can fail if the machine does not have access to the wider internet. This -location allows us to tell cartopy (and other similar tools) where to find the -files if they can not be downloaded at runtime. To reiterate, this setting is -not for model or observational datasets, rather it is for data files used in -plotting such as coastline descriptions and so on. +The ``auxiliary_data_dir`` setting is the path to place any required additional auxiliary data files. This location allows us to tell the diagnostic script where to find the files if they can not be downloaded at runtime. This option is not for model or observational datasets, rather it is for data files used in plotting such as coastline descriptions and so on. ~~~YAML auxiliary_data_dir: ~/auxiliary_data ~~~ - ## Output settings -.. code-block:: yaml - - # Diagnostics create plots? [true]/false - write_plots: true - # Diagnositcs write NetCDF files? [true]/false - write_netcdf: true - -The ``write_plots`` setting is used to inform ESMValTool about your preference -for saving figures. Similarly, the ``write_netcdf`` setting is a boolean which -turns on or off the writing of netCDF files. - -The ```rootpath`` specifies the directories where ESMValTool will look for input -data. Similarly, ``output_dir`` specifies where ESMValTool will store its -output, i.e. figures, data, logs, etc. Make sure to set appropriate paths. - -.. code-block:: yaml - - - - -You can tailor it for your system using the explanation below. - -.. note:: - - The ``config-user.yml`` file is specified as argument at run time, so it is - possible to have several available with different purposes: one for - formalised runs, one for debugging, etc... +These settings are used to inform ESMValTool about your preference. You can turn on or off the setting by ``true`` or ``false`` values. Most of these settings are fairly self-explanatory, ie: +~~~YAML +# Diagnostics create plots? [true]/false +write_plots: true +# Diagnositcs write NetCDF files? [true]/false +write_netcdf: true +# Set the console log level debug, [info], warning, error +log_level: info +# Exit on warning (only for NCL diagnostic scripts)? true/[false] +exit_on_warning: false +# Plot file format? [png]/pdf/ps/eps/epsi +output_file_type: png +# Use netCDF compression true/[false] +compress_netcdf: false +# Save intermediary cubes in the preprocessor true/[false] +save_intermediary_cubes: false +# Remove the preproc dir if all fine +remove_preproc_dir: true +# Path to custom config-developer file, to customise project configurations. +# See config-developer.yml for an example. Set to [null] to use the default +# config_developer_file: null +# Get profiling information for diagnostics +# Only available for Python diagnostics +profile_diagnostic: false +~~~ {% include links.md %} - From b2296cf6c618cc8b981b1644307adbcb887b2637 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Fri, 13 Mar 2020 15:31:42 +0000 Subject: [PATCH 012/647] created environment file, and added installation instructions to contributing. --- CONTRIBUTING.md | 21 +++++++++++++++++---- environment.yml | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 environment.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d1bf0e1a..99655e56 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,7 +71,7 @@ and submitting [bug reports][issues] about things that don't work, aren't clear, or are missing. If you are looking for ideas, please see the 'Issues' tab for a list of issues associated with this repository, -or you may also look at the issues for [Data Carpentry][dc-issues], +or you may also look at the issues for [Data Carpentry][dc-issues], [Software Carpentry][swc-issues], and [Library Carpentry][lc-issues] projects. Comments on issues and reviews of pull requests are just as welcome: @@ -130,17 +130,30 @@ Extensive instructions for building and viewing the pages locally can be found [ ```bash # apt (Ubuntu/Devian) sudo apt install ruby-dev ruby-bundler +``` +or +```bash # dnf (Fedora/Redhat) sudo dnf install rubygem-bundler ruby-devel -to install the required ruby packages and +``` + +Alternatively, there's an environment file available which can be installed in conda with: +```bash +conda env create -f environment.yml -n esmvaltool_tutorial +``` + +To install the required ruby packages, run the following command in the tutorial's +main directory to build and serve the website locally.: ```bash make serve ``` -to build and serve the website locally. The output on the terminal will contain a line similar to + +The output on the terminal will contain a line similar to: ``` Server address: http://127.0.0.1:4000 ``` -open the address in your browser to preview the website. +This address can be opened in your browser to preview the website. + ## Other Resources diff --git a/environment.yml b/environment.yml new file mode 100644 index 00000000..000c4b98 --- /dev/null +++ b/environment.yml @@ -0,0 +1,35 @@ +name: tutorial +channels: + - conda-forge + - defaults +dependencies: + - _libgcc_mutex=0.1=conda_forge + - _openmp_mutex=4.5=0_gnu + - binutils_impl_linux-64=2.33.1=h53a641e_8 + - binutils_linux-64=2.33.1=h9595d00_17 + - ca-certificates=2019.11.28=hecc5488_0 + - gcc_impl_linux-64=7.3.0=hd420e75_5 + - gcc_linux-64=7.3.0=h553295d_17 + - gdbm=1.18=h0a1914f_1 + - gmp=6.2.0=he1b5a44_2 + - gxx_impl_linux-64=7.3.0=hdf63c60_5 + - gxx_linux-64=7.3.0=h553295d_17 + - icu=64.2=he1b5a44_1 + - ld_impl_linux-64=2.33.1=h53a641e_8 + - libffi=3.2.1=he1b5a44_1006 + - libgcc-ng=9.2.0=h24d8f2e_2 + - libgomp=9.2.0=h24d8f2e_2 + - libiconv=1.15=h516909a_1005 + - libstdcxx-ng=9.2.0=hdf63c60_2 + - libxml2=2.9.10=hee79883_0 + - libxslt=1.1.33=h31b3aaa_0 + - ncurses=6.1=hf484d3e_1002 + - openssl=1.1.1d=h516909a_0 + - rb-mini_portile2=2.4.0=hc42de5b_0 + - rb-nokogiri=1.10.8=he0b3888_0 + - readline=8.0=hf8c457e_0 + - ruby=2.6.5=h305c5c1_0 + - xz=5.2.4=h14c3975_1001 + - yaml=0.1.7=h14c3975_1001 + - zlib=1.2.11=h516909a_1006 + From 5f769e9c097cebafcb0488ba954ace9b8afd17d6 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 16:51:50 +0100 Subject: [PATCH 013/647] update key points --- _episodes/03-configuration.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index ec9c88a0..813c314d 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -8,8 +8,9 @@ objectives: - "Understand the data directories structure" - "Configure ESMValTool to ignore some settings" keypoints: -- "The ``config-user.yml`` file tells ESMValTool what data are input" -- "The ``config-user.yml`` file tells ESMValTool what directory is the destination" +- "The ``config-user.yml`` tells ESMValTool about input, output and your preference." +- " ``rootpath`` determines root directory for input data." +- " ``output_dir`` is the destination directory." --- ## The configuration file @@ -38,7 +39,7 @@ This file contains the information for: > No matter what editor you use, you will need to know where it searches for and saves files. If you start it from the shell, it will (probably) use your current working directory as its default location. We use ``nano`` in examples because it is one of the least complex text editors. Press ctrl + O to save the file, and then ctrl + X to exit nano. {: .callout} -## Rootpaths to input data +## Rootpath to input data ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from the climate model intercomparison project whereas OBS for an observational dataset. The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. @@ -57,7 +58,7 @@ rootpath: default: ~/default_inputpath ~~~ -In this lesson, you work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). +In this lesson, we will work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). Add the root path of the folder where you downloaded the data during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). ~~~YAML From 9e47ed67291c38ea462dcdc633897c599e3c381c Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 13 Mar 2020 16:58:08 +0100 Subject: [PATCH 014/647] minor edit --- _episodes/03-configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 813c314d..bc3e1e69 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -36,7 +36,7 @@ This file contains the information for: > ## Which text editor > -> No matter what editor you use, you will need to know where it searches for and saves files. If you start it from the shell, it will (probably) use your current working directory as its default location. We use ``nano`` in examples because it is one of the least complex text editors. Press ctrl + O to save the file, and then ctrl + X to exit nano. +> No matter what editor you use, you will need to know where it searches for and saves files. If you start it from the shell, it will (probably) use your current working directory as its default location. We use ``nano`` in examples because it is one of the least complex text editors. Press ctrl + O to save the file, and then ctrl + X to exit ``nano``. {: .callout} ## Rootpath to input data From 0480d5110e3a633f6cc3930c40cf44f66e9ec080 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Mon, 16 Mar 2020 12:18:46 +0000 Subject: [PATCH 015/647] reduced environment complexity https://github.com/ESMValGroup/tutorial/issues/10#issuecomment-599470258 --- environment.yml | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/environment.yml b/environment.yml index 000c4b98..ee212724 100644 --- a/environment.yml +++ b/environment.yml @@ -1,35 +1,8 @@ -name: tutorial +name: tutorial_short channels: - conda-forge - defaults dependencies: - - _libgcc_mutex=0.1=conda_forge - - _openmp_mutex=4.5=0_gnu - - binutils_impl_linux-64=2.33.1=h53a641e_8 - - binutils_linux-64=2.33.1=h9595d00_17 - - ca-certificates=2019.11.28=hecc5488_0 - - gcc_impl_linux-64=7.3.0=hd420e75_5 - - gcc_linux-64=7.3.0=h553295d_17 - - gdbm=1.18=h0a1914f_1 - - gmp=6.2.0=he1b5a44_2 - - gxx_impl_linux-64=7.3.0=hdf63c60_5 - - gxx_linux-64=7.3.0=h553295d_17 - - icu=64.2=he1b5a44_1 - - ld_impl_linux-64=2.33.1=h53a641e_8 - - libffi=3.2.1=he1b5a44_1006 - - libgcc-ng=9.2.0=h24d8f2e_2 - - libgomp=9.2.0=h24d8f2e_2 - - libiconv=1.15=h516909a_1005 - - libstdcxx-ng=9.2.0=hdf63c60_2 - - libxml2=2.9.10=hee79883_0 - - libxslt=1.1.33=h31b3aaa_0 - - ncurses=6.1=hf484d3e_1002 - - openssl=1.1.1d=h516909a_0 - - rb-mini_portile2=2.4.0=hc42de5b_0 - - rb-nokogiri=1.10.8=he0b3888_0 - - readline=8.0=hf8c457e_0 - - ruby=2.6.5=h305c5c1_0 - - xz=5.2.4=h14c3975_1001 - - yaml=0.1.7=h14c3975_1001 - - zlib=1.2.11=h516909a_1006 - + - gxx_linux-64 + - rb-nokogiri + - ruby From 2710bfa5ba018530fecb760a3571fd26e964699d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 17 Mar 2020 14:48:31 +0100 Subject: [PATCH 016/647] add a template for pull request --- .github/PULL_REQUEST_TEMPLATE.md | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d9eb8c50..10c57fe1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,9 +1,26 @@ -Please delete this line and the text below before submitting your contribution. +# Pull Request checklist ---- +Thanks for contributing! +Please keep in mind that lesson maintainers are volunteers and it may be some time before they can respond to your contribution. Although not all contributions can be incorporated into the lesson materials, we appreciate your time and effort to improve the curriculum. +* * * -Thanks for contributing! If this contribution is for instructor training, please send an email to checkout@carpentries.org with a link to this contribution so we can record your progress. You’ve completed your contribution step for instructor checkout just by submitting this contribution. +**Tasks** -Please keep in mind that lesson maintainers are volunteers and it may be some time before they can respond to your contribution. Although not all contributions can be incorporated into the lesson materials, we appreciate your time and effort to improve the curriculum. If you have any questions about the lesson maintenance process or would like to volunteer your time as a contribution reviewer, please contact The Carpentries Team at team@carpentries.org. +- [ ] Read [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss what you are going to do. +- [ ] Give this pull request a descriptive title. +- [ ] If you are contributing to the lesson materials, make sure the content does not have spelling or grammar errors. +- [ ] Please use `markdownlinter` to check that your files do not contain errors. +- [ ] Preview changes on your own machine before pushing them to GitHub by running `make docker-serve`. ---- +New episode + +- [ ] Follow `Lesson Organization` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Follow `Lesson Formatting` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). + + +If you need help with any of the tasks above, please do not hesitate to ask by commenting in the issue or pull request. + +* * * + +Closes {Link to the corresponding issue} From 8031cc8317bdff0390ae435113e8bb1736747997 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 17 Mar 2020 16:44:37 +0100 Subject: [PATCH 017/647] add two templates for issues --- .github/ISSUE_TEMPLATE.md | 11 ----------- .github/ISSUE_TEMPLATE/bug_report.md | 11 +++++++++++ .github/ISSUE_TEMPLATE/lesson_contribution.md | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 11 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/lesson_contribution.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index ec2d4fe1..00000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,11 +0,0 @@ -Please delete this line and the text below before submitting your contribution. - ---- - -Thanks for contributing! If this contribution is for instructor training, please send an email to checkout@carpentries.org with a link to this contribution so we can record your progress. You’ve completed your contribution step for instructor checkout just by submitting this contribution. - -If this issue is about a specific episode within a lesson, please provide its link or filename. - -Please keep in mind that lesson maintainers are volunteers and it may be some time before they can respond to your contribution. Although not all contributions can be incorporated into the lesson materials, we appreciate your time and effort to improve the curriculum. If you have any questions about the lesson maintenance process or would like to volunteer your time as a contribution reviewer, please contact The Carpentries Team at team@carpentries.org. - ---- diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..d361f8cc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,11 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. If this issue is about a specific episode within a lesson, please provide its link or filename. diff --git a/.github/ISSUE_TEMPLATE/lesson_contribution.md b/.github/ISSUE_TEMPLATE/lesson_contribution.md new file mode 100644 index 00000000..7b8f3b00 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/lesson_contribution.md @@ -0,0 +1,14 @@ +--- +name: New lesson material +about: Develop lessons +title: '' +labels: enhancement +assignees: '' + +--- + +**Short description of the diagnostic** +Add a short description of the mterial that you would like to add. + +**Branch and pull request** +Once you've started working, add the branch (and pull request) link. From c9d8bac8b1ddeef598c7a79a8f1ceaebfb0bba0c Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Wed, 18 Mar 2020 11:46:13 +0100 Subject: [PATCH 018/647] Minor improvements Co-Authored-By: Lee de Mora --- CONTRIBUTING.md | 2 +- environment.yml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 99655e56..4c076207 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -143,7 +143,7 @@ conda env create -f environment.yml -n esmvaltool_tutorial ``` To install the required ruby packages, run the following command in the tutorial's -main directory to build and serve the website locally.: +main directory to build and serve the website locally: ```bash make serve ``` diff --git a/environment.yml b/environment.yml index ee212724..e80a7ff3 100644 --- a/environment.yml +++ b/environment.yml @@ -1,7 +1,6 @@ -name: tutorial_short +name: esmvaltool_tutorial channels: - conda-forge - - defaults dependencies: - gxx_linux-64 - rb-nokogiri From e506f9ac9b79e923e2677eafcf911658d4c22601 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 18 Mar 2020 17:12:37 +0100 Subject: [PATCH 019/647] update the drs for code and data --- _episodes/03-configuration.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index bc3e1e69..17aa13b8 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -17,11 +17,11 @@ keypoints: The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. This is an [YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be found in the root directory of the ESMValTool repository. -Let's change our working directory to ESMValTool, then make a copy of the file and rename it to ``config-user.yml``, then run a text editor called Nano to open it: +Let's change our working directory to ``esmvaltool_tutorial`` that is made during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). Then we copy the config file and rename it to ``config-user.yml``, then run a text editor called Nano to open it: ~~~bash - cd ESMValTool - cp config-user-example.yml config-user.yml + cd esmvaltool_tutorial + cp ESMValTool/config-user-example.yml config-user.yml nano config-user.yml ~~~ @@ -59,17 +59,18 @@ rootpath: ~~~ In this lesson, we will work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). -Add the root path of the folder where you downloaded the data during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). +We add the root path of the folder where data is available. ~~~YAML rootpath: ... - CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2, ~/tutorial/test_data] + CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2, ~/esmvaltool_tutorial/data] ~~~ > ## Setting the correct rootpath > -> For more information about setting the rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). +> * To get the data (or its correct rootpath), check instruction in [Setup](https://esmvalgroup.github.io/tutorial/setup.html). +> * For more information about setting the rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} ## Directory structure for the data from different projects From 4a759c977bedd41aed666c2b3a07856ee8925641 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 19 Mar 2020 15:33:10 +0100 Subject: [PATCH 020/647] fix mardownlint errors --- .github/PULL_REQUEST_TEMPLATE.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 10c57fe1..baa892d0 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,20 +4,19 @@ Thanks for contributing! Please keep in mind that lesson maintainers are volunteers and it may be some time before they can respond to your contribution. Although not all contributions can be incorporated into the lesson materials, we appreciate your time and effort to improve the curriculum. * * * -**Tasks** +## Tasks -- [ ] Read [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). -- [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss what you are going to do. -- [ ] Give this pull request a descriptive title. -- [ ] If you are contributing to the lesson materials, make sure the content does not have spelling or grammar errors. -- [ ] Please use `markdownlinter` to check that your files do not contain errors. -- [ ] Preview changes on your own machine before pushing them to GitHub by running `make docker-serve`. +- [ ] Read [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss what you are going to do. +- [ ] Give this pull request a descriptive title. +- [ ] If you are contributing to the lesson materials, make sure the content does not have spelling or grammar errors. +- [ ] Please use `markdownlint` to check that your files do not contain errors. +- [ ] Preview changes on your own machine before pushing them to GitHub by running `make docker-serve`. New episode -- [ ] Follow `Lesson Organization` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). -- [ ] Follow `Lesson Formatting` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). - +- [ ] Follow `Lesson Organization` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Follow `Lesson Formatting` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). If you need help with any of the tasks above, please do not hesitate to ask by commenting in the issue or pull request. From 9054f643774a24443723ee57a8b2dcc4e1219cd3 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 19 Mar 2020 15:37:58 +0100 Subject: [PATCH 021/647] update the template --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index baa892d0..ccfee6c9 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -13,7 +13,7 @@ Please keep in mind that lesson maintainers are volunteers and it may be some ti - [ ] Please use `markdownlint` to check that your files do not contain errors. - [ ] Preview changes on your own machine before pushing them to GitHub by running `make docker-serve`. -New episode +## More tasks for a new episode - [ ] Follow `Lesson Organization` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). - [ ] Follow `Lesson Formatting` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). From 0fb80f57472d2ce922e0ee0625942ac11b2637ff Mon Sep 17 00:00:00 2001 From: Jaro Camphuijsen Date: Thu, 19 Mar 2020 15:38:18 +0100 Subject: [PATCH 022/647] Update .github/ISSUE_TEMPLATE/lesson_contribution.md fix small typo --- .github/ISSUE_TEMPLATE/lesson_contribution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/lesson_contribution.md b/.github/ISSUE_TEMPLATE/lesson_contribution.md index 7b8f3b00..a979e9f0 100644 --- a/.github/ISSUE_TEMPLATE/lesson_contribution.md +++ b/.github/ISSUE_TEMPLATE/lesson_contribution.md @@ -8,7 +8,7 @@ assignees: '' --- **Short description of the diagnostic** -Add a short description of the mterial that you would like to add. +Add a short description of the material that you would like to add. **Branch and pull request** Once you've started working, add the branch (and pull request) link. From d70a85fbf4730e02e548961f0a0658081a0d6fd5 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 20 Mar 2020 13:55:51 +0100 Subject: [PATCH 023/647] update the tasks for linter, spell checker and codes check --- .github/PULL_REQUEST_TEMPLATE.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ccfee6c9..7fe11fea 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,6 +2,7 @@ Thanks for contributing! Please keep in mind that lesson maintainers are volunteers and it may be some time before they can respond to your contribution. Although not all contributions can be incorporated into the lesson materials, we appreciate your time and effort to improve the curriculum. + * * * ## Tasks @@ -9,14 +10,15 @@ Please keep in mind that lesson maintainers are volunteers and it may be some ti - [ ] Read [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). - [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss what you are going to do. - [ ] Give this pull request a descriptive title. -- [ ] If you are contributing to the lesson materials, make sure the content does not have spelling or grammar errors. -- [ ] Please use `markdownlint` to check that your files do not contain errors. -- [ ] Preview changes on your own machine before pushing them to GitHub by running `make docker-serve`. +- [ ] If you are contributing to the lesson materials, make sure the content does not have spelling or grammar errors. See `Lesson development` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Please use a `markdown lint tool` to check that your files do not contain errors. See `Lesson development` in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Preview changes on your own machine before pushing them to GitHub by running `make serve`, alternatively `make docker-serve`. See `Lesson development` in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] All code instructions have been tested. ## More tasks for a new episode -- [ ] Follow `Lesson Organization` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). -- [ ] Follow `Lesson Formatting` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Follow `Lesson organization` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Follow `Lesson formatting` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). If you need help with any of the tasks above, please do not hesitate to ask by commenting in the issue or pull request. From 55e700ebfb5c3e089ee5a9edd3c28225ab92ce5c Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 23 Mar 2020 18:51:30 +0100 Subject: [PATCH 024/647] Update .github/PULL_REQUEST_TEMPLATE.md Co-Authored-By: Lee de Mora --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7fe11fea..bd6345ef 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,7 +10,7 @@ Please keep in mind that lesson maintainers are volunteers and it may be some ti - [ ] Read [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). - [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss what you are going to do. - [ ] Give this pull request a descriptive title. -- [ ] If you are contributing to the lesson materials, make sure the content does not have spelling or grammar errors. See `Lesson development` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] If you are contributing to the lesson materials, please make sure the content conforms to the `Lesson development` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) and does not contain any spelling or grammatical errors. - [ ] Please use a `markdown lint tool` to check that your files do not contain errors. See `Lesson development` in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). - [ ] Preview changes on your own machine before pushing them to GitHub by running `make serve`, alternatively `make docker-serve`. See `Lesson development` in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). - [ ] All code instructions have been tested. From 620d7700d7e63dc97213cacd44e52314a827b8d3 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 23 Mar 2020 18:51:38 +0100 Subject: [PATCH 025/647] Update .github/PULL_REQUEST_TEMPLATE.md Co-Authored-By: Lee de Mora --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index bd6345ef..740f3666 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -11,7 +11,7 @@ Please keep in mind that lesson maintainers are volunteers and it may be some ti - [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss what you are going to do. - [ ] Give this pull request a descriptive title. - [ ] If you are contributing to the lesson materials, please make sure the content conforms to the `Lesson development` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) and does not contain any spelling or grammatical errors. -- [ ] Please use a `markdown lint tool` to check that your files do not contain errors. See `Lesson development` in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Please use a `markdown lint tool` to check that your markdown files do not contain errors, bugs, or stylistic errors. - [ ] Preview changes on your own machine before pushing them to GitHub by running `make serve`, alternatively `make docker-serve`. See `Lesson development` in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). - [ ] All code instructions have been tested. From 25f7c55a4af1d55713c063fd8ea4453e88fd7e89 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 23 Mar 2020 18:51:51 +0100 Subject: [PATCH 026/647] Update .github/PULL_REQUEST_TEMPLATE.md Co-Authored-By: Lee de Mora --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 740f3666..6b85b802 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,7 +12,7 @@ Please keep in mind that lesson maintainers are volunteers and it may be some ti - [ ] Give this pull request a descriptive title. - [ ] If you are contributing to the lesson materials, please make sure the content conforms to the `Lesson development` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) and does not contain any spelling or grammatical errors. - [ ] Please use a `markdown lint tool` to check that your markdown files do not contain errors, bugs, or stylistic errors. -- [ ] Preview changes on your own machine before pushing them to GitHub by running `make serve`, alternatively `make docker-serve`. See `Lesson development` in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). +- [ ] Preview changes on your own machine before pushing them to GitHub by running `make serve`, alternatively `make docker-serve`. Please see the `Previewing your changes locally` section in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) for installation instructions. - [ ] All code instructions have been tested. ## More tasks for a new episode From e09c2cbcd7f00b61f26f6244139a0db8f4f701b4 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 24 Mar 2020 10:06:46 +0100 Subject: [PATCH 027/647] Update .github/PULL_REQUEST_TEMPLATE.md Co-Authored-By: Jaro Camphuijsen --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6b85b802..674497fd 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -11,7 +11,7 @@ Please keep in mind that lesson maintainers are volunteers and it may be some ti - [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss what you are going to do. - [ ] Give this pull request a descriptive title. - [ ] If you are contributing to the lesson materials, please make sure the content conforms to the `Lesson development` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) and does not contain any spelling or grammatical errors. -- [ ] Please use a `markdown lint tool` to check that your markdown files do not contain errors, bugs, or stylistic errors. +- [ ] Please use a `markdownlint` tool to check that your markdown files do not contain errors, bugs, or stylistic errors. - [ ] Preview changes on your own machine before pushing them to GitHub by running `make serve`, alternatively `make docker-serve`. Please see the `Previewing your changes locally` section in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) for installation instructions. - [ ] All code instructions have been tested. From 5b8c4d8855627430bab7763d328cf681398745e7 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 25 Mar 2020 16:51:21 +0100 Subject: [PATCH 028/647] replace markdownlint with codacy --- .github/PULL_REQUEST_TEMPLATE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 674497fd..6235118c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,9 +10,9 @@ Please keep in mind that lesson maintainers are volunteers and it may be some ti - [ ] Read [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). - [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss what you are going to do. - [ ] Give this pull request a descriptive title. -- [ ] If you are contributing to the lesson materials, please make sure the content conforms to the `Lesson development` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) and does not contain any spelling or grammatical errors. -- [ ] Please use a `markdownlint` tool to check that your markdown files do not contain errors, bugs, or stylistic errors. -- [ ] Preview changes on your own machine before pushing them to GitHub by running `make serve`, alternatively `make docker-serve`. Please see the `Previewing your changes locally` section in[CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) for installation instructions. +- [ ] If you are contributing to the lesson materials, please make sure the content conforms to the `Lesson development` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) and does not contain any spelling or grammatical errors. +- [ ] Preferably Codacy code quality checks pass. However, a few remaining hard to solve Codacy issues are still acceptable. Status can be seen below your pull request. If there is an error, click the link to find out why. If you suspect Codacy may be wrong, please ask by commenting. +- [ ] Preview changes on your machine before pushing them to GitHub by running `make serve`, alternatively `make docker-serve`. Please see the `Previewing your changes locally` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) for installation instructions. - [ ] All code instructions have been tested. ## More tasks for a new episode From a98404a73e6a6b70c1b4e983461061dcab75a391 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 3 Apr 2020 13:33:10 +0200 Subject: [PATCH 029/647] refactor the task list --- .github/PULL_REQUEST_TEMPLATE.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6235118c..b8efd81c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -5,21 +5,20 @@ Please keep in mind that lesson maintainers are volunteers and it may be some ti * * * -## Tasks +## Before you start - [ ] Read [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). -- [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss what you are going to do. +- [ ] Create an [issue](https://github.com/ESMValGroup/tutorial/issues) to discuss your idea. This allows your contributions to be incorporated into the tutorial. + +## Tasks + - [ ] Give this pull request a descriptive title. -- [ ] If you are contributing to the lesson materials, please make sure the content conforms to the `Lesson development` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) and does not contain any spelling or grammatical errors. -- [ ] Preferably Codacy code quality checks pass. However, a few remaining hard to solve Codacy issues are still acceptable. Status can be seen below your pull request. If there is an error, click the link to find out why. If you suspect Codacy may be wrong, please ask by commenting. +- [ ] If you are contributing to existing lesson materials, please make sure the content conforms to the `Lesson development` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) and does not contain any spelling or grammatical errors. +- [ ] If you are making a new episode, please make sure the content conforms to the `Lesson organization` and `Lesson formatting` sections in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) and does not contain any spelling or grammatical errors. +- [ ] Preferably Codacy checks pass. Status can be seen below your pull request. If there is an error, click the link to find out why. - [ ] Preview changes on your machine before pushing them to GitHub by running `make serve`, alternatively `make docker-serve`. Please see the `Previewing your changes locally` section in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md) for installation instructions. - [ ] All code instructions have been tested. -## More tasks for a new episode - -- [ ] Follow `Lesson organization` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). -- [ ] Follow `Lesson formatting` in [CONTRIBUTING.md](https://github.com/ESMValGroup/tutorial/blob/master/CONTRIBUTING.md). - If you need help with any of the tasks above, please do not hesitate to ask by commenting in the issue or pull request. * * * From 8f2f86bc83a2e8fbae5e4a49d0f1314e7b7eb65d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 3 Apr 2020 13:38:20 +0200 Subject: [PATCH 030/647] update the top comment --- .github/PULL_REQUEST_TEMPLATE.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b8efd81c..f2057735 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,7 +1,6 @@ # Pull Request checklist -Thanks for contributing! -Please keep in mind that lesson maintainers are volunteers and it may be some time before they can respond to your contribution. Although not all contributions can be incorporated into the lesson materials, we appreciate your time and effort to improve the curriculum. +We appreciate your time and effort to improve the tutorial. Please keep in mind that lesson maintainers are volunteers and it may be some time before they can respond to your contribution. * * * From c0a113a01f2da1e4f2ea6c8844d09610f1d5693c Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 6 Apr 2020 13:36:43 +0200 Subject: [PATCH 031/647] update the template --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/lesson_contribution.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d361f8cc..cc3a90a6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -8,4 +8,4 @@ assignees: '' --- **Describe the bug** -A clear and concise description of what the bug is. If this issue is about a specific episode within a lesson, please provide its link or filename. +A clear and concise description of what the bug is. If this issue is about a specific episode, please provide its link or filename. diff --git a/.github/ISSUE_TEMPLATE/lesson_contribution.md b/.github/ISSUE_TEMPLATE/lesson_contribution.md index a979e9f0..003dddd8 100644 --- a/.github/ISSUE_TEMPLATE/lesson_contribution.md +++ b/.github/ISSUE_TEMPLATE/lesson_contribution.md @@ -7,7 +7,7 @@ assignees: '' --- -**Short description of the diagnostic** +**Short description of the material** Add a short description of the material that you would like to add. **Branch and pull request** From 9e66c130b61159420a07ef069ea8fbb978562750 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 6 Apr 2020 16:01:23 +0200 Subject: [PATCH 032/647] update readme and contributig --- CONTRIBUTING.md | 12 ++++++++---- README.md | 8 ++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4c076207..74deaa15 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,13 @@ # Contributing -The format of this tutorial is based on the [The Carpentries][c-site] ([Software Carpentry][swc-site], [Data Carpentry][dc-site], and [Library Carpentry][lc-site]), which are open source projects. We welcome contributions of all kinds: -fixes to this tutorial, -bug reports, -and reviews of proposed changes are all welcome. +We greatly value contributions of any kind. Contributions could include fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please do not hesitate to propose them. + +If you have a bug or other issue to report or just need help, please open an [issue]. + +If you would like to contribute a new diagnostic and recipe or a new feature, please discuss your idea with the development team before getting started, to avoid double work and/or disappointment later. A good way to do this is to open an issue on GitHub. This is also a good way to get help. + +The format of this tutorial is based on the [Software Carpentry][swc-site], which is an open source project. We welcome contributions of all kinds: +fixes to this tutorial, bug reports, and reviews of proposed changes. ## Contributor Agreement diff --git a/README.md b/README.md index 13a08f3b..99705cf7 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# FIXME Lesson title +# Welcome to ESMValTool tutorial [![Create a Slack Account with us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/) -This repository generates the corresponding lesson website from [The Carpentries](https://carpentries.org/) repertoire of lessons. +This repository generates the corresponding lesson website from [The Carpentries](https://carpentries.org/) repertoire of lessons. ## Contributing @@ -17,12 +17,12 @@ Please see the current list of [issues][FIXME] for ideas for contributing to thi repository. For making your contribution, we use the GitHub flow, which is nicely explained in the chapter [Contributing to a Project](http://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project) in Pro Git by Scott Chacon. -Look for the tag ![good_first_issue](https://img.shields.io/badge/-good%20first%20issue-gold.svg). This indicates that the maintainers will welcome a pull request fixing this issue. +Look for the tag ![good_first_issue](https://img.shields.io/badge/-good%20first%20issue-gold.svg). This indicates that the maintainers will welcome a pull request fixing this issue. ## Maintainer(s) -Current maintainers of this lesson are +Current maintainers of this lesson are * FIXME * FIXME From 84cccafac415ed98305e67ab7e5ca023acbf8a6d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 6 Apr 2020 16:09:40 +0200 Subject: [PATCH 033/647] add another template for a new feature --- .github/ISSUE_TEMPLATE/new_feature.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/new_feature.md diff --git a/.github/ISSUE_TEMPLATE/new_feature.md b/.github/ISSUE_TEMPLATE/new_feature.md new file mode 100644 index 00000000..0f1d5c16 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new_feature.md @@ -0,0 +1,14 @@ +--- +name: New feature +about: Suggest a feature for the tutorial repository +title: '' +labels: feature +assignees: '' + +--- + +**Is your feature related to a problem? Please describe.** +A clear and concise description of what the problem is. + +**Would you be able to help out?** +Would you have the time and skills to implement the solution yourself? From f607be16a6ee94a43302b527176bb2258d7e1e30 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 6 Apr 2020 17:57:08 +0200 Subject: [PATCH 034/647] restructure the content --- CONTRIBUTING.md | 147 +++++++++++++++++------------------------------- 1 file changed, 53 insertions(+), 94 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74deaa15..9c022e0d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,114 +1,77 @@ -# Contributing +# Contributing to ESMValTool tutorial -We greatly value contributions of any kind. Contributions could include fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please do not hesitate to propose them. +[ESMValTool](https://www.esmvaltool.org/) tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues] by choosing the ``new feature`` template. -If you have a bug or other issue to report or just need help, please open an [issue]. +## Acknowledgement -If you would like to contribute a new diagnostic and recipe or a new feature, please discuss your idea with the development team before getting started, to avoid double work and/or disappointment later. A good way to do this is to open an issue on GitHub. This is also a good way to get help. +The format of this tutorial is based on the [Software Carpentry][swc-site], which is an open-source project. +TODO escience academy -The format of this tutorial is based on the [Software Carpentry][swc-site], which is an open source project. We welcome contributions of all kinds: -fixes to this tutorial, bug reports, and reviews of proposed changes. +## Agreement -## Contributor Agreement - -By contributing, -you agree that we may redistribute your work under [our license](LICENSE.md). -In exchange, -we will address your issues and/or assess your change proposal as promptly as we can, -and help you become a member of our community. -Everyone involved in [The Carpentries][c-site] -agrees to abide by our [code of conduct](CODE_OF_CONDUCT.md). +By contributing, you agree that we may redistribute your work under [our license](LICENSE.md). +In exchange, we will address your issues and/or assess your change proposal as promptly as we can, and help you become a member of our community. +Everyone involved in this [tutorial](site) agrees to abide by our [code of conduct](CODE_OF_CONDUCT.md). ## How to Contribute -The easiest way to get started is to file an issue -to tell us about a spelling mistake, -some awkward wording, -or a factual error. -This is a good way to introduce yourself -and to meet some of our community members. +There are many ways to contribute: -1. If you do not have a [GitHub][github] account, - you can [send us comments by email][email]. - However, - we will be able to respond more quickly if you use one of the other methods described below. +If you wish to change this tutorial, +please work in , +which can be viewed at . +There are many ways to contribute, +from writing new exercises and improving existing ones +to updating or filling in the documentation +and submitting [bug reports][issues] +about things that don't work, aren't clear, or are missing. +If you are looking for ideas, please see the 'Issues' tab for +a list of issues associated with this repository, -2. If you have a [GitHub][github] account, - or are willing to [create one][github-join], - but do not know how to use Git, - you can report problems or suggest improvements by [creating an issue][issues]. - This allows us to assign the item to someone - and to respond to it in a threaded discussion. -3. If you are comfortable with Git, - and would like to add or change material, - you can submit a pull request (PR). - Instructions for doing this are [included below](#using-github). -## Where to Contribute +* If you do not have a [GitHub][github] account, +you can [send us comments by email][email]. +However, +we will be able to respond more quickly if you use one of the other methods described below. -1. If you wish to change this tutorial, - please work in , - which can be viewed at . +* If you have a [GitHub][github] account, +or are willing to [create one][github-join], +you can report problems or suggest improvements by [creating an issue][issues]. +This is the easiest way to tell us about your ideas, +and a good way to introduce yourself +and to meet some of our community members. +This allows us to assign the item to someone +and to respond to it in a threaded discussion. +There are three templates to make an issue: + * for reporting a bug, please use [bug reports][issues] + * for developing lesson material, please use [New lesson material][issues] + * for adding a feature to the repository, please use [New feature][issues] -2. If you wish to change the Carpentries example lesson, - please work in , - which documents the format of the Carpentry lessons - and can be viewed at . +* If you would like to add what is already discussed in an issue, +you can submit a [pull request][PR]. +To do so, you can make use of the [pull request checklist][PR]. +The reviewers are community volunteers to provide feedback. +The maintainers have final say over what gets merged into the tutorial. -3. If you wish to change the template used for Carpentry workshop websites, - please work in . - The home page of that repository explains how to set up Carpentry workshop websites, - while the extra pages in - provide more background on our design choices. +## Lesson development guides -4. If you wish to change CSS style files, tools, - or HTML boilerplate for lessons or workshops stored in `_includes` or `_layouts`, - please work in . +### Lesson development + +### Lesson organization + +### Lesson formatting + +### Preview your changes locally -## What to Contribute -There are many ways to contribute, -from writing new exercises and improving existing ones -to updating or filling in the documentation -and submitting [bug reports][issues] -about things that don't work, aren't clear, or are missing. -If you are looking for ideas, please see the 'Issues' tab for -a list of issues associated with this repository, -or you may also look at the issues for [Data Carpentry][dc-issues], -[Software Carpentry][swc-issues], and [Library Carpentry][lc-issues] projects. - -Comments on issues and reviews of pull requests are just as welcome: -we are smarter together than we are on our own. -Reviews from novices and newcomers are particularly valuable: -it's easy for people who have been using these lessons for a while -to forget how impenetrable some of this material can be, -so fresh eyes are always welcome. - -## What *Not* to Contribute - -Our lessons already contain more material than we can cover in a typical workshop, -so we are usually *not* looking for more concepts or tools to add to them. -As a rule, -if you want to introduce a new idea, -you must (a) estimate how long it will take to teach -and (b) explain what you would take out to make room for it. -The first encourages contributors to be honest about requirements; -the second, to think hard about priorities. - -We are also not looking for exercises or other material that only run on one platform. -Our workshops typically contain a mixture of Windows, macOS, and Linux users; -in order to be usable, -our lessons must run equally well on all three. ## Using GitHub If you choose to contribute via GitHub, you may want to look at [How to Contribute to an Open Source Project on GitHub][how-contribute]. To manage changes, we follow [GitHub flow][github-flow]. -Each lesson has two maintainers who review issues and pull requests or encourage others to do so. -The maintainers are community volunteers and have final say over what gets merged into the lesson. -To use the web interface for contributing to a lesson: + 1. Fork the originating repository to your GitHub profile. 2. Within your version of the forked repository, move to the `gh-pages` branch and @@ -117,9 +80,7 @@ create a new branch for each significant change being made. 4. Commit all changed files within the appropriate branches. 5. Create individual pull requests from each of your changed branches to the `gh-pages` branch within the originating repository. -6. If you receive feedback, make changes using your issue-specific branches of the forked -repository and the pull requests will update automatically. -7. Repeat as needed until all feedback has been addressed. + When starting work, please make sure your clone of the originating `gh-pages` branch is up-to-date before creating your own revision-specific branch(es) from there. @@ -167,15 +128,13 @@ which everyone is welcome to join. You can also [reach us by email][email]. [email]: mailto:admin@software-carpentry.org -[dc-issues]: https://github.com/issues?q=user%3Adatacarpentry -[dc-lessons]: http://datacarpentry.org/lessons/ -[dc-site]: http://datacarpentry.org/ +[site]: https://esmvalgroup.github.io/tutorial/ [discuss-list]: http://lists.software-carpentry.org/listinfo/discuss [github]: https://github.com [github-flow]: https://guides.github.com/introduction/flow/ [github-join]: https://github.com/join [how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github -[issues]: https://guides.github.com/features/issues/ +[issues]: https://github.com/ESMValGroup/tutorial/issues [swc-issues]: https://github.com/issues?q=user%3Aswcarpentry [swc-lessons]: https://software-carpentry.org/lessons/ [swc-site]: https://software-carpentry.org/ From 2bd93d766c2a3bf13d6f25612653c3759c6f36e0 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 7 Apr 2020 13:56:04 +0200 Subject: [PATCH 035/647] add guides for developing lessons --- CONTRIBUTING.md | 64 +++++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 45 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9c022e0d..fcf2502d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,11 @@ # Contributing to ESMValTool tutorial -[ESMValTool](https://www.esmvaltool.org/) tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues] by choosing the ``new feature`` template. +[ESMValTool](https://www.esmvaltool.org/) tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues] by choosing the ``New feature`` template in the ``issues`` tab of this repository. ## Acknowledgement +The [eScience academy][ea-site] initiated this tutorial. The format of this tutorial is based on the [Software Carpentry][swc-site], which is an open-source project. -TODO escience academy ## Agreement @@ -17,19 +17,6 @@ Everyone involved in this [tutorial](site) agrees to abide by our [code of condu There are many ways to contribute: -If you wish to change this tutorial, -please work in , -which can be viewed at . -There are many ways to contribute, -from writing new exercises and improving existing ones -to updating or filling in the documentation -and submitting [bug reports][issues] -about things that don't work, aren't clear, or are missing. -If you are looking for ideas, please see the 'Issues' tab for -a list of issues associated with this repository, - - - * If you do not have a [GitHub][github] account, you can [send us comments by email][email]. However, @@ -37,7 +24,9 @@ we will be able to respond more quickly if you use one of the other methods desc * If you have a [GitHub][github] account, or are willing to [create one][github-join], -you can report problems or suggest improvements by [creating an issue][issues]. +please work in this [repository][site], +which can be viewed at . +You can report problems or suggest improvements by [creating an issue][issues]. This is the easiest way to tell us about your ideas, and a good way to introduce yourself and to meet some of our community members. @@ -51,72 +40,54 @@ There are three templates to make an issue: * If you would like to add what is already discussed in an issue, you can submit a [pull request][PR]. To do so, you can make use of the [pull request checklist][PR]. -The reviewers are community volunteers to provide feedback. +The reviewers are community volunteers who provide feedback. The maintainers have final say over what gets merged into the tutorial. ## Lesson development guides +This tutorial is developed based on the [Carpentries Curriculum Development Handbook][swc-handbook]. + ### Lesson development ### Lesson organization ### Lesson formatting -### Preview your changes locally - - - -## Using GitHub - -If you choose to contribute via GitHub, you may want to look at -[How to Contribute to an Open Source Project on GitHub][how-contribute]. -To manage changes, we follow [GitHub flow][github-flow]. - - -1. Fork the originating repository to your GitHub profile. -2. Within your version of the forked repository, move to the `gh-pages` branch and -create a new branch for each significant change being made. -3. Navigate to the file(s) you wish to change within the new branches and make revisions as required. -4. Commit all changed files within the appropriate branches. -5. Create individual pull requests from each of your changed branches -to the `gh-pages` branch within the originating repository. - - -When starting work, please make sure your clone of the originating `gh-pages` branch is up-to-date -before creating your own revision-specific branch(es) from there. -Additionally, please only work from your newly-created branch(es) and *not* -your clone of the originating `gh-pages` branch. -Lastly, published copies of all the lessons are available in the `gh-pages` branch of the originating -repository for reference while revising. - ## Previewing your changes locally Extensive instructions for building and viewing the pages locally can be found [here](https://carpentries.github.io/lesson-example/setup.html). To get started quickly, run + ```bash # apt (Ubuntu/Devian) sudo apt install ruby-dev ruby-bundler ``` + or + ```bash # dnf (Fedora/Redhat) sudo dnf install rubygem-bundler ruby-devel ``` Alternatively, there's an environment file available which can be installed in conda with: + ```bash conda env create -f environment.yml -n esmvaltool_tutorial ``` To install the required ruby packages, run the following command in the tutorial's main directory to build and serve the website locally: + ```bash make serve ``` The output on the terminal will contain a line similar to: -``` + +```bash Server address: http://127.0.0.1:4000 ``` + This address can be opened in your browser to preview the website. @@ -135,9 +106,12 @@ You can also [reach us by email][email]. [github-join]: https://github.com/join [how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github [issues]: https://github.com/ESMValGroup/tutorial/issues +[PR]: https://github.com/ESMValGroup/tutorial/pulls [swc-issues]: https://github.com/issues?q=user%3Aswcarpentry [swc-lessons]: https://software-carpentry.org/lessons/ [swc-site]: https://software-carpentry.org/ +[swc-handbook]: https://carpentries.github.io/curriculum-development/ +[ea-site]: https://github.com/escience-academy [c-site]: https://carpentries.org/ [lc-site]: https://librarycarpentry.org/ [lc-issues]: https://github.com/issues?q=user%3Alibrarycarpentry From fb2b38e765fcb641062bea7140b327c670a343e9 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 8 Apr 2020 10:55:04 +0200 Subject: [PATCH 036/647] add SWC links --- CONTRIBUTING.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fcf2502d..7537768e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,16 +43,24 @@ To do so, you can make use of the [pull request checklist][PR]. The reviewers are community volunteers who provide feedback. The maintainers have final say over what gets merged into the tutorial. -## Lesson development guides +## Tutorial content guides -This tutorial is developed based on the [Carpentries Curriculum Development Handbook][swc-handbook]. +This section demonstrates all the features that can be used when developing a lesson in [RMarkdown] (https://rmarkdown.rstudio.com/). +TODO level ### Lesson development +The content of this tutorial is developed based on the [Carpentries Curriculum Development Handbook][swc-handbook]. + ### Lesson organization +https://carpentries.github.io/lesson-example/03-organization/index.html + + ### Lesson formatting +https://carpentries.github.io/lesson-example/04-formatting/index.html + ## Previewing your changes locally Extensive instructions for building and viewing the pages locally can be found [here](https://carpentries.github.io/lesson-example/setup.html). To get started quickly, run From 4e369d9d9683cb39865cb7d337d00d4b480baf94 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 8 Apr 2020 11:34:14 +0200 Subject: [PATCH 037/647] rename one of the templates, add a new template for questions --- .../{new_feature.md => feature_suggestion.md} | 4 ++-- .github/ISSUE_TEMPLATE/q_and_a.md | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) rename .github/ISSUE_TEMPLATE/{new_feature.md => feature_suggestion.md} (89%) create mode 100644 .github/ISSUE_TEMPLATE/q_and_a.md diff --git a/.github/ISSUE_TEMPLATE/new_feature.md b/.github/ISSUE_TEMPLATE/feature_suggestion.md similarity index 89% rename from .github/ISSUE_TEMPLATE/new_feature.md rename to .github/ISSUE_TEMPLATE/feature_suggestion.md index 0f1d5c16..73b41f30 100644 --- a/.github/ISSUE_TEMPLATE/new_feature.md +++ b/.github/ISSUE_TEMPLATE/feature_suggestion.md @@ -1,8 +1,8 @@ --- -name: New feature +name: Suggestion about: Suggest a feature for the tutorial repository title: '' -labels: feature +labels: enhancement assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/q_and_a.md b/.github/ISSUE_TEMPLATE/q_and_a.md new file mode 100644 index 00000000..a728580f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/q_and_a.md @@ -0,0 +1,11 @@ +--- +name: Question and answer +about: Ask your questions +title: '' +labels: question +assignees: '' + +--- + +**How can we help?** +Please write your questions in this issue. We are here to answer. From 9033e5bea3bcccf531cbfeaf4706584ed2c77b67 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 8 Apr 2020 11:55:13 +0200 Subject: [PATCH 038/647] fix the names of issue templates in the text --- CONTRIBUTING.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7537768e..7ae6bada 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to ESMValTool tutorial -[ESMValTool](https://www.esmvaltool.org/) tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues] by choosing the ``New feature`` template in the ``issues`` tab of this repository. +[ESMValTool](https://www.esmvaltool.org/) tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues] by choosing the ``Suggestion`` template in the ``issues`` tab of this repository. ## Acknowledgement @@ -26,16 +26,17 @@ we will be able to respond more quickly if you use one of the other methods desc or are willing to [create one][github-join], please work in this [repository][site], which can be viewed at . -You can report problems or suggest improvements by [creating an issue][issues]. +You can ask your questions, report problems or suggest improvements by [creating an issue][issues]. This is the easiest way to tell us about your ideas, and a good way to introduce yourself and to meet some of our community members. This allows us to assign the item to someone and to respond to it in a threaded discussion. -There are three templates to make an issue: - * for reporting a bug, please use [bug reports][issues] +There are several templates to make an issue: + * for asking a question, please use [Question and answer][issues] + * for reporting a bug, please use [Bug reports][issues] * for developing lesson material, please use [New lesson material][issues] - * for adding a feature to the repository, please use [New feature][issues] + * for adding a feature to the repository, please use [Suggestion][issues] * If you would like to add what is already discussed in an issue, you can submit a [pull request][PR]. From 65aecff3d1447e776ed85efddad3e0559700e6e3 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 8 Apr 2020 12:25:46 +0200 Subject: [PATCH 039/647] add text to the section tutorial guidelines --- CONTRIBUTING.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ae6bada..04031528 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to ESMValTool tutorial -[ESMValTool](https://www.esmvaltool.org/) tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues] by choosing the ``Suggestion`` template in the ``issues`` tab of this repository. +[ESMValTool][ESMValTool-site] tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues] by choosing the ``Suggestion`` template in the ``issues`` tab of this repository. ## Acknowledgement @@ -11,7 +11,7 @@ The format of this tutorial is based on the [Software Carpentry][swc-site], whic By contributing, you agree that we may redistribute your work under [our license](LICENSE.md). In exchange, we will address your issues and/or assess your change proposal as promptly as we can, and help you become a member of our community. -Everyone involved in this [tutorial](site) agrees to abide by our [code of conduct](CODE_OF_CONDUCT.md). +Everyone involved in this [tutorial](tutorial-repo) agrees to abide by our [code of conduct](CODE_OF_CONDUCT.md). ## How to Contribute @@ -24,8 +24,8 @@ we will be able to respond more quickly if you use one of the other methods desc * If you have a [GitHub][github] account, or are willing to [create one][github-join], -please work in this [repository][site], -which can be viewed at . +please work in this [repository][tutorial-repo], +which can be viewed at the [tutorial site][tutorial-site]. You can ask your questions, report problems or suggest improvements by [creating an issue][issues]. This is the easiest way to tell us about your ideas, and a good way to introduce yourself @@ -44,23 +44,24 @@ To do so, you can make use of the [pull request checklist][PR]. The reviewers are community volunteers who provide feedback. The maintainers have final say over what gets merged into the tutorial. -## Tutorial content guides +## Tutorial guidelines -This section demonstrates all the features that can be used when developing a lesson in [RMarkdown] (https://rmarkdown.rstudio.com/). -TODO level +This section demonstrates all the instructions for developing a lesson in the [ESMValTool tutorial][tutorial-site]. +The tutorial is a set of lessons (or episodes) that together teach **basic** skills needed to work with [ESMValTool][ESMValTool-site] in climate-related domains. ### Lesson development -The content of this tutorial is developed based on the [Carpentries Curriculum Development Handbook][swc-handbook]. +The content of this tutorial is mainly developed based on the [Carpentries Curriculum Development Handbook][swc-handbook]. +The handbook explains why we teach the way we do, and why our lessons are designed the way they are. ### Lesson organization -https://carpentries.github.io/lesson-example/03-organization/index.html +[swc-lesson-organization] ### Lesson formatting - -https://carpentries.github.io/lesson-example/04-formatting/index.html +[RMarkdown](https://rmarkdown.rstudio.com/) +[swc-lesson-formatting] ## Previewing your changes locally @@ -108,7 +109,9 @@ which everyone is welcome to join. You can also [reach us by email][email]. [email]: mailto:admin@software-carpentry.org -[site]: https://esmvalgroup.github.io/tutorial/ +[ESMValTool-site]: https://www.esmvaltool.org/ +[tutorial-repo]: https://esmvalgroup.github.io/tutorial/ +[tutorial-site]: https://esmvalgroup.github.io/tutorial [discuss-list]: http://lists.software-carpentry.org/listinfo/discuss [github]: https://github.com [github-flow]: https://guides.github.com/introduction/flow/ @@ -120,6 +123,8 @@ You can also [reach us by email][email]. [swc-lessons]: https://software-carpentry.org/lessons/ [swc-site]: https://software-carpentry.org/ [swc-handbook]: https://carpentries.github.io/curriculum-development/ +[swc-lesson-organization]: https://carpentries.github.io/lesson-example/03-organization/index.html +[swc-lesson-formatting]: https://carpentries.github.io/lesson-example/04-formatting/index.html [ea-site]: https://github.com/escience-academy [c-site]: https://carpentries.org/ [lc-site]: https://librarycarpentry.org/ From a5d9285cf796887d2acd7c94e22a333e4b88418b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 8 Apr 2020 13:07:06 +0200 Subject: [PATCH 040/647] update text in the section lesson development --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 04031528..9c783e73 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,6 +53,7 @@ The tutorial is a set of lessons (or episodes) that together teach **basic** ski The content of this tutorial is mainly developed based on the [Carpentries Curriculum Development Handbook][swc-handbook]. The handbook explains why we teach the way we do, and why our lessons are designed the way they are. +If you are contributing to existing lesson materials, please make sure the content conforms to the concepts provided in the handbook and does not contain any spelling or grammatical errors. ### Lesson organization From ff379561aa2290874463ff0c69aece3588ce282d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 8 Apr 2020 13:15:54 +0200 Subject: [PATCH 041/647] adding two more labels to the templates --- .github/ISSUE_TEMPLATE/feature_suggestion.md | 2 +- .github/ISSUE_TEMPLATE/lesson_contribution.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_suggestion.md b/.github/ISSUE_TEMPLATE/feature_suggestion.md index 73b41f30..5553e718 100644 --- a/.github/ISSUE_TEMPLATE/feature_suggestion.md +++ b/.github/ISSUE_TEMPLATE/feature_suggestion.md @@ -2,7 +2,7 @@ name: Suggestion about: Suggest a feature for the tutorial repository title: '' -labels: enhancement +labels: enhancement, feature assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/lesson_contribution.md b/.github/ISSUE_TEMPLATE/lesson_contribution.md index 003dddd8..8107942d 100644 --- a/.github/ISSUE_TEMPLATE/lesson_contribution.md +++ b/.github/ISSUE_TEMPLATE/lesson_contribution.md @@ -2,7 +2,7 @@ name: New lesson material about: Develop lessons title: '' -labels: enhancement +labels: enhancement, lesson assignees: '' --- From 9eeac8e7e16126c7ca75b63af097785fa03632f8 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 9 Apr 2020 17:43:29 +0200 Subject: [PATCH 042/647] update the section lesson development --- CONTRIBUTING.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9c783e73..2ef1e883 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,6 @@ ## Acknowledgement -The [eScience academy][ea-site] initiated this tutorial. The format of this tutorial is based on the [Software Carpentry][swc-site], which is an open-source project. ## Agreement @@ -42,7 +41,7 @@ There are several templates to make an issue: you can submit a [pull request][PR]. To do so, you can make use of the [pull request checklist][PR]. The reviewers are community volunteers who provide feedback. -The maintainers have final say over what gets merged into the tutorial. +The [maintainers][tutorial-maintainers] have final say over what gets merged into the tutorial. ## Tutorial guidelines @@ -51,9 +50,12 @@ The tutorial is a set of lessons (or episodes) that together teach **basic** ski ### Lesson development -The content of this tutorial is mainly developed based on the [Carpentries Curriculum Development Handbook][swc-handbook]. -The handbook explains why we teach the way we do, and why our lessons are designed the way they are. -If you are contributing to existing lesson materials, please make sure the content conforms to the concepts provided in the handbook and does not contain any spelling or grammatical errors. +The content of this tutorial is mainly developed based on the [Carpentries Curriculum Development Handbook][swc-handbook]. The handbook explains why we teach the way we do, and why our lessons are designed the way they are. +If you are contributing to existing lesson materials, please make sure the content conforms to the concepts provided in the handbook. + +We recommend using software to check spelling or grammatical errors. +The following link will guide you through a list of tools for several editors: + ### Lesson organization @@ -113,6 +115,7 @@ You can also [reach us by email][email]. [ESMValTool-site]: https://www.esmvaltool.org/ [tutorial-repo]: https://esmvalgroup.github.io/tutorial/ [tutorial-site]: https://esmvalgroup.github.io/tutorial +[tutorial-maintainers]: https://github.com/ESMValGroup/tutorial#maintainers [discuss-list]: http://lists.software-carpentry.org/listinfo/discuss [github]: https://github.com [github-flow]: https://guides.github.com/introduction/flow/ From 4ef064f90e4a816fbecbff09b4213c3704f3d9a4 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 9 Apr 2020 18:01:49 +0200 Subject: [PATCH 043/647] update the text in section lesson formatting --- CONTRIBUTING.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ef1e883..c7db5e97 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,12 +59,24 @@ The following link will guide you through a list of tools for several editors: ### Lesson organization -[swc-lesson-organization] - +Each lesson is made up of episodes, which are focused on a particular topic and include time for both teaching and exercises. If you are making a new episode, please make sure the content conforms to the [Carpentries lesson organization][swc-lesson-organization]. ### Lesson formatting -[RMarkdown](https://rmarkdown.rstudio.com/) -[swc-lesson-formatting] + +Episodes files are [Markdown](https://en.wikipedia.org/wiki/Markdown) files. If you are making a new episode or contributing to existing ones, please make sure the content conforms to the [Carpentries lesson formatting][swc-lesson-formatting]. +We recommend using a linter to check errors in Markdown files. +For example, a [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) can be installed as an extension in ``Visual Studio Code``. +Alternatively, it can installed with: + +```bash +gem install mdl +``` + +and can be used as: + +```bash +mdl your_markdown_filename +``` ## Previewing your changes locally From 5e3667fcf8d1572d1c9295647eb7c271436d6265 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 15:05:02 +0200 Subject: [PATCH 044/647] revise the text --- CONTRIBUTING.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7db5e97..8d2e114b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,18 +19,14 @@ There are many ways to contribute: * If you do not have a [GitHub][github] account, you can [send us comments by email][email]. However, -we will be able to respond more quickly if you use one of the other methods described below. +we will be able to respond more quickly when you use one of the other methods described below. -* If you have a [GitHub][github] account, -or are willing to [create one][github-join], -please work in this [repository][tutorial-repo], +* If you have a [GitHub][github] account, work in this [repository][tutorial-repo], which can be viewed at the [tutorial site][tutorial-site]. You can ask your questions, report problems or suggest improvements by [creating an issue][issues]. -This is the easiest way to tell us about your ideas, -and a good way to introduce yourself +This is the easiest way to tell us about your ideas, and a good way to introduce yourself and to meet some of our community members. -This allows us to assign the item to someone -and to respond to it in a threaded discussion. +This allows us to assign the item to someone and to respond to it in a threaded discussion. There are several templates to make an issue: * for asking a question, please use [Question and answer][issues] * for reporting a bug, please use [Bug reports][issues] @@ -40,7 +36,7 @@ There are several templates to make an issue: * If you would like to add what is already discussed in an issue, you can submit a [pull request][PR]. To do so, you can make use of the [pull request checklist][PR]. -The reviewers are community volunteers who provide feedback. +Each pull request is reviewed at least by one reviewer who is a community volunteer and provides feedback. The [maintainers][tutorial-maintainers] have final say over what gets merged into the tutorial. ## Tutorial guidelines @@ -66,7 +62,7 @@ Each lesson is made up of episodes, which are focused on a particular topic and Episodes files are [Markdown](https://en.wikipedia.org/wiki/Markdown) files. If you are making a new episode or contributing to existing ones, please make sure the content conforms to the [Carpentries lesson formatting][swc-lesson-formatting]. We recommend using a linter to check errors in Markdown files. For example, a [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) can be installed as an extension in ``Visual Studio Code``. -Alternatively, it can installed with: +Alternatively, a linter can be installed with: ```bash gem install mdl From 2a4620fb7bce59f7829bf50efa0fc9230a065d36 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 15:16:58 +0200 Subject: [PATCH 045/647] edit section preview_changes_locally, edit resources and references --- CONTRIBUTING.md | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8d2e114b..d07113aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -76,7 +76,8 @@ mdl your_markdown_filename ## Previewing your changes locally -Extensive instructions for building and viewing the pages locally can be found [here](https://carpentries.github.io/lesson-example/setup.html). To get started quickly, run +Please preview changes on your machine before pushing them to GitHub. +To do so, you need to install the software described below. ```bash # apt (Ubuntu/Devian) @@ -90,7 +91,7 @@ or sudo dnf install rubygem-bundler ruby-devel ``` -Alternatively, there's an environment file available which can be installed in conda with: +Alternatively, there is an environment file available which can be installed with: ```bash conda env create -f environment.yml -n esmvaltool_tutorial @@ -109,35 +110,23 @@ The output on the terminal will contain a line similar to: Server address: http://127.0.0.1:4000 ``` -This address can be opened in your browser to preview the website. - +This address can be opened in your browser to preview the tutorial website. ## Other Resources -General discussion of [Software Carpentry][swc-site] and [Data Carpentry][dc-site] -happens on the [discussion mailing list][discuss-list], -which everyone is welcome to join. -You can also [reach us by email][email]. +General discussion of the tutorial happens in `User Engagement Team`. +You can [reach us by email][email]. -[email]: mailto:admin@software-carpentry.org +[email]: mailto:TODO_FIX_ME.org [ESMValTool-site]: https://www.esmvaltool.org/ [tutorial-repo]: https://esmvalgroup.github.io/tutorial/ [tutorial-site]: https://esmvalgroup.github.io/tutorial [tutorial-maintainers]: https://github.com/ESMValGroup/tutorial#maintainers -[discuss-list]: http://lists.software-carpentry.org/listinfo/discuss [github]: https://github.com -[github-flow]: https://guides.github.com/introduction/flow/ -[github-join]: https://github.com/join -[how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github [issues]: https://github.com/ESMValGroup/tutorial/issues [PR]: https://github.com/ESMValGroup/tutorial/pulls -[swc-issues]: https://github.com/issues?q=user%3Aswcarpentry -[swc-lessons]: https://software-carpentry.org/lessons/ [swc-site]: https://software-carpentry.org/ [swc-handbook]: https://carpentries.github.io/curriculum-development/ [swc-lesson-organization]: https://carpentries.github.io/lesson-example/03-organization/index.html [swc-lesson-formatting]: https://carpentries.github.io/lesson-example/04-formatting/index.html [ea-site]: https://github.com/escience-academy -[c-site]: https://carpentries.org/ -[lc-site]: https://librarycarpentry.org/ -[lc-issues]: https://github.com/issues?q=user%3Alibrarycarpentry From e55a28b1a1c18431bbaa5df308414cf51e2517e4 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 15:47:11 +0200 Subject: [PATCH 046/647] revise the text --- CONTRIBUTING.md | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d07113aa..123c413c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to ESMValTool tutorial -[ESMValTool][ESMValTool-site] tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues] by choosing the ``Suggestion`` template in the ``issues`` tab of this repository. +[ESMValTool][ESMValTool-site] tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues]. To do so, click on `new issue` in the ``issues`` tab of this repository and choose the ``Suggestion`` template. ## Acknowledgement @@ -17,26 +17,25 @@ Everyone involved in this [tutorial](tutorial-repo) agrees to abide by our [code There are many ways to contribute: * If you do not have a [GitHub][github] account, -you can [send us comments by email][email]. +you can send us comments by [email][email]. However, we will be able to respond more quickly when you use one of the other methods described below. * If you have a [GitHub][github] account, work in this [repository][tutorial-repo], -which can be viewed at the [tutorial site][tutorial-site]. +which can be viewed at the tutorial [site][tutorial-site]. You can ask your questions, report problems or suggest improvements by [creating an issue][issues]. This is the easiest way to tell us about your ideas, and a good way to introduce yourself and to meet some of our community members. This allows us to assign the item to someone and to respond to it in a threaded discussion. -There are several templates to make an issue: - * for asking a question, please use [Question and answer][issues] - * for reporting a bug, please use [Bug reports][issues] - * for developing lesson material, please use [New lesson material][issues] - * for adding a feature to the repository, please use [Suggestion][issues] +To open an issue, click on `new issue` in the ``issues`` tab of this repository and choose a template from the list as described below: + * for asking a question, please use `Question and answer`. + * for reporting a bug, please use `Bug reports`. + * for developing lesson material, please use `New lesson material`. + * for adding a feature to the repository, please use `Suggestion`. * If you would like to add what is already discussed in an issue, -you can submit a [pull request][PR]. -To do so, you can make use of the [pull request checklist][PR]. -Each pull request is reviewed at least by one reviewer who is a community volunteer and provides feedback. +you can submit a [pull request][PR] and make use of the `pull request checklist`. +Each pull request is reviewed at least by one reviewer who is a community volunteer. The [maintainers][tutorial-maintainers] have final say over what gets merged into the tutorial. ## Tutorial guidelines @@ -60,8 +59,9 @@ Each lesson is made up of episodes, which are focused on a particular topic and ### Lesson formatting Episodes files are [Markdown](https://en.wikipedia.org/wiki/Markdown) files. If you are making a new episode or contributing to existing ones, please make sure the content conforms to the [Carpentries lesson formatting][swc-lesson-formatting]. -We recommend using a linter to check errors in Markdown files. -For example, a [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) can be installed as an extension in ``Visual Studio Code``. + +We also, recommend using a linter to check errors in Markdown files. +For example, a [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) can be installed as an extension in [Visual Studio Code](https://code.visualstudio.com/). Alternatively, a linter can be installed with: ```bash @@ -74,10 +74,11 @@ and can be used as: mdl your_markdown_filename ``` -## Previewing your changes locally +### Previewing your changes locally -Please preview changes on your machine before pushing them to GitHub. -To do so, you need to install the software described below. +If you are making a new episode or contributing to existing ones, +please preview changes on your machine before submitting a [pull request][PR]. +To do so, you need to install the software described below: ```bash # apt (Ubuntu/Devian) @@ -115,7 +116,7 @@ This address can be opened in your browser to preview the tutorial website. ## Other Resources General discussion of the tutorial happens in `User Engagement Team`. -You can [reach us by email][email]. +You can reach us by [email][email]. [email]: mailto:TODO_FIX_ME.org [ESMValTool-site]: https://www.esmvaltool.org/ From 1471b20664059f46381aa60efe12124ecc585fe6 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 15:54:24 +0200 Subject: [PATCH 047/647] add links for new issue and new pull request --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 123c413c..9a8f17f3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to ESMValTool tutorial -[ESMValTool][ESMValTool-site] tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues]. To do so, click on `new issue` in the ``issues`` tab of this repository and choose the ``Suggestion`` template. +[ESMValTool][ESMValTool-site] tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues]. To do so, click on [new issue](https://github.com/ESMValGroup/tutorial/issues/new/choose) in the ``issues`` tab of this repository and choose the ``Suggestion`` template. ## Acknowledgement @@ -27,14 +27,14 @@ You can ask your questions, report problems or suggest improvements by [creating This is the easiest way to tell us about your ideas, and a good way to introduce yourself and to meet some of our community members. This allows us to assign the item to someone and to respond to it in a threaded discussion. -To open an issue, click on `new issue` in the ``issues`` tab of this repository and choose a template from the list as described below: +To open an issue, click on [new issue](https://github.com/ESMValGroup/tutorial/issues/new/choose) in the ``issues`` tab of this repository and choose a template from the list as described below: * for asking a question, please use `Question and answer`. * for reporting a bug, please use `Bug reports`. * for developing lesson material, please use `New lesson material`. * for adding a feature to the repository, please use `Suggestion`. * If you would like to add what is already discussed in an issue, -you can submit a [pull request][PR] and make use of the `pull request checklist`. +you can submit a [pull request][PR] by clicking on [New pull request](https://github.com/ESMValGroup/tutorial/compare) and make use of the `pull request checklist`. Each pull request is reviewed at least by one reviewer who is a community volunteer. The [maintainers][tutorial-maintainers] have final say over what gets merged into the tutorial. From ac5d7e9cd4cf1904b0a15a6b92c8136d6ae4563c Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 15:56:40 +0200 Subject: [PATCH 048/647] remove the link for new pull request --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a8f17f3..aec8b3fd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,7 @@ To open an issue, click on [new issue](https://github.com/ESMValGroup/tutorial/i * for adding a feature to the repository, please use `Suggestion`. * If you would like to add what is already discussed in an issue, -you can submit a [pull request][PR] by clicking on [New pull request](https://github.com/ESMValGroup/tutorial/compare) and make use of the `pull request checklist`. +you can submit a [pull request][PR] and make use of the `pull request checklist`. Each pull request is reviewed at least by one reviewer who is a community volunteer. The [maintainers][tutorial-maintainers] have final say over what gets merged into the tutorial. From 30be340a0a4cd5b9d0bcc51900baa2ee3bd881a5 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 16:03:59 +0200 Subject: [PATCH 049/647] update the text and fix links --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aec8b3fd..9f3c62d3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to ESMValTool tutorial -[ESMValTool][ESMValTool-site] tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues]. To do so, click on [new issue](https://github.com/ESMValGroup/tutorial/issues/new/choose) in the ``issues`` tab of this repository and choose the ``Suggestion`` template. +[ESMValTool][ESMValTool-site] tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues]. To do so, click on `New issue` in the `issues` tab of this repository and choose the `Suggestion` template. ## Acknowledgement @@ -27,7 +27,7 @@ You can ask your questions, report problems or suggest improvements by [creating This is the easiest way to tell us about your ideas, and a good way to introduce yourself and to meet some of our community members. This allows us to assign the item to someone and to respond to it in a threaded discussion. -To open an issue, click on [new issue](https://github.com/ESMValGroup/tutorial/issues/new/choose) in the ``issues`` tab of this repository and choose a template from the list as described below: +To open an issue, click on `New issue` in the `issues` tab of this repository and choose a template from the [list](https://github.com/ESMValGroup/tutorial/issues/new/choose) as described below: * for asking a question, please use `Question and answer`. * for reporting a bug, please use `Bug reports`. * for developing lesson material, please use `New lesson material`. @@ -58,7 +58,7 @@ Each lesson is made up of episodes, which are focused on a particular topic and ### Lesson formatting -Episodes files are [Markdown](https://en.wikipedia.org/wiki/Markdown) files. If you are making a new episode or contributing to existing ones, please make sure the content conforms to the [Carpentries lesson formatting][swc-lesson-formatting]. +Episodes are [Markdown](https://en.wikipedia.org/wiki/Markdown) files. If you are making a new episode or contributing to existing ones, please make sure the content conforms to the [Carpentries lesson formatting][swc-lesson-formatting]. We also, recommend using a linter to check errors in Markdown files. For example, a [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) can be installed as an extension in [Visual Studio Code](https://code.visualstudio.com/). @@ -118,7 +118,7 @@ This address can be opened in your browser to preview the tutorial website. General discussion of the tutorial happens in `User Engagement Team`. You can reach us by [email][email]. -[email]: mailto:TODO_FIX_ME.org +[email]: mailto:TODO_FIX_ME [ESMValTool-site]: https://www.esmvaltool.org/ [tutorial-repo]: https://esmvalgroup.github.io/tutorial/ [tutorial-site]: https://esmvalgroup.github.io/tutorial From bc4baaeb8e27aaeb2136b4f8435ed6e927d4d6f8 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 16:09:45 +0200 Subject: [PATCH 050/647] fix the link for ESMValGroup --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9f3c62d3..f1063052 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to ESMValTool tutorial -[ESMValTool][ESMValTool-site] tutorial is an open-source project and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues]. To do so, click on `New issue` in the `issues` tab of this repository and choose the `Suggestion` template. +[ESMValTool][tutorial-site] tutorial is an open-source project in [ESMValGroup][ESMValTool-site] and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues]. To do so, click on `New issue` in the `issues` tab of this repository and choose the `Suggestion` template. ## Acknowledgement From bd586f5bd867d5ac5d15cdcb29bfe4f837a44587 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 16:34:08 +0200 Subject: [PATCH 051/647] add a link for esmvaltool documentation --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f1063052..0d33e06d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ The [maintainers][tutorial-maintainers] have final say over what gets merged int ## Tutorial guidelines This section demonstrates all the instructions for developing a lesson in the [ESMValTool tutorial][tutorial-site]. -The tutorial is a set of lessons (or episodes) that together teach **basic** skills needed to work with [ESMValTool][ESMValTool-site] in climate-related domains. +The tutorial is a set of lessons (or episodes) that together teach **basic** skills needed to work with [ESMValTool][ESMValTool-doc] in climate-related domains. ### Lesson development @@ -120,6 +120,7 @@ You can reach us by [email][email]. [email]: mailto:TODO_FIX_ME [ESMValTool-site]: https://www.esmvaltool.org/ +[ESMValTool-doc]: https://esmvaltool.readthedocs.io/en/latest/ [tutorial-repo]: https://esmvalgroup.github.io/tutorial/ [tutorial-site]: https://esmvalgroup.github.io/tutorial [tutorial-maintainers]: https://github.com/ESMValGroup/tutorial#maintainers From 20f6d5023780eb577802e0ec92ece1c52d87458f Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 16:37:29 +0200 Subject: [PATCH 052/647] remove changes to readme from this PR --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99705cf7..c674f1d6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Welcome to ESMValTool tutorial +# FIXME Lesson title [![Create a Slack Account with us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/) From 075878b732ceb21c7253349a8b333c4cee553ca2 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 14 Apr 2020 16:43:20 +0200 Subject: [PATCH 053/647] remove changes from readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c674f1d6..13a08f3b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Create a Slack Account with us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/) -This repository generates the corresponding lesson website from [The Carpentries](https://carpentries.org/) repertoire of lessons. +This repository generates the corresponding lesson website from [The Carpentries](https://carpentries.org/) repertoire of lessons. ## Contributing @@ -17,12 +17,12 @@ Please see the current list of [issues][FIXME] for ideas for contributing to thi repository. For making your contribution, we use the GitHub flow, which is nicely explained in the chapter [Contributing to a Project](http://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project) in Pro Git by Scott Chacon. -Look for the tag ![good_first_issue](https://img.shields.io/badge/-good%20first%20issue-gold.svg). This indicates that the maintainers will welcome a pull request fixing this issue. +Look for the tag ![good_first_issue](https://img.shields.io/badge/-good%20first%20issue-gold.svg). This indicates that the maintainers will welcome a pull request fixing this issue. ## Maintainer(s) -Current maintainers of this lesson are +Current maintainers of this lesson are * FIXME * FIXME From ec223b4a798494a99d76f5042ac6ae886e1d3bd3 Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Thu, 18 Jun 2020 08:39:15 +0000 Subject: [PATCH 054/647] Add Gitter badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 13a08f3b..dc0335eb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # FIXME Lesson title -[![Create a Slack Account with us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/) +[![Create a Slack Account with us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/) [![Join the chat at https://gitter.im/ESMValGroup/Tutorial](https://badges.gitter.im/ESMValGroup/Tutorial.svg)](https://gitter.im/ESMValGroup/Tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) This repository generates the corresponding lesson website from [The Carpentries](https://carpentries.org/) repertoire of lessons. From 79ae749dc2f64e8f4ca3381412ddd69e90a30274 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Thu, 18 Jun 2020 09:43:56 +0100 Subject: [PATCH 055/647] Added some minor changes to the contents (#25) * Added some minor changes to the contents Suggestions for file contents * Correct spelling Co-authored-by: Bouwe Andela --- _episodes/06-creating-a-diagnostic-script.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_episodes/06-creating-a-diagnostic-script.md b/_episodes/06-creating-a-diagnostic-script.md index c4e1c242..f11922f4 100644 --- a/_episodes/06-creating-a-diagnostic-script.md +++ b/_episodes/06-creating-a-diagnostic-script.md @@ -13,3 +13,7 @@ FIXME {% include links.md %} +Important part here is to introduce the standard tools that allow users to access ESMValTool settings configs. + + +This file should be renamed to advanced: creating a diagnostic From 274e1c9ba56b5d5f71e15b9cbe2b4fe4a02b8646 Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 26 Jun 2020 11:11:16 +0200 Subject: [PATCH 056/647] Move installation from source to a later chapter --- _episodes/02-installation.md => 10-development-setup.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename _episodes/02-installation.md => 10-development-setup.md (100%) diff --git a/_episodes/02-installation.md b/10-development-setup.md similarity index 100% rename from _episodes/02-installation.md rename to 10-development-setup.md From 4d0952712016c8786d4b2c88853e9311c9c4f16d Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 26 Jun 2020 11:13:05 +0200 Subject: [PATCH 057/647] Move episode into _episodes directory --- 10-development-setup.md => _episodes/10-development-setup.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename 10-development-setup.md => _episodes/10-development-setup.md (100%) diff --git a/10-development-setup.md b/_episodes/10-development-setup.md similarity index 100% rename from 10-development-setup.md rename to _episodes/10-development-setup.md From 3ee6ff5ca87485dafc2fef2825a4dd3d68a180db Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 26 Jun 2020 11:53:51 +0200 Subject: [PATCH 058/647] update the content on how to get config file --- _episodes/03-configuration.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 17aa13b8..07513784 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -5,23 +5,31 @@ exercises: 0 questions: - "What is the user configuration file and how can I use it?" objectives: -- "Understand the data directories structure" +- "Understand the contents of the user-config.yml file" +- "Prepare the user-config.yml file for use" - "Configure ESMValTool to ignore some settings" keypoints: -- "The ``config-user.yml`` tells ESMValTool about input, output and your preference." +- "The ``config-user.yml`` tells ESMValTool where to find input data." - " ``rootpath`` determines root directory for input data." - " ``output_dir`` is the destination directory." --- +Contents: + +Exercise: Copy the user config to your working area +Exercise: Make site specific configuration information(ie the changes needed to you config-user.yml file before you can run) + ## The configuration file The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. -This is an [YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be found in the root directory of the ESMValTool repository. -Let's change our working directory to ``esmvaltool_tutorial`` that is made during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). Then we copy the config file and rename it to ``config-user.yml``, then run a text editor called Nano to open it: +This is an [YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be found in the [root directory of the ESMValTool repository](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). +Let's download it in our working directory ``esmvaltool_tutorial`` that is made during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). +Click on [this link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) to see a raw version of the file, right-click and press save as, then you can rename it to ``config-user.yml`` and save it into the working directory ``esmvaltool_tutorial``. + +Lets change our working directory to ``esmvaltool_tutorial``. Then, we run a text editor called Nano to open it: ~~~bash cd esmvaltool_tutorial - cp ESMValTool/config-user-example.yml config-user.yml nano config-user.yml ~~~ From 6d1d3a55e1c235b65671958d8ec530f419882b97 Mon Sep 17 00:00:00 2001 From: Niels Drost Date: Fri, 26 Jun 2020 11:56:28 +0200 Subject: [PATCH 059/647] added installation section --- _episodes/02-installation.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 _episodes/02-installation.md diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md new file mode 100644 index 00000000..b6b85f8d --- /dev/null +++ b/_episodes/02-installation.md @@ -0,0 +1,15 @@ +--- +title: "Installation" +teaching: 0 +exercises: 0 +questions: +- "Key question (FIXME)" +objectives: +- "First learning objective. (FIXME)" +keypoints: +- "First key point. Brief Answer to questions. (FIXME)" +--- +FIXME + +{% include links.md %} + From 19b16616479be13b867f91da34768f00d4613643 Mon Sep 17 00:00:00 2001 From: Niels Drost Date: Fri, 26 Jun 2020 12:04:03 +0200 Subject: [PATCH 060/647] renamed advanced installation chapter to development setup --- _episodes/10-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index ece3ddc5..a7c5aebc 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -1,5 +1,5 @@ --- -title: "Installation" +title: "Development Setup" teaching: 0 exercises: 0 questions: From 4a525700fa589a6daedf89190b221520a1621653 Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 26 Jun 2020 12:05:38 +0200 Subject: [PATCH 061/647] Add questions, objectives, and key points --- _episodes/02-installation.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index b6b85f8d..43008114 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -1,15 +1,17 @@ --- title: "Installation" -teaching: 0 -exercises: 0 +teaching: 10 +exercises: 20 questions: -- "Key question (FIXME)" +- "What are the prerequisites for installing ESMValTool?" +- "How do I confirm that the installation was successful?" objectives: -- "First learning objective. (FIXME)" +- "Install ESMValTool" +- "Demonstate that the installation was successful" keypoints: -- "First key point. Brief Answer to questions. (FIXME)" +- "All the required packages can be installed using conda" +- "You can find more information about installation in the documentation" --- FIXME {% include links.md %} - From 3424cb7688cbcc7c70928e419b16d2ae0d005719 Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 26 Jun 2020 12:12:30 +0200 Subject: [PATCH 062/647] Add sections --- _episodes/02-installation.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 43008114..9eea5b80 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -12,6 +12,14 @@ keypoints: - "All the required packages can be installed using conda" - "You can find more information about installation in the documentation" --- -FIXME +## Overview + +## Install Conda + +## Install Julia + +## Install ESMValTool + +## Test that the installation was successful {% include links.md %} From afced67e0c32f0f798878b1cfc0c6ef57e930983 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 26 Jun 2020 12:15:06 +0200 Subject: [PATCH 063/647] Copy outine from document and extend it --- _episodes/01-introduction.md | 54 +++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 2e156c26..8afa4d93 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -3,13 +3,59 @@ title: "Introduction" teaching: 0 exercises: 0 questions: -- "Key question (FIXME)" +- What is ESMValTool? +- When to use ESMValTool? +- What are the main parts of ESMValTool that I need to know? +- How does ESMValTool contribute to making climate research FAIR? +- What is the role of the ESMValTool community? +- Where to find help if I'm stuck with ESMValTool? + objectives: -- "First learning objective. (FIXME)" +- Describe the difference between ESMValTool and other tools like CDO or xarray +- Understand the main parts of ESMValTool (recipe, diagnostic script) +- Browse the documentation of ESMValTool for help +- Exlain why ESMValTool is a great way to make climate analysis FAIR +- List three different ways to get help from to the ESMValTool community (docs, user engagement email, github issues) +- Know when (not) to use ESMValTool + keypoints: -- "First key point. Brief Answer to questions. (FIXME)" +- ESMValTool provides a reliable interface to analyse and evaluate climate data +- By streamlining common preprocessor functions, ESMValTool facilitates comparison +- ESMValTool is built and maintained by an active community of climate scientists and software developers +- Using ESMValTool stimulates standardization, collaboration, and reuse +- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages + --- -FIXME + +## Welcome + + +## What is ESMValTool? + +## ESMValTool and ESMValCore +Include figure describing ESMValTool + +## What are the main parts of ESMValTool that I need to know? + + +## Preprocessor + + +## Recipe (include callout on yml) + + +## Global settings (user-config.yml) + + +## Diagnostics + +## Community + +- How many people are connected to github? +- How many open issues? +- How many merged pull requests in the last month? + + {% include links.md %} From bcb6599a21a0c3cb815800f436faf2a84ba4bd5f Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 26 Jun 2020 12:27:33 +0200 Subject: [PATCH 064/647] Add overview text --- _episodes/02-installation.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 9eea5b80..5b69c46f 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -14,6 +14,15 @@ keypoints: --- ## Overview +In this tutorial we will be using the [Conda](https://conda.io/projects/conda/en/latest/index.html) +package manager to install the ESMValTool. +Other installation methods are also available, they can be found in the +[documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). +ESMValTool also contains diagnostics written in [Julia](https://julialang.org/). +Because Julia cannot be installed by Conda, we will install Julia separately. +We will first learn how to install Conda, Julia, and finally the ESMValTool. +We end this chapter by testing that the installation was successful. + ## Install Conda ## Install Julia From 84cdbd285392ab8d0aa9de44811683ba06c7f1dd Mon Sep 17 00:00:00 2001 From: Niels Drost Date: Fri, 26 Jun 2020 12:42:30 +0200 Subject: [PATCH 065/647] started Conda install section --- _episodes/02-installation.md | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 9eea5b80..9b5fd489 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -16,6 +16,45 @@ keypoints: ## Install Conda +ESMValTool is distributed using Conda(link). Most users use Linux or OSX, but succesful usage has also been reported through the Windows Subsystem for Linux(WSL) (link). + +We will be using the Miniconda minimal installer for conda. + +> ## Python 3 Only +> +> Please make sure to download a Python 3 based installation (Miniconda3), as ESMValTool only supports Python 3 +> +> +{: .callout} + + +### Linux + +1. Please download miniconda at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html) + +2. Next, run the installer: +~~~ +bash Miniconda3-latest-Linux-x86_64.sh +~~~ +{:.language-bash} + +3. Follow the instructions in the installer. The defaults should normally suffice. + +4. You will need to restart your terminal for the changes to have effect. + +5. Verify you have a working conda installation by listing all installed packages +~~~ +conda list +~~~ + +### MacOSX + +### Windows + +After installing the WSL, installation can be done using the Linux installation instructions. + + + ## Install Julia ## Install ESMValTool From 1679628cf311bfd120d32cf6fe456ddf8b4d83c1 Mon Sep 17 00:00:00 2001 From: Niels Drost Date: Fri, 26 Jun 2020 12:44:44 +0200 Subject: [PATCH 066/647] fix code block layout --- _episodes/02-installation.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 3c4a79d5..d8fa56b9 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -41,7 +41,8 @@ We will be using the Miniconda minimal installer for conda. 1. Please download miniconda at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html) -2. Next, run the installer: +2. Next, run the installer + ~~~ bash Miniconda3-latest-Linux-x86_64.sh ~~~ @@ -52,9 +53,11 @@ bash Miniconda3-latest-Linux-x86_64.sh 4. You will need to restart your terminal for the changes to have effect. 5. Verify you have a working conda installation by listing all installed packages + ~~~ conda list ~~~ +{:.language-bash} ### MacOSX From e7ea3c9a9e532a10d980107f4a0b30c7ff6e57c2 Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 26 Jun 2020 13:05:43 +0200 Subject: [PATCH 067/647] Add Julia installation instructions --- _episodes/02-installation.md | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index d8fa56b9..334c8240 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -69,6 +69,44 @@ After installing the WSL, installation can be done using the Linux installation ## Install Julia +Complete instructions for installing Julia can be found on the +[Julia installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). +In this tutorial, we will use the following steps. +First, open a bash terminal and create a directory to install Julia in +```bash +mkdir ~/julia +``` +Next, download the file +[`julia-1.0.5-linux-x86_64.tar.gz`](https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz) +by clicking the link or going to the [Julia downloads page](https://julialang.org/downloads/). +To extract the file, you can use the following command: +```bash +tar -xvzf ~/Downloads/julia-1.0.5-linux-x86\_64.tar.gz -C ~/julia +``` +This will extract the files to a folder named `~/julia/julia-1.0.5`. +To run Julia, you need to add the full path of Julia's `bin` folder to PATH environment variable. +To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. +Open the file in your favorite editor and add a new line as follows at the bottom of the file: +```bash +export PATH="$PATH:$HOME/julia/julia-1.0.5/bin" +``` +Finally, for the settings to take effect, either reload your bash profile +```bash +source ~/.bashrc +``` +(or `source ~/.bash_profile`), or close the bash terminal window and open a new one. + +To check that the Julia executable can be found, run +```bash +which julia +``` +to display the path to the Julia executable, it should be `~/julia/julia-1.0.5/bin/julia`. +To test that Julia is installed correctly, run +```bash +julia +``` +to start the interactive Julia interpreter. Press `Ctrl+D` to exit. + ## Install ESMValTool ## Test that the installation was successful From ada1288e9496b84603833380596c76b577196915 Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 26 Jun 2020 13:19:35 +0200 Subject: [PATCH 068/647] Add installation and test instructions --- _episodes/02-installation.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 334c8240..8c5b4b50 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -107,8 +107,31 @@ julia ``` to start the interactive Julia interpreter. Press `Ctrl+D` to exit. -## Install ESMValTool +## Install the ESMValTool package + +To install the ESMValTool package, run +```bash +conda create -n esmvaltool -c conda-forge -c esmvalgroup esmvaltool +``` +This will create a new +[Conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) +called `esmvaltool`, with the ESMValTool package and all of its dependencies installed in it. ## Test that the installation was successful +To test that the installation was successful, run +```bash +conda activate esmvaltool +``` +to activate the conda environment called `esmvaltool`. +Next, run +```bash +esmvaltool --help +``` +to display the command line help. +To find the location where the ESMValTool package was installed on your system, run +```bash +python -c 'import esmvaltool; print(esmvaltool.__path__[0])' +``` + {% include links.md %} From f1aa1066150e675231727f6df16781ac4c59e0b6 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 26 Jun 2020 13:37:07 +0200 Subject: [PATCH 069/647] add one challenge --- _episodes/03-configuration.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 07513784..b0a565ae 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -14,19 +14,18 @@ keypoints: - " ``output_dir`` is the destination directory." --- -Contents: - Exercise: Copy the user config to your working area Exercise: Make site specific configuration information(ie the changes needed to you config-user.yml file before you can run) ## The configuration file The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. -This is an [YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be found in the [root directory of the ESMValTool repository](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). -Let's download it in our working directory ``esmvaltool_tutorial`` that is made during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). -Click on [this link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) to see a raw version of the file, right-click and press save as, then you can rename it to ``config-user.yml`` and save it into the working directory ``esmvaltool_tutorial``. +This is an [YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be found in the root directory of the ESMValTool repository: [config-user-example.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). + +Let's download it to our working directory ``esmvaltool_tutorial`` that is made during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). +To do that, click on [this link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) to see a raw version of the file, right-click and press ``save as``, then you can rename it to ``config-user.yml`` and save it into the working directory ``esmvaltool_tutorial``. -Lets change our working directory to ``esmvaltool_tutorial``. Then, we run a text editor called Nano to open it: +Now in a terminal, let's change our working directory to ``esmvaltool_tutorial``. Then, we run a text editor called Nano to open the configuration file: ~~~bash cd esmvaltool_tutorial @@ -166,4 +165,20 @@ remove_preproc_dir: true profile_diagnostic: false ~~~ +> ## Make your own configuration file +> +> It is possible to have several configuration files with different purposes, for example: config-user_formalised_runs.yml, config-user_debugging.yml +{: .callout} + +> ## Set different preferences +> +> In the configuration file, which settings are useful to store preprocessed data? +> +>> ## Solution +>> +>> If the option ``save_intermediary_cubes`` is set to true in the config-user.yml file, then the intermediary cubes will also be saved in the folder ``preproc``. Also, if the option ``remove_preproc_dir`` is set to ``false``, then the ``preproc/`` directory contains all the preprocessed data and the metadata interface files. +> {: .solution} +{: .challenge} + + {% include links.md %} From 676ab7f2725e729fcd114da04a30400ff745e801 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 26 Jun 2020 13:59:48 +0200 Subject: [PATCH 070/647] fix a title --- _episodes/03-configuration.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index b0a565ae..421c1643 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -170,7 +170,7 @@ profile_diagnostic: false > It is possible to have several configuration files with different purposes, for example: config-user_formalised_runs.yml, config-user_debugging.yml {: .callout} -> ## Set different preferences +> ## Different settings > > In the configuration file, which settings are useful to store preprocessed data? > @@ -180,5 +180,4 @@ profile_diagnostic: false > {: .solution} {: .challenge} - {% include links.md %} From e797318477dceae00d8f1189a34ed9a50367cee3 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Fri, 26 Jun 2020 14:00:52 +0200 Subject: [PATCH 071/647] Draft for new "episode 4" --- _episodes/04-toy-example.md | 52 -------- _episodes/first_example_recipe.md | 189 ++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 52 deletions(-) delete mode 100644 _episodes/04-toy-example.md create mode 100644 _episodes/first_example_recipe.md diff --git a/_episodes/04-toy-example.md b/_episodes/04-toy-example.md deleted file mode 100644 index 1200e801..00000000 --- a/_episodes/04-toy-example.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Toy example" -teaching: 0 -exercises: 0 -questions: -- "Key question (FIXME)" -objectives: -- "Explain how ESMValTool is structured." -- "Execute ESMValTool using the example recipe and diagnostic script provided." -- "Inspect the output that was created by running ESMValTool" -keypoints: -- "" -- "The recipe tells ESMValTool what parts of its core functionality it should run and on what -data." -- "The diagnostic script is tailor made by the diagnostic developer where functionalities not -supported by ESMValTool can be implemented in the processing pipeline." ---- -Now we have installed and configured ESMValTool it is time to run a simple example and inspect -what it produces. - -For this we need our general ESMValTool settings from episode 3 (configuration), the example data -that you downloaded in the -[setup](https://escience-academy.github.io/lesson-esmvaltool/setup.html) and an example recipe to -tell ESMValTool what it should do. Let's make sure you have all set to continue. Check whether -you can find these three items in your ESMValTool folder. - -> ## Exercise -> -> Find all the -> -{: .challenge} - - -As already mentioned in the -[introduction](https://escience-academy.github.io/lesson-esmvaltool/01-introduction/index.html), -ESMValTool consists of two parts: the core and the diagnostics. The core part (also called -ESMValCore after its repository name) contains the code to run the actual software as well as -several preprocessing functions that are widely used. The diagnostics part (confusingly situated -in the repository called ESMValTool) mainly contains so called recipes and diagnostic scripts. - -The recipes describe the analysis pipeline and tell ESMValTool which actions to perform on what -data. - - - -~~~ -esmvaltool -c config-user.yml recipes/recipe_python.yml -~~~ -{: .source} - -{% include links.md %} - diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md new file mode 100644 index 00000000..c4ee00e9 --- /dev/null +++ b/_episodes/first_example_recipe.md @@ -0,0 +1,189 @@ +--- +title: "Running a recipe (First example)" +teaching: 10 +exercises: 25 +questions: +- "What is a recipe?" +- "How can I do the same preprocessing on many different datasets?" +- "What are the files and directories after running a recipe?" +- "What happens when I run a recipe?" +objectives: +- "Run an ESMValTool recipe" +- "Understand the purpose of different settings in the recipe" +- "Inspect the output directories" +- "Examine the log information" +keypoints: +- "A recipe does not break by fiddling with it" +- "Log information is useful to How to interpret the first warnings/errors" +- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." +--- + +This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. + +## Introduction to Recipes + +Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main section: +- datasets: what datasets you want to use + - the time range and time resolution, + - the MIP, ensemble member, + - the experiment (ie historical, ssp125 etc...) + - the grid type (CMIP6 only) + - This section can also be optional, as datasets can no preprocessing is needed. + +- proprocessors: one or preprocessors + - which preprocessor modules to apply + - the order to apply them + - and the preprocesor arguments. + - This section can also be optional, if no preprocessing is needed. + +- diagnostics: All the information about diagnostic + - + +- description: a brief description of the recipe + - who wrote the recipe, and who maintains it + - which project is responsible for it + - which publications, reference are linked with the recipe + - Note that the authors, publications and references and named in the config-references.yml + +This information + +## How to run ESMValTool + +Once you’ve set up your conda environment and installed ESMValTool (See episode #2) and set up your config-user.yml file to correctly match you local environment, (see episode #3), ESMValTool is invoked using a simple command: +~~~ +esmvaltool -c configuration recipe +~~~ + +To try your hand with a basic recipe, please work through this episode. + + +## Example recipe +This is a basic recipe that takes a simple dataset and produces a simple plot. +Please copy and paste the following recipe into your ESMValTool working area with the name: recipe_example.yml + + # ESMValTool + # recipe_example.yml + --- + documentation: + description: | + Demonstrate basic ESMValTool example + + authors: + - demora_lee + - Ben + - Ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + + + preprocessors: + # -------------------------------------------------- + # Time series preprocessors + # -------------------------------------------------- + prep_timeseries: # For 0D fields + multi_model_statistics: + span: full + statistics: [mean ] + + + diagnostics: + # -------------------------------------------------- + # Time series diagnostics + # -------------------------------------------------- + diag_timeseries_temperature: + variables: + thetaoga: + preprocessor: prep_timeseries + additional_datasets: + - {dataset: CESM1-BGC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: CNRM-CM5, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: CSIRO-Mk3-6-0, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: CanESM2, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: GFDL-ESM2M, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1861, end_year: 2005, } + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005, } + - {dataset: IPSL-CM5A-LR, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: MIROC-ESM, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: MPI-ESM-LR, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: NorESM1-M, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py + +> ## Explore the recipe +> +> Use the command and investigate the sample recipe. +> vim recipe.yml +> +> Please note the datasets, preprocessors, diagnostic sections. +> What is the short_name of the variable being analysed? +> What is the diagnostic script being used? +> How many years of data are being analysed? +> What do you think running this recipe will produce? +{: .challenge} + +> ## Not all parts of the recipe are mandatory +> Some functionalities of the example recipe are mandatory, while others are not. E.g., if you miss any of the documentation information, the call will break. +{: .callout} + +> ## Running ESMValTool +> +> Use the command: +> esmvaltool -c user-config.yml recipe_example.yml +> +> What +{: .challenge} + + +> ## Inspect the output: +> Now that you have run the esmvaltool command for the first time, please locate your output directory. +> Each time you run ESMValTool, it will produce a new output directory with the format: +> This directory should contain four folders: +> run work preproc plots +> If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true. + + +> +> Please locate and inspect the following files: +> You output plot(s). +> Your main output log file +> Your settings.yml file +> A metadata.yml file +{: .discussion} + + +> ## Edit the recipe and run +> So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: +> Land surface temperature +> Atmospheric surface temperature +> Ocean surface temperature (tos) +> You will need to edit the dataset request, c +{: .challenge} + + +> ## Common issues & tips +> +> ### ESMValTool can’t locate the data +> User didn’t correctly edit user-config.yml +> +> ### Esmvaltool not found +> User didn’t active or correctly install conda +> +> ### Diagnostic path problems +> explain ESMValTool’s methods to determine diagnostic path, and how it should appear in the recipe +> +> ### FX files not found. +> +> ### The preprocessor works but the diagnostic fails: +> How to tell them appart and how to re-run a failed diagnostic (but not the preprocessor) +> +> ### Your recipe’s name/project/reference isn’t recognised by ESMValTool. +> +{: .callout} From a5d5b6bb7987b4c1b6c12a6623cf0a96f38363bd Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Fri, 26 Jun 2020 14:10:59 +0200 Subject: [PATCH 072/647] update current edits --- _episodes/first_example_recipe.md | 136 ++++++++++++++++++------------ 1 file changed, 80 insertions(+), 56 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index c4ee00e9..c4922eb9 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -1,3 +1,6 @@ +File name : first_example_recipe.md +Episode 4. + --- title: "Running a recipe (First example)" teaching: 10 @@ -8,13 +11,13 @@ questions: - "What are the files and directories after running a recipe?" - "What happens when I run a recipe?" objectives: -- "Run an ESMValTool recipe" +- "Run an ESMValTool recipe” - "Understand the purpose of different settings in the recipe" - "Inspect the output directories" - "Examine the log information" keypoints: - "A recipe does not break by fiddling with it" -- "Log information is useful to How to interpret the first warnings/errors" +- "Log information is useful when interpreting the first warnings/errors" - "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." --- @@ -22,28 +25,36 @@ This episode describes how ESMValTool recipes work, how to run a recipe and how ## Introduction to Recipes -Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main section: -- datasets: what datasets you want to use +Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. + +- datasets: what datasets you want to use, including - the time range and time resolution, - the MIP, ensemble member, - - the experiment (ie historical, ssp125 etc...) - - the grid type (CMIP6 only) - - This section can also be optional, as datasets can no preprocessing is needed. + - the experiment (i.e. historical, ssp125 etc...), + - and the grid type (CMIP6 only) + + This section can also be optional, as datasets can no preprocessing is needed. + +- preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing + - which preprocessor modules to apply, + - the order to apply them, + - and the preprocessor arguments. + + This section can also be optional, if no preprocessing is needed. -- proprocessors: one or preprocessors - - which preprocessor modules to apply - - the order to apply them - - and the preprocesor arguments. - - This section can also be optional, if no preprocessing is needed. +- diagnostics: all the information about the diagnostic, including + - list of variables to evaluate (with their respective configurations), + - the desired diagnostic script to use, + - and additional diagnostic script options or arguments, if needed. -- diagnostics: All the information about diagnostic - - + Also Include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. -- description: a brief description of the recipe - - who wrote the recipe, and who maintains it - - which project is responsible for it - - which publications, reference are linked with the recipe - - Note that the authors, publications and references and named in the config-references.yml +- description: a brief description of the recipe, including + - who wrote the recipe and who maintains it, + - which project is responsible for it, + - and which publications, references are linked with the recipe. + + Note that the authors, publications and references are to be named in the config-references.yml This information @@ -53,6 +64,7 @@ Once you’ve set up your conda environment and installed ESMValTool (See episod ~~~ esmvaltool -c configuration recipe ~~~ +{: .source} To try your hand with a basic recipe, please work through this episode. @@ -70,8 +82,8 @@ Please copy and paste the following recipe into your ESMValTool working area wit authors: - demora_lee - - Ben - - Ranjini + - mueller_benjamin + - swaminathan_ranjini maintainer: - demora_lee @@ -83,16 +95,13 @@ Please copy and paste the following recipe into your ESMValTool working area wit projects: - ukesm + datasets: + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005, } preprocessors: - # -------------------------------------------------- - # Time series preprocessors - # -------------------------------------------------- - prep_timeseries: # For 0D fields - multi_model_statistics: - span: full - statistics: [mean ] - + prep_timeseries: # For 0D fields + annual_statistics: + operator: mean diagnostics: # -------------------------------------------------- @@ -100,27 +109,21 @@ Please copy and paste the following recipe into your ESMValTool working area wit # -------------------------------------------------- diag_timeseries_temperature: variables: - thetaoga: - preprocessor: prep_timeseries - additional_datasets: - - {dataset: CESM1-BGC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: CNRM-CM5, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: CSIRO-Mk3-6-0, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: CanESM2, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: GFDL-ESM2M, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1861, end_year: 2005, } - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005, } - - {dataset: IPSL-CM5A-LR, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: MIROC-ESM, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: MPI-ESM-LR, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: NorESM1-M, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + timeseries_variable: + short_name: thetaoga + preprocessor: prep_timeseries scripts: timeseries_diag: script: ocean/diagnostic_timeseries.py + > ## Explore the recipe > > Use the command and investigate the sample recipe. +> ~~~ > vim recipe.yml +> ~~~ +> {: .source} > > Please note the datasets, preprocessors, diagnostic sections. > What is the short_name of the variable being analysed? @@ -136,23 +139,24 @@ Please copy and paste the following recipe into your ESMValTool working area wit > ## Running ESMValTool > > Use the command: +> ~~~ > esmvaltool -c user-config.yml recipe_example.yml +> ~~~ > +> {: .source} > What {: .challenge} > ## Inspect the output: > Now that you have run the esmvaltool command for the first time, please locate your output directory. -> Each time you run ESMValTool, it will produce a new output directory with the format: +> Each time you run ESMValTool, it will produce a new output directory with the following format: > This directory should contain four folders: > run work preproc plots -> If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true. - - +> If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true (this is used to save disk space). Please set this value to false and run the recipe again. > > Please locate and inspect the following files: -> You output plot(s). +> Your output plot(s). > Your main output log file > Your settings.yml file > A metadata.yml file @@ -161,29 +165,49 @@ Please copy and paste the following recipe into your ESMValTool working area wit > ## Edit the recipe and run > So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: -> Land surface temperature -> Atmospheric surface temperature -> Ocean surface temperature (tos) -> You will need to edit the dataset request, c +> - Land surface average temperature (tsland) +> - Atmospheric surface average temperature (tas) +> - Ocean surface average temperature (tos) +> +> You will need to edit: +> - the dataset: +> - mip, start_year, end_year +> - the preprocessor: +> - These fields are all 2D fields, but thetaga was a 0D field. This means that we need to take the average over the latitude and longitude dimensions. To do this, add the area_statistics to the preprocessor. +> - the diagnostic +> - change the short_name value (thetaoga) for another: +> - Land surface average temperature (tsland) +> - Atmospheric surface average temperature (tas) +> - Ocean surface average temperature (tos) +> ### Advanced: +> If you want to add a different field, please have a look here: +> http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html {: .challenge} > ## Common issues & tips > +> ### Esmvaltool not found +> Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, epside [2] LINK. +> > ### ESMValTool can’t locate the data -> User didn’t correctly edit user-config.yml +> The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” +> Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? > -> ### Esmvaltool not found -> User didn’t active or correctly install conda > > ### Diagnostic path problems -> explain ESMValTool’s methods to determine diagnostic path, and how it should appear in the recipe +> The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? +> > > ### FX files not found. > +> > ### The preprocessor works but the diagnostic fails: -> How to tell them appart and how to re-run a failed diagnostic (but not the preprocessor) +> If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. +> > > ### Your recipe’s name/project/reference isn’t recognised by ESMValTool. +> Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” +> Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. > {: .callout} From 7ed2c5c0075db52c06e5ce37dcc341ca5e615bae Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 26 Jun 2020 14:35:42 +0200 Subject: [PATCH 073/647] remove unused items --- _episodes/03-configuration.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 421c1643..586d3325 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -14,9 +14,6 @@ keypoints: - " ``output_dir`` is the destination directory." --- -Exercise: Copy the user config to your working area -Exercise: Make site specific configuration information(ie the changes needed to you config-user.yml file before you can run) - ## The configuration file The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. From b4857f2d69d6dfdae6b9af2c192be43bbf206b8d Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 26 Jun 2020 14:38:31 +0200 Subject: [PATCH 074/647] Add Python 3 to the environment, because make serve needs it --- environment.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/environment.yml b/environment.yml index e80a7ff3..843216a3 100644 --- a/environment.yml +++ b/environment.yml @@ -3,5 +3,6 @@ channels: - conda-forge dependencies: - gxx_linux-64 + - python=3 - rb-nokogiri - ruby From 1767f7595bc256c9a77e5a3946c4a9b9aadb5b70 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 26 Jun 2020 15:38:00 +0200 Subject: [PATCH 075/647] fix markdown problem with title --- _episodes/03-configuration.md | 107 +++++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 27 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 586d3325..f56c08e7 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -16,13 +16,22 @@ keypoints: ## The configuration file -The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. -This is an [YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be found in the root directory of the ESMValTool repository: [config-user-example.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). - -Let's download it to our working directory ``esmvaltool_tutorial`` that is made during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). -To do that, click on [this link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) to see a raw version of the file, right-click and press ``save as``, then you can rename it to ``config-user.yml`` and save it into the working directory ``esmvaltool_tutorial``. - -Now in a terminal, let's change our working directory to ``esmvaltool_tutorial``. Then, we run a text editor called Nano to open the configuration file: +The ``config-user.yml`` configuration file contains all the global level information +needed by ESMValTool to run. This is an +[YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file +can be found in the root directory of the ESMValTool repository: +[config-user-example.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). + +Let's download it to our working directory ``esmvaltool_tutorial`` +that is made during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). +To do that, click on +[this link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) +to see a raw version of the file, right-click and press ``save as``, +then you can rename it to ``config-user.yml``and save it into the working directory +``esmvaltool_tutorial``. + +Now in a terminal, let's change our working directory to ``esmvaltool_tutorial``. +Then, we run a text editor called Nano to open the configuration file: ~~~bash cd esmvaltool_tutorial @@ -40,13 +49,22 @@ This file contains the information for: > ## Which text editor > -> No matter what editor you use, you will need to know where it searches for and saves files. If you start it from the shell, it will (probably) use your current working directory as its default location. We use ``nano`` in examples because it is one of the least complex text editors. Press ctrl + O to save the file, and then ctrl + X to exit ``nano``. +> No matter what editor you use, you will need to know where it searches +for and saves files. If you start it from the shell, it will (probably) +use your current working directory as its default location. We use ``nano`` +in examples because it is one of the least complex text editors. +Press ctrl + O to save the file, +and then ctrl + X to exit ``nano``. {: .callout} ## Rootpath to input data -ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. -The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from the climate model intercomparison project whereas OBS for an observational dataset. The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. +ESMValTool uses several categories (in ESMValTool, this is referred to as projects) +for input data based on their source. The current categories in the configuration +file are mentioned below. For example, CMIP is used for a dataset from +the climate model intercomparison project whereas OBS for an observational dataset. +The ``rootpath`` specifies the directories where ESMValTool will look for input data. +For each category, you can define either one path or several paths as a list. ~~~YAML rootpath: @@ -62,7 +80,8 @@ rootpath: default: ~/default_inputpath ~~~ -In this lesson, we will work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). +In this lesson, we will work with data from +[CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). We add the root path of the folder where data is available. ~~~YAML @@ -73,13 +92,18 @@ We add the root path of the folder where data is available. > ## Setting the correct rootpath > -> * To get the data (or its correct rootpath), check instruction in [Setup](https://esmvalgroup.github.io/tutorial/setup.html). -> * For more information about setting the rootpath, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). +> * To get the data (or its correct rootpath), check instruction in +[Setup](https://esmvalgroup.github.io/tutorial/setup.html). +> * For more information about setting the rootpath, you can visit the ESMValTool +[documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} ## Directory structure for the data from different projects -Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). To set a directory, you can use one of the values of ``default``, ``BADC``, ``DKRZ``, ``ETHZ``, .... Let's use ``default`` in our example: +Input data can be from various models, observations and reanalysis data that adhere +to the [CF/CMOR standard](https://cmor.llnl.gov/). +To set a directory, you can use one of the values of +``default``, ``BADC``, ``DKRZ``, ``ETHZ``, .... Let's use ``default`` in our example: ~~~YAML drs: @@ -88,12 +112,16 @@ drs: > ## Available drs > -> For more information about directories, you can visit ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/config.html#developer-configuration-file). +> For more information about directories, you can visit the ESMValTool +[documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/config.html#developer-configuration-file). {: .callout} ## Number of parallel tasks -This option enables you to perform parallel processing. You can choose the number of tasks in parallel as 1/2/3/4/... or you can set it to ``null`` that tells ESMValTool to use the number of available CPUs: +This option enables you to perform parallel processing. +You can choose the number of tasks in parallel as +1/2/3/4/... or you can set it to ``null`` that tells +ESMValTool to use the number of available CPUs: ~~~YAML @@ -102,12 +130,20 @@ max_parallel_tasks: null > ## Set the number of tasks > -> If you run out of memory, try setting ``max_parallel_tasks`` to 1. Then, check the amount of memory you need for that by inspecting the file ``run/resource_usage.txt`` in the output directory. Using the number there you can increase the number of parallel tasks again to a reasonable number for the amount of memory available in your system. +> If you run out of memory, try setting ``max_parallel_tasks`` to 1. +Then, check the amount of memory you need for that by inspecting +the file ``run/resource_usage.txt`` in the output directory. +Using the number there you can increase the number of parallel tasks +again to a reasonable number for the amount of memory available in your system. {: .callout} ## Destination directory -The destination directory is the rootpath where ESMValTool will store its output, i.e. figures, data, logs, etc. With every run, ESMValTool automatically generates a new output folder determined by the recipe name, and date and time using the format: YYYYMMDD_HHMMSS. This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. +The destination directory is the rootpath where ESMValTool will store its output, +i.e. figures, data, logs, etc. With every run, ESMValTool automatically generates +a new output folder determined by the recipe name, and date and time using +the format: YYYYMMDD_HHMMSS. +This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. Let's name our destination directory as ``esmvaltool_output`` in the working directory: @@ -118,16 +154,26 @@ output_dir: ./esmvaltool_output > ## Content of subfolders > > * ``plots``: the location for all plots, split by individual diagnostics and fields. -> * ``preproc``: this folder contains all the preprocessed data and metadata.yml interface files. Note that by default this directory will be deleted after each run because most users will only need the results from the diagnostic scripts. -> * ``run``: this folder includes all log files, a copy of the recipe, a summary of the resource usage, and the settings.yml interface files, resource_usage.txt and temporary files created by the diagnostic scripts. -> * ``work``: a place for any diagnostic script results that are not plots, e.g. files in NetCDF format (depends on the diagnostic script). +> * ``preproc``: this folder contains all the preprocessed data and metadata.yml +interface files. Note that by default this directory will be deleted after +each run because most users will only need the results from the diagnostic scripts. +> * ``run``: this folder includes all log files, a copy of the recipe, +a summary of the resource usage, and the settings.yml interface files, +resource_usage.txt and temporary files created by the diagnostic scripts. +> * ``work``: a place for any diagnostic script results that are not plots, e.g. +files in NetCDF format (depends on the diagnostic script). > -> We explain more about output in the next [lesson](https://esmvalgroup.github.io/tutorial/04-toy-example/index.html) +> We explain more about output in the next +[lesson](https://esmvalgroup.github.io/tutorial/04-toy-example/index.html) {: .callout} ## Auxiliary data directory -The ``auxiliary_data_dir`` setting is the path to place any required additional auxiliary data files. This location allows us to tell the diagnostic script where to find the files if they can not be downloaded at runtime. This option is not for model or observational datasets, rather it is for data files used in plotting such as coastline descriptions and so on. +The ``auxiliary_data_dir`` setting is the path to place any required +additional auxiliary data files. This location allows us to tell +the diagnostic script where to find the files if they can not be downloaded +at runtime. This option is not for model or observational datasets, rather +it is for data files used in plotting such as coastline descriptions and so on. ~~~YAML auxiliary_data_dir: ~/auxiliary_data @@ -135,7 +181,9 @@ auxiliary_data_dir: ~/auxiliary_data ## Output settings -These settings are used to inform ESMValTool about your preference. You can turn on or off the setting by ``true`` or ``false`` values. Most of these settings are fairly self-explanatory, ie: +These settings are used to inform ESMValTool about your preference. +You can turn on or off the setting by ``true`` or ``false`` values. +Most of these settings are fairly self-explanatory, ie: ~~~YAML # Diagnostics create plots? [true]/false @@ -164,16 +212,21 @@ profile_diagnostic: false > ## Make your own configuration file > -> It is possible to have several configuration files with different purposes, for example: config-user_formalised_runs.yml, config-user_debugging.yml +> It is possible to have several configuration files with different purposes, +for example: config-user_formalised_runs.yml, config-user_debugging.yml {: .callout} - +> > ## Different settings > > In the configuration file, which settings are useful to store preprocessed data? > >> ## Solution >> ->> If the option ``save_intermediary_cubes`` is set to true in the config-user.yml file, then the intermediary cubes will also be saved in the folder ``preproc``. Also, if the option ``remove_preproc_dir`` is set to ``false``, then the ``preproc/`` directory contains all the preprocessed data and the metadata interface files. +>> If the option ``save_intermediary_cubes`` is set to true in +the config-user.yml file, then the intermediary cubes will also be saved +in the folder ``preproc``. Also, if the option ``remove_preproc_dir`` +is set to ``false``, then the ``preproc/`` directory contains all +the preprocessed data and the metadata interface files. > {: .solution} {: .challenge} From 8651afbea7754045d8df84ca70da5b718ab7d456 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 26 Jun 2020 15:38:51 +0200 Subject: [PATCH 076/647] Add 'what is ESMValTool' section --- _episodes/01-introduction.md | 96 +++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 35 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 8afa4d93..c26065b1 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -1,53 +1,82 @@ --- title: "Introduction" teaching: 0 -exercises: 0 +exercises: 10 questions: -- What is ESMValTool? -- When to use ESMValTool? -- What are the main parts of ESMValTool that I need to know? -- How does ESMValTool contribute to making climate research FAIR? -- What is the role of the ESMValTool community? -- Where to find help if I'm stuck with ESMValTool? +- What is ESMValTool? +- When to use ESMValTool? +- What are the main parts of ESMValTool that I need to know? +- How does ESMValTool contribute to making climate research FAIR? +- What is the role of the ESMValTool community? +- Where to find help if I'm stuck with ESMValTool? objectives: -- Describe the difference between ESMValTool and other tools like CDO or xarray -- Understand the main parts of ESMValTool (recipe, diagnostic script) -- Browse the documentation of ESMValTool for help -- Exlain why ESMValTool is a great way to make climate analysis FAIR -- List three different ways to get help from to the ESMValTool community (docs, user engagement email, github issues) -- Know when (not) to use ESMValTool +- Describe the difference between ESMValTool and other tools like CDO or xarray +- Understand the main parts of ESMValTool (recipe, diagnostic script) +- Browse the documentation of ESMValTool for help +- Exlain why ESMValTool is a great way to make climate analysis FAIR +- List three different ways to get help from to the ESMValTool community (docs, user engagement email, github issues) +- Know when (not) to use ESMValTool keypoints: -- ESMValTool provides a reliable interface to analyse and evaluate climate data -- By streamlining common preprocessor functions, ESMValTool facilitates comparison -- ESMValTool is built and maintained by an active community of climate scientists and software developers -- Using ESMValTool stimulates standardization, collaboration, and reuse -- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages +- ESMValTool provides a reliable interface to analyse and evaluate climate data +- By streamlining common preprocessor functions, ESMValTool facilitates comparison +- ESMValTool is built and maintained by an active community of climate scientists and software developers +- Using ESMValTool stimulates standardization, collaboration, and reuse +- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages --- -## Welcome - - ## What is ESMValTool? +EMSValTool is first and foremost a tool to analyse climate data. But you probably already knew that, and we like to think there's more to it than that.So let's start with a quick check to synchronize our expectations. + +> ## Question: what is ESMValTool? +> +> Which of the following items would you say apply to ESMValTool? +> +> - A tool to analyse climate data +> - The easy way out +> - A community effort +> - Free +> - A command line tool +> - A way to make climate science more [FAIR](https://fair-software.eu/about) +> - Perfect +> - Quite suitable for (Jupyter) notebooks +> +> Check our answers by unfolding the boxes below. +> +>> ## ESMValTool is ... +>> +>> - A tool to analyse climate data. It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. +>> - A way to make climate science more [FAIR](https://fair-software.eu/about). ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readible recipe format that makes climate analysis consistent, reproducbile, and easy to share. +>> - A community effort. EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. It's longevity depends on these contributions. +>> - A command line tool. ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. +>> - Free. ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. We *do* encourage all users to contribute to the community once they get more comfortable with the tool, though. +>{: .solution} +> +>> ## ESMValTool is not ... +>> +>> - Perfect. Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you'll learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. +>> - The easy way out. If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. +>> - Quite suitable for (Jupyter) notebooks. ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. +>{: .solution} +{: .challenge} + +To learn more about ESMValTool, you can find more information in the [documentation](https://docs.esmvaltool.org/en/latest/introduction.html), or the [overview paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific Model Development*. + +## How does ESMValTool work? + +### ESMValTool and ESMValCore -## ESMValTool and ESMValCore Include figure describing ESMValTool -## What are the main parts of ESMValTool that I need to know? - - -## Preprocessor - +### Preprocessor -## Recipe (include callout on yml) +### Recipe (include callout on yml) +### Global settings (user-config.yml) -## Global settings (user-config.yml) - - -## Diagnostics +### Diagnostics ## Community @@ -55,7 +84,4 @@ Include figure describing ESMValTool - How many open issues? - How many merged pull requests in the last month? - - {% include links.md %} - From aeeca7539f76d1c317380d60870a6db29ba93fe1 Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 26 Jun 2020 14:44:57 +0100 Subject: [PATCH 077/647] First commit to the preprocessors section - just to check that everything is in order. This file is not finished yet --- _episodes/preprocessor.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 _episodes/preprocessor.md diff --git a/_episodes/preprocessor.md b/_episodes/preprocessor.md new file mode 100644 index 00000000..81527601 --- /dev/null +++ b/_episodes/preprocessor.md @@ -0,0 +1,17 @@ +--- +title: "Working with preprocessors" +teaching: 10 +exercises: 1 +questions: +- “How do I set up a preprocessor?” +- “Can I use different preprocessors for different variables?” +- “Can I use different datasets for different variables?” +Objectives: +- “Create a recipe with multiple preprocessors” +- “Use different preprocessors for different variables” +- “Run a recipe with variables from different datasets” +keypoints: +- “A recipe can run different preprocessors at the same time.” +- “The setting additional_datasets can be used to add a different dataset.” +- “Variable groups are useful for defining different settings for different variables.” +--- From a73e91c8a07a52262426064fda376f2784a00709 Mon Sep 17 00:00:00 2001 From: Niels Drost Date: Fri, 26 Jun 2020 16:28:13 +0200 Subject: [PATCH 078/647] added conda install instructions --- _episodes/02-installation.md | 54 ++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 8c5b4b50..fc8d95ea 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -25,28 +25,18 @@ We end this chapter by testing that the installation was successful. ## Install Conda -ESMValTool is distributed using Conda(link). Most users use Linux or OSX, but succesful usage has also been reported through the Windows Subsystem for Linux(WSL) (link). - -We will be using the Miniconda minimal installer for conda. - -> ## Python 3 Only -> -> Please make sure to download a Python 3 based installation (Miniconda3), as ESMValTool only supports Python 3 -> -> -{: .callout} - +ESMValTool is distributed using [Conda](https://conda.io/). We will be using the Miniconda minimal installer for conda. We suggest a Python 3 based installer, though if you happen to already have Conda installed it should also work with Python 2. For more information about installing conda, see [the conda installation documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). ### Linux -1. Please download miniconda at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html) +1. Please download Miniconda3 for Linux at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. 2. Next, run the installer -~~~ -bash Miniconda3-latest-Linux-x86_64.sh -~~~ -{:.language-bash} + ~~~ + bash Miniconda3-latest-Linux-x86_64.sh + ~~~ + {:.language-bash} 3. Follow the instructions in the installer. The defaults should normally suffice. @@ -54,18 +44,40 @@ bash Miniconda3-latest-Linux-x86_64.sh 5. Verify you have a working conda installation by listing all installed packages -~~~ -conda list -~~~ -{:.language-bash} + ~~~ + conda list + ~~~ + {:.language-bash} ### MacOSX +1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). + +2. Next, run the installer + + ~~~ + bash Miniconda3-latest-MacOSX-x86_64.sh + ~~~ + {:.language-bash} + +3. Follow the instructions in the installer. The defaults should normally suffice. + +4. You will need to restart your terminal for the changes to have effect. + +5. Verify you have a working conda installation by listing all installed packages + + ~~~ + conda list + ~~~ + {:.language-bash} + ### Windows -After installing the WSL, installation can be done using the Linux installation instructions. +ESMValTool does not directly support Windows, But succesful usage has been reported through the [Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows 10. +To install the WSL please follow the instructions [on the Windows Documentation page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). +After installing the WSL, installation can be done using the Linux installation instructions. ## Install Julia From a2460a17e999f6c1cc617876883b34c90a4783c9 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Fri, 26 Jun 2020 16:30:01 +0200 Subject: [PATCH 079/647] adds more detail to the recipe explanation adds the recipe as a file (not linked yet) --- _episodes/first_example_recipe.md | 175 +++++++++++++++++------------- data/recipe_example.yml | 42 +++++++ 2 files changed, 141 insertions(+), 76 deletions(-) create mode 100644 data/recipe_example.yml diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index c4922eb9..1c945e1d 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -56,11 +56,11 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w Note that the authors, publications and references are to be named in the config-references.yml -This information +This information ... ## How to run ESMValTool -Once you’ve set up your conda environment and installed ESMValTool (See episode #2) and set up your config-user.yml file to correctly match you local environment, (see episode #3), ESMValTool is invoked using a simple command: +Once you’ve set up your conda environment and installed ESMValTool (see episode #2 LINK) and set up your config-user.yml file to correctly match you local environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: ~~~ esmvaltool -c configuration recipe ~~~ @@ -69,63 +69,92 @@ esmvaltool -c configuration recipe To try your hand with a basic recipe, please work through this episode. -## Example recipe -This is a basic recipe that takes a simple dataset and produces a simple plot. -Please copy and paste the following recipe into your ESMValTool working area with the name: recipe_example.yml +## Introduction to the example recipe +Threcipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. - # ESMValTool - # recipe_example.yml - --- - documentation: - description: | - Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - - datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005, } - - preprocessors: - prep_timeseries: # For 0D fields - annual_statistics: - operator: mean - - diagnostics: - # -------------------------------------------------- - # Time series diagnostics - # -------------------------------------------------- - diag_timeseries_temperature: - variables: - timeseries_variable: - short_name: thetaoga - preprocessor: prep_timeseries - scripts: - timeseries_diag: - script: ocean/diagnostic_timeseries.py +Please copy and paste the following recipe into your ESMValTool working area with the name: recipe_example.yml +>## recipe_example.yml +>~~~YAML +> # ESMValTool +> # recipe_example.yml +> --- +> documentation: +> description: Demonstrate basic ESMValTool example +> +> authors: +> - demora_lee +> - mueller_benjamin +> - swaminathan_ranjini +> +> maintainer: +> - demora_lee +> +> references: +> - demora2018gmd +> # Some plots also appear in ESMValTool paper 2. +> +> projects: +> - ukesm +> +> datasets: +> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> +> preprocessors: +> prep_timeseries: # For 0D fields +> annual_statistics: +> operator: mean +> +> diagnostics: +> # -------------------------------------------------- +> # Time series diagnostics +> # -------------------------------------------------- +> diag_timeseries_temperature: +> description: simple_time_series +> variables: +> timeseries_variable: +> short_name: thetaoga +> preprocessor: prep_timeseries +> scripts: +> timeseries_diag: +> script: ocean/diagnostic_timeseries.py +>~~~ +{: .solution} > ## Explore the recipe -> > Use the command and investigate the sample recipe. > ~~~ -> vim recipe.yml +> vim recipe_example.yml > ~~~ > {: .source} > -> Please note the datasets, preprocessors, diagnostic sections. + +Please note the following sections: +- documentation: lines 4-20 + + The documentation consists of the following information: + - description: a one line description of the recipe + - authors: a list of authors (linked to esmvaltool/config-references.yml) + - maintainer: a list of maintainers (linked to esmvaltool/config-references.yml) + - references: a list of references (linked to a bibtexfile in esmvaltool/references with the same name) + - projects: a list of projects (linked to esmvaltool/config-references.yml) + + +- datasets: lines 22-23 + The dataset definition consists of a list of dictionaries with the information on the datasets. + [List of entries?] + + +- preprocessors: lines 25-28 + The definition for different preprocessors or combinations. + [go into detail] + + +- diagnostic section: lines 30-42 + The information of which diagnostic script to run with which variables. + [go into detail] + + > What is the short_name of the variable being analysed? > What is the diagnostic script being used? > How many years of data are being analysed? @@ -185,29 +214,23 @@ Please copy and paste the following recipe into your ESMValTool working area wit {: .challenge} -> ## Common issues & tips -> -> ### Esmvaltool not found -> Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, epside [2] LINK. -> -> ### ESMValTool can’t locate the data -> The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” -> Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? -> -> -> ### Diagnostic path problems -> The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? -> -> -> ### FX files not found. -> -> -> ### The preprocessor works but the diagnostic fails: -> If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. -> -> -> ### Your recipe’s name/project/reference isn’t recognised by ESMValTool. -> Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” -> Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. -> -{: .callout} +## Common issues & tips + +### Esmvaltool not found +Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, epside [2] LINK. + +### ESMValTool can’t locate the data +The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” +Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? + +### Diagnostic path problems +The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? + +### FX files not found. + +### The preprocessor works but the diagnostic fails: +If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. + +### Your recipe’s name/project/reference isn’t recognised by ESMValTool. +Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” +Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. diff --git a/data/recipe_example.yml b/data/recipe_example.yml new file mode 100644 index 00000000..67cee8b9 --- /dev/null +++ b/data/recipe_example.yml @@ -0,0 +1,42 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +datasets: + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} + +preprocessors: + prep_timeseries: # For 0D fields + annual_statistics: + operator: mean + +diagnostics: + # -------------------------------------------------- + # Time series diagnostics + # -------------------------------------------------- + diag_timeseries_temperature: + description: simple_time_series + variables: + timeseries_variable: + short_name: thetaoga + preprocessor: prep_timeseries + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py From db9ca6a162b670f877cd1272fa6b20cc523a47b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20M=C3=BCller?= Date: Fri, 26 Jun 2020 16:33:40 +0200 Subject: [PATCH 080/647] Update first_example_recipe.md remove header --- _episodes/first_example_recipe.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 1c945e1d..f58bba3c 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -1,6 +1,3 @@ -File name : first_example_recipe.md -Episode 4. - --- title: "Running a recipe (First example)" teaching: 10 From 6a34170c6e67e450c8aaaf6d16251cfaedb01735 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Fri, 26 Jun 2020 16:44:30 +0200 Subject: [PATCH 081/647] fix " typo --- _episodes/first_example_recipe.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index f58bba3c..e415e02f 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -1,6 +1,6 @@ --- title: "Running a recipe (First example)" -teaching: 10 +teaching: 20 exercises: 25 questions: - "What is a recipe?" @@ -8,14 +8,14 @@ questions: - "What are the files and directories after running a recipe?" - "What happens when I run a recipe?" objectives: -- "Run an ESMValTool recipe” +- "Run an ESMValTool recipe" - "Understand the purpose of different settings in the recipe" - "Inspect the output directories" - "Examine the log information" keypoints: - "A recipe does not break by fiddling with it" - "Log information is useful when interpreting the first warnings/errors" -- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." +- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP" --- This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. From 35d37aefabd01bc83e2f6dda39ea0a4148b85497 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 26 Jun 2020 17:15:11 +0200 Subject: [PATCH 082/647] Add 'how does esmvaltool work' section --- _episodes/01-introduction.md | 39 ++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index c26065b1..f463f731 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -28,7 +28,7 @@ keypoints: --- ## What is ESMValTool? -EMSValTool is first and foremost a tool to analyse climate data. But you probably already knew that, and we like to think there's more to it than that.So let's start with a quick check to synchronize our expectations. +EMSValTool is first and foremost a tool to analyse climate data. But you probably already knew that and we like to think there's more to it than that. So let's start with a quick check to synchronize our expectations. > ## Question: what is ESMValTool? > @@ -41,7 +41,7 @@ EMSValTool is first and foremost a tool to analyse climate data. But you probabl > - A command line tool > - A way to make climate science more [FAIR](https://fair-software.eu/about) > - Perfect -> - Quite suitable for (Jupyter) notebooks +> - Suitable for (Jupyter) notebooks > > Check our answers by unfolding the boxes below. > @@ -56,30 +56,39 @@ EMSValTool is first and foremost a tool to analyse climate data. But you probabl > >> ## ESMValTool is not ... >> +>> - The easy way out. If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. >> - Perfect. Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you'll learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. ->> - The easy way out. If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. ->> - Quite suitable for (Jupyter) notebooks. ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. +>> - Suitable for (Jupyter) notebooks. ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. >{: .solution} {: .challenge} -To learn more about ESMValTool, you can find more information in the [documentation](https://docs.esmvaltool.org/en/latest/introduction.html), or the [overview paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific Model Development*. +To learn more about ESMValTool is, you can look at the [documentation](https://docs.esmvaltool.org/en/latest/introduction.html), the [official website](https://www.esmvaltool.org/about.html), or the [overview paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific Model Development*. ## How does ESMValTool work? +The figure below shows the different components of ESMValTool. Most of the work is done in the 'core', which performs a number of preprocessor steps. Outside of the core we have some configuration files that specify things like *where to find the CMIP data*. The most important file however, is the *recipe* that specifies which preprocessor functions need to be applied to what data. The recipe also points to a diagnostic script that is executed after the preprocessor and performs a more specific analysis on the preprocessed data. -### ESMValTool and ESMValCore +![figure showing ESMValTool architecture]({{ page.root }}/fig/esmvaltool_architecture.png) -Include figure describing ESMValTool - -### Preprocessor - -### Recipe (include callout on yml) - -### Global settings (user-config.yml) - -### Diagnostics +>## Discussion: (dis)advantages of this approach? +> Discuss or think about the pro's and cons of this architecture for a moment. Then unfold the box below to see our answers. +> +> +>>## See our thoughts +>> +>> - Streamlining common preprocessing steps ensures consistency in the algorithms being used and the way they are executed. This facilitates comparison and reproducibility. +>> - Provenance and citation information can be tracked through the entire workflow. +>> - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) package, which is quite strict in order to minimize unexpected results. +>> - Recipes are easy to read and share. +>> - A collection of recipes and diagnostic scripts is shipped with ESMValTool, ready for re-use. Everyone can add to this collection. +>> - The recipe format takes some getting used to and may be a bit less flexible then working on the datasets directly. +>> - Missing features can be more of a limiting factor. +>{: .solution} +{: .discussion} ## Community +some exercises: + - How many people are connected to github? - How many open issues? - How many merged pull requests in the last month? From 101c04793232536064ce79c710374cb19f8c98de Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Fri, 26 Jun 2020 16:52:14 +0100 Subject: [PATCH 083/647] Added title page --- index.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/index.md b/index.md index 95ccdbdc..4bed3a81 100644 --- a/index.md +++ b/index.md @@ -3,15 +3,34 @@ layout: lesson root: . # Is the only page that doesn't follow the pattern /:path/index.html permalink: index.html # Is the only page that doesn't follow the pattern /:path/index.html --- -FIXME: home page introduction - +This tutorial is built to teach you ESMValTool. It starts from the basics, what it is, how it works, and goes to the advanced sections of how can I make my own diagnostics within ESMValTool and how do I contribute my code back to share with the ESMValTool community. -{% comment %} This is a comment in Liquid {% endcomment %} +Don’t be alarmed if you can’t work through it all in one sitting. It may take some time to get used to working with ESMValTool. + +> ## What will you learn in this course: +> +> - What is ESMValTool +> - How to install ESMValTool +> - How to run ESMValTool +> - How to develop your own diagnostics and recipes +> - How to contribute your recipes and diagnostics back into ESMValTool +{: .checklist} > ## Prerequisites > -> FIXME +> Basic understanding of git (optional - but useful) +> Basic understanding of your preferred command line interface (ie a bash terminal) +> Access to CMIP data +> Access to a suitable computing system (egie jasmin) +> Github account (optional, but useful!) {: .prereq} +> ## Main things you need to know before starting this course: +> +> 1. This tutorial can be taken online independently or taught by one of our instructors. +> 2. Please check the common issues page if you get stuck. Otherwise, help is always available from ESMValTool developers via the github issues page. +> 3. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. +{: .checklist} + {% include links.md %} From 997ce446ac0481c916fc316dd4066ee123d295d7 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Fri, 26 Jun 2020 17:03:32 +0100 Subject: [PATCH 084/647] debugging --- index.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/index.md b/index.md index 4bed3a81..34337bec 100644 --- a/index.md +++ b/index.md @@ -8,13 +8,18 @@ This tutorial is built to teach you ESMValTool. It starts from the basics, what Don’t be alarmed if you can’t work through it all in one sitting. It may take some time to get used to working with ESMValTool. -> ## What will you learn in this course: +> ## What will you learn in this course +> +> - What is ESMValTool +> +> - How to install ESMValTool +> +> - How to run ESMValTool +> +> - How to develop your own diagnostics and recipes +> +> - How to contribute your recipes and diagnostics back into ESMValTool > -> - What is ESMValTool -> - How to install ESMValTool -> - How to run ESMValTool -> - How to develop your own diagnostics and recipes -> - How to contribute your recipes and diagnostics back into ESMValTool {: .checklist} > ## Prerequisites @@ -26,7 +31,7 @@ Don’t be alarmed if you can’t work through it all in one sitting. It may tak > Github account (optional, but useful!) {: .prereq} -> ## Main things you need to know before starting this course: +> ## Main things you need to know before starting this course > > 1. This tutorial can be taken online independently or taught by one of our instructors. > 2. Please check the common issues page if you get stuck. Otherwise, help is always available from ESMValTool developers via the github issues page. From 9f6798966886aa799814d5583e96ee470ac83016 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Fri, 26 Jun 2020 17:15:20 +0100 Subject: [PATCH 085/647] added extra sections --- index.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/index.md b/index.md index 34337bec..65032b44 100644 --- a/index.md +++ b/index.md @@ -4,9 +4,7 @@ root: . # Is the only page that doesn't follow the pattern /:path/index.html permalink: index.html # Is the only page that doesn't follow the pattern /:path/index.html --- -This tutorial is built to teach you ESMValTool. It starts from the basics, what it is, how it works, and goes to the advanced sections of how can I make my own diagnostics within ESMValTool and how do I contribute my code back to share with the ESMValTool community. - -Don’t be alarmed if you can’t work through it all in one sitting. It may take some time to get used to working with ESMValTool. +This tutorial is built to teach you ESMValTool. > ## What will you learn in this course > @@ -36,6 +34,23 @@ Don’t be alarmed if you can’t work through it all in one sitting. It may tak > 1. This tutorial can be taken online independently or taught by one of our instructors. > 2. Please check the common issues page if you get stuck. Otherwise, help is always available from ESMValTool developers via the github issues page. > 3. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. +> 4. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. {: .checklist} {% include links.md %} + + +> ## Additional resources: +> +> - Read the docs page. +> - github main page. +> - GMD paper +> - ESMValTool home page +{: .callout} + + +Please cite this tutorial as: +ESMVAlTool 2.0 tutorial, website, version [ADD AUTO VERSION?] + + + From 9ca57371fd16f5617f11e95f1015898af30131d1 Mon Sep 17 00:00:00 2001 From: Niels Drost Date: Fri, 26 Jun 2020 19:30:00 +0200 Subject: [PATCH 086/647] fixing some linter errors --- _episodes/02-installation.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index fc8d95ea..392321ae 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -3,14 +3,14 @@ title: "Installation" teaching: 10 exercises: 20 questions: -- "What are the prerequisites for installing ESMValTool?" -- "How do I confirm that the installation was successful?" + - "What are the prerequisites for installing ESMValTool?" + - "How do I confirm that the installation was successful?" objectives: -- "Install ESMValTool" -- "Demonstate that the installation was successful" + - "Install ESMValTool" + - "Demonstate that the installation was successful" keypoints: -- "All the required packages can be installed using conda" -- "You can find more information about installation in the documentation" + - "All the required packages can be installed using conda" + - "You can find more information about installation in the documentation" --- ## Overview @@ -29,20 +29,20 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the ### Linux -1. Please download Miniconda3 for Linux at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. +1. Please download Miniconda3 for Linux at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. -2. Next, run the installer +2. Next, run the installer ~~~ bash Miniconda3-latest-Linux-x86_64.sh ~~~ {:.language-bash} -3. Follow the instructions in the installer. The defaults should normally suffice. +3. Follow the instructions in the installer. The defaults should normally suffice. -4. You will need to restart your terminal for the changes to have effect. +4. You will need to restart your terminal for the changes to have effect. -5. Verify you have a working conda installation by listing all installed packages +5. Verify you have a working conda installation by listing all installed packages ~~~ conda list @@ -51,20 +51,20 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the ### MacOSX -1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). +1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). -2. Next, run the installer +2. Next, run the installer ~~~ bash Miniconda3-latest-MacOSX-x86_64.sh ~~~ {:.language-bash} -3. Follow the instructions in the installer. The defaults should normally suffice. +3. Follow the instructions in the installer. The defaults should normally suffice. -4. You will need to restart your terminal for the changes to have effect. +4. You will need to restart your terminal for the changes to have effect. -5. Verify you have a working conda installation by listing all installed packages +5. Verify you have a working conda installation by listing all installed packages ~~~ conda list From 27331d7a90e5c9eebea7cff7bcc21af54fc6290a Mon Sep 17 00:00:00 2001 From: Niels Drost Date: Fri, 26 Jun 2020 19:33:09 +0200 Subject: [PATCH 087/647] fixing some linter errors --- _episodes/02-installation.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 392321ae..a4bac607 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -3,14 +3,14 @@ title: "Installation" teaching: 10 exercises: 20 questions: - - "What are the prerequisites for installing ESMValTool?" - - "How do I confirm that the installation was successful?" +- "What are the prerequisites for installing ESMValTool?" +- "How do I confirm that the installation was successful?" objectives: - - "Install ESMValTool" - - "Demonstate that the installation was successful" +- "Install ESMValTool" +- "Demonstate that the installation was successful" keypoints: - - "All the required packages can be installed using conda" - - "You can find more information about installation in the documentation" +- "All the required packages can be installed using conda" +- "You can find more information about installation in the documentation" --- ## Overview From 65f7bf69bf41eb37a52a5c7b6284b16ffabe0f32 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 29 Jun 2020 10:21:07 +0200 Subject: [PATCH 088/647] fix the links --- _episodes/03-configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index f56c08e7..3f395c01 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -93,7 +93,7 @@ We add the root path of the folder where data is available. > ## Setting the correct rootpath > > * To get the data (or its correct rootpath), check instruction in -[Setup](https://esmvalgroup.github.io/tutorial/setup.html). +[Setup]({{ page.root }}{% link setup.md %}). > * For more information about setting the rootpath, you can visit the ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} @@ -164,7 +164,7 @@ resource_usage.txt and temporary files created by the diagnostic scripts. files in NetCDF format (depends on the diagnostic script). > > We explain more about output in the next -[lesson](https://esmvalgroup.github.io/tutorial/04-toy-example/index.html) +[lesson]({{ page.root }}{% link _episodes/04-toy-example.md %}) {: .callout} ## Auxiliary data directory From 758d6d88ddd80a64b76c2dcd4973d03e233512af Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Mon, 29 Jun 2020 10:54:32 +0200 Subject: [PATCH 089/647] Add architecture figure --- _episodes/01-introduction.md | 30 +++++++++++++++--------------- fig/esmvaltool_architecture.png | Bin 0 -> 115471 bytes 2 files changed, 15 insertions(+), 15 deletions(-) create mode 100644 fig/esmvaltool_architecture.png diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index f463f731..0debc630 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -47,18 +47,18 @@ EMSValTool is first and foremost a tool to analyse climate data. But you probabl > >> ## ESMValTool is ... >> ->> - A tool to analyse climate data. It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. ->> - A way to make climate science more [FAIR](https://fair-software.eu/about). ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readible recipe format that makes climate analysis consistent, reproducbile, and easy to share. ->> - A community effort. EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. It's longevity depends on these contributions. ->> - A command line tool. ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. ->> - Free. ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. We *do* encourage all users to contribute to the community once they get more comfortable with the tool, though. +>> - A tool to analyse climate data. It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. +>> - A way to make climate science more [FAIR](https://fair-software.eu/about). ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readible recipe format that makes climate analysis consistent, reproducbile, and easy to share. +>> - A community effort. EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. It's longevity depends on these contributions. +>> - A command line tool. ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. +>> - Free. ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. We *do* encourage all users to contribute to the community once they get more comfortable with the tool, though. >{: .solution} > >> ## ESMValTool is not ... >> ->> - The easy way out. If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. ->> - Perfect. Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you'll learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. ->> - Suitable for (Jupyter) notebooks. ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. +>> - The easy way out. If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. +>> - Perfect. Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you'll learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. +>> - Suitable for (Jupyter) notebooks. ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. >{: .solution} {: .challenge} @@ -75,13 +75,13 @@ The figure below shows the different components of ESMValTool. Most of the work > >>## See our thoughts >> ->> - Streamlining common preprocessing steps ensures consistency in the algorithms being used and the way they are executed. This facilitates comparison and reproducibility. ->> - Provenance and citation information can be tracked through the entire workflow. ->> - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) package, which is quite strict in order to minimize unexpected results. ->> - Recipes are easy to read and share. ->> - A collection of recipes and diagnostic scripts is shipped with ESMValTool, ready for re-use. Everyone can add to this collection. ->> - The recipe format takes some getting used to and may be a bit less flexible then working on the datasets directly. ->> - Missing features can be more of a limiting factor. +>> - Streamlining common preprocessing steps ensures consistency in the algorithms being used and the way they are executed. This facilitates comparison and reproducibility. +>> - Provenance and citation information can be tracked through the entire workflow. +>> - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) package, which is quite strict in order to minimize unexpected results. +>> - Recipes are easy to read and share. +>> - A collection of recipes and diagnostic scripts is shipped with ESMValTool, ready for re-use. Everyone can add to this collection. +>> - The recipe format takes some getting used to and may be a bit less flexible then working on the datasets directly. +>> - Missing features can be more of a limiting factor. >{: .solution} {: .discussion} diff --git a/fig/esmvaltool_architecture.png b/fig/esmvaltool_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..43167b3359b4553e8c36497aed810bb1c946f104 GIT binary patch literal 115471 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 Date: Mon, 29 Jun 2020 12:04:04 +0200 Subject: [PATCH 090/647] Add section about community and conclusion --- _episodes/01-introduction.md | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 0debc630..0217cd65 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -1,7 +1,7 @@ --- title: "Introduction" teaching: 0 -exercises: 10 +exercises: 25 questions: - What is ESMValTool? - When to use ESMValTool? @@ -28,6 +28,7 @@ keypoints: --- ## What is ESMValTool? + EMSValTool is first and foremost a tool to analyse climate data. But you probably already knew that and we like to think there's more to it than that. So let's start with a quick check to synchronize our expectations. > ## Question: what is ESMValTool? @@ -87,10 +88,30 @@ The figure below shows the different components of ESMValTool. Most of the work ## Community -some exercises: +ESMValTool is built and maintained by an active community of scientists and engineers. Many of the interactions take place on GitHub. Here, we briefly introduce you to some of the most important pages. + +> ## Challenge: meet ESMValGroup +> +> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is our 'organization' GitHub page. Have a look around. How many collaborators are there? Do you know any of them? You should see 2 main repositories: ESMValTool and ESMValCore. Clicking on them will take you to there. How many people have contributed to each of them? Can you also find out how many people have contributed to this tutorial? +> +>> ## Solution +>> +>> At the time of making this lesson, there were 138 members of ESMValGroup. 55 of them contributed to ESMValTool, 48 to ESMValCore. 52 (!) people contributed to this tutorial. +>{: .solution} +{: .challenge} + +>## Challenge: issues and pull requests +> +> Go back to the repository pages of [ESMValTool](https://github.com/ESMValGroup/ESMValTool) or [ESMValCore](https://github.com/ESMValGroup/ESMValCore). You should see tabs for 'issues' and 'pull requests'. You can use the labels to navigate them a bit more. How many open issues are about enhancements of ESMValTool? And how many bugs have been fixed in ESMValCore? There is also an 'insights' tab, where you can see a summary of recent activity. How many issues have been opened and closed in the past month? +> +>> ## Solution +>> +>> At the time of making this tutorial, there were 50 ESMValTool issues (the majority) about enhancement and 31 bugs had been fixed in the Core. 13 ESMValTool issues had been closed in the past month, versus 8 opened: overall good progress. +>{: .solution} +{: .challenge} + +## Conclusion -- How many people are connected to github? -- How many open issues? -- How many merged pull requests in the last month? +This concludes the introduction of the tutorial. You should now have a basic knowledge of ESMValTool and our community. The following episodes will walk you through the installation, configuration and running your first recipes. {% include links.md %} From 34b0e3794f512a035324e0b77e0567c665e43925 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 29 Jun 2020 12:09:11 +0200 Subject: [PATCH 091/647] revise the text --- _episodes/03-configuration.md | 65 +++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 3f395c01..95b98f3d 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -3,15 +3,15 @@ title: "Configuration" teaching: 0 exercises: 0 questions: -- "What is the user configuration file and how can I use it?" +- "What is the user configuration file and how should I use it?" objectives: - "Understand the contents of the user-config.yml file" -- "Prepare the user-config.yml file for use" -- "Configure ESMValTool to ignore some settings" +- "Prepare a personalized user-config.yml file" +- "Configure ESMValTool to use some settings" keypoints: - "The ``config-user.yml`` tells ESMValTool where to find input data." -- " ``rootpath`` determines root directory for input data." -- " ``output_dir`` is the destination directory." +- " ``rootpath`` defines the root directory for the input data." +- " ``output_dir`` defines the destination directory." --- ## The configuration file @@ -23,14 +23,14 @@ can be found in the root directory of the ESMValTool repository: [config-user-example.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). Let's download it to our working directory ``esmvaltool_tutorial`` -that is made during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). +that was created during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). To do that, click on [this link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) to see a raw version of the file, right-click and press ``save as``, then you can rename it to ``config-user.yml``and save it into the working directory ``esmvaltool_tutorial``. -Now in a terminal, let's change our working directory to ``esmvaltool_tutorial``. +Now, let's change our working directory in a terminal window to ``esmvaltool_tutorial``. Then, we run a text editor called Nano to open the configuration file: ~~~bash @@ -42,17 +42,17 @@ This file contains the information for: * Rootpath to input data * Directory structure for the data from different projects -* Number of parallel tasks +* Number of tasks that can be run in parallel * Destination directory * Auxiliary data directory * Output settings -> ## Which text editor +> ## Text editor side note > > No matter what editor you use, you will need to know where it searches for and saves files. If you start it from the shell, it will (probably) use your current working directory as its default location. We use ``nano`` -in examples because it is one of the least complex text editors. +in examples here because it is one of the least complex text editors. Press ctrl + O to save the file, and then ctrl + X to exit ``nano``. {: .callout} @@ -62,7 +62,7 @@ and then ctrl + X to exit ``nano``. ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from -the climate model intercomparison project whereas OBS for an observational dataset. +the climate model intercomparison project whereas OBS is used for an observational dataset. The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. @@ -82,7 +82,7 @@ rootpath: In this lesson, we will work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). -We add the root path of the folder where data is available. +We add the root path of the folder where our/your data is available. ~~~YAML rootpath: @@ -94,7 +94,8 @@ We add the root path of the folder where data is available. > > * To get the data (or its correct rootpath), check instruction in [Setup]({{ page.root }}{% link setup.md %}). -> * For more information about setting the rootpath, you can visit the ESMValTool +> * For more information about setting the rootpath, see also the ESMValTool +For more information about setting the roothpath, see also ESMValTool... [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} @@ -102,8 +103,8 @@ We add the root path of the folder where data is available. Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). -To set a directory, you can use one of the values of -``default``, ``BADC``, ``DKRZ``, ``ETHZ``, .... Let's use ``default`` in our example: +The ``drs`` setting describes the file structure. +Let's use ``default`` for ``CMIP5`` in our example here: ~~~YAML drs: @@ -112,16 +113,19 @@ drs: > ## Available drs > -> For more information about directories, you can visit the ESMValTool -[documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/config.html#developer-configuration-file). +> The ``drs`` setting describes the file structure for several projects +(e.g. ``CMIP6``, ``CMIP5``, ``obs4mips``, ``OBS6``, ``OBS``) on several key machines +(e.g. ``BADC``, ``CP4CDS``, ``DKRZ``, ``ETHZ``, ``SMHI``, ``BSC``). +For more information about ``drs``, you can visit the ESMValTool +[documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html#cmor-drs). {: .callout} ## Number of parallel tasks This option enables you to perform parallel processing. You can choose the number of tasks in parallel as -1/2/3/4/... or you can set it to ``null`` that tells -ESMValTool to use the number of available CPUs: +1/2/3/4/... or you can set it to ``null``. That tells +ESMValTool to use the maximum number of available CPUs: ~~~YAML @@ -141,11 +145,11 @@ again to a reasonable number for the amount of memory available in your system. The destination directory is the rootpath where ESMValTool will store its output, i.e. figures, data, logs, etc. With every run, ESMValTool automatically generates -a new output folder determined by the recipe name, and date and time using +a new output folder determined by recipe name, and date and time using the format: YYYYMMDD_HHMMSS. This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. -Let's name our destination directory as ``esmvaltool_output`` in the working directory: +Let's name our destination directory ``esmvaltool_output`` in the working directory: ~~~YAML output_dir: ./esmvaltool_output @@ -160,8 +164,8 @@ each run because most users will only need the results from the diagnostic scrip > * ``run``: this folder includes all log files, a copy of the recipe, a summary of the resource usage, and the settings.yml interface files, resource_usage.txt and temporary files created by the diagnostic scripts. -> * ``work``: a place for any diagnostic script results that are not plots, e.g. -files in NetCDF format (depends on the diagnostic script). +> * ``work``: this folder is a place for any diagnostic script results that +are not plots, e.g. files in NetCDF format (depends on the diagnostic script). > > We explain more about output in the next [lesson]({{ page.root }}{% link _episodes/04-toy-example.md %}) @@ -169,11 +173,11 @@ files in NetCDF format (depends on the diagnostic script). ## Auxiliary data directory -The ``auxiliary_data_dir`` setting is the path to place any required -additional auxiliary data files. This location allows us to tell +The ``auxiliary_data_dir`` setting is the path where any required +additional auxiliary data files are stored. This location allows us to tell the diagnostic script where to find the files if they can not be downloaded -at runtime. This option is not for model or observational datasets, rather -it is for data files used in plotting such as coastline descriptions and so on. +at runtime. This option should not be used for model or observational datasets, but +for data files (e.g. shape files) used in plotting such as coastline descriptions and so on. ~~~YAML auxiliary_data_dir: ~/auxiliary_data @@ -181,7 +185,7 @@ auxiliary_data_dir: ~/auxiliary_data ## Output settings -These settings are used to inform ESMValTool about your preference. +These settings are used to inform ESMValTool about your preference about specific actions. You can turn on or off the setting by ``true`` or ``false`` values. Most of these settings are fairly self-explanatory, ie: @@ -216,9 +220,10 @@ profile_diagnostic: false for example: config-user_formalised_runs.yml, config-user_debugging.yml {: .callout} > -> ## Different settings +> ## Saving preprocessed data > -> In the configuration file, which settings are useful to store preprocessed data? +> In the configuration file, which settings are useful to make sure preprocessed data +is stored when ESMValTool is run? > >> ## Solution >> From cd12e8bb0e6b781b28b44be407b6b26278896cb9 Mon Sep 17 00:00:00 2001 From: Jaro Camphuijsen Date: Mon, 29 Jun 2020 12:13:15 +0200 Subject: [PATCH 092/647] reformat question answers --- _episodes/01-introduction.md | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 0debc630..42a59c03 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -43,22 +43,18 @@ EMSValTool is first and foremost a tool to analyse climate data. But you probabl > - Perfect > - Suitable for (Jupyter) notebooks > -> Check our answers by unfolding the boxes below. +> Check our answers by unfolding the box below. > >> ## ESMValTool is ... >> ->> - A tool to analyse climate data. It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. ->> - A way to make climate science more [FAIR](https://fair-software.eu/about). ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readible recipe format that makes climate analysis consistent, reproducbile, and easy to share. ->> - A community effort. EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. It's longevity depends on these contributions. ->> - A command line tool. ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. ->> - Free. ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. We *do* encourage all users to contribute to the community once they get more comfortable with the tool, though. ->{: .solution} -> ->> ## ESMValTool is not ... ->> ->> - The easy way out. If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. ->> - Perfect. Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you'll learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. ->> - Suitable for (Jupyter) notebooks. ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. +>> ✓ **A tool to analyse climate data.** It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. +>> ✕ **The easy way out.** If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. +>> ✓ **A community effort.** EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. Its longevity depends on these contributions. +>> ✓ **Free.** ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. However, we *do* encourage all users to contribute to the community once they get more comfortable with the tool. +>> ✓ **A command line tool.** ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. +>> ✓ **A way to make climate science more [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readible recipe format that makes climate analysis consistent, reproducible, and easy to share. +>> ✕ **Perfect.** Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you will learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. +>> ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. >{: .solution} {: .challenge} @@ -70,18 +66,18 @@ The figure below shows the different components of ESMValTool. Most of the work ![figure showing ESMValTool architecture]({{ page.root }}/fig/esmvaltool_architecture.png) >## Discussion: (dis)advantages of this approach? -> Discuss or think about the pro's and cons of this architecture for a moment. Then unfold the box below to see our answers. +> Discuss or think about the pros and cons of this architecture for a moment. Then unfold the box below to see our answers. > > >>## See our thoughts >> ->> - Streamlining common preprocessing steps ensures consistency in the algorithms being used and the way they are executed. This facilitates comparison and reproducibility. +>> - Streamlining common preprocessing steps ensures consistency in the algorithms being used and the way they are executed. This facilitates comparison and reproducibility. >> - Provenance and citation information can be tracked through the entire workflow. ->> - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) package, which is quite strict in order to minimize unexpected results. +>> - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) package, which is quite strict in order to comply with CF conventions and minimize unexpected results. >> - Recipes are easy to read and share. >> - A collection of recipes and diagnostic scripts is shipped with ESMValTool, ready for re-use. Everyone can add to this collection. >> - The recipe format takes some getting used to and may be a bit less flexible then working on the datasets directly. ->> - Missing features can be more of a limiting factor. +>> - Features or dataset support that are missing from ESMValCore can be a limiting factor. >{: .solution} {: .discussion} From 3d575149937a141de439b8832da7419c906f3dea Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Mon, 29 Jun 2020 11:48:29 +0100 Subject: [PATCH 093/647] Added conclusions page --- _episodes/conclusions.md | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 _episodes/conclusions.md diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md new file mode 100644 index 00000000..a9d26ca7 --- /dev/null +++ b/_episodes/conclusions.md @@ -0,0 +1,73 @@ +--- +title: "Conclusion of the basic tutorial" +teaching: 10 +exercises: 0 +questions: +- "What do I do now?" +- "Where can I get help?" +- "What if I find a bug?" +- "Where can I find more information about ESMValtool?" +- "How can I cite ESMValtool?" + +objectives: +- "Congratulations & Thanks!” +- “In this episode, you should find out about the rest of the tutorial, and where to do next." +--- + +## Congratulations! + +Congratulations on completing the ESMValTool tutorial! You should be now ready to go and start using ESMValTool independently. + +The rest of this tutorial contains individual mini-tutorials to help work through a specific issue. Please see the contents page for specific + + +### What next? + +From here, there are lots of ways that you can continue to use ESMValTool. +- You can start from the list of existing recipes and run one of those. +- You can learn how to write your own diagnostics and recipes. +- You can contribute your recipe and diagnostics back into ESMValTool +- You can learn how to prepare observational datasets to be suitable for use by ESMValTool. + + +### Where can I get more information on ESMValTool? + +Read the docs page: https://esmvaltool.readthedocs.io/ + +Technical description paper: https://doi.org/10.5194/gmd-13-1179-2020 + +Source code (ESMValTool): https://github.com/ESMValGroup/ESMValTool + +Source code (ESMValCore ): https://github.com/ESMValGroup/ESMValCore + + +### Where can I get more help? + +There are lots of resources available for helping you use ESMValTool. + + + + +### What if I find a bug? + +If you find a bug, please report it back to the ESMValTool team. This will help us fix it so that you can continue working, but also it means that ESMValTool will be more stable for everyone else as well. + +Please create a new issue using this page: https://github.com/ESMValGroup/ESMValTool/issues + +In your issue, please describe the problem as clearly and as completely as possible. + + + + +### How do I cite ESMValTool? + +Please use the following reference: + +Righi, M., Andela, B., Eyring, V., Lauer, A., Predoi, V., Schlund, M., Vegas-Regidor, J., Bock, L., Brötz, B., de Mora, L., Diblen, F., Dreyer, L., Drost, N., Earnshaw, P., Hassler, B., Koldunov, N., Little, B., Loosveldt Tomas, S., and Zimmermann, K.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – technical overview, Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020, 2020. + + +{% include links.md %} + + + + From 41f429726547d54a849b4d49b414900cf76c7139 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 13:14:47 +0200 Subject: [PATCH 094/647] adds details for the recipe --- _episodes/first_example_recipe.md | 40 +++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index e415e02f..cc538aaa 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -130,26 +130,47 @@ Please note the following sections: - documentation: lines 4-20 The documentation consists of the following information: - - description: a one line description of the recipe + - description: a short description of the recipe - authors: a list of authors (linked to esmvaltool/config-references.yml) - maintainer: a list of maintainers (linked to esmvaltool/config-references.yml) - references: a list of references (linked to a bibtexfile in esmvaltool/references with the same name) - projects: a list of projects (linked to esmvaltool/config-references.yml) -- datasets: lines 22-23 - The dataset definition consists of a list of dictionaries with the information on the datasets. - [List of entries?] + - datasets: lines 22-23 + The dataset definition consists of a list of python dictionaries with the information on the datasets. + - dataset name (key: dataset) + - project (key: project) + - experiment (key: exp) + - mip (for CMIP data, key: mip) + - ensemble member (key: ensemble) + - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) + - model grid (for CMIP6 data only, key: grid) + - alias (key: alias; use the alias for e.g. a more human readable name) -- preprocessors: lines 25-28 - The definition for different preprocessors or combinations. - [go into detail] + + - preprocessors: lines 25-28 + + The definition for different preprocessors or combinations. + If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). + Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). + (See episode #5 LINK for more details.) - diagnostic section: lines 30-42 + The information of which diagnostic script to run with which variables. - [go into detail] + The diagnostics section has some indents that are free to call. + - the first indent (here: diag_timeseries_temperature) is the diagnostic’s name (a string without whitespace), used for setting up the respective directories + - description: a short description of the diagnostic + - variables: a definition of all variables that are used in this diagnostic + - the next indent (here: timeseries_variable) is the variables’ names (a string without whitespace) for the diagnostic to use + - short_name: the variable name as listed in the dataset + - preprocessor: the preprocessor(s) applied to the variable before running the diagnostic + - scripts: a definition of all scripts that are used in this diagnostic + - the next indent (here: timeseries_diag) is the scripts’ names (a string without whitespace) for the script to use + - script: a executable script with a directory relative to the `esmvaltool/diag_scripts/` directory > What is the short_name of the variable being analysed? @@ -168,9 +189,8 @@ Please note the following sections: > ~~~ > esmvaltool -c user-config.yml recipe_example.yml > ~~~ -> > {: .source} -> What +> What ... {: .challenge} From 997889f56ace0e32a164da81deff37e85b352b34 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 29 Jun 2020 13:16:25 +0200 Subject: [PATCH 095/647] fix setup link --- _episodes/03-configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 95b98f3d..30e13556 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -23,7 +23,7 @@ can be found in the root directory of the ESMValTool repository: [config-user-example.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). Let's download it to our working directory ``esmvaltool_tutorial`` -that was created during the [Setup](https://esmvalgroup.github.io/tutorial/setup.html). +that was created during the [Setup]({{ page.root }}{% link setup.md %}). To do that, click on [this link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) to see a raw version of the file, right-click and press ``save as``, From fc376b21b6068fe8800dc2a5c8915db16eb64194 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 29 Jun 2020 13:16:30 +0200 Subject: [PATCH 096/647] Add instructions to run Codacy analysis locally Refs #39 --- CONTRIBUTING.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0d33e06d..067d78d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -74,6 +74,19 @@ and can be used as: mdl your_markdown_filename ``` +We use [Codacy](https://app.codacy.com/gh/ESMValGroup/tutorial) as an automated code analysis services. To run the analyis [locally](https://github.com/codacy/codacy-analysis-cli) on Markdown files with Docker use + +```bash +docker run \ + --rm=true \ + --env CODACY_CODE=${PWD} \ + --volume /var/run/docker.sock:/var/run/docker.sock \ + --volume ${PWD}:${PWD} \ + --volume /tmp:/tmp \ + codacy/codacy-analysis-cli \ + analyse --tool remark-int +``` + ### Previewing your changes locally If you are making a new episode or contributing to existing ones, From f595c7b8e57f195bc36f8e08022b09bca2a87261 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 13:23:40 +0200 Subject: [PATCH 097/647] adds header detail --- _episodes/first_example_recipe.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index cc538aaa..120e058e 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -1,11 +1,12 @@ --- + title: "Running a recipe (First example)" teaching: 20 exercises: 25 questions: - "What is a recipe?" - "How can I do the same preprocessing on many different datasets?" -- "What are the files and directories after running a recipe?" +- "What are the files and directories that are created after running a recipe?" - "What happens when I run a recipe?" objectives: - "Run an ESMValTool recipe" @@ -15,9 +16,11 @@ objectives: keypoints: - "A recipe does not break by fiddling with it" - "Log information is useful when interpreting the first warnings/errors" -- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP" +- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." + --- + This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. ## Introduction to Recipes From 4b17ffad3e9c1622c9868e05f3a527b0b943c54e Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Mon, 29 Jun 2020 12:26:01 +0100 Subject: [PATCH 098/647] added minor changes. --- _episodes/conclusions.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md index a9d26ca7..4bf0fefc 100644 --- a/_episodes/conclusions.md +++ b/_episodes/conclusions.md @@ -10,24 +10,26 @@ questions: - "How can I cite ESMValtool?" objectives: +- "breathe - you're finished now!" - "Congratulations & Thanks!” -- “In this episode, you should find out about the rest of the tutorial, and where to do next." +- "Find out about the mini-tutorials, and what to do next." --- ## Congratulations! Congratulations on completing the ESMValTool tutorial! You should be now ready to go and start using ESMValTool independently. -The rest of this tutorial contains individual mini-tutorials to help work through a specific issue. Please see the contents page for specific +The rest of this tutorial contains individual mini-tutorials to help work through a specific issue. ### What next? From here, there are lots of ways that you can continue to use ESMValTool. -- You can start from the list of existing recipes and run one of those. -- You can learn how to write your own diagnostics and recipes. -- You can contribute your recipe and diagnostics back into ESMValTool -- You can learn how to prepare observational datasets to be suitable for use by ESMValTool. + +- You can start from the list of existing recipes and run one of those. [LINK to ep 8] +- You can learn how to write your own diagnostics and recipes. [LINK to ep 9] +- You can contribute your recipe and diagnostics back into ESMValTool. [Link to ep 10] +- You can learn how to prepare observational datasets to be suitable for use by ESMValTool. [ Link to ep 11] ### Where can I get more information on ESMValTool? @@ -45,6 +47,7 @@ Source code (ESMValCore ): https://github.com/ESMValGroup/ESMValCore There are lots of resources available for helping you use ESMValTool. +If you get stuck, a great starting point is to create a new issue. [Link to ep 10] @@ -57,8 +60,6 @@ Please create a new issue using this page: https://github.com/ESMValGroup/ESMVal In your issue, please describe the problem as clearly and as completely as possible. - - ### How do I cite ESMValTool? Please use the following reference: From d752a7b3b4379e2c58a85a5cfc45210b3c7dfbd3 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Mon, 29 Jun 2020 12:47:57 +0100 Subject: [PATCH 099/647] added text from google drive --- setup.md | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/setup.md b/setup.md index b8c50321..60a6e6c1 100644 --- a/setup.md +++ b/setup.md @@ -1,7 +1,153 @@ --- -title: Setup +title: Preparing for participating in the tutorial --- + +This page includes some basic information on how to prepare to participate in this tutorial. + +> ## Prerequisites +> The prerequisites for the tutorial are listed here: +> Basic understanding of git (optional - but useful) +> Basic understanding of your preferred command line interface (ie a bash terminal) +> Access to CMIP data +> Access to a suitable computing system (egie jasmin) +> Github account (optional, but useful!) +{: .prereq} + + +## Optional tutorials + +Where available, we include links to other software carpentry courses. + +### Command line + +We typically use the command line to interact with ESMValTool. Here’s a software carpentry tutorial on the unix shell: +https://swcarpentry.github.io/shell-novice/ + + +### Basic understanding of git + +Git is a distributed version-control system for tracking changes in source code during software development. It’s how we distribute, share, and manage the ESMValTool code. + +There are many basic introductions to git available. + +Here’s a software carpentry tutorial on git: +https://swcarpentry.github.io/git-novice/ + + + +## Access to CMIP data and a suitable computing system + +There are multiple ways to use the +We typically recommend using the one of the following systems: +- JASMIN computing system (UK) +- Something in DLR (Germany) +- Local installation on your machine + + +### JASMIN + +If you do not already have an account on JASMIN, then request an account as +soon as possible. The instructions on how to create a jasmin account are here: https://help.jasmin.ac.uk/article/4435-get-a-jasmin-account-portal + +During the account creation, you will need an SSH key, which can be generated following these instructions: https://help.jasmin.ac.uk/article/185-generate-ssh-key-pair + +More instructions on how to get started: +https://help.jasmin.ac.uk/article/189-get-started-with-jasmin + +Also note that if you are working from home, JASMIN may not be directly +accessible from your home. You may need to use ssh to connect to a machine +in your institute and then on to JASMIN. Please test your connection before +the tutorial. + +#### Jasmin-login + +Note that you have only created an account for the web-interface. To log into the jasmin machine and do work, you'll need to create a login account too: https://help.jasmin.ac.uk/article/161-get-login-account + +#### Access to data on JASMIN + +Please request access to the working groups: +● https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval +●https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research + +Once you have access to the data archive on CEDA, make sure to link your +CEDA and JASMIN accounts. This can be done by checking the link to CEDA box on your JASMIN profile page: +https://accounts.jasmin.ac.uk/account/profile/ + +The linking may take a few hours to take effect and is necessary for you to +access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC +are not accessible by default and special permission has to be requested to +access them via the CEDA catalogue page https://catalogue.ceda.ac.uk/ + +#### Test your Setup +Log into jasmin-login: +ssh -X JASMIN-USERNAME@jasmin-login1.ceda.ac.uk + +Then log into the sci1 machine: +ssh -X jasmin-sci1 + +Can you see the following locations: +- ls /group_workspaces/jasmin4/esmeval/obsdata/Tier2 +- ls /badc/cmip5/data/cmip5/output1/MOHC/HadGEM2-ES +- ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.nc + +Note that the JASMIN is only open to certain locations (mostly universities, and research centres). You may need a VPN if you wish to connect from your home network. + +### DLR +FIXME + +### Other computing systems FIXME +### Your own machine + +If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space available to install conda & ESMVAlTool, but also enough to make a copy of some data. + +You will also need to able to use: +- git +- conda + +#### Linux/unix + +#### Mac OSx + +#### Windows + +ESMValTool does not directly support Windows, But successful usage has been reported through the [Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows 10. + + + +## Github account (Advanced) + +You don’t need a github account to participate in the tutorial. However, if you want to raise an issue, contribute to the discussions, or share your code, please create a github account, here: https://github.com/ + +To learn how to use github, please have a look at this page: +https://lab.github.com/githubtraining/introduction-to-github + +You may hear a few of the following phrases during the tutorial. Don’t be alarmed, they will make sense eventually. + +### github issues +Issues are github’s ticketing system. They allow users and developers to discuss problems, identify bugs, or to make suggestions. Each issue is assigned a number and will have it’s own page on github. + +Here’s an explanation of the github issues: https://guides.github.com/features/issues/ + +Raising an issue is the act of creating a new issue. If you are asked to raise an issue, please follow any instructions that you are given, and also make sure that you read the default issue text. + +### pull request + +A github pull request is the act of requesting that a branch is merged with another branch. + +This is an advanced feature of ESMValTool, and will generally be performed by the Core development team. + + + + +## Install conda + +The python package manager Conda (anaconda or miniconda) needs to be installed on your system before the tutorial starts. In some cases, your system may have a central version installed already. + +More details on this process are available in the Installation episode. + + {% include links.md %} + From 6abfe139a937d017a49dfc22232bf96855c1fa9e Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 13:59:29 +0200 Subject: [PATCH 100/647] restructure some challenges --- _episodes/first_example_recipe.md | 33 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 120e058e..abd9d9bc 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -20,7 +20,6 @@ keypoints: --- - This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. ## Introduction to Recipes @@ -177,8 +176,11 @@ Please note the following sections: > What is the short_name of the variable being analysed? +> > What is the diagnostic script being used? +> > How many years of data are being analysed? +> > What do you think running this recipe will produce? {: .challenge} @@ -190,29 +192,36 @@ Please note the following sections: > > Use the command: > ~~~ -> esmvaltool -c user-config.yml recipe_example.yml +> esmvaltool -c ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml > ~~~ > {: .source} -> What ... +> +> Follow the terminal guiding you through the subprocesses that are running. Can you find where the preprocessor and the diagnostic are starting? Which one took longer to process? {: .challenge} +Each time you run the ESMValTool, it will produce a new output directory within your specified work directory with the name of the recipe and the tagged runtime. This folder should contain four folders: +- run +- work +- preproc +- plots > ## Inspect the output: -> Now that you have run the esmvaltool command for the first time, please locate your output directory. -> Each time you run ESMValTool, it will produce a new output directory with the following format: -> This directory should contain four folders: -> run work preproc plots +> Now that you have ran the esmvaltool command for the first time, please locate your output directory. > If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true (this is used to save disk space). Please set this value to false and run the recipe again. > +{: .challenge} + +> ## Inspect specific files: > Please locate and inspect the following files: -> Your output plot(s). -> Your main output log file -> Your settings.yml file -> A metadata.yml file +> - Your output plot(s). +> - Your main output log file. +> - Your settings.yml file. +> - A metadata.yml file. +> - The diagnostic log file. {: .discussion} -> ## Edit the recipe and run +> ## Edit the recipe and run again > So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: > - Land surface average temperature (tsland) > - Atmospheric surface average temperature (tas) From 6524626f9e4703cbf7a20607f559870ceab8f37b Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 29 Jun 2020 14:09:47 +0200 Subject: [PATCH 101/647] Ignore same files as on https://app.codacy.com/gh/ESMValGroup/tutorial --- .codacy.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .codacy.yml diff --git a/.codacy.yml b/.codacy.yml new file mode 100644 index 00000000..c58e8973 --- /dev/null +++ b/.codacy.yml @@ -0,0 +1,4 @@ +exclude_paths: + - assets/css/bootstrap.css + - assets/js/bootstrap.min.js + - assets/js/jquery.min.js From 312fc3769ad862918808e61ddf546cb0a1b9523c Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Mon, 29 Jun 2020 13:24:55 +0100 Subject: [PATCH 102/647] got started with the about page --- _extras/about.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/_extras/about.md b/_extras/about.md index 72f1c130..b22d4d0b 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -1,5 +1,38 @@ --- title: About --- + +## ESMValTool + +The Earth System Model Evaluation Tool (ESMValTool) is a community-development that aims at improving diagnosing and understanding of the causes and effects of model biases and inter-model spread. The ESMValTool is open to both users and developers encouraging open exchange of diagnostic source code and evaluation results from the Coupled Model Intercomparison Project (CMIP) ensemble. This will facilitate and improve ESM evaluation beyond the state-of-the-art and aims at supporting the activities within CMIP and at individual modelling centers. We envisage running the ESMValTool routinely on the CMIP model output utilizing observations available through the Earth System Grid Federation (ESGF) in standard formats (obs4MIPs) or made available at ESGF nodes. + +The goal is to develop a benchmarking and evaluation tool that produces well-established analyses as soon as model output from CMIP simulations becomes available, e.g., at one of the central repositories of the ESGF. This is realized through standard recipes that reproduce a certain set of diagnostics and performance metrics that have demonstrated its importance in benchmarking Earth System Models (ESMs) in a paper or assessment report, such as Chapter 9 of the Intergovernmental Panel on Climate Change (IPCC) Fifth Assessment Report (AR5) (Flato et al., 2013). The expectation is that in this way a routine and systematic evaluation of model results can be made more efficient, thereby enabling scientists to focus on developing more innovative methods of analysis rather than constantly having to “reinvent the wheel”. + +## ESMValTool developper community. + + + +## OBS4Mips + +In parallel to standardization of model output, the ESGF also hosts observations for Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). obs4MIPs provides open access data sets of satellite data that are comparable in terms of variables, temporal and spatial frequency, and periods to CMIP model output (Taylor et al., 2012). The ESMValTool utilizes these observations and reanalyses from ana4MIPs plus additionally available observations in order to evaluate the models performance. In many diagnostics and metrics, more than one observational data set or meteorological reanalysis is used to assess uncertainties in observations. + +The main idea of the ESMValTool is to provide a broad suite of diagnostics which can be performed easily when new model simulations are run. The suite of diagnostics needs to be broad enough to reflect the diversity and complexity of Earth System Models, but must also be robust enough to be run routinely or semi-operationally. In order the address these challenging objectives the ESMValTool is conceived as a framework which allows community contributions to be bound into a coherent framework. + +## License +The ESMValTool is released under the Apache License, version 2.0. Citation of the ESMValTool paper (“Software Documentation Paper”) is kindly requested upon use, alongside with the software DOI for ESMValTool (doi:10.5281/zenodo.3401363) and ESMValCore (doi:10.5281/zenodo.3387139) and version number: + +## Citation + +Please cite ESMValTool using: + +Righi, M., Andela, B., Eyring, V., Lauer, A., Predoi, V., Schlund, M., Vegas-Regidor, J., Bock, L., Brötz, B., de Mora, L., Diblen, F., Dreyer, L., Drost, N., Earnshaw, P., Hassler, B., Koldunov, N., Little, B., Loosveldt Tomas, S., and Zimmermann, K.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – technical overview, Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020, 2020. + +Besides the above citation, users are kindly asked to register any journal articles (or other scientific documents) that use the software at the ESMValTool webpage (http://www.esmvaltool.org/). Citing the Software Documentation Paper and registering your paper(s) will serve to document the scientific impact of the Software, which is of vital importance for securing future funding. You should consider this an obligation if you have taken advantage of the ESMValTool, which represents the end product of considerable effort by the development team. + +## Acknowledgements + +The technical development work for ESValTool v2.0 was funded by various projects, in particular (1) the Copernicus Climate Change Service (C3S) “Metrics and Access to Global Indices for Climate Projections (C3S-MAGIC)” project; (2) the European Union's Horizon 2020 Framework Programme for Research and Innovation “Infrastructure for the European Network for Earth System Modelling (IS-ENES3)” project under grant agreement no. 824084; (3) the European Union's Horizon 2020 Framework Programme for Research and Innovation “Coordinated Research in Earth Systems and Climate: Experiments, kNowledge, Dissemination and Outreach (CRESCENDO)” project under grant agreement no. 641816; (4) the the European Union's Horizon 2020 Framework Programme for Research and Innovation “PRocess-based climate sIMulation: AdVances in high-resolution modelling and European climate Risk Assessment (PRIMAVERA)” project under grant agreement no. 641727; (5) the Helmholtz Society project “Advanced Earth System Model Evaluation for CMIP (EVal4CMIP)”; (6) project S1 (Diagnosis and Metrics in Climate Models) of the Collaborative Research Centre TRR 181 “Energy Transfer in Atmosphere and Ocean” funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) project no. 274762653; and (7) National Environmental Research Council (NERC) National Capability Science Multi-Centre (NCSMC) funding for the UK, Earth System Modelling project (grant no. NE/N018036/1). + + {% include escience_academy.html %} {% include links.md %} From 7e98437f09ccca5610ce0489d496b6c5f1da9208 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Mon, 29 Jun 2020 13:26:32 +0100 Subject: [PATCH 103/647] Removed discussion page --- _extras/discuss.md | 6 ------ bin/lesson_check.py | 1 - bin/lesson_initialize.py | 1 - 3 files changed, 8 deletions(-) delete mode 100644 _extras/discuss.md diff --git a/_extras/discuss.md b/_extras/discuss.md deleted file mode 100644 index bfc33c50..00000000 --- a/_extras/discuss.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Discussion ---- -FIXME - -{% include links.md %} diff --git a/bin/lesson_check.py b/bin/lesson_check.py index ee84d849..ccc97a6e 100644 --- a/bin/lesson_check.py +++ b/bin/lesson_check.py @@ -31,7 +31,6 @@ 'CONTRIBUTING.md': False, 'LICENSE.md': True, 'README.md': False, - os.path.join('_extras', 'discuss.md'): True, os.path.join('_extras', 'guide.md'): True, 'index.md': True, 'reference.md': True, diff --git a/bin/lesson_initialize.py b/bin/lesson_initialize.py index 2f7b8e67..e05bb9b3 100644 --- a/bin/lesson_initialize.py +++ b/bin/lesson_initialize.py @@ -14,7 +14,6 @@ '_config.yml', os.path.join('_episodes', '01-introduction.md'), os.path.join('_extras', 'about.md'), - os.path.join('_extras', 'discuss.md'), os.path.join('_extras', 'figures.md'), os.path.join('_extras', 'guide.md'), 'index.md', From 97f02ae3803fdfc26d1b45f35bda7567f22a9dd4 Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Mon, 29 Jun 2020 13:46:01 +0100 Subject: [PATCH 104/647] started editing the setup file --- setup.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/setup.md b/setup.md index 60a6e6c1..b481b032 100644 --- a/setup.md +++ b/setup.md @@ -8,8 +8,8 @@ This page includes some basic information on how to prepare to participate in th > The prerequisites for the tutorial are listed here: > Basic understanding of git (optional - but useful) > Basic understanding of your preferred command line interface (ie a bash terminal) -> Access to CMIP data -> Access to a suitable computing system (egie jasmin) +> Access to CMIP and observational data +> Access to a suitable compute cluster (e.g. CEDA-Jasmin) > Github account (optional, but useful!) {: .prereq} @@ -35,19 +35,23 @@ https://swcarpentry.github.io/git-novice/ -## Access to CMIP data and a suitable computing system +## Access to CMIP and OBS data and a suitable compute cluster -There are multiple ways to use the -We typically recommend using the one of the following systems: -- JASMIN computing system (UK) -- Something in DLR (Germany) -- Local installation on your machine +ESMValTool may be run on multiple platforms, including local machines and +large compute clusters; the benefit of using a compute cluster is that most often than not, +it will host an ESGF node where CMIP data is locally stored on disk and accessible directly by the tool; +in the same manner, observational (OBS) data will be found centrally stored as well. Here are a few options +for compute clusters with ESGF nodes: +- CEDA-Jasmin (UK): +- DKRZ (Germany): +- ETHZ (Switzerland): -### JASMIN + +### CEDA-Jasmin If you do not already have an account on JASMIN, then request an account as -soon as possible. The instructions on how to create a jasmin account are here: https://help.jasmin.ac.uk/article/4435-get-a-jasmin-account-portal +soon as possible. The instructions on how to create a Jasmin account are here: https://help.jasmin.ac.uk/article/4435-get-a-jasmin-account-portal During the account creation, you will need an SSH key, which can be generated following these instructions: https://help.jasmin.ac.uk/article/185-generate-ssh-key-pair From 6093a43f840721242a1c5a8a2783cc6ebda41300 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Mon, 29 Jun 2020 14:48:31 +0200 Subject: [PATCH 105/647] codacy stuff --- _episodes/01-introduction.md | 52 +++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 637fed17..6ddd9483 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -3,27 +3,27 @@ title: "Introduction" teaching: 0 exercises: 25 questions: -- What is ESMValTool? -- When to use ESMValTool? -- What are the main parts of ESMValTool that I need to know? -- How does ESMValTool contribute to making climate research FAIR? -- What is the role of the ESMValTool community? -- Where to find help if I'm stuck with ESMValTool? + - What is ESMValTool? + - When to use ESMValTool? + - What are the main parts of ESMValTool that I need to know? + - How does ESMValTool contribute to making climate research FAIR? + - What is the role of the ESMValTool community? + - Where to find help if I'm stuck with ESMValTool? objectives: -- Describe the difference between ESMValTool and other tools like CDO or xarray -- Understand the main parts of ESMValTool (recipe, diagnostic script) -- Browse the documentation of ESMValTool for help -- Exlain why ESMValTool is a great way to make climate analysis FAIR -- List three different ways to get help from to the ESMValTool community (docs, user engagement email, github issues) -- Know when (not) to use ESMValTool + - Describe the difference between ESMValTool and other tools like CDO or xarray + - Understand the main parts of ESMValTool (recipe, diagnostic script) + - Browse the documentation of ESMValTool for help + - Exlain why ESMValTool is a great way to make climate analysis FAIR + - List three different ways to get help from to the ESMValTool community (docs, user engagement email, github issues) + - Know when (not) to use ESMValTool keypoints: -- ESMValTool provides a reliable interface to analyse and evaluate climate data -- By streamlining common preprocessor functions, ESMValTool facilitates comparison -- ESMValTool is built and maintained by an active community of climate scientists and software developers -- Using ESMValTool stimulates standardization, collaboration, and reuse -- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages + - ESMValTool provides a reliable interface to analyse and evaluate climate data + - By streamlining common preprocessor functions, ESMValTool facilitates comparison + - ESMValTool is built and maintained by an active community of climate scientists and software developers + - Using ESMValTool stimulates standardization, collaboration, and reuse + - ESMValTool is written in Python, but supports diagnostic scripts in multiple languages --- @@ -48,25 +48,27 @@ EMSValTool is first and foremost a tool to analyse climate data. But you probabl > >> ## ESMValTool is ... >> ->> ✓ **A tool to analyse climate data.** It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. ->> ✕ **The easy way out.** If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. ->> ✓ **A community effort.** EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. Its longevity depends on these contributions. ->> ✓ **Free.** ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. However, we *do* encourage all users to contribute to the community once they get more comfortable with the tool. ->> ✓ **A command line tool.** ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. ->> ✓ **A way to make climate science more [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readible recipe format that makes climate analysis consistent, reproducible, and easy to share. ->> ✕ **Perfect.** Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you will learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. ->> ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. +>> ✓ **A tool to analyse climate data.** It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. +>> ✕ **The easy way out.** If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. +>> ✓ **A community effort.** EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. Its longevity depends on these contributions. +>> ✓ **Free.** ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. However, we *do* encourage all users to contribute to the community once they get more comfortable with the tool. +>> ✓ **A command line tool.** ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. +>> ✓ **A way to make climate science more [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readible recipe format that makes climate analysis consistent, reproducible, and easy to share. +>> ✕ **Perfect.** Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you will learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. +>> ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. >{: .solution} {: .challenge} To learn more about ESMValTool is, you can look at the [documentation](https://docs.esmvaltool.org/en/latest/introduction.html), the [official website](https://www.esmvaltool.org/about.html), or the [overview paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific Model Development*. ## How does ESMValTool work? + The figure below shows the different components of ESMValTool. Most of the work is done in the 'core', which performs a number of preprocessor steps. Outside of the core we have some configuration files that specify things like *where to find the CMIP data*. The most important file however, is the *recipe* that specifies which preprocessor functions need to be applied to what data. The recipe also points to a diagnostic script that is executed after the preprocessor and performs a more specific analysis on the preprocessed data. ![figure showing ESMValTool architecture]({{ page.root }}/fig/esmvaltool_architecture.png) >## Discussion: (dis)advantages of this approach? +> > Discuss or think about the pros and cons of this architecture for a moment. Then unfold the box below to see our answers. > > From 4b04e61785e51782c02c45b428c16fa947bd5d8b Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Mon, 29 Jun 2020 14:54:08 +0200 Subject: [PATCH 106/647] first try on preprocessor episode --- _episodes/05-preprocessor.md | 287 +++++++++++++++++++++++++++ _episodes/05-working-with-recipes.md | 15 -- _episodes/preprocessor.md | 17 -- fig/esmvaltool_architecture.png | Bin 0 -> 115471 bytes 4 files changed, 287 insertions(+), 32 deletions(-) create mode 100644 _episodes/05-preprocessor.md delete mode 100644 _episodes/05-working-with-recipes.md delete mode 100644 _episodes/preprocessor.md create mode 100644 fig/esmvaltool_architecture.png diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md new file mode 100644 index 00000000..b888473d --- /dev/null +++ b/_episodes/05-preprocessor.md @@ -0,0 +1,287 @@ +--- +title: "Working with preprocessors" +teaching: 20? +exercises: 15? +questions: +- "How do I set up a preprocessor?" +- "Can I use different preprocessors for different variables?" +- "Can I use different datasets for different variables?" +objectives: +- "Create a recipe with multiple preprocessors" +- "Use different preprocessors for different variables" +- "Run a recipe with variables from different datasets" +keypoints: +- "A recipe can run different preprocessors at the same time." +- "The setting additional_datasets can be used to add a different dataset." +- "Variable groups are useful for defining different settings for different variables." +--- + +## Preprocessors: What are they and how do they work? + +Preprocessing is the process of performing a set of modular operations on the data before applying diagnostics or metrics. In the figure below you see the preprocessor functions in the light blue box on the right. + +![figure showing ESMValTool architecture]({{ page.root }}/fig/esmvaltool_architecture.png) + +Underneath the hood, each preprocessor is a modular python function that receives an iris cube and sometimes some arguments. The preprocessor applies some mathematical or computational transformation to the input iris cube, then returns the processed iris cube. + +## Inspect the example preprocessor + +Each preprocessor section includes a preprocessor name, a list of preprocessor steps to be executed and any arguments needed by the preprocessor steps. + +>~~~YAML +> preprocessors: +> prep_timeseries: +> annual_statistics: +> operator: mean +>~~~ +{: .source} + +For instance, the 'annual_statistics' with the 'operation: mean' argument preprocessor receives an iris cube, takes the annual average for each year of data in the cube, and returns the processed cube. + +You could use several preprocessor steps listed in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). The standardised interface between the preprocessors allows them to be used modularly - like lego blocks. Almost any conceivable preprocessing order of operations can be performed using ESMValTool preprocessors. + +> ## The 'custom order' command. +> +>If you do not want your preprocessors to be applied in the [default order](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html), then add the following line to your preprocessor chain: +> +>~~~ +> custom_order: true +>~~~ +> +>The default preprocessor order is listed in the [ESMValCore preprocessor API page](>https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html). +> +> Also note that not preprocessor operations aren't always commutative - meaning that the order of operations matters. For instance, if you run the preprocessor 'extract_volume' to extract the top 100m of the ocean surface, then 'volume_statistics' to calculate the volume-weighted mean of the data, then your result will differ depending on the order of these two preprocessors. In fact, the 'extract_volume' preprocessor will fail if you try to run it on a 2D dataset. +> +> Changing the order of preprocessors can also speed up your processing. For instance, if you want to extract a two-dimensional layer from a 3D field and re-grid it, the layer extraction should be done first. If you did it the other way around, then the regridding function would be applied to all the layers of your 3D cube and it would take much more time. +{: .callout} + +Some preprocessor stages are always applied and do not need to be called. This includes the preprocessors that load the data, apply the fixes, and save the data file afterwards. They do not need to be explicitly included in recipes. + +> ## Exercise: Adding more preprocessor steps +> +> Edit the [example recipe](LINK to episode #4) to change the variable in ?thetao? and to add preprocessors which take the average over the latitude and longitude dimensions and the average over the depth. And then run the recipe. +> +>> ## Solution +>> +>>~~~YAML +>> preprocessors: +>> prep_timeseries: +>> annual_statistics: +>> operator: mean +>> area_statistics: +>> operator: mean +>> depth_integration: +>>~~~ +>>{: .source} +>{: .solution} +{: .challenge} + +## Using different preprocessors for different variables + +You could define different preprocessors with several preprocessor sections (setting different preprocessor names). In the variable section you call the specific preprocessor which should be applied. + +> ## Example +>~~~YAML +> preprocessors: +> prep_timeseries_1: +> annual_statistics: +> Operator: mean +> prep_timeseries_2: +> annual_statistics: +> operator: mean +> area_statistics: +> operator: mean +> Depth_integration: +> --- +> diagnostics: +> # -------------------------------------------------- +> # Time series diagnostics +> # -------------------------------------------------- +> diag_timeseries_temperature_1: +> description: simple_time_series> +> variables: +> timeseries_variable: +> short_name: thetaoga +> preprocessor: prep_timeseries_1 +> scripts: +> timeseries_diag: +> script: ocean/diagnostic_timeseries.py +> +> diag_timeseries_temperature_2: +> description: simple_time_series +> variables: +> timeseries_variable: +> short_name: thetao +> preprocessor: prep_timeseries_2 +> scripts: +> timeseries_diag: +> script: ocean/diagnostic_timeseries.py +>~~~ +>{: .source} +{: .solution} + +>## Challenge : How to write a recipe with multiple preprocessors +> We now know that a recipe can have more than one diagnostic, variable or preprocessor. As we saw in the examples so far, we can group preprocessors with a single user defined name and can have more than one such preprocessor group in the recipe as well. Write two different preprocessors - one to regrid the data to a 1x1 resolution and the second preprocessor to mask out sea and ice grid cells before regridding to the saem resolution. In the second case, ensure you perform the masking first before regridding (hint: custom order your operations). Now, use the two preprocessors in different diagnostics within the same recipe. You may use any variable(s) of your choice. Once you succeed, try to add new datasets to the same recipe. Placeholders for the different components are provided below: +> +>> ## Recipe +>> +>>~~~YAML +>> +>> datasets: +>> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, +>> ensemble: r1i1p1f2} #single dataset as an example +>> +>> preprocessors: +>> prep_map: #preprocessor to just regrid data +>> #fill preprocessor details here +>> +>> prep_map_land: #preprocessor to mask grid cells and then regrid +>> #fill preprocessor details here including ordering +>> +>> diagnostics: +>> # -------------------------------------------------- +>> # Two Simple diagnostics that illustrate the use of +>> # different preprocessors +>> # -------------------------------------------------- +>> diag_simple_plot: +>> description: # preprocess a variable for a simple 2D plot +>> variables: +>> # put your variable of choice here +>> # apply the first preprocessor i.e. name your preprocessor +>> # edit the following 4 lines for mip, grid and time +>> # based on your variable choice +>> mip: Amon +>> grid: gn #can change for variables from the same model +>> start_year: 1970 +>> end_year: 2000 +>> scripts: null #no scripts called +>> diag_land_only_plot: #second diagnostic +>> description: #preprocess a variable for a 2D land only plot +>> variables: +>> # include a variable and information +>> # as in the previous diagnostic and +>> # include your second preprocessor (masking and regridding) +>> scripts: null # no scripts +>>~~~ +>>{: .source} +>{: .solution} +> +>> ## Solution: +>> +>> Here is one possible way to use two different preprocessors including a +>> group of preprocessors on different variables. +>> +>>~~~YAML +>> +>> datasets: +>> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, +>> ensemble: r1i1p1f2} #single dataset as an example +>> +>> preprocessors: +>> prep_map: +>> regrid: #apply the preprocessor to regrid +>> target_grid: 1x1 # target resolution +>> scheme: linear #how to interpolate for regridding +>> +>> prep_map_land: +>> custom_order: true #ensure order follows a given +>> mask_landsea: #apply a mask +>> mask_out: sea #mask out sea grid cells +>> regrid: # now apply the preprocessor to regrid +>> target_grid: 1x1 # target resolution +>> scheme: linear #how to interpolate for regridding +>> +>> diagnostics: +>> # -------------------------------------------------- +>> # Two Simple diagnostics that illustrate the use of +>> # different preprocessors +>> # -------------------------------------------------- +>> diag_simple_plot: +>> description: # preprocess a variable for a simple 2D plot +>> variables: +>> tas: # surface temperature +>> preprocessor: prep_map +>> mip: Amon +>> grid: gn #can change for variables from the same model +>> start_year: 1970 +>> end_year: 2000 +>> additional_datasets: +>> scripts: null +>> +>> diag_land_only_plot: +>> description: #preprocess a variable for a 2D land only plot +>> variables: +>> tas: # surface temperature +>> preprocessor: prep_map_land +>> mip: Amon +>> grid: gn #can change for variables from the same model +>> start_year: 1970 +>> end_year: 2000 +>> additional_datasets: +>> scripts: null +>> ~~~ +>> {: .source} +> {: .solution} +{: .challenge} + +## Adding different datasets for different variables + +Sometimes, we may want to include specific datasets for certain variables. An example is when we use observations for two different variables in a diagnostic. While the CMIP dataset details for the two variables may be common, the observations will likely not be so. It would be useful to know how to include different datasets for different variables. Here is an example of a simple preprocessor and diagnostic setup for that: + +> ## Example +>~~~YAML +> +> datasets: +> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, +> ensemble: r1i1p1f2} #common to both variables discussed below +> +> preprocessors: +> prep_regrid: # regrid to get all data to the same resolution +> regrid: #apply the preprocessor to regrid +> target_grid: 2.5x2.5 # target resolution +> scheme: linear #how to interpolate for regridding +> +> diagnostics: +> # -------------------------------------------------- +> # Simple diagnostic to illustrate use of different +> # datasets for different variables +> # -------------------------------------------------- +> diag_diff_datasets: +> description: diff_datasets_for_vars +> variables: +> pr: #first variable is precipitation +> preprocessor: prep_regrid +> mip: Amon +> grid: gn #can change for variables from the same model +> start_year: 1970 +> end_year: 2000 # start and end years for a30 year period, +> # we assume this is common and exists for all +> # model and obs data +> additional_datasets: +> - {dataset: GPCP-SG, project: obs4mips, level: L3, +> version: v2.2, tier: 1} #dataset specific to this variable +> +> tas: #second variable is surface temperature +> preprocessor: prep_regrid +> mip: Amon +> grid: gn #can change for variables from the same model +> start_year: 1970 #some 30 year period +> end_year: 2000 +> additional_datasets: +> - {dataset: HadCRUT4, project: OBS, type: ground, +> version: 1, tier: 2} #dataset specific to the temperature var +> +> scripts: null +>~~~ +>{: .source} +{: .solution} + +> ## How to find what CMIP data is available? +> +> [CMIP5](https://pcmdi.llnl.gov/mips/cmip5/index.html) and [CMIP6](https://pcmdi.llnl.gov/CMIP6/Guide/dataUsers.html) data obey the [CF-conventions](http://cfconventions.org/). Available variables could be found under the [CMIP5 data request](https://pcmdi.llnl.gov/mips/cmip5/docs/standard_output.pdf?id=28) and the [CMIP6 Data Request](http://clipc-services.ceda.ac.uk/dreq/index.html). +> +> CMIP data is widely available via the Earth System Grid Federation ([ESGF](https://esgf.llnl.gov/)) and is accessible to users either via download from the ESGF portal or through the ESGF data nodes hosted by large computing facilities (like [CEDA-Jasmin](https://esgf-index1.ceda.ac.uk/), [DKRZ](https://esgf-data.dkrz.de/), etc). The ESGF also hosts observations for Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). +> +> A full list of all CMIP named variables is available here: [http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html](http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html). +{: .callout} + diff --git a/_episodes/05-working-with-recipes.md b/_episodes/05-working-with-recipes.md deleted file mode 100644 index 267513dc..00000000 --- a/_episodes/05-working-with-recipes.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: "Working with the recipe" -teaching: 0 -exercises: 0 -questions: -- "Key question (FIXME)" -objectives: -- "First learning objective. (FIXME)" -keypoints: -- "First key point. Brief Answer to questions. (FIXME)" ---- -FIXME - -{% include links.md %} - diff --git a/_episodes/preprocessor.md b/_episodes/preprocessor.md deleted file mode 100644 index 81527601..00000000 --- a/_episodes/preprocessor.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: "Working with preprocessors" -teaching: 10 -exercises: 1 -questions: -- “How do I set up a preprocessor?” -- “Can I use different preprocessors for different variables?” -- “Can I use different datasets for different variables?” -Objectives: -- “Create a recipe with multiple preprocessors” -- “Use different preprocessors for different variables” -- “Run a recipe with variables from different datasets” -keypoints: -- “A recipe can run different preprocessors at the same time.” -- “The setting additional_datasets can be used to add a different dataset.” -- “Variable groups are useful for defining different settings for different variables.” ---- diff --git a/fig/esmvaltool_architecture.png b/fig/esmvaltool_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..43167b3359b4553e8c36497aed810bb1c946f104 GIT binary patch literal 115471 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 Date: Mon, 29 Jun 2020 14:54:24 +0200 Subject: [PATCH 107/647] rename the file --- _episodes/{06-creating-a-diagnostic-script.md => 06-debugging.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename _episodes/{06-creating-a-diagnostic-script.md => 06-debugging.md} (100%) diff --git a/_episodes/06-creating-a-diagnostic-script.md b/_episodes/06-debugging.md similarity index 100% rename from _episodes/06-creating-a-diagnostic-script.md rename to _episodes/06-debugging.md From 799525ce3cf8fcf6cc51ac24668a942143af7eb1 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Mon, 29 Jun 2020 14:57:41 +0200 Subject: [PATCH 108/647] newlines in answers --- _episodes/01-introduction.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 6ddd9483..4d77f1e7 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -49,17 +49,24 @@ EMSValTool is first and foremost a tool to analyse climate data. But you probabl >> ## ESMValTool is ... >> >> ✓ **A tool to analyse climate data.** It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. +>> >> ✕ **The easy way out.** If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. +>> >> ✓ **A community effort.** EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. Its longevity depends on these contributions. +>> >> ✓ **Free.** ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. However, we *do* encourage all users to contribute to the community once they get more comfortable with the tool. +>> >> ✓ **A command line tool.** ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. ->> ✓ **A way to make climate science more [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readible recipe format that makes climate analysis consistent, reproducible, and easy to share. +>> +>> ✓ **A way to make climate science more [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readable recipe format that makes climate analysis consistent, reproducible, and easy to share. +>> >> ✕ **Perfect.** Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you will learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. +>> >> ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. >{: .solution} {: .challenge} -To learn more about ESMValTool is, you can look at the [documentation](https://docs.esmvaltool.org/en/latest/introduction.html), the [official website](https://www.esmvaltool.org/about.html), or the [overview paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific Model Development*. +To learn more about ESMValTool, you can look at the [documentation](https://docs.esmvaltool.org/en/latest/introduction.html), the [official website](https://www.esmvaltool.org/about.html), or the [overview paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific Model Development*. ## How does ESMValTool work? From 7b42e14c9804a50aa6e16544bd84f100df0000a0 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Mon, 29 Jun 2020 15:03:41 +0200 Subject: [PATCH 109/647] codacy still --- _episodes/01-introduction.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 4d77f1e7..b369e39b 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -3,27 +3,27 @@ title: "Introduction" teaching: 0 exercises: 25 questions: - - What is ESMValTool? - - When to use ESMValTool? - - What are the main parts of ESMValTool that I need to know? - - How does ESMValTool contribute to making climate research FAIR? - - What is the role of the ESMValTool community? - - Where to find help if I'm stuck with ESMValTool? + -What is ESMValTool? + -When to use ESMValTool? + -What are the main parts of ESMValTool that I need to know? + -How does ESMValTool contribute to making climate research FAIR? + -What is the role of the ESMValTool community? + -Where to find help if I'm stuck with ESMValTool? objectives: - - Describe the difference between ESMValTool and other tools like CDO or xarray - - Understand the main parts of ESMValTool (recipe, diagnostic script) - - Browse the documentation of ESMValTool for help - - Exlain why ESMValTool is a great way to make climate analysis FAIR - - List three different ways to get help from to the ESMValTool community (docs, user engagement email, github issues) - - Know when (not) to use ESMValTool + -Describe the difference between ESMValTool and other tools like CDO or xarray + -Understand the main parts of ESMValTool (recipe, diagnostic script) + -Browse the documentation of ESMValTool for help + -Exlain why ESMValTool is a great way to make climate analysis FAIR + -List three different ways to get help from to the ESMValTool community (docs, user engagement email, github issues) + -Know when (not) to use ESMValTool keypoints: - - ESMValTool provides a reliable interface to analyse and evaluate climate data - - By streamlining common preprocessor functions, ESMValTool facilitates comparison - - ESMValTool is built and maintained by an active community of climate scientists and software developers - - Using ESMValTool stimulates standardization, collaboration, and reuse - - ESMValTool is written in Python, but supports diagnostic scripts in multiple languages + -ESMValTool provides a reliable interface to analyse and evaluate climate data + -By streamlining common preprocessor functions, ESMValTool facilitates comparison + -ESMValTool is built and maintained by an active community of climate scientists and software developers + -Using ESMValTool stimulates standardization, collaboration, and reuse + -ESMValTool is written in Python, but supports diagnostic scripts in multiple languages --- From 5695cf3639e7a5ed3763579053c9a91560f96e09 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 15:28:45 +0200 Subject: [PATCH 110/647] add line numbers to recipe --- _episodes/first_example_recipe.md | 120 +++++++++++++++--------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index abd9d9bc..185ec0de 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -30,9 +30,7 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w - the time range and time resolution, - the MIP, ensemble member, - the experiment (i.e. historical, ssp125 etc...), - - and the grid type (CMIP6 only) - - This section can also be optional, as datasets can no preprocessing is needed. + - and the grid type (CMIP6 only). - preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing - which preprocessor modules to apply, @@ -75,51 +73,52 @@ Please copy and paste the following recipe into your ESMValTool working area wit >## recipe_example.yml >~~~YAML -> # ESMValTool -> # recipe_example.yml -> --- -> documentation: -> description: Demonstrate basic ESMValTool example -> -> authors: -> - demora_lee -> - mueller_benjamin -> - swaminathan_ranjini -> -> maintainer: -> - demora_lee -> -> references: -> - demora2018gmd -> # Some plots also appear in ESMValTool paper 2. -> -> projects: -> - ukesm -> -> datasets: -> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} -> -> preprocessors: -> prep_timeseries: # For 0D fields -> annual_statistics: -> operator: mean -> -> diagnostics: -> # -------------------------------------------------- -> # Time series diagnostics -> # -------------------------------------------------- -> diag_timeseries_temperature: -> description: simple_time_series -> variables: -> timeseries_variable: -> short_name: thetaoga -> preprocessor: prep_timeseries -> scripts: -> timeseries_diag: -> script: ocean/diagnostic_timeseries.py +> 1 # ESMValTool +> 2 # recipe_example.yml +> 3 --- +> 4 documentation: +> 5 description: Demonstrate basic ESMValTool example +> 6 +> 7 authors: +> 8 - demora_lee +> 9 - mueller_benjamin +>10 - swaminathan_ranjini +>11 +>12 maintainer: +>13 - demora_lee +>14 +>15 references: +>16 - demora2018gmd +>17 # Some plots also appear in ESMValTool paper 2. +>18 +>19 projects: +>20 - ukesm +>21 +>22 datasets: +>23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +>24 +>25 preprocessors: +>26 prep_timeseries: # For 0D fields +>27 annual_statistics: +>28 operator: mean +>29 +>30 diagnostics: +>31 # -------------------------------------------------- +>32 # Time series diagnostics +>33 # -------------------------------------------------- +>34 diag_timeseries_temperature: +>35 description: simple_time_series +>36 variables: +>37 timeseries_variable: +>38 short_name: thetaoga +>39 preprocessor: prep_timeseries +>40 scripts: +>41 timeseries_diag: +>42 script: ocean/diagnostic_timeseries.py >~~~ {: .solution} + > ## Explore the recipe > Use the command and investigate the sample recipe. > ~~~ @@ -245,21 +244,26 @@ Each time you run the ESMValTool, it will produce a new output directory within ## Common issues & tips -### Esmvaltool not found -Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, epside [2] LINK. +> ## Esmvaltool not found +> Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, episode #2 LINK. +{: .solution} -### ESMValTool can’t locate the data -The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” -Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? +> ## ESMValTool can’t locate the data. The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” +> Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? +{: .solution} -### Diagnostic path problems -The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? +> ## Diagnostic path problems +> The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? +{: .solution} -### FX files not found. +> ## FX files not found +> +{: .solution} -### The preprocessor works but the diagnostic fails: -If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. +> ## The preprocessor works but the diagnostic fails +> If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. +{: .solution} -### Your recipe’s name/project/reference isn’t recognised by ESMValTool. -Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” -Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. +> ## Your recipe’s name/project/reference isn’t recognised by ESMValTool. Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” +> Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. +{: .solution} From b6ed064aef823d83415cf25c05a7c441a23ad23d Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Mon, 29 Jun 2020 15:43:03 +0200 Subject: [PATCH 111/647] remove formatting errors --- _episodes/05-preprocessor.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index b888473d..67f80b18 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -85,13 +85,13 @@ You could define different preprocessors with several preprocessor sections (set > preprocessors: > prep_timeseries_1: > annual_statistics: -> Operator: mean +> operator: mean > prep_timeseries_2: > annual_statistics: > operator: mean > area_statistics: > operator: mean -> Depth_integration: +> depth_integration: > --- > diagnostics: > # -------------------------------------------------- From 5719f1d624a96b7cefc7afdd5ccf063d1ec68dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20M=C3=BCller?= Date: Mon, 29 Jun 2020 15:43:41 +0200 Subject: [PATCH 112/647] Update first_example_recipe.md corrects indents --- _episodes/first_example_recipe.md | 62 +++++++++++++++---------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 185ec0de..4e33ce98 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -27,31 +27,31 @@ This episode describes how ESMValTool recipes work, how to run a recipe and how Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. - datasets: what datasets you want to use, including - - the time range and time resolution, - - the MIP, ensemble member, - - the experiment (i.e. historical, ssp125 etc...), - - and the grid type (CMIP6 only). + - the time range and time resolution, + - the MIP, ensemble member, + - the experiment (i.e. historical, ssp125 etc...), + - and the grid type (CMIP6 only). - preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing - - which preprocessor modules to apply, - - the order to apply them, - - and the preprocessor arguments. + - which preprocessor modules to apply, + - the order to apply them, + - and the preprocessor arguments. - This section can also be optional, if no preprocessing is needed. + This section can also be optional, if no preprocessing is needed. - diagnostics: all the information about the diagnostic, including - - list of variables to evaluate (with their respective configurations), - - the desired diagnostic script to use, - - and additional diagnostic script options or arguments, if needed. + - list of variables to evaluate (with their respective configurations), + - the desired diagnostic script to use, + - and additional diagnostic script options or arguments, if needed. - Also Include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. + Also Include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. - description: a brief description of the recipe, including - - who wrote the recipe and who maintains it, - - which project is responsible for it, - - and which publications, references are linked with the recipe. + - who wrote the recipe and who maintains it, + - which project is responsible for it, + - and which publications, references are linked with the recipe. - Note that the authors, publications and references are to be named in the config-references.yml + Note that the authors, publications and references are to be named in the config-references.yml This information ... @@ -138,25 +138,25 @@ Please note the following sections: - projects: a list of projects (linked to esmvaltool/config-references.yml) - - datasets: lines 22-23 +- datasets: lines 22-23 - The dataset definition consists of a list of python dictionaries with the information on the datasets. - - dataset name (key: dataset) - - project (key: project) - - experiment (key: exp) - - mip (for CMIP data, key: mip) - - ensemble member (key: ensemble) - - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) - - model grid (for CMIP6 data only, key: grid) - - alias (key: alias; use the alias for e.g. a more human readable name) + The dataset definition consists of a list of python dictionaries with the information on the datasets. + - dataset name (key: dataset) + - project (key: project) + - experiment (key: exp) + - mip (for CMIP data, key: mip) + - ensemble member (key: ensemble) + - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) + - model grid (for CMIP6 data only, key: grid) + - alias (key: alias; use the alias for e.g. a more human readable name) - - preprocessors: lines 25-28 +- preprocessors: lines 25-28 - The definition for different preprocessors or combinations. - If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). - Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). - (See episode #5 LINK for more details.) + The definition for different preprocessors or combinations. + If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). + Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). + (See episode #5 LINK for more details.) - diagnostic section: lines 30-42 From ccfab636f28310adca1c75499288103bf955ad9a Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Mon, 29 Jun 2020 15:09:06 +0100 Subject: [PATCH 113/647] added additional text --- _extras/about.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/_extras/about.md b/_extras/about.md index b22d4d0b..6f963b1f 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -8,8 +8,11 @@ The Earth System Model Evaluation Tool (ESMValTool) is a community-development t The goal is to develop a benchmarking and evaluation tool that produces well-established analyses as soon as model output from CMIP simulations becomes available, e.g., at one of the central repositories of the ESGF. This is realized through standard recipes that reproduce a certain set of diagnostics and performance metrics that have demonstrated its importance in benchmarking Earth System Models (ESMs) in a paper or assessment report, such as Chapter 9 of the Intergovernmental Panel on Climate Change (IPCC) Fifth Assessment Report (AR5) (Flato et al., 2013). The expectation is that in this way a routine and systematic evaluation of model results can be made more efficient, thereby enabling scientists to focus on developing more innovative methods of analysis rather than constantly having to “reinvent the wheel”. -## ESMValTool developper community. +## ESMValTool community. +The ESMValTool community includes scientists and programmers from around the world. + +ESMValTool has been used to analyse data ## OBS4Mips From 5560ad446419c5e3af090ba0f1300b5cad86bb40 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 16:17:00 +0200 Subject: [PATCH 114/647] adds explanations and further reading --- _episodes/first_example_recipe.md | 33 +++++++++++++++++++------------ 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 4e33ce98..2af1b59b 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -16,7 +16,7 @@ objectives: keypoints: - "A recipe does not break by fiddling with it" - "Log information is useful when interpreting the first warnings/errors" -- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." +- "The dataset section resembles the filename or directory structure (e.g. CMIP subdirectories)." --- @@ -29,7 +29,7 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w - datasets: what datasets you want to use, including - the time range and time resolution, - the MIP, ensemble member, - - the experiment (i.e. historical, ssp125 etc...), + - the experiment (i.e. historical, ssp125, etc.), - and the grid type (CMIP6 only). - preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing @@ -44,7 +44,7 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w - the desired diagnostic script to use, - and additional diagnostic script options or arguments, if needed. - Also Include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. + Also include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. - description: a brief description of the recipe, including - who wrote the recipe and who maintains it, @@ -53,7 +53,8 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w Note that the authors, publications and references are to be named in the config-references.yml -This information ... +The information you provide in the recipe is not only affecting the processes you are starting, but also the directory names your output will be structured in. +For additional reeds, please have a look at the recipe format description in the [ESMValTool manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). ## How to run ESMValTool @@ -67,9 +68,9 @@ To try your hand with a basic recipe, please work through this episode. ## Introduction to the example recipe -Threcipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. +The recipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. -Please copy and paste the following recipe into your ESMValTool working area with the name: recipe_example.yml +Please download the following recipe into your ESMValTool working area with the name: recipe_example.yml LINK >## recipe_example.yml >~~~YAML @@ -205,7 +206,7 @@ Each time you run the ESMValTool, it will produce a new output directory within - plots > ## Inspect the output: -> Now that you have ran the esmvaltool command for the first time, please locate your output directory. +> Now that you have run the esmvaltool command for the first time, please locate your output directory. > If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true (this is used to save disk space). Please set this value to false and run the recipe again. > {: .challenge} @@ -230,16 +231,18 @@ Each time you run the ESMValTool, it will produce a new output directory within > - the dataset: > - mip, start_year, end_year > - the preprocessor: -> - These fields are all 2D fields, but thetaga was a 0D field. This means that we need to take the average over the latitude and longitude dimensions. To do this, add the area_statistics to the preprocessor. +> - These fields are all 2D fields, but thetaoga was a 0D field. This means that we need to take the average over the latitude and longitude dimensions. To do this, add the area_statistics to the preprocessor. > - the diagnostic > - change the short_name value (thetaoga) for another: > - Land surface average temperature (tsland) > - Atmospheric surface average temperature (tas) > - Ocean surface average temperature (tos) -> ### Advanced: +{: .challenge} + +> ## Advanced: > If you want to add a different field, please have a look here: > http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html -{: .challenge} +{: .callout} ## Common issues & tips @@ -248,22 +251,26 @@ Each time you run the ESMValTool, it will produce a new output directory within > Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, episode #2 LINK. {: .solution} -> ## ESMValTool can’t locate the data. The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” +> ## ESMValTool can’t locate the data. The error message is `esmvalcore._recipe_checks.RecipeError: Missing data` > Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? {: .solution} + > ## Diagnostic path problems > The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? {: .solution} + > ## FX files not found -> +> There is no FX file for your corresponding dataset. Are your datasets’ names spelled correctly? Is there a FX file for this dataset? {: .solution} + > ## The preprocessor works but the diagnostic fails > If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. {: .solution} -> ## Your recipe’s name/project/reference isn’t recognised by ESMValTool. Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” + +> ## Your recipe’s name/project/reference isn’t recognised by ESMValTool. Error message is `ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml` > Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. {: .solution} From 11777adfa18df6e9508c58a9acbfe4489a7e09fd Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Mon, 29 Jun 2020 16:03:19 +0100 Subject: [PATCH 115/647] Added several comments to address review --- _episodes/conclusions.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md index 4bf0fefc..0675838d 100644 --- a/_episodes/conclusions.md +++ b/_episodes/conclusions.md @@ -11,7 +11,7 @@ questions: objectives: - "breathe - you're finished now!" -- "Congratulations & Thanks!” +- "Congratulations & Thanks!" - "Find out about the mini-tutorials, and what to do next." --- @@ -36,12 +36,21 @@ From here, there are lots of ways that you can continue to use ESMValTool. Read the docs page: https://esmvaltool.readthedocs.io/ +ESMValTool home page: https://www.esmvaltool.org/ + Technical description paper: https://doi.org/10.5194/gmd-13-1179-2020 Source code (ESMValTool): https://github.com/ESMValGroup/ESMValTool Source code (ESMValCore ): https://github.com/ESMValGroup/ESMValCore +Additional publications: +- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, K., and Zechlau, S.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for emergent constraints and future projections from Earth system models in CMIP, Geosci. Model Dev. Discuss., https://doi.org/10.5194/gmd-2020-60, in review, 2020. + +- Eyring, V., Bock, L., Lauer, A., Righi, M., Schlund, M., Andela, B., Arnone, E., Bellprat, O., Brötz, B., Caron, L.-P., Carvalhais, N., Cionni, I., Cortesi, N., Crezee, B., Davin, E., Davini, P., Debeire, K., de Mora, L., Deser, C., Docquier, D., Earnshaw, P., Ehbrecht, C., Gier, B. K., Gonzalez-Reviriego, N., Goodman, P., Hagemann, S., Hardiman, S., Hassler, B., Hunter, A., Kadow, C., Kindermann, S., Koirala, S., Koldunov, N. V., Lejeune, Q., Lembo, V., Lovato, T., Lucarini, V., Massonnet, F., Müller, B., Pandde, A., Pérez-Zanón, N., Phillips, A., Predoi, V., Russell, J., Sellar, A., Serva, F., Stacke, T., Swaminathan, R., Torralba, V., Vegas-Regidor, J., von Hardenberg, J., Weigel, K., and Zimmermann, K.: ESMValTool v2.0 – Extended set of large-scale diagnostics for quasi-operational and comprehensive evaluation of Earth system models in CMIP, Geosci. Model Dev. Discuss., https://doi.org/10.5194/gmd-2019-291, in review, 2019. + +- Eyring, V., Righi, M., Lauer, A., Evaldsson, M., Wenzel, S., Jones, C., Anav, A., Andrews, O., Cionni, I., Davin, E. L., Deser, C., Ehbrecht, C., Friedlingstein, P., Gleckler, P., Gottschaldt, K.-D., Hagemann, S., Juckes, M., Kindermann, S., Krasting, J., Kunert, D., Levine, R., Loew, A., Mäkelä, J., Martin, G., Mason, E., Phillips, A. S., Read, S., Rio, C., Roehrig, R., Senftleben, D., Sterl, A., van Ulft, L. H., Walton, J., Wang, S., and Williams, K. D.: ESMValTool (v1.0) – a community diagnostic and performance metrics tool for routine evaluation of Earth system models in CMIP, Geosci. Model Dev., 9, 1747–1802, https://doi.org/10.5194/gmd-9-1747-2016, 2016. + ### Where can I get more help? @@ -53,11 +62,15 @@ If you get stuck, a great starting point is to create a new issue. [Link to ep 1 ### What if I find a bug? -If you find a bug, please report it back to the ESMValTool team. This will help us fix it so that you can continue working, but also it means that ESMValTool will be more stable for everyone else as well. +If you find a bug, please report it back to the ESMValTool team. +This will help us fix it so that you can continue working, +but also it means that ESMValTool will be more stable for everyone else as well. + +To report a bug, please create a new issue using this page: https://github.com/ESMValGroup/ESMValTool/issues/new/choose -Please create a new issue using this page: https://github.com/ESMValGroup/ESMValTool/issues +In your bug report, please describe the problem as clearly and as completely as possible. +You may need to include a recipe or the output log as well. -In your issue, please describe the problem as clearly and as completely as possible. ### How do I cite ESMValTool? @@ -67,6 +80,8 @@ Please use the following reference: Righi, M., Andela, B., Eyring, V., Lauer, A., Predoi, V., Schlund, M., Vegas-Regidor, J., Bock, L., Brötz, B., de Mora, L., Diblen, F., Dreyer, L., Drost, N., Earnshaw, P., Hassler, B., Koldunov, N., Little, B., Loosveldt Tomas, S., and Zimmermann, K.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – technical overview, Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020, 2020. +The following papers + {% include links.md %} From a5725d73a67347c4eacc15b32efd24f64cd00d51 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Mon, 29 Jun 2020 17:08:40 +0200 Subject: [PATCH 116/647] Rewrite keypoints, objectives and questions; solve codacy stuff --- _episodes/01-introduction.md | 111 +++++++++++++++++------------------ 1 file changed, 53 insertions(+), 58 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index b369e39b..10bc28ab 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -3,35 +3,30 @@ title: "Introduction" teaching: 0 exercises: 25 questions: - -What is ESMValTool? - -When to use ESMValTool? - -What are the main parts of ESMValTool that I need to know? - -How does ESMValTool contribute to making climate research FAIR? - -What is the role of the ESMValTool community? - -Where to find help if I'm stuck with ESMValTool? +- What is ESMValTool and when is it useful? +- What are the main components of ESMValTool? +- How does ESMValTool contribute to FAIR climate research? +- What is the role of the ESMValTool community? objectives: - -Describe the difference between ESMValTool and other tools like CDO or xarray - -Understand the main parts of ESMValTool (recipe, diagnostic script) - -Browse the documentation of ESMValTool for help - -Exlain why ESMValTool is a great way to make climate analysis FAIR - -List three different ways to get help from to the ESMValTool community (docs, user engagement email, github issues) - -Know when (not) to use ESMValTool +- Describe key strengths and weaknesses of ESMValTool +- Know the different components of ESMValTool +- Understand the concept of a community-driven software project +- keypoints: - -ESMValTool provides a reliable interface to analyse and evaluate climate data - -By streamlining common preprocessor functions, ESMValTool facilitates comparison - -ESMValTool is built and maintained by an active community of climate scientists and software developers - -Using ESMValTool stimulates standardization, collaboration, and reuse - -ESMValTool is written in Python, but supports diagnostic scripts in multiple languages +- ESMValTool provides a reliable interface to analyse and evaluate climate data +- Using ESMValTool promotes standardization, collaboration, and reuse +- ESMValTool is built and maintained by an active community of scientists and developers +- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages --- -## What is ESMValTool? +## What is ESMValTool EMSValTool is first and foremost a tool to analyse climate data. But you probably already knew that and we like to think there's more to it than that. So let's start with a quick check to synchronize our expectations. -> ## Question: what is ESMValTool? +> ## Question: what is ESMValTool > > Which of the following items would you say apply to ESMValTool? > @@ -46,49 +41,49 @@ EMSValTool is first and foremost a tool to analyse climate data. But you probabl > > Check our answers by unfolding the box below. > ->> ## ESMValTool is ... ->> ->> ✓ **A tool to analyse climate data.** It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. ->> ->> ✕ **The easy way out.** If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. ->> ->> ✓ **A community effort.** EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. Its longevity depends on these contributions. ->> ->> ✓ **Free.** ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. However, we *do* encourage all users to contribute to the community once they get more comfortable with the tool. ->> ->> ✓ **A command line tool.** ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. ->> ->> ✓ **A way to make climate science more [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readable recipe format that makes climate analysis consistent, reproducible, and easy to share. ->> ->> ✕ **Perfect.** Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you will learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. ->> ->> ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. ->{: .solution} +> > ## ESMValTool is +> > +> > ✓ **A tool to analyse climate data.** It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. +> > +> > ✕ **The easy way out.** If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. +> > +> > ✓ **A community effort.** EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. Its longevity depends on these contributions. +> > +> > ✓ **Free.** ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. However, we *do* encourage all users to contribute to the community once they get more comfortable with the tool. +> > +> > ✓ **A command line tool.** ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. +> > +> > ✓ **A way to make climate science more [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readable recipe format that makes climate analysis consistent, reproducible, and easy to share. +> > +> > ✕ **Perfect.** Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you will learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. +> > +> > ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. +> {: .solution} {: .challenge} To learn more about ESMValTool, you can look at the [documentation](https://docs.esmvaltool.org/en/latest/introduction.html), the [official website](https://www.esmvaltool.org/about.html), or the [overview paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific Model Development*. -## How does ESMValTool work? +## How does ESMValTool work The figure below shows the different components of ESMValTool. Most of the work is done in the 'core', which performs a number of preprocessor steps. Outside of the core we have some configuration files that specify things like *where to find the CMIP data*. The most important file however, is the *recipe* that specifies which preprocessor functions need to be applied to what data. The recipe also points to a diagnostic script that is executed after the preprocessor and performs a more specific analysis on the preprocessed data. ![figure showing ESMValTool architecture]({{ page.root }}/fig/esmvaltool_architecture.png) ->## Discussion: (dis)advantages of this approach? +> ## Discussion: (dis)advantages of this approach > > Discuss or think about the pros and cons of this architecture for a moment. Then unfold the box below to see our answers. > > ->>## See our thoughts ->> ->> - Streamlining common preprocessing steps ensures consistency in the algorithms being used and the way they are executed. This facilitates comparison and reproducibility. ->> - Provenance and citation information can be tracked through the entire workflow. ->> - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) package, which is quite strict in order to comply with CF conventions and minimize unexpected results. ->> - Recipes are easy to read and share. ->> - A collection of recipes and diagnostic scripts is shipped with ESMValTool, ready for re-use. Everyone can add to this collection. ->> - The recipe format takes some getting used to and may be a bit less flexible then working on the datasets directly. ->> - Features or dataset support that are missing from ESMValCore can be a limiting factor. ->{: .solution} +> > ## See our thoughts +> > +> > - Streamlining common preprocessing steps ensures consistency in the algorithms being used and the way they are executed. This facilitates comparison and reproducibility. +> > - Provenance and citation information can be tracked through the entire workflow. +> > - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) package, which is quite strict in order to comply with CF conventions and minimize unexpected results. +> > - Recipes are easy to read and share. +> > - A collection of recipes and diagnostic scripts is shipped with ESMValTool, ready for re-use. Everyone can add to this collection. +> > - The recipe format takes some getting used to and may be a bit less flexible then working on the datasets directly. +> > - Features or dataset support that are missing from ESMValCore can be a limiting factor. +> {: .solution} {: .discussion} ## Community @@ -99,20 +94,20 @@ ESMValTool is built and maintained by an active community of scientists and engi > > Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is our 'organization' GitHub page. Have a look around. How many collaborators are there? Do you know any of them? You should see 2 main repositories: ESMValTool and ESMValCore. Clicking on them will take you to there. How many people have contributed to each of them? Can you also find out how many people have contributed to this tutorial? > ->> ## Solution ->> ->> At the time of making this lesson, there were 138 members of ESMValGroup. 55 of them contributed to ESMValTool, 48 to ESMValCore. 52 (!) people contributed to this tutorial. ->{: .solution} +> > ## Solution +> > +> > At the time of making this lesson, there were 138 members of ESMValGroup. 55 of them contributed to ESMValTool, 48 to ESMValCore. 52 (!) people contributed to this tutorial. +> {: .solution} {: .challenge} ->## Challenge: issues and pull requests +> ## Challenge: issues and pull requests > > Go back to the repository pages of [ESMValTool](https://github.com/ESMValGroup/ESMValTool) or [ESMValCore](https://github.com/ESMValGroup/ESMValCore). You should see tabs for 'issues' and 'pull requests'. You can use the labels to navigate them a bit more. How many open issues are about enhancements of ESMValTool? And how many bugs have been fixed in ESMValCore? There is also an 'insights' tab, where you can see a summary of recent activity. How many issues have been opened and closed in the past month? > ->> ## Solution ->> ->> At the time of making this tutorial, there were 50 ESMValTool issues (the majority) about enhancement and 31 bugs had been fixed in the Core. 13 ESMValTool issues had been closed in the past month, versus 8 opened: overall good progress. ->{: .solution} +> > ## Solution +> > +> > At the time of making this tutorial, there were 50 ESMValTool issues (the majority) about enhancement and 31 bugs had been fixed in the Core. 13 ESMValTool issues had been closed in the past month, versus 8 opened: overall good progress. +> {: .solution} {: .challenge} ## Conclusion From f41d8d00506a92567644e3627f86987a6889e1b8 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Mon, 29 Jun 2020 16:09:35 +0100 Subject: [PATCH 117/647] Added some changes as per the review --- index.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/index.md b/index.md index 65032b44..bb2445b1 100644 --- a/index.md +++ b/index.md @@ -25,14 +25,14 @@ This tutorial is built to teach you ESMValTool. > Basic understanding of git (optional - but useful) > Basic understanding of your preferred command line interface (ie a bash terminal) > Access to CMIP data -> Access to a suitable computing system (egie jasmin) +> Access to a suitable computing system (eg Jasmin) > Github account (optional, but useful!) {: .prereq} > ## Main things you need to know before starting this course > > 1. This tutorial can be taken online independently or taught by one of our instructors. -> 2. Please check the common issues page if you get stuck. Otherwise, help is always available from ESMValTool developers via the github issues page. +> 2. Please check the common issues page if you get stuck [Link to common issues page]. Otherwise, help is always available from ESMValTool developers via the github issues page. > 3. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. > 4. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. {: .checklist} @@ -42,10 +42,11 @@ This tutorial is built to teach you ESMValTool. > ## Additional resources: > -> - Read the docs page. -> - github main page. -> - GMD paper -> - ESMValTool home page +> - Read the docs page: https://esmvaltool.readthedocs.io/ +> - ESMValTool home page: https://www.esmvaltool.org/ +> - Technical description paper: https://doi.org/10.5194/gmd-13-1179-2020 +> - Source code (ESMValTool): https://github.com/ESMValGroup/ESMValTool +> - Source code (ESMValCore ): https://github.com/ESMValGroup/ESMValCore {: .callout} From b3701c30e4004d2d85ed7ab3c89a95f39ab26394 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 29 Jun 2020 23:30:13 +0200 Subject: [PATCH 118/647] update the content --- _episodes/06-debugging.md | 306 +++++++++++++++++++++++++++++++++++++- 1 file changed, 298 insertions(+), 8 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index f11922f4..115bac23 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -1,19 +1,309 @@ --- -title: "Creating a diagnostic script" +title: "Debugging" teaching: 0 exercises: 0 questions: -- "Key question (FIXME)" +- "How can I handle errors/warnings?" objectives: -- "First learning objective. (FIXME)" +- "Fix a broken recipe" keypoints: -- "First key point. Brief Answer to questions. (FIXME)" +- "The log files contain information about errors and warnings." --- -FIXME -{% include links.md %} +Every user encounters errors. Once you know why you get certain types of errors, +they become much easier to fix. +The good news is, ``ESMValTool`` creates a record of the output messages and stores them in log files. +They can be used for debugging or monitoring the process. +This lesson helps to understand what the different types of errors are and when you are likely to encounter them. + +## log files + +Each time we run the ESMValTool, it will produce a new output directory. +This directory should contain the ``run`` folder that is automatically generated by ESMValTool. +To examine this, we run an example recipe that can be found in: +[recipe_example.yml](link). +Let's download it to our working directory ``esmvaltool_tutorial`` that was created during +the [Setup]({{ page.root }}{% link setup.md %}). + +In a new terminal, go to our working directory ``esmvaltool_tutorial`` where +both files ``user-config.yml`` and ``recipe_example.yml`` are located and run the recipe: + +~~~bash + cd esmvaltool_tutorial + esmvaltool -c user-config.yml recipe_example.yml +~~~ + +~~~ +esmvaltool: command not found +~~~ +{: .error} + +ESMValTool encounters this error because +the conda environment ``esmvaltool`` has not been activated. +To fix the error, before running the recipe, activate the environment: + +~~~bash +conda activate esmvaltool +~~~ + +> ## conda environment +> +> More information about conda environment can be found at +[Installation]({{ page.root }}{% link _episodes/02-installation.md %}) +{: .callout} + +Let's change the working directory to the folder ``run`` and list its files: + +~~~bash + cd path_to_output_directory/run + ls +~~~ + +~~~ +main_log_debug.txt main_log.txt recipe_example.yml resource_usage.txt +~~~ +{: .output} + +In the ``main_log_debug.txt`` and ``main_log.txt``, ESMValTool tells us the output messages, +warnings and possible errors that might happen during pre-processings. +To inspect them, we can look inside the files. For example: + +~~~bash + cat main_log.txt +~~~ + +> ## Different log files +> +> In the ``run`` directory, there are two log files ``main_log_debug.txt`` and ``main_log.txt``. +What are their differences? +> +>> ## Solution +>> +>> The ``main_log_debug.txt`` contains the output messages from the pr-processors whereas +the ``main_log.txt`` shows general errors and warnings that might happen in running the recipe and diagnostics script. +> {: .solution} +{: .challenge} + +If you encounter an error and don’t know what it means, it is important to read the log information. +Sometimes knowing where the error occurred is enough to fix it, even if you don’t entirely understand the message. +However, note that you may not always be able to find the error or fix it. +In that case, ESMValTool community helps you figure out what went wrong. + +Let's change some settings in the recipe to run a regional pre-processor. +We run a text editor called ``Nano`` to open the recipe file: + +~~~bash + cd esmvaltool_tutorial + nano recipe_example.yml +~~~ + +> ## Text editor side note +> +> No matter what editor you use, you will need to know where it searches +for and saves files. If you start it from the shell, it will (probably) +use your current working directory as its default location. We use ``nano`` +in examples here because it is one of the least complex text editors. +Press ctrl + O to save the file, +and then ctrl + X to exit ``nano``. +{: .callout} + +>## See the recipe_example.yml +>~~~YAML +>01 # ESMValTool +>02 # recipe_example.yml +>03 --- +>04 documentation: +>05 description: Demonstrate basic ESMValTool example +>06 +>07 authors: +>08 - demora_lee +>09 - mueller_benjamin +>10 - swaminathan_ranjini +>11 +>12 maintainer: +>13 - demora_lee +>14 +>15 references: +>16 - demora2018gmd +>17 # Some plots also appear in ESMValTool paper 2. +>18 +>19 projects: +>20 - ukesm +>21 +>22 datasets: +>23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +>24 +>25 preprocessors: +>26 prep_timeseries: # For 0D fields +>27 annual_statistics: +>28 operator: mean +>29 +>30 diagnostics: +>31 # -------------------------------------------------- +>32 # Time series diagnostics +>33 # -------------------------------------------------- +>34 diag_timeseries_temperature: +>35 description: simple_time_series +>36 variables: +>37 timeseries_variable: +>38 short_name: thetaoga +>39 preprocessor: prep_timeseries +>40 scripts: +>41 timeseries_diag: +>42 script: ocean/diagnostic_timeseries.py +>~~~ +{: .solution} + +We change the ``projects`` value ``ukesm`` to ``tutorial``: +~~~YAML +19 projects: +20 - tutorial +~~~ -Important part here is to introduce the standard tools that allow users to access ESMValTool settings configs. +Also, let's add the preprocessor ``extract_region`` to the section ``prep_timeseries``: +~~~YAML +25 preprocessors: +26 prep_timeseries: # For 0D fields +27 annual_statistics: +28 operator: mean +29 extract_region: +30 start_longitude: -10 +31 end_longitude: 40 +32 start_latitude: 27 +33 end_latitude: 70 +~~~ -This file should be renamed to advanced: creating a diagnostic +Then, we save the file and run the recipe: +~~~bash + esmvaltool -c user-config.yml recipe_example.yml +~~~ + +~~~ +ValueError: Tag 'tutorial' does not exist in section 'projects' of esmvaltool/config-references.yml +2020-06-29 18:09:56,641 UTC [46055] INFO If you suspect this is a bug or need help, +please open an issue on https://github.com/ESMValGroup/ESMValTool/issues and +attach the run/recipe_*.yml and run/main_log_debug.txt files from the output directory. +~~~ +{: .error} + +The values for the keys ``author``, ``maintainer``, ``projects`` and ``references`` in the recipe should be known by ESMValTool. + +> ## ESMValTool pre-processors +> +> The [ESMValTool pre-processors](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/recipe/preprocessor.html?highlight=preprocessor) cover a broad range of operations on the input data, +like time manipulation, area manipulation, land-sea masking, variable derivation, ... . +{: .callout} + +> ## ESMValTool can’t locate the data +> +> You are assisting a researcher with ``ESMValTool``. The researcher changes the ``project`` entry to ``CMIP6`` +and runs the recipe. However, ESMValTool encounters an error like: +> +~~~bash + esmvalcore._recipe_checks.RecipeError: Missing data +2020-06-29 17:26:41,303 UTC [43830] INFO If you suspect this is a bug or need help, +please open an issue on https://github.com/ESMValGroup/ESMValTool/issues and +attach the run/recipe_*.yml and run/main_log_debug.txt files from the output directory. +~~~ +What suggestions would you give the researcher for fixing the error? +> +>> ## Solution +>> +>> 1. inspect the ``main_log.txt`` +>> 2. check the user-config.yml to see if the correct directory for input data is introduced. +>> 3. check the available data, regarding exp, mip, ensemble, start_year, and end_year +>> 4. check the variable name in the ``diag_timeseries_temperature`` section in the recipe. +> {: .solution} +{: .challenge} + +> ## Check pre-processed data +> +> The setting ``save_intermediary_cubes`` in the configuration file can be used +save the pre-processed data. More information about this setting can be found at +[Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}) +{: .callout} + +The result of the pre-processors is passed to the ``diagnostic_timeseries.py`` script, +that is introduced in the recipe as: + +~~~YAML +40 scripts: +41 timeseries_diag: +42 script: ocean/diagnostic_timeseries.py +~~~ + +The diagnostic scripts are located in the folder ``diag_scripts`` in +the ESMValTool installation directory ``path_to_esmvaltool``. +To find ``path_to_esmvaltool`` on your system, +see [Installation]({{ page.root }}{% link_episodes/02-installation.md %}). + +let's see if we can change the script path as: + +~~~YAML +40 scripts: +41 timeseries_diag: +42 script: diag_scripts/ocean/diagnostic_timeseries.py +~~~ + +~~~bash + esmvaltool -c user-config.yml recipe_example.yml +~~~ + +~~~ +esmvalcore._task.DiagnosticError: Cannot execute script 'diag_scripts/examples/diagnostic.py' (esmvaltool/diag_scripts/diag_scripts/examples/diagnostic.py): file does not exist. +2020-06-29 20:39:31,669 UTC [53008] INFO If you suspect this is a bug or need help, please open an issue on https://github.com/ESMValGroup/ESMValTool/issues and attach the run/recipe_*.yml and run/main_log_debug.txt files from the output directory. +~~~ +{: .error} + +The script path should be relative to ``diag_scripts`` directory. +It means that the script ``diagnostic_timeseries.py`` is located in ``path_to_esmvaltool/diag_scripts/ocean/``. +Alternatively, the script path can be an absolute path. +To examine this, we change the script path and run the recipe: + +~~~YAML +40 scripts: +41 timeseries_diag: +42 script: path_to_esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py +~~~ + +~~~bash + esmvaltool -c user-config.yml recipe_example.yml +~~~ + +> ## Available recipe and diagnostic scripts +> +> ESMValTool provides a broad suite of +[recipes and diagnostic](https://docs.esmvaltool.org/en/latest/recipes/index.html) +scripts for different disciplines like atmosphere, climate metrics, future projections, +IPCC, land, ocean, .... +{: .callout} + +> ## Re-running a diagnostic +> +> Look at the ``main_log.txt`` file and answer the following question: +How to re-run the diagnostic script? +> +>> ## Solution +>> +>> The ``main_log.txt`` file contains information on how to re-run the diagnostic script +without re-running the pre-processors: +>> +~~~bash +2020-06-29 20:36:32,844 UTC [52810] INFO To re-run this diagnostic script, run: +~~~ +>> +>> If you run the command in the next line, you will be able to re-run the diagnostic. +> {: .solution} +{: .challenge} + +> ## Memory issues +> +> If you run out of memory, try setting ``max_parallel_tasks`` to 1. +Then, check the amount of memory you need for that by inspecting +the file ``run/resource_usage.txt`` in the output directory. +Using the number there you can increase the number of parallel tasks again to a reasonable number +for the amount of memory available in your system. +{: .callout} + +{% include links.md %} From 629a94babd867ffa6b7eb7cf817e6e199280e0b1 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 29 Jun 2020 23:38:03 +0200 Subject: [PATCH 119/647] revise the text --- _episodes/06-debugging.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 115bac23..6bf648bd 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -72,6 +72,11 @@ To inspect them, we can look inside the files. For example: cat main_log.txt ~~~ +If you encounter an error and don’t know what it means, it is important to read the log information. +Sometimes knowing where the error occurred is enough to fix it, even if you don’t entirely understand the message. +However, note that you may not always be able to find the error or fix it. +In that case, ESMValTool community helps you figure out what went wrong. + > ## Different log files > > In the ``run`` directory, there are two log files ``main_log_debug.txt`` and ``main_log.txt``. @@ -84,11 +89,6 @@ the ``main_log.txt`` shows general errors and warnings that might happen in runn > {: .solution} {: .challenge} -If you encounter an error and don’t know what it means, it is important to read the log information. -Sometimes knowing where the error occurred is enough to fix it, even if you don’t entirely understand the message. -However, note that you may not always be able to find the error or fix it. -In that case, ESMValTool community helps you figure out what went wrong. - Let's change some settings in the recipe to run a regional pre-processor. We run a text editor called ``Nano`` to open the recipe file: @@ -236,7 +236,7 @@ that is introduced in the recipe as: The diagnostic scripts are located in the folder ``diag_scripts`` in the ESMValTool installation directory ``path_to_esmvaltool``. To find ``path_to_esmvaltool`` on your system, -see [Installation]({{ page.root }}{% link_episodes/02-installation.md %}). +see [Installation]({{ page.root }}{% link _episodes/02-installation.md %}). let's see if we can change the script path as: @@ -299,7 +299,7 @@ without re-running the pre-processors: > ## Memory issues > -> If you run out of memory, try setting ``max_parallel_tasks`` to 1. +> If you run out of memory, try setting ``max_parallel_tasks`` to 1 in the configuration file. Then, check the amount of memory you need for that by inspecting the file ``run/resource_usage.txt`` in the output directory. Using the number there you can increase the number of parallel tasks again to a reasonable number From 828ee0254970e83146910d94ce9ac1e275381df0 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 16:38:29 +0200 Subject: [PATCH 120/647] add solutions to most challenges FIXME is supposed to be done by someone who has access to JASMIN in order to have the correct solutions. --- _episodes/first_example_recipe.md | 181 ++++++++++++++++++++---------- 1 file changed, 124 insertions(+), 57 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 2af1b59b..d80b1d40 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -59,10 +59,11 @@ For additional reeds, please have a look at the recipe format description in the ## How to run ESMValTool Once you’ve set up your conda environment and installed ESMValTool (see episode #2 LINK) and set up your config-user.yml file to correctly match you local environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: -~~~ + +~~~source esmvaltool -c configuration recipe ~~~ -{: .source} + To try your hand with a basic recipe, please work through this episode. @@ -72,61 +73,60 @@ The recipe presented here is a simple, basic recipe that takes a single dataset Please download the following recipe into your ESMValTool working area with the name: recipe_example.yml LINK ->## recipe_example.yml ->~~~YAML -> 1 # ESMValTool -> 2 # recipe_example.yml -> 3 --- -> 4 documentation: -> 5 description: Demonstrate basic ESMValTool example -> 6 -> 7 authors: -> 8 - demora_lee -> 9 - mueller_benjamin ->10 - swaminathan_ranjini ->11 ->12 maintainer: ->13 - demora_lee ->14 ->15 references: ->16 - demora2018gmd ->17 # Some plots also appear in ESMValTool paper 2. ->18 ->19 projects: ->20 - ukesm ->21 ->22 datasets: ->23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} ->24 ->25 preprocessors: ->26 prep_timeseries: # For 0D fields ->27 annual_statistics: ->28 operator: mean ->29 ->30 diagnostics: ->31 # -------------------------------------------------- ->32 # Time series diagnostics ->33 # -------------------------------------------------- ->34 diag_timeseries_temperature: ->35 description: simple_time_series ->36 variables: ->37 timeseries_variable: ->38 short_name: thetaoga ->39 preprocessor: prep_timeseries ->40 scripts: ->41 timeseries_diag: ->42 script: ocean/diagnostic_timeseries.py ->~~~ +> ## recipe_example.yml +> ~~~YAML +> 1 # ESMValTool +> 2 # recipe_example.yml +> 3 --- +> 4 documentation: +> 5 description: Demonstrate basic ESMValTool example +> 6 +> 7 authors: +> 8 - demora_lee +> 9 - mueller_benjamin +> 10 - swaminathan_ranjini +> 11 +> 12 maintainer: +> 13 - demora_lee +> 14 +> 15 references: +> 16 - demora2018gmd +> 17 # Some plots also appear in ESMValTool paper 2. +> 18 +> 19 projects: +> 20 - ukesm +> 21 +> 22 datasets: +> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> 24 +> 25 preprocessors: +> 26 prep_timeseries: # For 0D fields +> 27 annual_statistics: +> 28 operator: mean +> 29 +> 30 diagnostics: +> 31 # -------------------------------------------------- +> 32 # Time series diagnostics +> 33 # -------------------------------------------------- +> 34 diag_timeseries_temperature: +> 35 description: simple_time_series +> 36 variables: +> 37 timeseries_variable: +> 38 short_name: thetaoga +> 39 preprocessor: prep_timeseries +> 40 scripts: +> 41 timeseries_diag: +> 42 script: ocean/diagnostic_timeseries.py +> ~~~ {: .solution} > ## Explore the recipe > Use the command and investigate the sample recipe. -> ~~~ +> ~~~bash > vim recipe_example.yml > ~~~ -> {: .source} -> +{: .challenge} Please note the following sections: - documentation: lines 4-20 @@ -174,16 +174,33 @@ Please note the following sections: - the next indent (here: timeseries_diag) is the scripts’ names (a string without whitespace) for the script to use - script: a executable script with a directory relative to the `esmvaltool/diag_scripts/` directory - -> What is the short_name of the variable being analysed? +> ## Please answer the following questions: +> What is the short_name of the variable being analyzed? > > What is the diagnostic script being used? > -> How many years of data are being analysed? +> How many years of data are being analyzed? > > What do you think running this recipe will produce? {: .challenge} + +> ## What is the short_name of the variable being analyzed? +> thetaoga - Global Average Sea Water Potential Temperature +{: .solution} + +> ## What is the diagnostic script being used? +> `ocean/diagnostic_timeseries.py` +{: .solution} + +> ## How many years of data are being analyzed? +> 1859 to 2005, that is 147 years. +{: .solution} + +> ## What do you think running this recipe will produce? +> A time series plot of thetaoga with increements of 1 year. +{: .solution} + > ## Not all parts of the recipe are mandatory > Some functionalities of the example recipe are mandatory, while others are not. E.g., if you miss any of the documentation information, the call will break. {: .callout} @@ -191,14 +208,17 @@ Please note the following sections: > ## Running ESMValTool > > Use the command: -> ~~~ +> ~~~bash > esmvaltool -c ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml > ~~~ -> {: .source} > > Follow the terminal guiding you through the subprocesses that are running. Can you find where the preprocessor and the diagnostic are starting? Which one took longer to process? {: .challenge} +> ## Exemplary output +> FIXME +{: .solution} + Each time you run the ESMValTool, it will produce a new output directory within your specified work directory with the name of the recipe and the tagged runtime. This folder should contain four folders: - run - work @@ -218,8 +238,31 @@ Each time you run the ESMValTool, it will produce a new output directory within > - Your settings.yml file. > - A metadata.yml file. > - The diagnostic log file. -{: .discussion} +{: .checklist} + +Exemplary output (depending on the directory paths and package versions that are available) can be found below: + +> ## Your output plot(s). +> FIXME (include plots) +{: .solution} + +> ## Your main output log file. +> FIXME (include example log) +{: .solution} + +> ## Your settings.yml file. +> FIXME (include the settings) +{: .solution} + +> ## A metadata.yml file. +> FIXME (include the metadata) +{: .solution} + +> ## The diagnostic log file. +> FIXME (include the diag log) +{: .solution} +## Do your first edits > ## Edit the recipe and run again > So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: @@ -239,6 +282,30 @@ Each time you run the ESMValTool, it will produce a new output directory within > - Ocean surface average temperature (tos) {: .challenge} +The snippets for the edits can be found below: + +> ## Land surface average temperature +> FIXME (include line numbers, see below) +> ~~~YAML +> ... +> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> ... +> 27 annual_statistics: +> 28 operator: mean +> ... +> 38 short_name: thetaoga +> 39 preprocessor: prep_timeseries +> ~~~~ +{: .solution} + +> ## Atmospheric surface average temperature +> FIXME +{: .solution} + +> ## Ocean surface average temperature +> FIXME +{: .solution} + > ## Advanced: > If you want to add a different field, please have a look here: > http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html @@ -247,7 +314,7 @@ Each time you run the ESMValTool, it will produce a new output directory within ## Common issues & tips -> ## Esmvaltool not found +> ## esmvaltool not found > Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, episode #2 LINK. {: .solution} From c8a4e96a3edfb92e1baeb4df4bfffcca09c447ed Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 30 Jun 2020 09:00:11 +0200 Subject: [PATCH 121/647] revise the text --- _episodes/03-configuration.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 30e13556..6fb0995d 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -4,10 +4,12 @@ teaching: 0 exercises: 0 questions: - "What is the user configuration file and how should I use it?" + objectives: - "Understand the contents of the user-config.yml file" - "Prepare a personalized user-config.yml file" - "Configure ESMValTool to use some settings" + keypoints: - "The ``config-user.yml`` tells ESMValTool where to find input data." - " ``rootpath`` defines the root directory for the input data." @@ -31,7 +33,7 @@ then you can rename it to ``config-user.yml``and save it into the working direct ``esmvaltool_tutorial``. Now, let's change our working directory in a terminal window to ``esmvaltool_tutorial``. -Then, we run a text editor called Nano to open the configuration file: +Then, we run a text editor called Nano to have a look inside the configuration file: ~~~bash cd esmvaltool_tutorial @@ -40,12 +42,12 @@ Then, we run a text editor called Nano to open the configuration file: This file contains the information for: -* Rootpath to input data -* Directory structure for the data from different projects -* Number of tasks that can be run in parallel -* Destination directory -* Auxiliary data directory -* Output settings +- Rootpath to input data +- Directory structure for the data from different projects +- Number of tasks that can be run in parallel +- Destination directory +- Auxiliary data directory +- Output settings > ## Text editor side note > @@ -92,9 +94,9 @@ We add the root path of the folder where our/your data is available. > ## Setting the correct rootpath > -> * To get the data (or its correct rootpath), check instruction in +> - To get the data (or its correct rootpath), check instruction in [Setup]({{ page.root }}{% link setup.md %}). -> * For more information about setting the rootpath, see also the ESMValTool +> - For more information about setting the rootpath, see also the ESMValTool For more information about setting the roothpath, see also ESMValTool... [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} @@ -157,14 +159,14 @@ output_dir: ./esmvaltool_output > ## Content of subfolders > -> * ``plots``: the location for all plots, split by individual diagnostics and fields. -> * ``preproc``: this folder contains all the preprocessed data and metadata.yml +> - ``plots``: the location for all plots, split by individual diagnostics and fields. +> - ``preproc``: this folder contains all the preprocessed data and metadata.yml interface files. Note that by default this directory will be deleted after each run because most users will only need the results from the diagnostic scripts. -> * ``run``: this folder includes all log files, a copy of the recipe, +> - ``run``: this folder includes all log files, a copy of the recipe, a summary of the resource usage, and the settings.yml interface files, resource_usage.txt and temporary files created by the diagnostic scripts. -> * ``work``: this folder is a place for any diagnostic script results that +> - ``work``: this folder is a place for any diagnostic script results that are not plots, e.g. files in NetCDF format (depends on the diagnostic script). > > We explain more about output in the next From ed0bc8a6e5c054cde9dc291f173a6ef6b8f48e71 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Fri, 26 Jun 2020 14:00:52 +0200 Subject: [PATCH 122/647] Draft for new "episode 4" --- _episodes/04-toy-example.md | 52 -------- _episodes/first_example_recipe.md | 189 ++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 52 deletions(-) delete mode 100644 _episodes/04-toy-example.md create mode 100644 _episodes/first_example_recipe.md diff --git a/_episodes/04-toy-example.md b/_episodes/04-toy-example.md deleted file mode 100644 index 1200e801..00000000 --- a/_episodes/04-toy-example.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "Toy example" -teaching: 0 -exercises: 0 -questions: -- "Key question (FIXME)" -objectives: -- "Explain how ESMValTool is structured." -- "Execute ESMValTool using the example recipe and diagnostic script provided." -- "Inspect the output that was created by running ESMValTool" -keypoints: -- "" -- "The recipe tells ESMValTool what parts of its core functionality it should run and on what -data." -- "The diagnostic script is tailor made by the diagnostic developer where functionalities not -supported by ESMValTool can be implemented in the processing pipeline." ---- -Now we have installed and configured ESMValTool it is time to run a simple example and inspect -what it produces. - -For this we need our general ESMValTool settings from episode 3 (configuration), the example data -that you downloaded in the -[setup](https://escience-academy.github.io/lesson-esmvaltool/setup.html) and an example recipe to -tell ESMValTool what it should do. Let's make sure you have all set to continue. Check whether -you can find these three items in your ESMValTool folder. - -> ## Exercise -> -> Find all the -> -{: .challenge} - - -As already mentioned in the -[introduction](https://escience-academy.github.io/lesson-esmvaltool/01-introduction/index.html), -ESMValTool consists of two parts: the core and the diagnostics. The core part (also called -ESMValCore after its repository name) contains the code to run the actual software as well as -several preprocessing functions that are widely used. The diagnostics part (confusingly situated -in the repository called ESMValTool) mainly contains so called recipes and diagnostic scripts. - -The recipes describe the analysis pipeline and tell ESMValTool which actions to perform on what -data. - - - -~~~ -esmvaltool -c config-user.yml recipes/recipe_python.yml -~~~ -{: .source} - -{% include links.md %} - diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md new file mode 100644 index 00000000..c4ee00e9 --- /dev/null +++ b/_episodes/first_example_recipe.md @@ -0,0 +1,189 @@ +--- +title: "Running a recipe (First example)" +teaching: 10 +exercises: 25 +questions: +- "What is a recipe?" +- "How can I do the same preprocessing on many different datasets?" +- "What are the files and directories after running a recipe?" +- "What happens when I run a recipe?" +objectives: +- "Run an ESMValTool recipe" +- "Understand the purpose of different settings in the recipe" +- "Inspect the output directories" +- "Examine the log information" +keypoints: +- "A recipe does not break by fiddling with it" +- "Log information is useful to How to interpret the first warnings/errors" +- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." +--- + +This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. + +## Introduction to Recipes + +Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main section: +- datasets: what datasets you want to use + - the time range and time resolution, + - the MIP, ensemble member, + - the experiment (ie historical, ssp125 etc...) + - the grid type (CMIP6 only) + - This section can also be optional, as datasets can no preprocessing is needed. + +- proprocessors: one or preprocessors + - which preprocessor modules to apply + - the order to apply them + - and the preprocesor arguments. + - This section can also be optional, if no preprocessing is needed. + +- diagnostics: All the information about diagnostic + - + +- description: a brief description of the recipe + - who wrote the recipe, and who maintains it + - which project is responsible for it + - which publications, reference are linked with the recipe + - Note that the authors, publications and references and named in the config-references.yml + +This information + +## How to run ESMValTool + +Once you’ve set up your conda environment and installed ESMValTool (See episode #2) and set up your config-user.yml file to correctly match you local environment, (see episode #3), ESMValTool is invoked using a simple command: +~~~ +esmvaltool -c configuration recipe +~~~ + +To try your hand with a basic recipe, please work through this episode. + + +## Example recipe +This is a basic recipe that takes a simple dataset and produces a simple plot. +Please copy and paste the following recipe into your ESMValTool working area with the name: recipe_example.yml + + # ESMValTool + # recipe_example.yml + --- + documentation: + description: | + Demonstrate basic ESMValTool example + + authors: + - demora_lee + - Ben + - Ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + + + preprocessors: + # -------------------------------------------------- + # Time series preprocessors + # -------------------------------------------------- + prep_timeseries: # For 0D fields + multi_model_statistics: + span: full + statistics: [mean ] + + + diagnostics: + # -------------------------------------------------- + # Time series diagnostics + # -------------------------------------------------- + diag_timeseries_temperature: + variables: + thetaoga: + preprocessor: prep_timeseries + additional_datasets: + - {dataset: CESM1-BGC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: CNRM-CM5, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: CSIRO-Mk3-6-0, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: CanESM2, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: GFDL-ESM2M, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1861, end_year: 2005, } + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005, } + - {dataset: IPSL-CM5A-LR, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: MIROC-ESM, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: MPI-ESM-LR, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + - {dataset: NorESM1-M, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py + +> ## Explore the recipe +> +> Use the command and investigate the sample recipe. +> vim recipe.yml +> +> Please note the datasets, preprocessors, diagnostic sections. +> What is the short_name of the variable being analysed? +> What is the diagnostic script being used? +> How many years of data are being analysed? +> What do you think running this recipe will produce? +{: .challenge} + +> ## Not all parts of the recipe are mandatory +> Some functionalities of the example recipe are mandatory, while others are not. E.g., if you miss any of the documentation information, the call will break. +{: .callout} + +> ## Running ESMValTool +> +> Use the command: +> esmvaltool -c user-config.yml recipe_example.yml +> +> What +{: .challenge} + + +> ## Inspect the output: +> Now that you have run the esmvaltool command for the first time, please locate your output directory. +> Each time you run ESMValTool, it will produce a new output directory with the format: +> This directory should contain four folders: +> run work preproc plots +> If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true. + + +> +> Please locate and inspect the following files: +> You output plot(s). +> Your main output log file +> Your settings.yml file +> A metadata.yml file +{: .discussion} + + +> ## Edit the recipe and run +> So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: +> Land surface temperature +> Atmospheric surface temperature +> Ocean surface temperature (tos) +> You will need to edit the dataset request, c +{: .challenge} + + +> ## Common issues & tips +> +> ### ESMValTool can’t locate the data +> User didn’t correctly edit user-config.yml +> +> ### Esmvaltool not found +> User didn’t active or correctly install conda +> +> ### Diagnostic path problems +> explain ESMValTool’s methods to determine diagnostic path, and how it should appear in the recipe +> +> ### FX files not found. +> +> ### The preprocessor works but the diagnostic fails: +> How to tell them appart and how to re-run a failed diagnostic (but not the preprocessor) +> +> ### Your recipe’s name/project/reference isn’t recognised by ESMValTool. +> +{: .callout} From 27c5be721962ff9629bf8fc929341b9217582e01 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Fri, 26 Jun 2020 14:10:59 +0200 Subject: [PATCH 123/647] update current edits --- _episodes/first_example_recipe.md | 136 ++++++++++++++++++------------ 1 file changed, 80 insertions(+), 56 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index c4ee00e9..c4922eb9 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -1,3 +1,6 @@ +File name : first_example_recipe.md +Episode 4. + --- title: "Running a recipe (First example)" teaching: 10 @@ -8,13 +11,13 @@ questions: - "What are the files and directories after running a recipe?" - "What happens when I run a recipe?" objectives: -- "Run an ESMValTool recipe" +- "Run an ESMValTool recipe” - "Understand the purpose of different settings in the recipe" - "Inspect the output directories" - "Examine the log information" keypoints: - "A recipe does not break by fiddling with it" -- "Log information is useful to How to interpret the first warnings/errors" +- "Log information is useful when interpreting the first warnings/errors" - "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." --- @@ -22,28 +25,36 @@ This episode describes how ESMValTool recipes work, how to run a recipe and how ## Introduction to Recipes -Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main section: -- datasets: what datasets you want to use +Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. + +- datasets: what datasets you want to use, including - the time range and time resolution, - the MIP, ensemble member, - - the experiment (ie historical, ssp125 etc...) - - the grid type (CMIP6 only) - - This section can also be optional, as datasets can no preprocessing is needed. + - the experiment (i.e. historical, ssp125 etc...), + - and the grid type (CMIP6 only) + + This section can also be optional, as datasets can no preprocessing is needed. + +- preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing + - which preprocessor modules to apply, + - the order to apply them, + - and the preprocessor arguments. + + This section can also be optional, if no preprocessing is needed. -- proprocessors: one or preprocessors - - which preprocessor modules to apply - - the order to apply them - - and the preprocesor arguments. - - This section can also be optional, if no preprocessing is needed. +- diagnostics: all the information about the diagnostic, including + - list of variables to evaluate (with their respective configurations), + - the desired diagnostic script to use, + - and additional diagnostic script options or arguments, if needed. -- diagnostics: All the information about diagnostic - - + Also Include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. -- description: a brief description of the recipe - - who wrote the recipe, and who maintains it - - which project is responsible for it - - which publications, reference are linked with the recipe - - Note that the authors, publications and references and named in the config-references.yml +- description: a brief description of the recipe, including + - who wrote the recipe and who maintains it, + - which project is responsible for it, + - and which publications, references are linked with the recipe. + + Note that the authors, publications and references are to be named in the config-references.yml This information @@ -53,6 +64,7 @@ Once you’ve set up your conda environment and installed ESMValTool (See episod ~~~ esmvaltool -c configuration recipe ~~~ +{: .source} To try your hand with a basic recipe, please work through this episode. @@ -70,8 +82,8 @@ Please copy and paste the following recipe into your ESMValTool working area wit authors: - demora_lee - - Ben - - Ranjini + - mueller_benjamin + - swaminathan_ranjini maintainer: - demora_lee @@ -83,16 +95,13 @@ Please copy and paste the following recipe into your ESMValTool working area wit projects: - ukesm + datasets: + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005, } preprocessors: - # -------------------------------------------------- - # Time series preprocessors - # -------------------------------------------------- - prep_timeseries: # For 0D fields - multi_model_statistics: - span: full - statistics: [mean ] - + prep_timeseries: # For 0D fields + annual_statistics: + operator: mean diagnostics: # -------------------------------------------------- @@ -100,27 +109,21 @@ Please copy and paste the following recipe into your ESMValTool working area wit # -------------------------------------------------- diag_timeseries_temperature: variables: - thetaoga: - preprocessor: prep_timeseries - additional_datasets: - - {dataset: CESM1-BGC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: CNRM-CM5, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: CSIRO-Mk3-6-0, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: CanESM2, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: GFDL-ESM2M, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1861, end_year: 2005, } - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005, } - - {dataset: IPSL-CM5A-LR, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: MIROC-ESM, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: MPI-ESM-LR, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } - - {dataset: NorESM1-M, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1850, end_year: 2005, } + timeseries_variable: + short_name: thetaoga + preprocessor: prep_timeseries scripts: timeseries_diag: script: ocean/diagnostic_timeseries.py + > ## Explore the recipe > > Use the command and investigate the sample recipe. +> ~~~ > vim recipe.yml +> ~~~ +> {: .source} > > Please note the datasets, preprocessors, diagnostic sections. > What is the short_name of the variable being analysed? @@ -136,23 +139,24 @@ Please copy and paste the following recipe into your ESMValTool working area wit > ## Running ESMValTool > > Use the command: +> ~~~ > esmvaltool -c user-config.yml recipe_example.yml +> ~~~ > +> {: .source} > What {: .challenge} > ## Inspect the output: > Now that you have run the esmvaltool command for the first time, please locate your output directory. -> Each time you run ESMValTool, it will produce a new output directory with the format: +> Each time you run ESMValTool, it will produce a new output directory with the following format: > This directory should contain four folders: > run work preproc plots -> If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true. - - +> If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true (this is used to save disk space). Please set this value to false and run the recipe again. > > Please locate and inspect the following files: -> You output plot(s). +> Your output plot(s). > Your main output log file > Your settings.yml file > A metadata.yml file @@ -161,29 +165,49 @@ Please copy and paste the following recipe into your ESMValTool working area wit > ## Edit the recipe and run > So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: -> Land surface temperature -> Atmospheric surface temperature -> Ocean surface temperature (tos) -> You will need to edit the dataset request, c +> - Land surface average temperature (tsland) +> - Atmospheric surface average temperature (tas) +> - Ocean surface average temperature (tos) +> +> You will need to edit: +> - the dataset: +> - mip, start_year, end_year +> - the preprocessor: +> - These fields are all 2D fields, but thetaga was a 0D field. This means that we need to take the average over the latitude and longitude dimensions. To do this, add the area_statistics to the preprocessor. +> - the diagnostic +> - change the short_name value (thetaoga) for another: +> - Land surface average temperature (tsland) +> - Atmospheric surface average temperature (tas) +> - Ocean surface average temperature (tos) +> ### Advanced: +> If you want to add a different field, please have a look here: +> http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html {: .challenge} > ## Common issues & tips > +> ### Esmvaltool not found +> Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, epside [2] LINK. +> > ### ESMValTool can’t locate the data -> User didn’t correctly edit user-config.yml +> The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” +> Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? > -> ### Esmvaltool not found -> User didn’t active or correctly install conda > > ### Diagnostic path problems -> explain ESMValTool’s methods to determine diagnostic path, and how it should appear in the recipe +> The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? +> > > ### FX files not found. > +> > ### The preprocessor works but the diagnostic fails: -> How to tell them appart and how to re-run a failed diagnostic (but not the preprocessor) +> If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. +> > > ### Your recipe’s name/project/reference isn’t recognised by ESMValTool. +> Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” +> Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. > {: .callout} From bdba357c5ae310519dda226eed6bf2a54e658ee4 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Fri, 26 Jun 2020 16:30:01 +0200 Subject: [PATCH 124/647] adds more detail to the recipe explanation adds the recipe as a file (not linked yet) --- _episodes/first_example_recipe.md | 175 +++++++++++++++++------------- data/recipe_example.yml | 42 +++++++ 2 files changed, 141 insertions(+), 76 deletions(-) create mode 100644 data/recipe_example.yml diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index c4922eb9..1c945e1d 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -56,11 +56,11 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w Note that the authors, publications and references are to be named in the config-references.yml -This information +This information ... ## How to run ESMValTool -Once you’ve set up your conda environment and installed ESMValTool (See episode #2) and set up your config-user.yml file to correctly match you local environment, (see episode #3), ESMValTool is invoked using a simple command: +Once you’ve set up your conda environment and installed ESMValTool (see episode #2 LINK) and set up your config-user.yml file to correctly match you local environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: ~~~ esmvaltool -c configuration recipe ~~~ @@ -69,63 +69,92 @@ esmvaltool -c configuration recipe To try your hand with a basic recipe, please work through this episode. -## Example recipe -This is a basic recipe that takes a simple dataset and produces a simple plot. -Please copy and paste the following recipe into your ESMValTool working area with the name: recipe_example.yml +## Introduction to the example recipe +Threcipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. - # ESMValTool - # recipe_example.yml - --- - documentation: - description: | - Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - - datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005, } - - preprocessors: - prep_timeseries: # For 0D fields - annual_statistics: - operator: mean - - diagnostics: - # -------------------------------------------------- - # Time series diagnostics - # -------------------------------------------------- - diag_timeseries_temperature: - variables: - timeseries_variable: - short_name: thetaoga - preprocessor: prep_timeseries - scripts: - timeseries_diag: - script: ocean/diagnostic_timeseries.py +Please copy and paste the following recipe into your ESMValTool working area with the name: recipe_example.yml +>## recipe_example.yml +>~~~YAML +> # ESMValTool +> # recipe_example.yml +> --- +> documentation: +> description: Demonstrate basic ESMValTool example +> +> authors: +> - demora_lee +> - mueller_benjamin +> - swaminathan_ranjini +> +> maintainer: +> - demora_lee +> +> references: +> - demora2018gmd +> # Some plots also appear in ESMValTool paper 2. +> +> projects: +> - ukesm +> +> datasets: +> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> +> preprocessors: +> prep_timeseries: # For 0D fields +> annual_statistics: +> operator: mean +> +> diagnostics: +> # -------------------------------------------------- +> # Time series diagnostics +> # -------------------------------------------------- +> diag_timeseries_temperature: +> description: simple_time_series +> variables: +> timeseries_variable: +> short_name: thetaoga +> preprocessor: prep_timeseries +> scripts: +> timeseries_diag: +> script: ocean/diagnostic_timeseries.py +>~~~ +{: .solution} > ## Explore the recipe -> > Use the command and investigate the sample recipe. > ~~~ -> vim recipe.yml +> vim recipe_example.yml > ~~~ > {: .source} > -> Please note the datasets, preprocessors, diagnostic sections. + +Please note the following sections: +- documentation: lines 4-20 + + The documentation consists of the following information: + - description: a one line description of the recipe + - authors: a list of authors (linked to esmvaltool/config-references.yml) + - maintainer: a list of maintainers (linked to esmvaltool/config-references.yml) + - references: a list of references (linked to a bibtexfile in esmvaltool/references with the same name) + - projects: a list of projects (linked to esmvaltool/config-references.yml) + + +- datasets: lines 22-23 + The dataset definition consists of a list of dictionaries with the information on the datasets. + [List of entries?] + + +- preprocessors: lines 25-28 + The definition for different preprocessors or combinations. + [go into detail] + + +- diagnostic section: lines 30-42 + The information of which diagnostic script to run with which variables. + [go into detail] + + > What is the short_name of the variable being analysed? > What is the diagnostic script being used? > How many years of data are being analysed? @@ -185,29 +214,23 @@ Please copy and paste the following recipe into your ESMValTool working area wit {: .challenge} -> ## Common issues & tips -> -> ### Esmvaltool not found -> Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, epside [2] LINK. -> -> ### ESMValTool can’t locate the data -> The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” -> Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? -> -> -> ### Diagnostic path problems -> The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? -> -> -> ### FX files not found. -> -> -> ### The preprocessor works but the diagnostic fails: -> If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. -> -> -> ### Your recipe’s name/project/reference isn’t recognised by ESMValTool. -> Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” -> Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. -> -{: .callout} +## Common issues & tips + +### Esmvaltool not found +Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, epside [2] LINK. + +### ESMValTool can’t locate the data +The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” +Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? + +### Diagnostic path problems +The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? + +### FX files not found. + +### The preprocessor works but the diagnostic fails: +If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. + +### Your recipe’s name/project/reference isn’t recognised by ESMValTool. +Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” +Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. diff --git a/data/recipe_example.yml b/data/recipe_example.yml new file mode 100644 index 00000000..67cee8b9 --- /dev/null +++ b/data/recipe_example.yml @@ -0,0 +1,42 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +datasets: + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} + +preprocessors: + prep_timeseries: # For 0D fields + annual_statistics: + operator: mean + +diagnostics: + # -------------------------------------------------- + # Time series diagnostics + # -------------------------------------------------- + diag_timeseries_temperature: + description: simple_time_series + variables: + timeseries_variable: + short_name: thetaoga + preprocessor: prep_timeseries + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py From 8995381668c87da25a45dd52a42905262576c5fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20M=C3=BCller?= Date: Fri, 26 Jun 2020 16:33:40 +0200 Subject: [PATCH 125/647] Update first_example_recipe.md remove header --- _episodes/first_example_recipe.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 1c945e1d..f58bba3c 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -1,6 +1,3 @@ -File name : first_example_recipe.md -Episode 4. - --- title: "Running a recipe (First example)" teaching: 10 From 3e56331319216df03155cec62d5e042983b74de4 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Fri, 26 Jun 2020 16:44:30 +0200 Subject: [PATCH 126/647] fix " typo --- _episodes/first_example_recipe.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index f58bba3c..e415e02f 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -1,6 +1,6 @@ --- title: "Running a recipe (First example)" -teaching: 10 +teaching: 20 exercises: 25 questions: - "What is a recipe?" @@ -8,14 +8,14 @@ questions: - "What are the files and directories after running a recipe?" - "What happens when I run a recipe?" objectives: -- "Run an ESMValTool recipe” +- "Run an ESMValTool recipe" - "Understand the purpose of different settings in the recipe" - "Inspect the output directories" - "Examine the log information" keypoints: - "A recipe does not break by fiddling with it" - "Log information is useful when interpreting the first warnings/errors" -- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." +- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP" --- This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. From 0053aa01289782258336ad82be060aa5d03af302 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 13:14:47 +0200 Subject: [PATCH 127/647] adds details for the recipe --- _episodes/first_example_recipe.md | 40 +++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index e415e02f..cc538aaa 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -130,26 +130,47 @@ Please note the following sections: - documentation: lines 4-20 The documentation consists of the following information: - - description: a one line description of the recipe + - description: a short description of the recipe - authors: a list of authors (linked to esmvaltool/config-references.yml) - maintainer: a list of maintainers (linked to esmvaltool/config-references.yml) - references: a list of references (linked to a bibtexfile in esmvaltool/references with the same name) - projects: a list of projects (linked to esmvaltool/config-references.yml) -- datasets: lines 22-23 - The dataset definition consists of a list of dictionaries with the information on the datasets. - [List of entries?] + - datasets: lines 22-23 + The dataset definition consists of a list of python dictionaries with the information on the datasets. + - dataset name (key: dataset) + - project (key: project) + - experiment (key: exp) + - mip (for CMIP data, key: mip) + - ensemble member (key: ensemble) + - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) + - model grid (for CMIP6 data only, key: grid) + - alias (key: alias; use the alias for e.g. a more human readable name) -- preprocessors: lines 25-28 - The definition for different preprocessors or combinations. - [go into detail] + + - preprocessors: lines 25-28 + + The definition for different preprocessors or combinations. + If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). + Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). + (See episode #5 LINK for more details.) - diagnostic section: lines 30-42 + The information of which diagnostic script to run with which variables. - [go into detail] + The diagnostics section has some indents that are free to call. + - the first indent (here: diag_timeseries_temperature) is the diagnostic’s name (a string without whitespace), used for setting up the respective directories + - description: a short description of the diagnostic + - variables: a definition of all variables that are used in this diagnostic + - the next indent (here: timeseries_variable) is the variables’ names (a string without whitespace) for the diagnostic to use + - short_name: the variable name as listed in the dataset + - preprocessor: the preprocessor(s) applied to the variable before running the diagnostic + - scripts: a definition of all scripts that are used in this diagnostic + - the next indent (here: timeseries_diag) is the scripts’ names (a string without whitespace) for the script to use + - script: a executable script with a directory relative to the `esmvaltool/diag_scripts/` directory > What is the short_name of the variable being analysed? @@ -168,9 +189,8 @@ Please note the following sections: > ~~~ > esmvaltool -c user-config.yml recipe_example.yml > ~~~ -> > {: .source} -> What +> What ... {: .challenge} From da6cb8a84ffc87f686794c10d435ba9190728a66 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 13:23:40 +0200 Subject: [PATCH 128/647] adds header detail --- _episodes/first_example_recipe.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index cc538aaa..120e058e 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -1,11 +1,12 @@ --- + title: "Running a recipe (First example)" teaching: 20 exercises: 25 questions: - "What is a recipe?" - "How can I do the same preprocessing on many different datasets?" -- "What are the files and directories after running a recipe?" +- "What are the files and directories that are created after running a recipe?" - "What happens when I run a recipe?" objectives: - "Run an ESMValTool recipe" @@ -15,9 +16,11 @@ objectives: keypoints: - "A recipe does not break by fiddling with it" - "Log information is useful when interpreting the first warnings/errors" -- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP" +- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." + --- + This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. ## Introduction to Recipes From d6f49294a367fcce67f33848ea5cf90842729797 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 13:59:29 +0200 Subject: [PATCH 129/647] restructure some challenges --- _episodes/first_example_recipe.md | 33 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 120e058e..abd9d9bc 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -20,7 +20,6 @@ keypoints: --- - This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. ## Introduction to Recipes @@ -177,8 +176,11 @@ Please note the following sections: > What is the short_name of the variable being analysed? +> > What is the diagnostic script being used? +> > How many years of data are being analysed? +> > What do you think running this recipe will produce? {: .challenge} @@ -190,29 +192,36 @@ Please note the following sections: > > Use the command: > ~~~ -> esmvaltool -c user-config.yml recipe_example.yml +> esmvaltool -c ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml > ~~~ > {: .source} -> What ... +> +> Follow the terminal guiding you through the subprocesses that are running. Can you find where the preprocessor and the diagnostic are starting? Which one took longer to process? {: .challenge} +Each time you run the ESMValTool, it will produce a new output directory within your specified work directory with the name of the recipe and the tagged runtime. This folder should contain four folders: +- run +- work +- preproc +- plots > ## Inspect the output: -> Now that you have run the esmvaltool command for the first time, please locate your output directory. -> Each time you run ESMValTool, it will produce a new output directory with the following format: -> This directory should contain four folders: -> run work preproc plots +> Now that you have ran the esmvaltool command for the first time, please locate your output directory. > If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true (this is used to save disk space). Please set this value to false and run the recipe again. > +{: .challenge} + +> ## Inspect specific files: > Please locate and inspect the following files: -> Your output plot(s). -> Your main output log file -> Your settings.yml file -> A metadata.yml file +> - Your output plot(s). +> - Your main output log file. +> - Your settings.yml file. +> - A metadata.yml file. +> - The diagnostic log file. {: .discussion} -> ## Edit the recipe and run +> ## Edit the recipe and run again > So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: > - Land surface average temperature (tsland) > - Atmospheric surface average temperature (tas) From efa72a2bf3c7a582c8bc8dae54bb15aee840a78f Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 15:28:45 +0200 Subject: [PATCH 130/647] add line numbers to recipe --- _episodes/first_example_recipe.md | 120 +++++++++++++++--------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index abd9d9bc..185ec0de 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -30,9 +30,7 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w - the time range and time resolution, - the MIP, ensemble member, - the experiment (i.e. historical, ssp125 etc...), - - and the grid type (CMIP6 only) - - This section can also be optional, as datasets can no preprocessing is needed. + - and the grid type (CMIP6 only). - preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing - which preprocessor modules to apply, @@ -75,51 +73,52 @@ Please copy and paste the following recipe into your ESMValTool working area wit >## recipe_example.yml >~~~YAML -> # ESMValTool -> # recipe_example.yml -> --- -> documentation: -> description: Demonstrate basic ESMValTool example -> -> authors: -> - demora_lee -> - mueller_benjamin -> - swaminathan_ranjini -> -> maintainer: -> - demora_lee -> -> references: -> - demora2018gmd -> # Some plots also appear in ESMValTool paper 2. -> -> projects: -> - ukesm -> -> datasets: -> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} -> -> preprocessors: -> prep_timeseries: # For 0D fields -> annual_statistics: -> operator: mean -> -> diagnostics: -> # -------------------------------------------------- -> # Time series diagnostics -> # -------------------------------------------------- -> diag_timeseries_temperature: -> description: simple_time_series -> variables: -> timeseries_variable: -> short_name: thetaoga -> preprocessor: prep_timeseries -> scripts: -> timeseries_diag: -> script: ocean/diagnostic_timeseries.py +> 1 # ESMValTool +> 2 # recipe_example.yml +> 3 --- +> 4 documentation: +> 5 description: Demonstrate basic ESMValTool example +> 6 +> 7 authors: +> 8 - demora_lee +> 9 - mueller_benjamin +>10 - swaminathan_ranjini +>11 +>12 maintainer: +>13 - demora_lee +>14 +>15 references: +>16 - demora2018gmd +>17 # Some plots also appear in ESMValTool paper 2. +>18 +>19 projects: +>20 - ukesm +>21 +>22 datasets: +>23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +>24 +>25 preprocessors: +>26 prep_timeseries: # For 0D fields +>27 annual_statistics: +>28 operator: mean +>29 +>30 diagnostics: +>31 # -------------------------------------------------- +>32 # Time series diagnostics +>33 # -------------------------------------------------- +>34 diag_timeseries_temperature: +>35 description: simple_time_series +>36 variables: +>37 timeseries_variable: +>38 short_name: thetaoga +>39 preprocessor: prep_timeseries +>40 scripts: +>41 timeseries_diag: +>42 script: ocean/diagnostic_timeseries.py >~~~ {: .solution} + > ## Explore the recipe > Use the command and investigate the sample recipe. > ~~~ @@ -245,21 +244,26 @@ Each time you run the ESMValTool, it will produce a new output directory within ## Common issues & tips -### Esmvaltool not found -Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, epside [2] LINK. +> ## Esmvaltool not found +> Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, episode #2 LINK. +{: .solution} -### ESMValTool can’t locate the data -The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” -Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? +> ## ESMValTool can’t locate the data. The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” +> Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? +{: .solution} -### Diagnostic path problems -The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? +> ## Diagnostic path problems +> The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? +{: .solution} -### FX files not found. +> ## FX files not found +> +{: .solution} -### The preprocessor works but the diagnostic fails: -If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. +> ## The preprocessor works but the diagnostic fails +> If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. +{: .solution} -### Your recipe’s name/project/reference isn’t recognised by ESMValTool. -Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” -Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. +> ## Your recipe’s name/project/reference isn’t recognised by ESMValTool. Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” +> Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. +{: .solution} From 99a0c74584466ccb3e0706b6e08ca6bb8c16ea05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20M=C3=BCller?= Date: Mon, 29 Jun 2020 15:43:41 +0200 Subject: [PATCH 131/647] Update first_example_recipe.md corrects indents --- _episodes/first_example_recipe.md | 62 +++++++++++++++---------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 185ec0de..4e33ce98 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -27,31 +27,31 @@ This episode describes how ESMValTool recipes work, how to run a recipe and how Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. - datasets: what datasets you want to use, including - - the time range and time resolution, - - the MIP, ensemble member, - - the experiment (i.e. historical, ssp125 etc...), - - and the grid type (CMIP6 only). + - the time range and time resolution, + - the MIP, ensemble member, + - the experiment (i.e. historical, ssp125 etc...), + - and the grid type (CMIP6 only). - preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing - - which preprocessor modules to apply, - - the order to apply them, - - and the preprocessor arguments. + - which preprocessor modules to apply, + - the order to apply them, + - and the preprocessor arguments. - This section can also be optional, if no preprocessing is needed. + This section can also be optional, if no preprocessing is needed. - diagnostics: all the information about the diagnostic, including - - list of variables to evaluate (with their respective configurations), - - the desired diagnostic script to use, - - and additional diagnostic script options or arguments, if needed. + - list of variables to evaluate (with their respective configurations), + - the desired diagnostic script to use, + - and additional diagnostic script options or arguments, if needed. - Also Include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. + Also Include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. - description: a brief description of the recipe, including - - who wrote the recipe and who maintains it, - - which project is responsible for it, - - and which publications, references are linked with the recipe. + - who wrote the recipe and who maintains it, + - which project is responsible for it, + - and which publications, references are linked with the recipe. - Note that the authors, publications and references are to be named in the config-references.yml + Note that the authors, publications and references are to be named in the config-references.yml This information ... @@ -138,25 +138,25 @@ Please note the following sections: - projects: a list of projects (linked to esmvaltool/config-references.yml) - - datasets: lines 22-23 +- datasets: lines 22-23 - The dataset definition consists of a list of python dictionaries with the information on the datasets. - - dataset name (key: dataset) - - project (key: project) - - experiment (key: exp) - - mip (for CMIP data, key: mip) - - ensemble member (key: ensemble) - - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) - - model grid (for CMIP6 data only, key: grid) - - alias (key: alias; use the alias for e.g. a more human readable name) + The dataset definition consists of a list of python dictionaries with the information on the datasets. + - dataset name (key: dataset) + - project (key: project) + - experiment (key: exp) + - mip (for CMIP data, key: mip) + - ensemble member (key: ensemble) + - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) + - model grid (for CMIP6 data only, key: grid) + - alias (key: alias; use the alias for e.g. a more human readable name) - - preprocessors: lines 25-28 +- preprocessors: lines 25-28 - The definition for different preprocessors or combinations. - If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). - Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). - (See episode #5 LINK for more details.) + The definition for different preprocessors or combinations. + If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). + Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). + (See episode #5 LINK for more details.) - diagnostic section: lines 30-42 From 54ac881d362b9aef92267c890a2802470650764f Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 16:17:00 +0200 Subject: [PATCH 132/647] adds explanations and further reading --- _episodes/first_example_recipe.md | 33 +++++++++++++++++++------------ 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 4e33ce98..2af1b59b 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -16,7 +16,7 @@ objectives: keypoints: - "A recipe does not break by fiddling with it" - "Log information is useful when interpreting the first warnings/errors" -- "The dataset section in the recipe relates to Understanding the directory structure of CMIP data on your server/disk and knowing how to use data from different experiments such as CMIP/ScenarioMIP." +- "The dataset section resembles the filename or directory structure (e.g. CMIP subdirectories)." --- @@ -29,7 +29,7 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w - datasets: what datasets you want to use, including - the time range and time resolution, - the MIP, ensemble member, - - the experiment (i.e. historical, ssp125 etc...), + - the experiment (i.e. historical, ssp125, etc.), - and the grid type (CMIP6 only). - preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing @@ -44,7 +44,7 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w - the desired diagnostic script to use, - and additional diagnostic script options or arguments, if needed. - Also Include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. + Also include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. - description: a brief description of the recipe, including - who wrote the recipe and who maintains it, @@ -53,7 +53,8 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w Note that the authors, publications and references are to be named in the config-references.yml -This information ... +The information you provide in the recipe is not only affecting the processes you are starting, but also the directory names your output will be structured in. +For additional reeds, please have a look at the recipe format description in the [ESMValTool manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). ## How to run ESMValTool @@ -67,9 +68,9 @@ To try your hand with a basic recipe, please work through this episode. ## Introduction to the example recipe -Threcipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. +The recipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. -Please copy and paste the following recipe into your ESMValTool working area with the name: recipe_example.yml +Please download the following recipe into your ESMValTool working area with the name: recipe_example.yml LINK >## recipe_example.yml >~~~YAML @@ -205,7 +206,7 @@ Each time you run the ESMValTool, it will produce a new output directory within - plots > ## Inspect the output: -> Now that you have ran the esmvaltool command for the first time, please locate your output directory. +> Now that you have run the esmvaltool command for the first time, please locate your output directory. > If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true (this is used to save disk space). Please set this value to false and run the recipe again. > {: .challenge} @@ -230,16 +231,18 @@ Each time you run the ESMValTool, it will produce a new output directory within > - the dataset: > - mip, start_year, end_year > - the preprocessor: -> - These fields are all 2D fields, but thetaga was a 0D field. This means that we need to take the average over the latitude and longitude dimensions. To do this, add the area_statistics to the preprocessor. +> - These fields are all 2D fields, but thetaoga was a 0D field. This means that we need to take the average over the latitude and longitude dimensions. To do this, add the area_statistics to the preprocessor. > - the diagnostic > - change the short_name value (thetaoga) for another: > - Land surface average temperature (tsland) > - Atmospheric surface average temperature (tas) > - Ocean surface average temperature (tos) -> ### Advanced: +{: .challenge} + +> ## Advanced: > If you want to add a different field, please have a look here: > http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html -{: .challenge} +{: .callout} ## Common issues & tips @@ -248,22 +251,26 @@ Each time you run the ESMValTool, it will produce a new output directory within > Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, episode #2 LINK. {: .solution} -> ## ESMValTool can’t locate the data. The error message is “esmvalcore._recipe_checks.RecipeError: Missing data” +> ## ESMValTool can’t locate the data. The error message is `esmvalcore._recipe_checks.RecipeError: Missing data` > Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? {: .solution} + > ## Diagnostic path problems > The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? {: .solution} + > ## FX files not found -> +> There is no FX file for your corresponding dataset. Are your datasets’ names spelled correctly? Is there a FX file for this dataset? {: .solution} + > ## The preprocessor works but the diagnostic fails > If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. {: .solution} -> ## Your recipe’s name/project/reference isn’t recognised by ESMValTool. Error message is “ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml” + +> ## Your recipe’s name/project/reference isn’t recognised by ESMValTool. Error message is `ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml` > Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. {: .solution} From 4ca3be8811fe0a5197e3e7eadc766c1a9e136af2 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Mon, 29 Jun 2020 16:38:29 +0200 Subject: [PATCH 133/647] add solutions to most challenges FIXME is supposed to be done by someone who has access to JASMIN in order to have the correct solutions. --- _episodes/first_example_recipe.md | 181 ++++++++++++++++++++---------- 1 file changed, 124 insertions(+), 57 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 2af1b59b..d80b1d40 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -59,10 +59,11 @@ For additional reeds, please have a look at the recipe format description in the ## How to run ESMValTool Once you’ve set up your conda environment and installed ESMValTool (see episode #2 LINK) and set up your config-user.yml file to correctly match you local environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: -~~~ + +~~~source esmvaltool -c configuration recipe ~~~ -{: .source} + To try your hand with a basic recipe, please work through this episode. @@ -72,61 +73,60 @@ The recipe presented here is a simple, basic recipe that takes a single dataset Please download the following recipe into your ESMValTool working area with the name: recipe_example.yml LINK ->## recipe_example.yml ->~~~YAML -> 1 # ESMValTool -> 2 # recipe_example.yml -> 3 --- -> 4 documentation: -> 5 description: Demonstrate basic ESMValTool example -> 6 -> 7 authors: -> 8 - demora_lee -> 9 - mueller_benjamin ->10 - swaminathan_ranjini ->11 ->12 maintainer: ->13 - demora_lee ->14 ->15 references: ->16 - demora2018gmd ->17 # Some plots also appear in ESMValTool paper 2. ->18 ->19 projects: ->20 - ukesm ->21 ->22 datasets: ->23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} ->24 ->25 preprocessors: ->26 prep_timeseries: # For 0D fields ->27 annual_statistics: ->28 operator: mean ->29 ->30 diagnostics: ->31 # -------------------------------------------------- ->32 # Time series diagnostics ->33 # -------------------------------------------------- ->34 diag_timeseries_temperature: ->35 description: simple_time_series ->36 variables: ->37 timeseries_variable: ->38 short_name: thetaoga ->39 preprocessor: prep_timeseries ->40 scripts: ->41 timeseries_diag: ->42 script: ocean/diagnostic_timeseries.py ->~~~ +> ## recipe_example.yml +> ~~~YAML +> 1 # ESMValTool +> 2 # recipe_example.yml +> 3 --- +> 4 documentation: +> 5 description: Demonstrate basic ESMValTool example +> 6 +> 7 authors: +> 8 - demora_lee +> 9 - mueller_benjamin +> 10 - swaminathan_ranjini +> 11 +> 12 maintainer: +> 13 - demora_lee +> 14 +> 15 references: +> 16 - demora2018gmd +> 17 # Some plots also appear in ESMValTool paper 2. +> 18 +> 19 projects: +> 20 - ukesm +> 21 +> 22 datasets: +> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> 24 +> 25 preprocessors: +> 26 prep_timeseries: # For 0D fields +> 27 annual_statistics: +> 28 operator: mean +> 29 +> 30 diagnostics: +> 31 # -------------------------------------------------- +> 32 # Time series diagnostics +> 33 # -------------------------------------------------- +> 34 diag_timeseries_temperature: +> 35 description: simple_time_series +> 36 variables: +> 37 timeseries_variable: +> 38 short_name: thetaoga +> 39 preprocessor: prep_timeseries +> 40 scripts: +> 41 timeseries_diag: +> 42 script: ocean/diagnostic_timeseries.py +> ~~~ {: .solution} > ## Explore the recipe > Use the command and investigate the sample recipe. -> ~~~ +> ~~~bash > vim recipe_example.yml > ~~~ -> {: .source} -> +{: .challenge} Please note the following sections: - documentation: lines 4-20 @@ -174,16 +174,33 @@ Please note the following sections: - the next indent (here: timeseries_diag) is the scripts’ names (a string without whitespace) for the script to use - script: a executable script with a directory relative to the `esmvaltool/diag_scripts/` directory - -> What is the short_name of the variable being analysed? +> ## Please answer the following questions: +> What is the short_name of the variable being analyzed? > > What is the diagnostic script being used? > -> How many years of data are being analysed? +> How many years of data are being analyzed? > > What do you think running this recipe will produce? {: .challenge} + +> ## What is the short_name of the variable being analyzed? +> thetaoga - Global Average Sea Water Potential Temperature +{: .solution} + +> ## What is the diagnostic script being used? +> `ocean/diagnostic_timeseries.py` +{: .solution} + +> ## How many years of data are being analyzed? +> 1859 to 2005, that is 147 years. +{: .solution} + +> ## What do you think running this recipe will produce? +> A time series plot of thetaoga with increements of 1 year. +{: .solution} + > ## Not all parts of the recipe are mandatory > Some functionalities of the example recipe are mandatory, while others are not. E.g., if you miss any of the documentation information, the call will break. {: .callout} @@ -191,14 +208,17 @@ Please note the following sections: > ## Running ESMValTool > > Use the command: -> ~~~ +> ~~~bash > esmvaltool -c ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml > ~~~ -> {: .source} > > Follow the terminal guiding you through the subprocesses that are running. Can you find where the preprocessor and the diagnostic are starting? Which one took longer to process? {: .challenge} +> ## Exemplary output +> FIXME +{: .solution} + Each time you run the ESMValTool, it will produce a new output directory within your specified work directory with the name of the recipe and the tagged runtime. This folder should contain four folders: - run - work @@ -218,8 +238,31 @@ Each time you run the ESMValTool, it will produce a new output directory within > - Your settings.yml file. > - A metadata.yml file. > - The diagnostic log file. -{: .discussion} +{: .checklist} + +Exemplary output (depending on the directory paths and package versions that are available) can be found below: + +> ## Your output plot(s). +> FIXME (include plots) +{: .solution} + +> ## Your main output log file. +> FIXME (include example log) +{: .solution} + +> ## Your settings.yml file. +> FIXME (include the settings) +{: .solution} + +> ## A metadata.yml file. +> FIXME (include the metadata) +{: .solution} + +> ## The diagnostic log file. +> FIXME (include the diag log) +{: .solution} +## Do your first edits > ## Edit the recipe and run again > So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: @@ -239,6 +282,30 @@ Each time you run the ESMValTool, it will produce a new output directory within > - Ocean surface average temperature (tos) {: .challenge} +The snippets for the edits can be found below: + +> ## Land surface average temperature +> FIXME (include line numbers, see below) +> ~~~YAML +> ... +> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> ... +> 27 annual_statistics: +> 28 operator: mean +> ... +> 38 short_name: thetaoga +> 39 preprocessor: prep_timeseries +> ~~~~ +{: .solution} + +> ## Atmospheric surface average temperature +> FIXME +{: .solution} + +> ## Ocean surface average temperature +> FIXME +{: .solution} + > ## Advanced: > If you want to add a different field, please have a look here: > http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html @@ -247,7 +314,7 @@ Each time you run the ESMValTool, it will produce a new output directory within ## Common issues & tips -> ## Esmvaltool not found +> ## esmvaltool not found > Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, episode #2 LINK. {: .solution} From 42fa29cae2bbe0f29747ef27d0f4954c7f778fb5 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 30 Jun 2020 09:02:54 +0200 Subject: [PATCH 134/647] remove three dots --- _episodes/03-configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 6fb0995d..9ad716f5 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -97,7 +97,7 @@ We add the root path of the folder where our/your data is available. > - To get the data (or its correct rootpath), check instruction in [Setup]({{ page.root }}{% link setup.md %}). > - For more information about setting the rootpath, see also the ESMValTool -For more information about setting the roothpath, see also ESMValTool... +For more information about setting the roothpath, see also ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} From ad1c9ad465b6b0741dba656c81e030ca9708d4f3 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Tue, 30 Jun 2020 09:18:39 +0200 Subject: [PATCH 135/647] solve codacy issues --- _episodes/first_example_recipe.md | 129 ++++++++++++++---------------- 1 file changed, 59 insertions(+), 70 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index d80b1d40..30fd7d08 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -1,5 +1,4 @@ --- - title: "Running a recipe (First example)" teaching: 20 exercises: 25 @@ -16,8 +15,7 @@ objectives: keypoints: - "A recipe does not break by fiddling with it" - "Log information is useful when interpreting the first warnings/errors" -- "The dataset section resembles the filename or directory structure (e.g. CMIP subdirectories)." - +- "The dataset section resembles the filename or directory structure (e.g. CMIP subdirectories)" --- This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. @@ -26,32 +24,32 @@ This episode describes how ESMValTool recipes work, how to run a recipe and how Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. -- datasets: what datasets you want to use, including - - the time range and time resolution, - - the MIP, ensemble member, - - the experiment (i.e. historical, ssp125, etc.), - - and the grid type (CMIP6 only). + - datasets: what datasets you want to use, including + - the time range and time resolution, + - the MIP, ensemble member, + - the experiment (i.e. historical, ssp125, etc.), + - and the grid type (CMIP6 only). -- preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing - - which preprocessor modules to apply, - - the order to apply them, - - and the preprocessor arguments. + - preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing + - which preprocessor modules to apply, + - the order to apply them, + - and the preprocessor arguments. - This section can also be optional, if no preprocessing is needed. + This section can also be optional, if no preprocessing is needed. -- diagnostics: all the information about the diagnostic, including - - list of variables to evaluate (with their respective configurations), - - the desired diagnostic script to use, - - and additional diagnostic script options or arguments, if needed. + - diagnostics: all the information about the diagnostic, including + - list of variables to evaluate (with their respective configurations), + - the desired diagnostic script to use, + - and additional diagnostic script options or arguments, if needed. - Also include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. + Also include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. -- description: a brief description of the recipe, including - - who wrote the recipe and who maintains it, - - which project is responsible for it, - - and which publications, references are linked with the recipe. + - description: a brief description of the recipe, including + - who wrote the recipe and who maintains it, + - which project is responsible for it, + - and which publications, references are linked with the recipe. - Note that the authors, publications and references are to be named in the config-references.yml + Note that the authors, publications and references are to be named in the config-references.yml The information you provide in the recipe is not only affecting the processes you are starting, but also the directory names your output will be structured in. For additional reeds, please have a look at the recipe format description in the [ESMValTool manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). @@ -64,10 +62,8 @@ Once you’ve set up your conda environment and installed ESMValTool (see episod esmvaltool -c configuration recipe ~~~ - To try your hand with a basic recipe, please work through this episode. - ## Introduction to the example recipe The recipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. @@ -120,7 +116,6 @@ Please download the following recipe into your ESMValTool working area with the > ~~~ {: .solution} - > ## Explore the recipe > Use the command and investigate the sample recipe. > ~~~bash @@ -129,50 +124,50 @@ Please download the following recipe into your ESMValTool working area with the {: .challenge} Please note the following sections: -- documentation: lines 4-20 + - documentation: lines 4-20 - The documentation consists of the following information: - - description: a short description of the recipe - - authors: a list of authors (linked to esmvaltool/config-references.yml) - - maintainer: a list of maintainers (linked to esmvaltool/config-references.yml) - - references: a list of references (linked to a bibtexfile in esmvaltool/references with the same name) - - projects: a list of projects (linked to esmvaltool/config-references.yml) + The documentation consists of the following information: + - description: a short description of the recipe + - authors: a list of authors (linked to esmvaltool/config-references.yml) + - maintainer: a list of maintainers (linked to esmvaltool/config-references.yml) + - references: a list of references (linked to a bibtexfile in esmvaltool/references with the same name) + - projects: a list of projects (linked to esmvaltool/config-references.yml) -- datasets: lines 22-23 + - datasets: lines 22-23 - The dataset definition consists of a list of python dictionaries with the information on the datasets. - - dataset name (key: dataset) - - project (key: project) - - experiment (key: exp) - - mip (for CMIP data, key: mip) - - ensemble member (key: ensemble) - - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) - - model grid (for CMIP6 data only, key: grid) - - alias (key: alias; use the alias for e.g. a more human readable name) + The dataset definition consists of a list of python dictionaries with the information on the datasets. + - dataset name (key: dataset) + - project (key: project) + - experiment (key: exp) + - mip (for CMIP data, key: mip) + - ensemble member (key: ensemble) + - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) + - model grid (for CMIP6 data only, key: grid) + - alias (key: alias; use the alias for e.g. a more human readable name) -- preprocessors: lines 25-28 + - preprocessors: lines 25-28 - The definition for different preprocessors or combinations. - If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). - Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). - (See episode #5 LINK for more details.) + The definition for different preprocessors or combinations. + If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). + Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). + (See episode #5 LINK for more details.) -- diagnostic section: lines 30-42 + - diagnostic section: lines 30-42 - The information of which diagnostic script to run with which variables. - The diagnostics section has some indents that are free to call. - - the first indent (here: diag_timeseries_temperature) is the diagnostic’s name (a string without whitespace), used for setting up the respective directories - - description: a short description of the diagnostic - - variables: a definition of all variables that are used in this diagnostic - - the next indent (here: timeseries_variable) is the variables’ names (a string without whitespace) for the diagnostic to use - - short_name: the variable name as listed in the dataset - - preprocessor: the preprocessor(s) applied to the variable before running the diagnostic - - scripts: a definition of all scripts that are used in this diagnostic - - the next indent (here: timeseries_diag) is the scripts’ names (a string without whitespace) for the script to use - - script: a executable script with a directory relative to the `esmvaltool/diag_scripts/` directory + The information of which diagnostic script to run with which variables. + The diagnostics section has some indents that are free to call. + - the first indent (here: diag_timeseries_temperature) is the diagnostic’s name (a string without whitespace), used for setting up the respective directories + - description: a short description of the diagnostic + - variables: a definition of all variables that are used in this diagnostic + - the next indent (here: timeseries_variable) is the variables’ names (a string without whitespace) for the diagnostic to use + - short_name: the variable name as listed in the dataset + - preprocessor: the preprocessor(s) applied to the variable before running the diagnostic + - scripts: a definition of all scripts that are used in this diagnostic + - the next indent (here: timeseries_diag) is the scripts’ names (a string without whitespace) for the script to use + - script: a executable script with a directory relative to the `esmvaltool/diag_scripts/` directory > ## Please answer the following questions: > What is the short_name of the variable being analyzed? @@ -184,7 +179,6 @@ Please note the following sections: > What do you think running this recipe will produce? {: .challenge} - > ## What is the short_name of the variable being analyzed? > thetaoga - Global Average Sea Water Potential Temperature {: .solution} @@ -220,10 +214,10 @@ Please note the following sections: {: .solution} Each time you run the ESMValTool, it will produce a new output directory within your specified work directory with the name of the recipe and the tagged runtime. This folder should contain four folders: -- run -- work -- preproc -- plots + - run + - work + - preproc + - plots > ## Inspect the output: > Now that you have run the esmvaltool command for the first time, please locate your output directory. @@ -311,7 +305,6 @@ The snippets for the edits can be found below: > http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html {: .callout} - ## Common issues & tips > ## esmvaltool not found @@ -322,22 +315,18 @@ The snippets for the edits can be found below: > Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? {: .solution} - > ## Diagnostic path problems > The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? {: .solution} - > ## FX files not found > There is no FX file for your corresponding dataset. Are your datasets’ names spelled correctly? Is there a FX file for this dataset? {: .solution} - > ## The preprocessor works but the diagnostic fails > If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. {: .solution} - > ## Your recipe’s name/project/reference isn’t recognised by ESMValTool. Error message is `ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml` > Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. {: .solution} From 8f5a77542296022cf720ac5ee9e306399e786e55 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 30 Jun 2020 09:43:41 +0200 Subject: [PATCH 136/647] codacy new things --- _episodes/01-introduction.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 10bc28ab..de1c8eea 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -3,22 +3,21 @@ title: "Introduction" teaching: 0 exercises: 25 questions: -- What is ESMValTool and when is it useful? -- What are the main components of ESMValTool? -- How does ESMValTool contribute to FAIR climate research? -- What is the role of the ESMValTool community? + - What is ESMValTool and when is it useful? + - What are the main components of ESMValTool? + - How does ESMValTool contribute to FAIR climate research? + - What is the role of the ESMValTool community? objectives: -- Describe key strengths and weaknesses of ESMValTool -- Know the different components of ESMValTool -- Understand the concept of a community-driven software project -- + - Describe key strengths and weaknesses of ESMValTool + - Know the different components of ESMValTool + - Understand the concept of a community-driven software project keypoints: -- ESMValTool provides a reliable interface to analyse and evaluate climate data -- Using ESMValTool promotes standardization, collaboration, and reuse -- ESMValTool is built and maintained by an active community of scientists and developers -- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages + - ESMValTool provides a reliable interface to analyse and evaluate climate data + - Using ESMValTool promotes standardization, collaboration, and reuse + - ESMValTool is built and maintained by an active community of scientists and developers + - ESMValTool is written in Python, but supports diagnostic scripts in multiple languages --- From 3a4e93f568a20b12ed3a69d820f0f8e4fea3b8ae Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 30 Jun 2020 10:11:21 +0200 Subject: [PATCH 137/647] Does this solve codacy? --- _episodes/01-introduction.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index de1c8eea..661b7871 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -3,21 +3,21 @@ title: "Introduction" teaching: 0 exercises: 25 questions: - - What is ESMValTool and when is it useful? - - What are the main components of ESMValTool? - - How does ESMValTool contribute to FAIR climate research? - - What is the role of the ESMValTool community? +- What is ESMValTool and when is it useful? +- What are the main components of ESMValTool? +- How does ESMValTool contribute to FAIR climate research? +- What is the role of the ESMValTool community? objectives: - - Describe key strengths and weaknesses of ESMValTool - - Know the different components of ESMValTool - - Understand the concept of a community-driven software project +- Describe key strengths and weaknesses of ESMValTool +- Know the different components of ESMValTool +- Understand the concept of a community-driven software project keypoints: - - ESMValTool provides a reliable interface to analyse and evaluate climate data - - Using ESMValTool promotes standardization, collaboration, and reuse - - ESMValTool is built and maintained by an active community of scientists and developers - - ESMValTool is written in Python, but supports diagnostic scripts in multiple languages +- ESMValTool provides a reliable interface to analyse and evaluate climate data +- Using ESMValTool promotes standardization, collaboration, and reuse +- ESMValTool is built and maintained by an active community of scientists and developers +- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages --- From 6b76571ea6e29997f72fdccb572d84e0070082bc Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 30 Jun 2020 10:19:01 +0200 Subject: [PATCH 138/647] Codacy sucks --- _episodes/01-introduction.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 661b7871..fd08a3ed 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -3,21 +3,21 @@ title: "Introduction" teaching: 0 exercises: 25 questions: -- What is ESMValTool and when is it useful? -- What are the main components of ESMValTool? -- How does ESMValTool contribute to FAIR climate research? -- What is the role of the ESMValTool community? +- What is ESMValTool and when is it useful? +- What are the main components of ESMValTool? +- How does ESMValTool contribute to FAIR climate research? +- What is the role of the ESMValTool community? objectives: -- Describe key strengths and weaknesses of ESMValTool -- Know the different components of ESMValTool -- Understand the concept of a community-driven software project +- Describe key strengths and weaknesses of ESMValTool +- Know the different components of ESMValTool +- Understand the concept of a community-driven software project keypoints: -- ESMValTool provides a reliable interface to analyse and evaluate climate data -- Using ESMValTool promotes standardization, collaboration, and reuse -- ESMValTool is built and maintained by an active community of scientists and developers -- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages +- ESMValTool provides a reliable interface to analyse and evaluate climate data +- Using ESMValTool promotes standardization, collaboration, and reuse +- ESMValTool is built and maintained by an active community of scientists and developers +- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages --- From cfbc4f922d860db7b522eb87494cfc2f13844c35 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 30 Jun 2020 10:43:26 +0200 Subject: [PATCH 139/647] add more text about projects, fix minor issue, change the instruction about working directory --- _episodes/03-configuration.md | 40 +++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 9ad716f5..9ce69945 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -3,17 +3,18 @@ title: "Configuration" teaching: 0 exercises: 0 questions: -- "What is the user configuration file and how should I use it?" +- What is the user configuration file and how should I use it? objectives: -- "Understand the contents of the user-config.yml file" -- "Prepare a personalized user-config.yml file" -- "Configure ESMValTool to use some settings" +- Understand the contents of the user-config.yml file +- Prepare a personalized user-config.yml file +- Configure ESMValTool to use some settings keypoints: -- "The ``config-user.yml`` tells ESMValTool where to find input data." -- " ``rootpath`` defines the root directory for the input data." -- " ``output_dir`` defines the destination directory." +- The ``config-user.yml`` tells ESMValTool where to find input data. +- "``rootpath`` defines the root directory for the input data." +- "``output_dir`` defines the destination directory." + --- ## The configuration file @@ -24,8 +25,15 @@ needed by ESMValTool to run. This is an can be found in the root directory of the ESMValTool repository: [config-user-example.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). -Let's download it to our working directory ``esmvaltool_tutorial`` -that was created during the [Setup]({{ page.root }}{% link setup.md %}). +First, we make a working directory ``esmvaltool_tutorial``. +In a new terminal, run: + +~~~bash + mkdir esmvaltool_tutorial + cd esmvaltool_tutorial +~~~ + +Now, we download the configuration file to our working directory. To do that, click on [this link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) to see a raw version of the file, right-click and press ``save as``, @@ -36,7 +44,6 @@ Now, let's change our working directory in a terminal window to ``esmvaltool_tut Then, we run a text editor called Nano to have a look inside the configuration file: ~~~bash - cd esmvaltool_tutorial nano config-user.yml ~~~ @@ -52,11 +59,11 @@ This file contains the information for: > ## Text editor side note > > No matter what editor you use, you will need to know where it searches -for and saves files. If you start it from the shell, it will (probably) -use your current working directory as its default location. We use ``nano`` -in examples here because it is one of the least complex text editors. -Press ctrl + O to save the file, -and then ctrl + X to exit ``nano``. +> for and saves files. If you start it from the shell, it will (probably) +> use your current working directory as its default location. We use ``nano`` +> in examples here because it is one of the least complex text editors. +> Press ctrl + O to save the file, +> and then ctrl + X to exit ``nano``. {: .callout} ## Rootpath to input data @@ -65,6 +72,8 @@ ESMValTool uses several categories (in ESMValTool, this is referred to as projec for input data based on their source. The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from the climate model intercomparison project whereas OBS is used for an observational dataset. +We can find more information about the projects in the ESMValTool +[documentation](https://docs.esmvaltool.org/en/latest/input.html). The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. @@ -97,7 +106,6 @@ We add the root path of the folder where our/your data is available. > - To get the data (or its correct rootpath), check instruction in [Setup]({{ page.root }}{% link setup.md %}). > - For more information about setting the rootpath, see also the ESMValTool -For more information about setting the roothpath, see also ESMValTool [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} From 726835a632869bb4cd92ab9e74f547375b21de2a Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 09:56:33 +0100 Subject: [PATCH 140/647] addressed several issues raised in the review --- index.md | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/index.md b/index.md index bb2445b1..97ddb8c1 100644 --- a/index.md +++ b/index.md @@ -4,7 +4,12 @@ root: . # Is the only page that doesn't follow the pattern /:path/index.html permalink: index.html # Is the only page that doesn't follow the pattern /:path/index.html --- -This tutorial is built to teach you ESMValTool. +This tutorial is built to teach you how to use ESMValTool. + +The Earth System Model Evaluation Tool (ESMValTool) is a community developped software toolkit that aims to faciliate +the diagnosis and evaluation of the causes and effects of model biases and inter-model spread within the CMIP model +ensemble. + > ## What will you learn in this course > @@ -22,11 +27,15 @@ This tutorial is built to teach you ESMValTool. > ## Prerequisites > -> Basic understanding of git (optional - but useful) -> Basic understanding of your preferred command line interface (ie a bash terminal) -> Access to CMIP data -> Access to a suitable computing system (eg Jasmin) -> Github account (optional, but useful!) +> - Basic understanding of git (optional - but useful) +> +> - Basic understanding of your preferred command line interface (ie a bash terminal) +> +> - Access to CMIP data +> +> - Access to a suitable computing system (eg Jasmin) +> +> - Github account (optional, but useful!) {: .prereq} > ## Main things you need to know before starting this course @@ -41,17 +50,16 @@ This tutorial is built to teach you ESMValTool. > ## Additional resources: -> -> - Read the docs page: https://esmvaltool.readthedocs.io/ -> - ESMValTool home page: https://www.esmvaltool.org/ -> - Technical description paper: https://doi.org/10.5194/gmd-13-1179-2020 -> - Source code (ESMValTool): https://github.com/ESMValGroup/ESMValTool -> - Source code (ESMValCore ): https://github.com/ESMValGroup/ESMValCore +> - [Read the docs page](https://esmvaltool.readthedocs.io/) +> - [ESMValTool home page](https://www.esmvaltool.org/) +> - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) +> - [Source code (ESMValTool)](https://github.com/ESMValGroup/ESMValTool) +> - [Source code (ESMValCore )](https://github.com/ESMValGroup/ESMValCore) {: .callout} - +## Citation Please cite this tutorial as: -ESMVAlTool 2.0 tutorial, website, version [ADD AUTO VERSION?] +ESMVAlTool 2.0 tutorial, ESMValtool developpers, version [ADD VERSION], https://github.com/ESMValGroup/tutorial/, '`r format(Sys.Date(), "%B %d, %Y")`'. From bbfde053634ac937bfd74e993924763473356850 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 11:01:12 +0200 Subject: [PATCH 141/647] Made local Codacy analysis happy --- _episodes/02-installation.md | 59 ++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index a4bac607..bab775d2 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -29,47 +29,43 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the ### Linux -1. Please download Miniconda3 for Linux at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. +1. Please download Miniconda3 for Linux at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. -2. Next, run the installer +1. Next, run the installer - ~~~ + ```bash bash Miniconda3-latest-Linux-x86_64.sh - ~~~ - {:.language-bash} + ``` -3. Follow the instructions in the installer. The defaults should normally suffice. +1. Follow the instructions in the installer. The defaults should normally suffice. -4. You will need to restart your terminal for the changes to have effect. +1. You will need to restart your terminal for the changes to have effect. -5. Verify you have a working conda installation by listing all installed packages +1. Verify you have a working conda installation by listing all installed packages - ~~~ + ```bash conda list - ~~~ - {:.language-bash} + ``` ### MacOSX -1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). +1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). -2. Next, run the installer +1. Next, run the installer - ~~~ + ```bash bash Miniconda3-latest-MacOSX-x86_64.sh - ~~~ - {:.language-bash} + ``` -3. Follow the instructions in the installer. The defaults should normally suffice. +1. Follow the instructions in the installer. The defaults should normally suffice. -4. You will need to restart your terminal for the changes to have effect. +1. You will need to restart your terminal for the changes to have effect. -5. Verify you have a working conda installation by listing all installed packages +1. Verify you have a working conda installation by listing all installed packages - ~~~ + ```bash conda list - ~~~ - {:.language-bash} + ```` ### Windows @@ -85,46 +81,60 @@ Complete instructions for installing Julia can be found on the [Julia installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). In this tutorial, we will use the following steps. First, open a bash terminal and create a directory to install Julia in + ```bash mkdir ~/julia ``` + Next, download the file [`julia-1.0.5-linux-x86_64.tar.gz`](https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz) by clicking the link or going to the [Julia downloads page](https://julialang.org/downloads/). To extract the file, you can use the following command: + ```bash tar -xvzf ~/Downloads/julia-1.0.5-linux-x86\_64.tar.gz -C ~/julia ``` + This will extract the files to a folder named `~/julia/julia-1.0.5`. To run Julia, you need to add the full path of Julia's `bin` folder to PATH environment variable. To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. Open the file in your favorite editor and add a new line as follows at the bottom of the file: + ```bash export PATH="$PATH:$HOME/julia/julia-1.0.5/bin" ``` + Finally, for the settings to take effect, either reload your bash profile + ```bash source ~/.bashrc ``` + (or `source ~/.bash_profile`), or close the bash terminal window and open a new one. To check that the Julia executable can be found, run + ```bash which julia ``` + to display the path to the Julia executable, it should be `~/julia/julia-1.0.5/bin/julia`. To test that Julia is installed correctly, run + ```bash julia ``` + to start the interactive Julia interpreter. Press `Ctrl+D` to exit. ## Install the ESMValTool package To install the ESMValTool package, run + ```bash conda create -n esmvaltool -c conda-forge -c esmvalgroup esmvaltool ``` + This will create a new [Conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) called `esmvaltool`, with the ESMValTool package and all of its dependencies installed in it. @@ -132,16 +142,21 @@ called `esmvaltool`, with the ESMValTool package and all of its dependencies ins ## Test that the installation was successful To test that the installation was successful, run + ```bash conda activate esmvaltool ``` + to activate the conda environment called `esmvaltool`. Next, run + ```bash esmvaltool --help ``` + to display the command line help. To find the location where the ESMValTool package was installed on your system, run + ```bash python -c 'import esmvaltool; print(esmvaltool.__path__[0])' ``` From 4f33bc91a5f6f9e48f8e05dc91236e136afb2ae5 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 10:08:07 +0100 Subject: [PATCH 142/647] Added further details. --- index.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/index.md b/index.md index 97ddb8c1..cade60bf 100644 --- a/index.md +++ b/index.md @@ -2,6 +2,7 @@ layout: lesson root: . # Is the only page that doesn't follow the pattern /:path/index.html permalink: index.html # Is the only page that doesn't follow the pattern /:path/index.html +date: '`r format(Sys.time(), "%d %B, %Y")`' --- This tutorial is built to teach you how to use ESMValTool. @@ -59,7 +60,19 @@ ensemble. ## Citation Please cite this tutorial as: -ESMVAlTool 2.0 tutorial, ESMValtool developpers, version [ADD VERSION], https://github.com/ESMValGroup/tutorial/, '`r format(Sys.Date(), "%B %d, %Y")`'. +- ESMVAlTool 2.0 tutorial, ESMValtool developpers, version [ADD VERSION], + https://github.com/ESMValGroup/tutorial/, + $date. + +Please cite ESMValTool as: + +- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., + Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., + Weigel, K., and Zechlau, S.: + Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for + emergent constraints and future projections from Earth system models in CMIP, + Geosci. Model Dev. Discuss., + https://doi.org/10.5194/gmd-2020-60, in review, 2020. From 52f707e63ba25e419c58eb8800d0a3a8b7cc5e58 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:09:51 +0200 Subject: [PATCH 143/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 6bf648bd..1fe407a3 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -16,7 +16,7 @@ The good news is, ``ESMValTool`` creates a record of the output messages and sto They can be used for debugging or monitoring the process. This lesson helps to understand what the different types of errors are and when you are likely to encounter them. -## log files +## Log files Each time we run the ESMValTool, it will produce a new output directory. This directory should contain the ``run`` folder that is automatically generated by ESMValTool. From ef59966f61c9154dab24ce28d5f71803a22476b7 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:09:59 +0200 Subject: [PATCH 144/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 1fe407a3..f8259a4d 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -12,7 +12,7 @@ keypoints: Every user encounters errors. Once you know why you get certain types of errors, they become much easier to fix. -The good news is, ``ESMValTool`` creates a record of the output messages and stores them in log files. +The good news is, ESMValTool creates a record of the output messages and stores them in log files. They can be used for debugging or monitoring the process. This lesson helps to understand what the different types of errors are and when you are likely to encounter them. From a3ba10fce3c48a68441e0f2253dd0f1e1c15ac56 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:10:09 +0200 Subject: [PATCH 145/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index f8259a4d..b6aa9b07 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -18,7 +18,7 @@ This lesson helps to understand what the different types of errors are and when ## Log files -Each time we run the ESMValTool, it will produce a new output directory. +Each time we run ESMValTool, it will produce a new output directory. This directory should contain the ``run`` folder that is automatically generated by ESMValTool. To examine this, we run an example recipe that can be found in: [recipe_example.yml](link). From 60dd4dd62609287b476725227198f3768989ea27 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:10:34 +0200 Subject: [PATCH 146/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index b6aa9b07..8878cab9 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -64,7 +64,7 @@ main_log_debug.txt main_log.txt recipe_example.yml resource_usage.txt ~~~ {: .output} -In the ``main_log_debug.txt`` and ``main_log.txt``, ESMValTool tells us the output messages, +In the ``main_log_debug.txt`` and ``main_log.txt``, ESMValTool writes the output messages, warnings and possible errors that might happen during pre-processings. To inspect them, we can look inside the files. For example: From 1ac19d904576ffe674645a174abcdfe21d7794c4 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:10:50 +0200 Subject: [PATCH 147/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 8878cab9..7cbf82f6 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -210,10 +210,10 @@ What suggestions would you give the researcher for fixing the error? > >> ## Solution >> ->> 1. inspect the ``main_log.txt`` ->> 2. check the user-config.yml to see if the correct directory for input data is introduced. ->> 3. check the available data, regarding exp, mip, ensemble, start_year, and end_year ->> 4. check the variable name in the ``diag_timeseries_temperature`` section in the recipe. +>> 1. Inspect ``main_log.txt`` +>> 2. Check ``user-config.yml`` to see if the correct directory for input data is introduced +>> 3. Check the available data, regarding exp, mip, ensemble, start_year, and end_year +>> 4. Check the variable name in the ``diag_timeseries_temperature`` section in the recipe > {: .solution} {: .challenge} From 6a1b4edded8821204176ff3690bc580d0de3adb8 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:11:19 +0200 Subject: [PATCH 148/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 7cbf82f6..ebcce97d 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -224,7 +224,7 @@ save the pre-processed data. More information about this setting can be found at [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}) {: .callout} -The result of the pre-processors is passed to the ``diagnostic_timeseries.py`` script, +The result of the pre-processor is passed to the ``diagnostic_timeseries.py`` script, that is introduced in the recipe as: ~~~YAML From f88732e65ddde603feeaf3dc17e7234c046c9df3 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:12:42 +0200 Subject: [PATCH 149/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index ebcce97d..f2643f8c 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -84,7 +84,7 @@ What are their differences? > >> ## Solution >> ->> The ``main_log_debug.txt`` contains the output messages from the pr-processors whereas +>> The ``main_log_debug.txt`` contains the output messages from the pre-processor whereas the ``main_log.txt`` shows general errors and warnings that might happen in running the recipe and diagnostics script. > {: .solution} {: .challenge} From 757b18d92f349fce138d6599219a39c1a5adb010 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:13:04 +0200 Subject: [PATCH 150/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index f2643f8c..d93ff348 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -90,7 +90,7 @@ the ``main_log.txt`` shows general errors and warnings that might happen in runn {: .challenge} Let's change some settings in the recipe to run a regional pre-processor. -We run a text editor called ``Nano`` to open the recipe file: +We use a text editor called ``nano`` to open the recipe file: ~~~bash cd esmvaltool_tutorial From 8b2ee8277125c14419e90296efecb980dd683b61 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:13:40 +0200 Subject: [PATCH 151/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index d93ff348..de7f6f46 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -155,6 +155,7 @@ and then ctrl + X to exit ``nano``. {: .solution} We change the ``projects`` value ``ukesm`` to ``tutorial``: + ~~~YAML 19 projects: 20 - tutorial From c6ad30deee4d93eab253dfbd1d40c3209bd788ac Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:14:41 +0200 Subject: [PATCH 152/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index de7f6f46..be53d439 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -198,7 +198,7 @@ like time manipulation, area manipulation, land-sea masking, variable derivation > ## ESMValTool can’t locate the data > -> You are assisting a researcher with ``ESMValTool``. The researcher changes the ``project`` entry to ``CMIP6`` +> You are assisting a colleague with ESMValTool. The colleague changes the ``project`` entry to ``CMIP6`` and runs the recipe. However, ESMValTool encounters an error like: > ~~~bash From 603b6ae2a793876ed40078f8b2b0ee0b53097782 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:15:07 +0200 Subject: [PATCH 153/647] Update _episodes/06-debugging.md Co-authored-by: Peter Kalverla --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index be53d439..97f136e2 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -202,7 +202,7 @@ like time manipulation, area manipulation, land-sea masking, variable derivation and runs the recipe. However, ESMValTool encounters an error like: > ~~~bash - esmvalcore._recipe_checks.RecipeError: Missing data +esmvalcore._recipe_checks.RecipeError: Missing data 2020-06-29 17:26:41,303 UTC [43830] INFO If you suspect this is a bug or need help, please open an issue on https://github.com/ESMValGroup/ESMValTool/issues and attach the run/recipe_*.yml and run/main_log_debug.txt files from the output directory. From 95d801b41a7e0ec8e6e5450ab6cdb16b8dd28549 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 10:32:14 +0100 Subject: [PATCH 154/647] Added more introduction and more to the what you will learn column --- index.md | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/index.md b/index.md index cade60bf..e422629f 100644 --- a/index.md +++ b/index.md @@ -12,31 +12,37 @@ the diagnosis and evaluation of the causes and effects of model biases and inter ensemble. +This tutorial is structured such that the main body of the tutorial, up to the episode 7, can be done in one sitting. +From there, there are several mini-tutorials which each covers one aspect of working with ESMValTool. +These mini-tutorials can be appended to the main tutorial or worked through independently. + > ## What will you learn in this course > > - What is ESMValTool > > - How to install ESMValTool -> +> - How to configure ESMValTool for your local system > - How to run ESMValTool -> -> - How to develop your own diagnostics and recipes -> -> - How to contribute your recipes and diagnostics back into ESMValTool +> - How to work with ESMValTool's suite of preprocessors +> - How to debug your recipes +> - How to access and deploy recipes from the ESMValTools gallery (Advanced) +> - How to develop your own diagnostics and recipes (Advanced) +> - How to contribute your recipes and diagnostics back into ESMValTool (Advanced) +> - How to include new observational datasets (Advanced) > {: .checklist} > ## Prerequisites > -> - Basic understanding of git (optional - but useful) +> - Basic understanding of git (optional) > -> - Basic understanding of your preferred command line interface (ie a bash terminal) +> - Basic understanding of your preferred command line interface (ie a bash terminal) > -> - Access to CMIP data +> - Access to CMIP data > -> - Access to a suitable computing system (eg Jasmin) +> - Access to a suitable computing system (eg Jasmin, DLR machine) > -> - Github account (optional, but useful!) +> - Github account (optional) {: .prereq} > ## Main things you need to know before starting this course @@ -59,10 +65,11 @@ ensemble. {: .callout} ## Citation + Please cite this tutorial as: - ESMVAlTool 2.0 tutorial, ESMValtool developpers, version [ADD VERSION], - https://github.com/ESMValGroup/tutorial/, + [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), $date. Please cite ESMValTool as: @@ -73,6 +80,7 @@ Please cite ESMValTool as: Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for emergent constraints and future projections from Earth system models in CMIP, Geosci. Model Dev. Discuss., - https://doi.org/10.5194/gmd-2020-60, in review, 2020. + [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), + in review, 2020. From f71aeda5fe8c78c4950c1388827e0464d18fb8b9 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 10:35:44 +0100 Subject: [PATCH 155/647] Update index.md Co-authored-by: Jaro Camphuijsen --- index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.md b/index.md index e422629f..3adc4e8d 100644 --- a/index.md +++ b/index.md @@ -68,7 +68,7 @@ These mini-tutorials can be appended to the main tutorial or worked through inde Please cite this tutorial as: -- ESMVAlTool 2.0 tutorial, ESMValtool developpers, version [ADD VERSION], +- ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), $date. @@ -83,4 +83,3 @@ Please cite ESMValTool as: [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), in review, 2020. - From 5a0b03faba0d1025e0e28d1e8499ff91b8200427 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 10:36:09 +0100 Subject: [PATCH 156/647] Update index.md --- index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.md b/index.md index 3adc4e8d..0a9f449e 100644 --- a/index.md +++ b/index.md @@ -70,7 +70,7 @@ Please cite this tutorial as: - ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), - $date. + [DATE]. Please cite ESMValTool as: @@ -82,4 +82,3 @@ Please cite ESMValTool as: Geosci. Model Dev. Discuss., [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), in review, 2020. - From f6bf780ef08af56d7ea13a20ebc0499596dbdc17 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 11:37:29 +0200 Subject: [PATCH 157/647] Added callout for common issues --- _episodes/02-installation.md | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index bab775d2..274acf89 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -29,19 +29,19 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the ### Linux -1. Please download Miniconda3 for Linux at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. +1. Please download Miniconda3 for Linux at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. -1. Next, run the installer +2. Next, run the installer ```bash bash Miniconda3-latest-Linux-x86_64.sh ``` -1. Follow the instructions in the installer. The defaults should normally suffice. +3. Follow the instructions in the installer. The defaults should normally suffice. -1. You will need to restart your terminal for the changes to have effect. +4. You will need to restart your terminal for the changes to have effect. -1. Verify you have a working conda installation by listing all installed packages +5. Verify you have a working conda installation by listing all installed packages ```bash conda list @@ -49,19 +49,19 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the ### MacOSX -1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). +1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). -1. Next, run the installer +2. Next, run the installer ```bash bash Miniconda3-latest-MacOSX-x86_64.sh ``` -1. Follow the instructions in the installer. The defaults should normally suffice. +3. Follow the instructions in the installer. The defaults should normally suffice. -1. You will need to restart your terminal for the changes to have effect. +4. You will need to restart your terminal for the changes to have effect. -1. Verify you have a working conda installation by listing all installed packages +5. Verify you have a working conda installation by listing all installed packages ```bash conda list @@ -139,6 +139,18 @@ This will create a new [Conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) called `esmvaltool`, with the ESMValTool package and all of its dependencies installed in it. +> ## Conda common problems +> +> Below are some common problems that could happen while installing. +> +> - installation takes long time, +> - downloads and compilations can take several minutes to complete, please be patient +> - you might have bad luck and the dependencies can not be resolved at the moment, please try again later or [raise an issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose) +> - if you have a old conda installation you could get a `UnsatisfiableError` error. Please install a new conda and try again +> - downloads fail due to company proxy, see [conda docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to resolve +> +{: .callout} + ## Test that the installation was successful To test that the installation was successful, run From d671a7892d4ab24c829d46d95b007077fdb185b1 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 10:41:41 +0100 Subject: [PATCH 158/647] Update setup.md Co-authored-by: Stefan Verhoeven --- setup.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup.md b/setup.md index b481b032..dfc82572 100644 --- a/setup.md +++ b/setup.md @@ -70,8 +70,8 @@ Note that you have only created an account for the web-interface. To log into th #### Access to data on JASMIN Please request access to the working groups: -● https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval -●https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research +- https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval +- https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research Once you have access to the data archive on CEDA, make sure to link your CEDA and JASMIN accounts. This can be done by checking the link to CEDA box on your JASMIN profile page: @@ -154,4 +154,3 @@ More details on this process are available in the Installation episode. {% include links.md %} - From 325b263433a2e9c85048be6441b9c4fe35eed88f Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 10:42:16 +0100 Subject: [PATCH 159/647] Update setup.md Co-authored-by: Stefan Verhoeven --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index dfc82572..299a6346 100644 --- a/setup.md +++ b/setup.md @@ -140,7 +140,7 @@ Raising an issue is the act of creating a new issue. If you are asked to raise a A github pull request is the act of requesting that a branch is merged with another branch. -This is an advanced feature of ESMValTool, and will generally be performed by the Core development team. +This is an advanced feature of GitHub, and will generally be performed by the ESMValTool development team. From 70a3e961581e28afd2a6c8cea6ca461f84acf54d Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 10:42:39 +0100 Subject: [PATCH 160/647] Update setup.md Co-authored-by: Stefan Verhoeven --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index 299a6346..f99b7832 100644 --- a/setup.md +++ b/setup.md @@ -149,7 +149,7 @@ This is an advanced feature of GitHub, and will generally be performed by the ES The python package manager Conda (anaconda or miniconda) needs to be installed on your system before the tutorial starts. In some cases, your system may have a central version installed already. -More details on this process are available in the Installation episode. +More details on this process are available in the [Installation episode]({{ page.root}}[% link _episodes/02-installation.md %}). From a1bea9d8df2c0aaa25c1c9c0ccd62e115f2e779c Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 11:51:34 +0200 Subject: [PATCH 161/647] why Julia install --- _episodes/02-installation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 274acf89..a4cb7c81 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -77,6 +77,8 @@ After installing the WSL, installation can be done using the Linux installation ## Install Julia +Some parts of ESMValTool are written in Julia, to be able to execute those parts a Julia installation is needed. + Complete instructions for installing Julia can be found on the [Julia installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). In this tutorial, we will use the following steps. From bec969db54c9819c051acd023406bb4e9558450a Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 11:52:09 +0200 Subject: [PATCH 162/647] Removed package location command The location of the Python package is not being used right away in the next episode. This looks like a test for people with multiple esmvaltool installations, not for a first time tutorial reader. --- _episodes/02-installation.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index a4cb7c81..45b125d0 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -169,10 +169,5 @@ esmvaltool --help ``` to display the command line help. -To find the location where the ESMValTool package was installed on your system, run - -```bash -python -c 'import esmvaltool; print(esmvaltool.__path__[0])' -``` {% include links.md %} From a634ba31a6e69dbcf7cd72843061563b8afa4b36 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 11:58:25 +0200 Subject: [PATCH 163/647] Describe for who this episode is --- _episodes/10-development-setup.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index a7c5aebc..74c234ae 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -13,10 +13,12 @@ keypoints: - "You can find more information about installation in the [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html)" --- +So you want to contribute code to ESMValTool, what follows describes a development installation to help you get going. + > ## Attention -> -> * This episode is based on the ESMValTool installation instructions, for more information and advanced cases you can visit the ESMValTool [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html). -> * For this episode it is assumed you have knowledge of [git](https://git-scm.com/) you can refresh your knowledge in the corresponding [git carpentries course](http://swcarpentry.github.io/git-novice/). +> +> - This episode is based on the ESMValTool installation instructions, for more information and advanced cases you can visit the ESMValTool [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html). +> - For this episode it is assumed you have knowledge of [git](https://git-scm.com/) you can refresh your knowledge in the corresponding [git carpentries course](http://swcarpentry.github.io/git-novice/). {: .callout} ## Obtaining the source code From 73dad511b802c3a98d31ce9a1a91cdb5d47e1548 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 12:02:34 +0200 Subject: [PATCH 164/647] Correcc rendering --- _episodes/10-development-setup.md | 40 +++++++++++++------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index 74c234ae..70bfb89b 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -24,15 +24,14 @@ So you want to contribute code to ESMValTool, what follows describes a developme ## Obtaining the source code The ESMValTool source code is available on a public GitHub repository: -https://github.com/ESMValGroup/ESMValTool +[https://github.com/ESMValGroup/ESMValTool](https://github.com/ESMValGroup/ESMValTool) The easiest way to obtain it is to clone the repository using git. To clone the public repository open a terminal window and type: +~~~bash +git clone https://github.com/ESMValGroup/ESMValTool.git ~~~ - git clone https://github.com/ESMValGroup/ESMValTool.git -~~~ -{: .source} By default, this command will create a folder called ESMValTool containing the source code of the tool. @@ -42,16 +41,15 @@ Move into the directory to continue installation. > ## Attention > > Make sure that the master branch is checked out before continuing intallation: -> ~~~ +> ~~~bash > git checkout master > ~~~ -> {: .source} {: .callout} ## Prerequisites It is recommended to use conda to manage ESMValTool dependencies. -For a minimal conda installation go to https://conda.io/miniconda.html. To +For a minimal conda installation go to [https://conda.io/miniconda.html](https://conda.io/miniconda.html). To simplify the installation process, an environment definition file is provided in the repository (``environment.yml`` in the root folder). @@ -69,21 +67,19 @@ independent from any other Python tools present in the system. To create an environment, go to the directory containing the ESMValTool source code (called ESMValTool if you did not choose a different name) and run +~~~bash +conda env create --name esmvaltool --file environment.yml ~~~ - conda env create --name esmvaltool --file environment.yml -~~~ -{: .source} The environment is called ``esmvaltool`` by default, but it is possible to use the option ``--name ENVIRONMENT_NAME`` to define a custom name. You can activate the environment using the command: +~~~bash +conda activate esmvaltool ~~~ - conda activate esmvaltool -~~~ -{: .source} -If you run into trouble, please try recreating the environment. More information can be found in the (conda documentation)[https://docs.conda.io/en/latest/]. +If you run into trouble, please try recreating the environment. More information can be found in the [conda documentation](https://docs.conda.io/en/latest/). ## Software installation @@ -91,20 +87,18 @@ If you run into trouble, please try recreating the environment. More information Once all prerequisites are fulfilled, ESMValTool can be installed by running the following commands in the directory containing the ESMValTool source code: +~~~bash +pip install . ~~~ - pip install . -~~~ -{: .source} ## Test the installation The next step is to check that the installation works properly. To do this, run the tool with: +~~~bash +esmvaltool --help ~~~ - esmvaltool --help -~~~ -{: .source} If everything was installed properly, ESMValTool should have printed a help message to the console. @@ -112,10 +106,8 @@ help message to the console. For a more complete installation verification, run the automated tests and confirm that no errors are reported: +~~~bash +python setup.py test --installation ~~~ - python setup.py test --installation -~~~ -{: .source} {% include links.md %} - From a87234fd65da37138452a5e9bee6a5cf5c9ca783 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 11:11:16 +0100 Subject: [PATCH 165/647] Update setup.md Co-authored-by: Stefan Verhoeven --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index f99b7832..fcf2b847 100644 --- a/setup.md +++ b/setup.md @@ -39,7 +39,7 @@ https://swcarpentry.github.io/git-novice/ ESMValTool may be run on multiple platforms, including local machines and large compute clusters; the benefit of using a compute cluster is that most often than not, -it will host an ESGF node where CMIP data is locally stored on disk and accessible directly by the tool; +it will host an [Earth System Grid Federation (ESGF) node](https://esgf.llnl.gov/nodes.html) where [Coupled Model Intercomparison Project (CMIP)](https://en.wikipedia.org/wiki/Coupled_Model_Intercomparison_Project) data is locally stored on disk and accessible directly by the tool; in the same manner, observational (OBS) data will be found centrally stored as well. Here are a few options for compute clusters with ESGF nodes: From 25dc6c9dcbed7bd3c42c9c42c2148d6e94ce1389 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 11:11:39 +0100 Subject: [PATCH 166/647] working here --- setup.md | 57 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/setup.md b/setup.md index f99b7832..1a7cdafd 100644 --- a/setup.md +++ b/setup.md @@ -1,16 +1,22 @@ --- -title: Preparing for participating in the tutorial +title: Preparations for participating in the tutorial --- This page includes some basic information on how to prepare to participate in this tutorial. > ## Prerequisites -> The prerequisites for the tutorial are listed here: -> Basic understanding of git (optional - but useful) -> Basic understanding of your preferred command line interface (ie a bash terminal) -> Access to CMIP and observational data -> Access to a suitable compute cluster (e.g. CEDA-Jasmin) -> Github account (optional, but useful!) +> The prerequisites for the tutorial are listed on the +> [tutorials home page]({{ page.root}}[% index.md %}) +> and are also eproduced here: +> - Basic understanding of git (optional) +> +> - Basic understanding of your preferred command line interface (ie a bash terminal) +> +> - Access to CMIP data +> +> - Access to a suitable computing system (eg Jasmin, DLR machine) +> +> - Github account (optional) {: .prereq} @@ -20,33 +26,47 @@ Where available, we include links to other software carpentry courses. ### Command line -We typically use the command line to interact with ESMValTool. Here’s a software carpentry tutorial on the unix shell: -https://swcarpentry.github.io/shell-novice/ - +We typically use the command line to interact with ESMValTool. +Here’s a software carpentry tutorial on the unix shell: +[https://swcarpentry.github.io/shell-novice/](https://swcarpentry.github.io/shell-novice/) ### Basic understanding of git -Git is a distributed version-control system for tracking changes in source code during software development. It’s how we distribute, share, and manage the ESMValTool code. +Git is a distributed version-control system for tracking changes in source code during software development. +It’s how we distribute, share, and manage the ESMValTool code. There are many basic introductions to git available. Here’s a software carpentry tutorial on git: -https://swcarpentry.github.io/git-novice/ +[https://swcarpentry.github.io/git-novice/](https://swcarpentry.github.io/git-novice/) + + +## Access to CMIP and Observational data and a suitable compute cluster +To complete this tutorial and use ESMValTool, you will need access to data in a reasonable format. +Some data will be provided, but there is too much CMIP data available for your tutors to make it all available directly. -## Access to CMIP and OBS data and a suitable compute cluster +ESMValTool may be run on multiple platforms, from your local machine to +large computing clusters. +The best option is to use a computing cluster with an ESGF node. +The benefit of using a compute cluster with an ESGF node is that the CMIP data is locally stored on disk and accessible directly by the tool. +Similarly, observational data would also be available at these sites. -ESMValTool may be run on multiple platforms, including local machines and -large compute clusters; the benefit of using a compute cluster is that most often than not, -it will host an ESGF node where CMIP data is locally stored on disk and accessible directly by the tool; -in the same manner, observational (OBS) data will be found centrally stored as well. Here are a few options -for compute clusters with ESGF nodes: +Here are a few options for compute clusters with ESGF nodes: - CEDA-Jasmin (UK): - DKRZ (Germany): - ETHZ (Switzerland): +If you're running on a computing cluster without an ESGF node, such as +your local machine, or your institue machine, you will most likely +have to make a local copy of the data that you need. + +If neccesairy, data can be downloaded using the +[synda tool](https://prodiguer.github.io/synda/index.html). + + ### CEDA-Jasmin @@ -109,6 +129,7 @@ If you are planning on running ESMValTool on your own machine, please make sure You will also need to able to use: - git - conda +- synda #### Linux/unix From d53fc31e618e3842f40d886aff1b022ddf4461e9 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 12:13:19 +0200 Subject: [PATCH 167/647] Added challenge --- _episodes/02-installation.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 45b125d0..844dbafa 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -170,4 +170,25 @@ esmvaltool --help to display the command line help. +> ## Challenge Title +> +> Can you figure out which version of ESMValTool has been installed? +> +> > ## Solution +> > +> > The `esmvaltool --help` command lists `-v` or `--version` as optional argument to get the version +> > +> > In my case when I run +> > ~~~ +> > esmvaltool --version +> > ~~~ +> > {: .bash} +> > I get that my installed ESMValTool version is +> > ~~~ +> > 2.0.0b9 +> > ~~~ +> > {: .output} +> {: .solution} +{: .challenge} + {% include links.md %} From 89c34efe28c23eb134d522df381ade3c2b3b73ab Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 12:15:42 +0200 Subject: [PATCH 168/647] Dont repeat yourself --- _episodes/02-installation.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 844dbafa..d23a4fbb 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -77,8 +77,6 @@ After installing the WSL, installation can be done using the Linux installation ## Install Julia -Some parts of ESMValTool are written in Julia, to be able to execute those parts a Julia installation is needed. - Complete instructions for installing Julia can be found on the [Julia installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). In this tutorial, we will use the following steps. From 6c5bcc78d616a331a89b3c0b5a2aad95cefc506e Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 30 Jun 2020 12:15:42 +0200 Subject: [PATCH 169/647] Lisa's suggestions --- _episodes/01-introduction.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index fd08a3ed..f3edef4f 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -54,7 +54,7 @@ EMSValTool is first and foremost a tool to analyse climate data. But you probabl > > > > ✓ **A way to make climate science more [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readable recipe format that makes climate analysis consistent, reproducible, and easy to share. > > -> > ✕ **Perfect.** Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In this lesson, you will learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. +> > ✕ **Perfect.** Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In the following episodes, you will learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. > > > > ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. > {: .solution} @@ -64,7 +64,7 @@ To learn more about ESMValTool, you can look at the [documentation](https://docs ## How does ESMValTool work -The figure below shows the different components of ESMValTool. Most of the work is done in the 'core', which performs a number of preprocessor steps. Outside of the core we have some configuration files that specify things like *where to find the CMIP data*. The most important file however, is the *recipe* that specifies which preprocessor functions need to be applied to what data. The recipe also points to a diagnostic script that is executed after the preprocessor and performs a more specific analysis on the preprocessed data. +The figure below shows the different components of ESMValTool. Some of the most important work is done in the 'core', which performs a number of preprocessor steps. Outside of the core we have some configuration files that specify things like *where to find the CMIP data*. The most important file however, is the *recipe* that specifies which preprocessor functions need to be applied to what data. The recipe also points to a diagnostic script that is executed after the preprocessor and performs a more specific analysis on the preprocessed data. ![figure showing ESMValTool architecture]({{ page.root }}/fig/esmvaltool_architecture.png) @@ -87,11 +87,11 @@ The figure below shows the different components of ESMValTool. Most of the work ## Community -ESMValTool is built and maintained by an active community of scientists and engineers. Many of the interactions take place on GitHub. Here, we briefly introduce you to some of the most important pages. +ESMValTool is built and maintained by an active community of scientists and software engineers. Many of the interactions take place on GitHub. Here, we briefly introduce you to some of the most important pages. > ## Challenge: meet ESMValGroup > -> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is our 'organization' GitHub page. Have a look around. How many collaborators are there? Do you know any of them? You should see 2 main repositories: ESMValTool and ESMValCore. Clicking on them will take you to there. How many people have contributed to each of them? Can you also find out how many people have contributed to this tutorial? +> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is our 'organization' GitHub page. Have a look around. How many collaborators are there? Do you know any of them? You should see 2 main repositories: ESMValTool and ESMValCore. Visit each of the repositofires. How many people have contributed to each of them? Can you also find out how many people have contributed to this tutorial? > > > ## Solution > > @@ -105,7 +105,7 @@ ESMValTool is built and maintained by an active community of scientists and engi > > > ## Solution > > -> > At the time of making this tutorial, there were 50 ESMValTool issues (the majority) about enhancement and 31 bugs had been fixed in the Core. 13 ESMValTool issues had been closed in the past month, versus 8 opened: overall good progress. +> > At the time of making this lesson, there were 50 ESMValTool issues (the majority) about enhancement and 31 bugs had been fixed in the Core. 13 ESMValTool issues had been closed in the past month, versus 8 opened: overall good progress. > {: .solution} {: .challenge} From 90d3a2be67ef5adc3ea0503acac5e345a0df6aab Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 12:17:40 +0200 Subject: [PATCH 170/647] Replace place holder --- _episodes/02-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index d23a4fbb..621ea597 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -168,7 +168,7 @@ esmvaltool --help to display the command line help. -> ## Challenge Title +> ## Version of ESMValTool > > Can you figure out which version of ESMValTool has been installed? > From 50082befbbb24f82443e996ec38a5205a23100f8 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 30 Jun 2020 12:33:27 +0200 Subject: [PATCH 171/647] revise the sections and text --- _episodes/06-debugging.md | 54 +++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 97f136e2..d174c6c1 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -7,7 +7,7 @@ questions: objectives: - "Fix a broken recipe" keypoints: -- "The log files contain information about errors and warnings." +- "There are two different kinds of log files: ``main_log.txt``, and ``main_log_debug.txt``." --- Every user encounters errors. Once you know why you get certain types of errors, @@ -20,10 +20,10 @@ This lesson helps to understand what the different types of errors are and when Each time we run ESMValTool, it will produce a new output directory. This directory should contain the ``run`` folder that is automatically generated by ESMValTool. -To examine this, we run an example recipe that can be found in: -[recipe_example.yml](link). +To examine this, we run a ``recipe_example.yml`` that can be found in +[Setup]({{ page.root }}{% link setup.md %}). Let's download it to our working directory ``esmvaltool_tutorial`` that was created during -the [Setup]({{ page.root }}{% link setup.md %}). +the [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}). In a new terminal, go to our working directory ``esmvaltool_tutorial`` where both files ``user-config.yml`` and ``recipe_example.yml`` are located and run the recipe: @@ -154,14 +154,11 @@ and then ctrl + X to exit ``nano``. >~~~ {: .solution} -We change the ``projects`` value ``ukesm`` to ``tutorial``: +## Keys and values in recipe settings -~~~YAML -19 projects: -20 - tutorial -~~~ - -Also, let's add the preprocessor ``extract_region`` to the section ``prep_timeseries``: +The [ESMValTool pre-processors](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/recipe/preprocessor.html?highlight=preprocessor) cover a broad range of operations on the input data, +like time manipulation, area manipulation, land-sea masking, variable derivation, ... . +Let's add the preprocessor ``extract_region`` to the section ``prep_timeseries``: ~~~YAML 25 preprocessors: @@ -175,6 +172,13 @@ Also, let's add the preprocessor ``extract_region`` to the section ``prep_timese 33 end_latitude: 70 ~~~ +Also, we change the ``projects`` value ``ukesm`` to ``tutorial``: + +~~~YAML +19 projects: +20 - tutorial +~~~ + Then, we save the file and run the recipe: ~~~bash esmvaltool -c user-config.yml recipe_example.yml @@ -188,13 +192,12 @@ attach the run/recipe_*.yml and run/main_log_debug.txt files from the output dir ~~~ {: .error} -The values for the keys ``author``, ``maintainer``, ``projects`` and ``references`` in the recipe should be known by ESMValTool. - -> ## ESMValTool pre-processors -> -> The [ESMValTool pre-processors](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/recipe/preprocessor.html?highlight=preprocessor) cover a broad range of operations on the input data, -like time manipulation, area manipulation, land-sea masking, variable derivation, ... . -{: .callout} +The values for the keys ``author``, ``maintainer``, ``projects`` and ``references`` in the recipe should +be known by ESMValTool. A list of ESMValTool author, maintainer, references, and projects can be found +in the ``config-references.yml`` that is located in the folder ``references`` +in the ESMValTool installation directory ``path_to_esmvaltool``. To find ``path_to_esmvaltool`` +on your system, see +[Installation]({{ page.root }}{% link _episodes/02-installation.md %}). > ## ESMValTool can’t locate the data > @@ -218,13 +221,20 @@ What suggestions would you give the researcher for fixing the error? > {: .solution} {: .challenge} -> ## Check pre-processed data +## Check pre-processed data + +The setting ``save_intermediary_cubes`` in the configuration file can be used +to save the pre-processed data. More information about this setting can be found at +[Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}). + +> ## save_intermediary_cubes > -> The setting ``save_intermediary_cubes`` in the configuration file can be used -save the pre-processed data. More information about this setting can be found at -[Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}) +> Note that this setting should be only used for debugging, as it significantly slows down the recipe +and increases disk usage because a lot of output files need to be stored. {: .callout} +## Check diagnostic script path + The result of the pre-processor is passed to the ``diagnostic_timeseries.py`` script, that is introduced in the recipe as: From e22f7b9ef1047e872edef57080dbe03298cdeb60 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 12:51:31 +0200 Subject: [PATCH 172/647] Apply suggestions from code review Co-authored-by: Peter Kalverla --- _episodes/02-installation.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 621ea597..8ac7e169 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -69,7 +69,7 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the ### Windows -ESMValTool does not directly support Windows, But succesful usage has been reported through the [Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows 10. +ESMValTool does not directly support Windows, but succesful usage has been reported through the [Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows 10. To install the WSL please follow the instructions [on the Windows Documentation page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). @@ -143,11 +143,11 @@ called `esmvaltool`, with the ESMValTool package and all of its dependencies ins > > Below are some common problems that could happen while installing. > -> - installation takes long time, -> - downloads and compilations can take several minutes to complete, please be patient -> - you might have bad luck and the dependencies can not be resolved at the moment, please try again later or [raise an issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose) -> - if you have a old conda installation you could get a `UnsatisfiableError` error. Please install a new conda and try again -> - downloads fail due to company proxy, see [conda docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to resolve +> - Installation takes long time +> - Downloads and compilations can take several minutes to complete, please be patient. +> - You might have bad luck and the dependencies can not be resolved at the moment, please try again later or [raise an issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose) +> - If you have an old conda installation you could get a `UnsatisfiableError` message. Please install a newer version of conda and try again +> - Downloads fail due to company proxy, see [conda docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to resolve > {: .callout} From c94980a5d1a0c88e82749944021fde996c60face Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 11:52:08 +0100 Subject: [PATCH 173/647] fixed the links --- setup.md | 80 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/setup.md b/setup.md index f6e5d26a..bfdc1c14 100644 --- a/setup.md +++ b/setup.md @@ -45,7 +45,8 @@ Here’s a software carpentry tutorial on git: ## Access to CMIP and Observational data and a suitable compute cluster To complete this tutorial and use ESMValTool, you will need access to data in a reasonable format. -Some data will be provided, but there is too much CMIP data available for your tutors to make it all available directly. +Some data will be provided, but there is simply too much data available +for your tutors to make it all available directly. ESMValTool may be run on multiple platforms, from your local machine to large computing clusters. @@ -78,12 +79,13 @@ If neccesairy, data can be downloaded using the ### CEDA-Jasmin If you do not already have an account on JASMIN, then request an account as -soon as possible. The instructions on how to create a Jasmin account are here: https://help.jasmin.ac.uk/article/4435-get-a-jasmin-account-portal +soon as possible. +Please follow [these instructions on how to create a Jasmin account](https://help.jasmin.ac.uk/article/4435-get-a-jasmin-account-portal) -During the account creation, you will need an SSH key, which can be generated following these instructions: https://help.jasmin.ac.uk/article/185-generate-ssh-key-pair +During the account creation, you will need an SSH key, which can be generated following +[these instructions](https://help.jasmin.ac.uk/article/185-generate-ssh-key-pair) -More instructions on how to get started: -https://help.jasmin.ac.uk/article/189-get-started-with-jasmin +Here are some more [instructions on how to get started with jasmin](https://help.jasmin.ac.uk/article/189-get-started-with-jasmin). Also note that if you are working from home, JASMIN may not be directly accessible from your home. You may need to use ssh to connect to a machine @@ -92,36 +94,53 @@ the tutorial. #### Jasmin-login -Note that you have only created an account for the web-interface. To log into the jasmin machine and do work, you'll need to create a login account too: https://help.jasmin.ac.uk/article/161-get-login-account +Note that you have only created an account for the web-interface. +To log into the jasmin machine and do work, you'll need to create a +login account too using [this page](https://help.jasmin.ac.uk/article/161-get-login-account). + #### Access to data on JASMIN Please request access to the working groups: -- https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval -- https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research +- [esmeval working group](https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval) +- [CMIP5 data](https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research) Once you have access to the data archive on CEDA, make sure to link your -CEDA and JASMIN accounts. This can be done by checking the link to CEDA box on your JASMIN profile page: -https://accounts.jasmin.ac.uk/account/profile/ +CEDA and JASMIN accounts. +This can be done by checking the link to CEDA box on +[your JASMIN profile page](https://accounts.jasmin.ac.uk/account/profile/). The linking may take a few hours to take effect and is necessary for you to access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC are not accessible by default and special permission has to be requested to -access them via the CEDA catalogue page https://catalogue.ceda.ac.uk/ +access them via [the CEDA catalogue page](https://catalogue.ceda.ac.uk/). #### Test your Setup + Log into jasmin-login: -ssh -X JASMIN-USERNAME@jasmin-login1.ceda.ac.uk + +~~~ +ssh -X JASMIN-USERNAME@jasmin-login1.ceda.ac.uk +~~~ +{: .language-bash} Then log into the sci1 machine: + +~~~ ssh -X jasmin-sci1 +~~~ +{: .language-bash} Can you see the following locations: +~~~ - ls /group_workspaces/jasmin4/esmeval/obsdata/Tier2 - ls /badc/cmip5/data/cmip5/output1/MOHC/HadGEM2-ES - ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.nc +~~~ +{: .language-bash} -Note that the JASMIN is only open to certain locations (mostly universities, and research centres). You may need a VPN if you wish to connect from your home network. +Note that the JASMIN is only open to certain locations (mostly universities, and research centres). +You may need a VPN if you wish to connect from your home network. ### DLR FIXME @@ -144,40 +163,53 @@ You will also need to able to use: #### Windows -ESMValTool does not directly support Windows, But successful usage has been reported through the [Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows 10. +ESMValTool does not directly support Windows, +but successful usage has been reported through the +[Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), +available in Windows 10. ## Github account (Advanced) -You don’t need a github account to participate in the tutorial. However, if you want to raise an issue, contribute to the discussions, or share your code, please create a github account, here: https://github.com/ +You don’t need a github account to participate in the tutorial. +However, if you want to raise an issue, contribute to the discussions, +or share your code, please [create a github account](https://github.com/). -To learn how to use github, please have a look at this page: -https://lab.github.com/githubtraining/introduction-to-github +To learn how to use github, please have a look at this [introduction to github] +(https://lab.github.com/githubtraining/introduction-to-github). You may hear a few of the following phrases during the tutorial. Don’t be alarmed, they will make sense eventually. ### github issues -Issues are github’s ticketing system. They allow users and developers to discuss problems, identify bugs, or to make suggestions. Each issue is assigned a number and will have it’s own page on github. +Issues are github’s ticketing system. +They allow users and developers to discuss problems, +identify bugs, or to make suggestions. +Each issue is assigned a number and will have it’s own page on github. + +Here’s an explanation of the [github issues](https://guides.github.com/features/issues/). -Here’s an explanation of the github issues: https://guides.github.com/features/issues/ +Raising an issue is the act of creating a new issue. +If you are asked to raise an issue, please follow any instructions that you are given, +and also make sure that you read the default issue text. -Raising an issue is the act of creating a new issue. If you are asked to raise an issue, please follow any instructions that you are given, and also make sure that you read the default issue text. ### pull request A github pull request is the act of requesting that a branch is merged with another branch. -This is an advanced feature of GitHub, and will generally be performed by the ESMValTool development team. - +This is an advanced feature of GitHub, and will generally be performed by the ESMValTool development team. ## Install conda -The python package manager Conda (anaconda or miniconda) needs to be installed on your system before the tutorial starts. In some cases, your system may have a central version installed already. +The python package manager Conda (anaconda or miniconda) +needs to be installed on your system before the tutorial starts. +In some cases, your system may have a central version installed already. -More details on this process are available in the [Installation episode]({{ page.root}}[% link _episodes/02-installation.md %}). +More details on this process are available in the +[Installation episode]({{ page.root}}[% link _episodes/02-installation.md %}). From af04d8eb56014016f0114e91250e5cdba5675d7b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 30 Jun 2020 13:03:55 +0200 Subject: [PATCH 174/647] add time estimates --- _episodes/06-debugging.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index d174c6c1..afb7e7ac 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -1,7 +1,7 @@ --- title: "Debugging" -teaching: 0 -exercises: 0 +teaching: 30 +exercises: 15 questions: - "How can I handle errors/warnings?" objectives: From 7f3b88500bbd08e40f221ad398bafdf773077991 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 13:08:04 +0200 Subject: [PATCH 175/647] Show conda list output + specify wher Julia tarball should be downloaded to --- _episodes/02-installation.md | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 8ac7e169..c4f28c1c 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -47,6 +47,18 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the conda list ``` + Should output something like + + ``` + # packages in environment at ~/miniconda3: + # + # Name Version Build Channel + ... + conda 4.8.3 py37_0 + ... + ``` + {: .output} + ### MacOSX 1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). @@ -67,6 +79,19 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the conda list ```` + Should output something like + + ``` + # packages in environment at ~/miniconda3: + # + # Name Version Build Channel + ... + conda 4.8.3 py37_0 + ... + ``` + {: .output} + + ### Windows ESMValTool does not directly support Windows, but succesful usage has been reported through the [Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows 10. @@ -80,22 +105,24 @@ After installing the WSL, installation can be done using the Linux installation Complete instructions for installing Julia can be found on the [Julia installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). In this tutorial, we will use the following steps. -First, open a bash terminal and create a directory to install Julia in +First, open a bash terminal and create a directory to install Julia in and cd into it ```bash mkdir ~/julia +cd ~/julia ``` Next, download the file [`julia-1.0.5-linux-x86_64.tar.gz`](https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz) by clicking the link or going to the [Julia downloads page](https://julialang.org/downloads/). +Download the file directly to the `~/julia` directory or move it there after downloading. To extract the file, you can use the following command: ```bash -tar -xvzf ~/Downloads/julia-1.0.5-linux-x86\_64.tar.gz -C ~/julia +tar -xvzf julia-1.0.5-linux-x86\_64.tar.gz ``` -This will extract the files to a folder named `~/julia/julia-1.0.5`. +This will extract the files to a directory named `~/julia/julia-1.0.5`. To run Julia, you need to add the full path of Julia's `bin` folder to PATH environment variable. To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. Open the file in your favorite editor and add a new line as follows at the bottom of the file: From 60dc606aeee030a08aed096ad730b6c10395a9b9 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 12:08:25 +0100 Subject: [PATCH 176/647] minor fix. --- setup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.md b/setup.md index bfdc1c14..34e6f840 100644 --- a/setup.md +++ b/setup.md @@ -1,4 +1,4 @@ - --- +--- title: Preparations for participating in the tutorial --- @@ -133,9 +133,9 @@ ssh -X jasmin-sci1 Can you see the following locations: ~~~ -- ls /group_workspaces/jasmin4/esmeval/obsdata/Tier2 -- ls /badc/cmip5/data/cmip5/output1/MOHC/HadGEM2-ES -- ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.nc +ls /group_workspaces/jasmin4/esmeval/obsdata/Tier2 +ls /badc/cmip5/data/cmip5/output1/MOHC/HadGEM2-ES +ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.nc ~~~ {: .language-bash} From c138ae92e450c048d685a8caba106c1fc8d9ead0 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 12:12:20 +0100 Subject: [PATCH 177/647] Update index.md Co-authored-by: Jaro Camphuijsen --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index 0a9f449e..e43d4c99 100644 --- a/index.md +++ b/index.md @@ -13,7 +13,7 @@ ensemble. This tutorial is structured such that the main body of the tutorial, up to the episode 7, can be done in one sitting. -From there, there are several mini-tutorials which each covers one aspect of working with ESMValTool. +From episode 8, each episode is a mini-tutorial covering an advanced aspect of working with ESMValTool. These mini-tutorials can be appended to the main tutorial or worked through independently. > ## What will you learn in this course From f2d472b420f12e82dede1e8374ba8f5c0a5a588c Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 12:13:52 +0100 Subject: [PATCH 178/647] Update index.md Co-authored-by: Jaro Camphuijsen --- index.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/index.md b/index.md index e43d4c99..8b2c2d39 100644 --- a/index.md +++ b/index.md @@ -45,13 +45,14 @@ These mini-tutorials can be appended to the main tutorial or worked through inde > - Github account (optional) {: .prereq} -> ## Main things you need to know before starting this course -> -> 1. This tutorial can be taken online independently or taught by one of our instructors. -> 2. Please check the common issues page if you get stuck [Link to common issues page]. Otherwise, help is always available from ESMValTool developers via the github issues page. -> 3. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. -> 4. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. -{: .checklist} + +### Main things you need to know before starting this course + +1. This tutorial can be taken online independently or taught by one of our instructors. +2. Please check the common issues page if you get stuck [Link to common issues page]. Otherwise, help is always available from ESMValTool developers via the github issues page. +3. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. +4. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. + {% include links.md %} From 3e4660469633521c9345449bc76e6052552babba Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 12:14:04 +0100 Subject: [PATCH 179/647] Update index.md Co-authored-by: Jaro Camphuijsen --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index 8b2c2d39..5944e67e 100644 --- a/index.md +++ b/index.md @@ -7,7 +7,7 @@ date: '`r format(Sys.time(), "%d %B, %Y")`' This tutorial is built to teach you how to use ESMValTool. -The Earth System Model Evaluation Tool (ESMValTool) is a community developped software toolkit that aims to faciliate +The Earth System Model Evaluation Tool (ESMValTool) is a community developed software toolkit that aims to facilitate the diagnosis and evaluation of the causes and effects of model biases and inter-model spread within the CMIP model ensemble. From 19d218542e48f6754dd35987dc8bb923c12f13fc Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 13:16:22 +0200 Subject: [PATCH 180/647] Added output which jula + conda activate output --- _episodes/02-installation.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index c4f28c1c..06f7f99e 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -145,7 +145,13 @@ To check that the Julia executable can be found, run which julia ``` -to display the path to the Julia executable, it should be `~/julia/julia-1.0.5/bin/julia`. +to display the path to the Julia executable, it should be + +``` +~/julia/julia-1.0.5/bin/julia +``` +{: .output} + To test that Julia is installed correctly, run ```bash @@ -187,6 +193,8 @@ conda activate esmvaltool ``` to activate the conda environment called `esmvaltool`. +In the shell prompt the active conda environment should have been changed from `(base)` to `(esmvaltool)`. + Next, run ```bash From b37e82e60bb803a32e3f80e865a931a8fd125467 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 12:17:38 +0100 Subject: [PATCH 181/647] Update setup.md --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index 34e6f840..bcf8c20d 100644 --- a/setup.md +++ b/setup.md @@ -2,7 +2,7 @@ title: Preparations for participating in the tutorial --- -This page includes some basic information on how to prepare to participate in this tutorial. +This page includes some information on how to prepare for participating in this tutorial. > ## Prerequisites > The prerequisites for the tutorial are listed on the From 001e5492a27eb4df00a576fdd51088c3e6b278c7 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 30 Jun 2020 13:18:24 +0200 Subject: [PATCH 182/647] add some text for log file in the diagnostic --- _episodes/06-debugging.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index afb7e7ac..a40072ea 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -7,7 +7,7 @@ questions: objectives: - "Fix a broken recipe" keypoints: -- "There are two different kinds of log files: ``main_log.txt``, and ``main_log_debug.txt``." +- "There are three different kinds of log files: ``main_log.txt``, and ``main_log_debug.txt`` and ``log.txt``." --- Every user encounters errors. Once you know why you get certain types of errors, @@ -60,7 +60,7 @@ Let's change the working directory to the folder ``run`` and list its files: ~~~ ~~~ -main_log_debug.txt main_log.txt recipe_example.yml resource_usage.txt +diag_timeseries_temperature main_log_debug.txt main_log.txt recipe_example.yml resource_usage.txt ~~~ {: .output} @@ -72,6 +72,21 @@ To inspect them, we can look inside the files. For example: cat main_log.txt ~~~ +Now, let's have a look inside the folder ``diag_timeseries_temperature``: + +~~~bash + cd path_to_output_directory/run/diag_timeseries_temperature + ls +~~~ + +~~~ +diag_provenance.yml log.txt resource_usage.txt settings.yml +~~~ +{: .output} + +In the ``log.txt``, ESMValTool writes the output messages, +warnings and possible errors that are related to the diagnostic script. + If you encounter an error and don’t know what it means, it is important to read the log information. Sometimes knowing where the error occurred is enough to fix it, even if you don’t entirely understand the message. However, note that you may not always be able to find the error or fix it. From 91350e21bcd096e95a26503bb565912f0c5deb20 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 13:19:09 +0200 Subject: [PATCH 183/647] from the place where you downloaded it --- _episodes/02-installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 06f7f99e..2ca58d91 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -31,7 +31,7 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the 1. Please download Miniconda3 for Linux at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. -2. Next, run the installer +2. Next, run the installer from the place where you downloaded it ```bash bash Miniconda3-latest-Linux-x86_64.sh @@ -63,7 +63,7 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the 1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). -2. Next, run the installer +2. Next, run the installer from the place where you downloaded it ```bash bash Miniconda3-latest-MacOSX-x86_64.sh From 3cc34c0ccde5d9bbb5fe2240005cf116f6354cfd Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 12:20:43 +0100 Subject: [PATCH 184/647] Update setup.md --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index bcf8c20d..d13c24dd 100644 --- a/setup.md +++ b/setup.md @@ -20,7 +20,7 @@ This page includes some information on how to prepare for participating in this {: .prereq} -## Optional tutorials +## Optional tutorials to be prepared to use ESMValTool Where available, we include links to other software carpentry courses. From cecc35430b23739a31b8242b9026abf560fe8994 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 12:23:41 +0100 Subject: [PATCH 185/647] shortened tutorials section --- setup.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/setup.md b/setup.md index 34e6f840..76282f6b 100644 --- a/setup.md +++ b/setup.md @@ -22,23 +22,19 @@ This page includes some basic information on how to prepare to participate in th ## Optional tutorials -Where available, we include links to other software carpentry courses. -### Command line +We typically use the command line to interact with ESMValTool. +While most of us are likely to have experience with the command line, +novices may want to work through this software carpentry unix shell course. -We typically use the command line to interact with ESMValTool. -Here’s a software carpentry tutorial on the unix shell: -[https://swcarpentry.github.io/shell-novice/](https://swcarpentry.github.io/shell-novice/) +- Command line: [https://swcarpentry.github.io/shell-novice/](https://swcarpentry.github.io/shell-novice/) -### Basic understanding of git Git is a distributed version-control system for tracking changes in source code during software development. It’s how we distribute, share, and manage the ESMValTool code. -There are many basic introductions to git available. - -Here’s a software carpentry tutorial on git: -[https://swcarpentry.github.io/git-novice/](https://swcarpentry.github.io/git-novice/) +- git: [https://swcarpentry.github.io/git-novice/](https://swcarpentry.github.io/git-novice/) + From d02590785b39db688ea8801dd8bf305888944ddf Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 13:31:22 +0200 Subject: [PATCH 186/647] Added time estimates --- _episodes/10-development-setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index 70bfb89b..3235a9e6 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -1,7 +1,7 @@ --- title: "Development Setup" -teaching: 0 -exercises: 0 +teaching: 10 +exercises: 20 questions: - "What are the prerequisites for installing ESMValTool?" - "How do I confirm that the installation was succesful?" From 330137f6d93942caaa8b5f4e4070b7a17cfd3668 Mon Sep 17 00:00:00 2001 From: rswamina Date: Tue, 30 Jun 2020 12:38:43 +0100 Subject: [PATCH 187/647] Made changes from Birgit's revies, added section on grouping variables, altered timing numbers at the top --- _episodes/05-preprocessor.md | 103 ++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 20 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index b888473d..87bdf2db 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -1,17 +1,18 @@ --- title: "Working with preprocessors" -teaching: 20? -exercises: 15? +teaching: 20 +exercises: 20 questions: - "How do I set up a preprocessor?" - "Can I use different preprocessors for different variables?" - "Can I use different datasets for different variables?" +- "How can I combine different preprocessor functions?" objectives: - "Create a recipe with multiple preprocessors" - "Use different preprocessors for different variables" - "Run a recipe with variables from different datasets" keypoints: -- "A recipe can run different preprocessors at the same time." +- "A recipe can work with different preprocessors at the same time." - "The setting additional_datasets can be used to add a different dataset." - "Variable groups are useful for defining different settings for different variables." --- @@ -38,7 +39,7 @@ Each preprocessor section includes a preprocessor name, a list of preprocessor s For instance, the 'annual_statistics' with the 'operation: mean' argument preprocessor receives an iris cube, takes the annual average for each year of data in the cube, and returns the processed cube. -You could use several preprocessor steps listed in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). The standardised interface between the preprocessors allows them to be used modularly - like lego blocks. Almost any conceivable preprocessing order of operations can be performed using ESMValTool preprocessors. +You may use one or more of several preprocessors listed in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). The standardised interface between the preprocessors allows them to be used modularly - like lego blocks. Almost any conceivable preprocessing order of operations can be performed using ESMValTool preprocessors. > ## The 'custom order' command. > @@ -50,16 +51,16 @@ You could use several preprocessor steps listed in the [documentation](https://d > >The default preprocessor order is listed in the [ESMValCore preprocessor API page](>https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html). > -> Also note that not preprocessor operations aren't always commutative - meaning that the order of operations matters. For instance, if you run the preprocessor 'extract_volume' to extract the top 100m of the ocean surface, then 'volume_statistics' to calculate the volume-weighted mean of the data, then your result will differ depending on the order of these two preprocessors. In fact, the 'extract_volume' preprocessor will fail if you try to run it on a 2D dataset. +> Also note that preprocessor operations aren't always commutative - meaning that the order of operations matters. For instance, when you run the two preprocessors -- 'extract_volume' to extract the top 100m of the ocean surface and 'volume_statistics' to calculate the volume-weighted mean of the data, your result will differ depending on the order of these two preprocessors. In fact, the 'extract_volume' preprocessor will fail if you try to run it on a 2D dataset. > > Changing the order of preprocessors can also speed up your processing. For instance, if you want to extract a two-dimensional layer from a 3D field and re-grid it, the layer extraction should be done first. If you did it the other way around, then the regridding function would be applied to all the layers of your 3D cube and it would take much more time. {: .callout} -Some preprocessor stages are always applied and do not need to be called. This includes the preprocessors that load the data, apply the fixes, and save the data file afterwards. They do not need to be explicitly included in recipes. +Some preprocessor modeules are always applied and do not need to be called. This includes the preprocessors that load the data, apply any fixes and save the data file afterwards. These do not need to be explicitly included in recipes. > ## Exercise: Adding more preprocessor steps > -> Edit the [example recipe](LINK to episode #4) to change the variable in ?thetao? and to add preprocessors which take the average over the latitude and longitude dimensions and the average over the depth. And then run the recipe. +> Edit the [example recipe](LINK to episode #4) to first change the variable thetao, then add preprocessors to average over the latitude and longitude dimensions and finally average over the depth. Now run the recipe. > >> ## Solution >> @@ -78,7 +79,7 @@ Some preprocessor stages are always applied and do not need to be called. This i ## Using different preprocessors for different variables -You could define different preprocessors with several preprocessor sections (setting different preprocessor names). In the variable section you call the specific preprocessor which should be applied. +You can also define different preprocessors with several preprocessor sections (setting different preprocessor names). In the variable section you call the specific preprocessor which should be applied. > ## Example >~~~YAML @@ -91,7 +92,7 @@ You could define different preprocessors with several preprocessor sections (set > operator: mean > area_statistics: > operator: mean -> Depth_integration: +> depth_integration: > --- > diagnostics: > # -------------------------------------------------- @@ -114,14 +115,14 @@ You could define different preprocessors with several preprocessor sections (set > short_name: thetao > preprocessor: prep_timeseries_2 > scripts: -> timeseries_diag: +> timeseries_diag: > script: ocean/diagnostic_timeseries.py >~~~ >{: .source} {: .solution} >## Challenge : How to write a recipe with multiple preprocessors -> We now know that a recipe can have more than one diagnostic, variable or preprocessor. As we saw in the examples so far, we can group preprocessors with a single user defined name and can have more than one such preprocessor group in the recipe as well. Write two different preprocessors - one to regrid the data to a 1x1 resolution and the second preprocessor to mask out sea and ice grid cells before regridding to the saem resolution. In the second case, ensure you perform the masking first before regridding (hint: custom order your operations). Now, use the two preprocessors in different diagnostics within the same recipe. You may use any variable(s) of your choice. Once you succeed, try to add new datasets to the same recipe. Placeholders for the different components are provided below: +> We now know that a recipe can have more than one diagnostic, variable or preprocessor. As we saw in the examples so far, we can group preprocessors with a single user defined name and can have more than one such preprocessor group in the recipe as well. Write two different preprocessors - one to regrid the data to a 1x1 resolution and the second preprocessor to mask out sea and ice grid cells before regridding to the same resolution. In the second case, ensure you perform the masking first before regridding (hint: custom order your operations). Now, use the two preprocessors in different diagnostics within the same recipe. You may use any variable(s) of your choice. Once you succeed, try to add new datasets to the same recipe. Placeholders for the different components are provided below: > >> ## Recipe >> @@ -168,8 +169,7 @@ You could define different preprocessors with several preprocessor sections (set > >> ## Solution: >> ->> Here is one possible way to use two different preprocessors including a ->> group of preprocessors on different variables. +>> Here is one solution to complete the challenge above using two different preprocessors >> >>~~~YAML >> @@ -184,7 +184,7 @@ You could define different preprocessors with several preprocessor sections (set >> scheme: linear #how to interpolate for regridding >> >> prep_map_land: ->> custom_order: true #ensure order follows a given +>> custom_order: true #ensure that given order of preprocessing is followed >> mask_landsea: #apply a mask >> mask_out: sea #mask out sea grid cells >> regrid: # now apply the preprocessor to regrid @@ -205,7 +205,6 @@ You could define different preprocessors with several preprocessor sections (set >> grid: gn #can change for variables from the same model >> start_year: 1970 >> end_year: 2000 ->> additional_datasets: >> scripts: null >> >> diag_land_only_plot: @@ -217,7 +216,6 @@ You could define different preprocessors with several preprocessor sections (set >> grid: gn #can change for variables from the same model >> start_year: 1970 >> end_year: 2000 ->> additional_datasets: >> scripts: null >> ~~~ >> {: .source} @@ -226,7 +224,7 @@ You could define different preprocessors with several preprocessor sections (set ## Adding different datasets for different variables -Sometimes, we may want to include specific datasets for certain variables. An example is when we use observations for two different variables in a diagnostic. While the CMIP dataset details for the two variables may be common, the observations will likely not be so. It would be useful to know how to include different datasets for different variables. Here is an example of a simple preprocessor and diagnostic setup for that: +Sometimes, we may want to include specific datasets only for certain variables. An example is when we use observations for two different variables in a diagnostic. While the CMIP dataset details for the two variables may be common, the observations will likely not be so. It would be useful to know how to include different datasets for different variables. Here is an example of a simple preprocessor and diagnostic setup for that: > ## Example >~~~YAML @@ -254,7 +252,7 @@ Sometimes, we may want to include specific datasets for certain variables. An ex > mip: Amon > grid: gn #can change for variables from the same model > start_year: 1970 -> end_year: 2000 # start and end years for a30 year period, +> end_year: 2000 # start and end years for a 30 year period, > # we assume this is common and exists for all > # model and obs data > additional_datasets: @@ -269,16 +267,81 @@ Sometimes, we may want to include specific datasets for certain variables. An ex > end_year: 2000 > additional_datasets: > - {dataset: HadCRUT4, project: OBS, type: ground, -> version: 1, tier: 2} #dataset specific to the temperature var +> version: 1, tier: 2} #dataset specific to the temperature variable > > scripts: null >~~~ >{: .source} {: .solution} +## Creating variable groups + +Variable grouping can be used to preprocess different clusters of data for the same variable. For instance, the example below illustrates how we can compute separate multimodel means for CMIP5 and CMIP6 data given the same variable. Additionally we can also preprocess observed data for evaluation. + +> ## Example +>~~~YAML +> +>preprocessors: +> prep_mmm: +> custom_order: true +> regrid: +> target_grid: 2.5 x 2.5 +> scheme: linear +> multi_model_statistics: +> span: full +> statistics: [mean, median] +> +> prep_obs: +> mask_landsea: +> mask_out: sea +> regrid: +> target_grid: 2.5 x 2.5 +> scheme: linear +> +> #note that there is no field called datasets anymore +> #note how multiple ensembles are added by using (1:4) +>cmip5_datasets: &cmip5_datasets +> - {dataset: CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5} +> - {dataset: MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5} +> +>cmip6_datasets: &cmip6_datasets +> - {dataset: UKESM1-0-LL, ensemble: "r(1:4)i1p1f2", grid: gn, project: CMIP6} +> - {dataset: CanESM5, ensemble: "r(1:4)i1p2f1", grid: gn, project: CMIP6} +> +>diagnostics: +> +> diag_variable_groups: +> description: Demonstrate the use of variable groups. +> variables: +> tas_cmip5: &variable_settings # need a key name for the grouping +> short_name: tas # specify variable to look for +> preprocessor: prep_mmm +> mip: Amon +> exp: historical +> start_year: 2000 +> end_year: 2005 +> tag: TAS_CMIP5 #tag is optional if you are using these settings just once +> additional_datasets: *cmip5_datasets +> tas_obs: +> <<: *variable_settings +> preprocessor: prep_obs +> tag: TAS_OBS +> additional_datasets: +> - {dataset: HadCRUT4, project: OBS, type: ground, version: 1, tier: 2} +> tas_cmip6: +> <<: *variable_settings +> tag: TAS_CMIP6 +> additional_datasets: *cmip6_datasets #nothing changes from cmip5 except the data set +> scripts: null +>~~~ +>{: .source} +{: .solution} + +You should be able to see the variables grouped under different subdirectories under your output preproc directory. The different groupings can be accessed in your diagnostic by selecting the key name of the field variable_group such as tas_cmip5, tas_cmip6 or tas_obs. +> > ## How to find what CMIP data is available? > -> [CMIP5](https://pcmdi.llnl.gov/mips/cmip5/index.html) and [CMIP6](https://pcmdi.llnl.gov/CMIP6/Guide/dataUsers.html) data obey the [CF-conventions](http://cfconventions.org/). Available variables could be found under the [CMIP5 data request](https://pcmdi.llnl.gov/mips/cmip5/docs/standard_output.pdf?id=28) and the [CMIP6 Data Request](http://clipc-services.ceda.ac.uk/dreq/index.html). +> [CMIP5](https://pcmdi.llnl.gov/mips/cmip5/index.html) and [CMIP6](https://pcmdi.llnl.gov/CMIP6/Guide/dataUsers.html) data obey the [CF-conventions](http://cfconventions.org/). Available variables can be found under the [CMIP5 data request](https://pcmdi.llnl.gov/mips/cmip5/docs/standard_output.pdf?id=28) and the [CMIP6 Data Request](http://clipc-services.ceda.ac.uk/dreq/index.html). > > CMIP data is widely available via the Earth System Grid Federation ([ESGF](https://esgf.llnl.gov/)) and is accessible to users either via download from the ESGF portal or through the ESGF data nodes hosted by large computing facilities (like [CEDA-Jasmin](https://esgf-index1.ceda.ac.uk/), [DKRZ](https://esgf-data.dkrz.de/), etc). The ESGF also hosts observations for Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). > From 3312568d66c1b14b889eb6b47bf2c38c12e8a678 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 13:48:45 +0200 Subject: [PATCH 188/647] Correct pip --- _episodes/10-development-setup.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index 3235a9e6..ebbf0c23 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -81,16 +81,17 @@ conda activate esmvaltool If you run into trouble, please try recreating the environment. More information can be found in the [conda documentation](https://docs.conda.io/en/latest/). - ## Software installation Once all prerequisites are fulfilled, ESMValTool can be installed by running the following commands in the directory containing the ESMValTool source code: ~~~bash -pip install . +pip install --editable '.[develop]' ~~~ +This will add the `esmvaltool` directory to the Python path in editable mode and install the developemnt dependencies. + ## Test the installation The next step is to check that the installation works properly. From 2c28577c2288d324d5529f60b968e232546ea005 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Tue, 30 Jun 2020 13:55:13 +0200 Subject: [PATCH 189/647] fixed typo --- _episodes/05-preprocessor.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index dab2f95b..c0e6c686 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -56,7 +56,7 @@ You may use one or more of several preprocessors listed in the [documentation](h > Changing the order of preprocessors can also speed up your processing. For instance, if you want to extract a two-dimensional layer from a 3D field and re-grid it, the layer extraction should be done first. If you did it the other way around, then the regridding function would be applied to all the layers of your 3D cube and it would take much more time. {: .callout} -Some preprocessor modeules are always applied and do not need to be called. This includes the preprocessors that load the data, apply any fixes and save the data file afterwards. These do not need to be explicitly included in recipes. +Some preprocessor modules are always applied and do not need to be called. This includes the preprocessors that load the data, apply any fixes and save the data file afterwards. These do not need to be explicitly included in recipes. > ## Exercise: Adding more preprocessor steps > @@ -298,8 +298,8 @@ Variable grouping can be used to preprocess different clusters of data for the s > target_grid: 2.5 x 2.5 > scheme: linear > -> #note that there is no field called datasets anymore -> #note how multiple ensembles are added by using (1:4) +># note that there is no field called datasets anymore +># note how multiple ensembles are added by using (1:4) >cmip5_datasets: &cmip5_datasets > - {dataset: CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5} > - {dataset: MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5} From 91f6d95a8c27d045d27988068fc3f564fba76630 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 13:56:18 +0200 Subject: [PATCH 190/647] Mention the core --- _episodes/10-development-setup.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index ebbf0c23..bbc5af17 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -111,4 +111,10 @@ confirm that no errors are reported: python setup.py test --installation ~~~ +> ## ESMValCore +> +> Most core functionality for the ESMValTool is available in [ESMValCore](https://github.com/ESMValGroup/ESMValCore) Python package. +> If your contribution in ESMValTool needs changes to ESMValCore please follow [its contribution guide](https://github.com/ESMValGroup/ESMValCore/blob/master/CONTRIBUTING.md). +{: .callout} + {% include links.md %} From 84c8db7917a875875c3e395b18657abfff89460d Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 13:57:17 +0200 Subject: [PATCH 191/647] Apply suggestions from code review Co-authored-by: Peter Kalverla --- _episodes/10-development-setup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index bbc5af17..dc8902ae 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -6,19 +6,19 @@ questions: - "What are the prerequisites for installing ESMValTool?" - "How do I confirm that the installation was succesful?" objectives: -- "Execute a succesful ESMValTool installation" +- "Execute a succesful ESMValTool installation from source" keypoints: - "ESMValTool is installed from source code that lives in the [GitHub repository](https://github.com/ESMValGroup/ESMValTool)" - "All the required packages can be installed using conda and the [environment.yml file](https://github.com/ESMValGroup/ESMValTool/blob/master/environment.yml)" - "You can find more information about installation in the [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html)" --- -So you want to contribute code to ESMValTool, what follows describes a development installation to help you get going. +So you want to contribute code to ESMValTool. What follows describes a development installation to help you get going. > ## Attention > > - This episode is based on the ESMValTool installation instructions, for more information and advanced cases you can visit the ESMValTool [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html). -> - For this episode it is assumed you have knowledge of [git](https://git-scm.com/) you can refresh your knowledge in the corresponding [git carpentries course](http://swcarpentry.github.io/git-novice/). +> - For this episode it is assumed you have knowledge of [git](https://git-scm.com/). You can refresh your knowledge in the corresponding [git carpentries course](http://swcarpentry.github.io/git-novice/). {: .callout} ## Obtaining the source code @@ -61,7 +61,7 @@ in the repository (``environment.yml`` in the root folder). From now on, we will assume that the installation is going to be done through conda. -Ideally, you should create a conda environment for ESMValTool, so it is +Ideally, you should create a dedicated conda environment for ESMValTool, so it is independent from any other Python tools present in the system. To create an environment, go to the directory containing the ESMValTool source From 2af0d92f901d080344e0c55f0c80d90a319a467b Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 13:57:34 +0200 Subject: [PATCH 192/647] Update _episodes/10-development-setup.md Co-authored-by: Peter Kalverla --- _episodes/10-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index dc8902ae..2f374615 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -3,7 +3,7 @@ title: "Development Setup" teaching: 10 exercises: 20 questions: -- "What are the prerequisites for installing ESMValTool?" +- "What are the prerequisites for installing ESMValTool from source?" - "How do I confirm that the installation was succesful?" objectives: - "Execute a succesful ESMValTool installation from source" From f437580621a59022c354315252f69d247fd4ac18 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 13:58:51 +0200 Subject: [PATCH 193/647] Spelling --- _episodes/10-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index bbc5af17..becece71 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -113,7 +113,7 @@ python setup.py test --installation > ## ESMValCore > -> Most core functionality for the ESMValTool is available in [ESMValCore](https://github.com/ESMValGroup/ESMValCore) Python package. +> Most core functionality for the ESMValTool is available in the [ESMValCore](https://github.com/ESMValGroup/ESMValCore) Python package. > If your contribution in ESMValTool needs changes to ESMValCore please follow [its contribution guide](https://github.com/ESMValGroup/ESMValCore/blob/master/CONTRIBUTING.md). {: .callout} From 973052602e8f87792c6583798c4837377ac906ca Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 13:15:26 +0100 Subject: [PATCH 194/647] added some fixes. --- _episodes/conclusions.md | 41 ++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md index 0675838d..21f34818 100644 --- a/_episodes/conclusions.md +++ b/_episodes/conclusions.md @@ -34,15 +34,14 @@ From here, there are lots of ways that you can continue to use ESMValTool. ### Where can I get more information on ESMValTool? -Read the docs page: https://esmvaltool.readthedocs.io/ +> ## Additional resources: +> - [Read the docs page](https://esmvaltool.readthedocs.io/) +> - [ESMValTool home page](https://www.esmvaltool.org/) +> - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) +> - [Source code (ESMValTool)](https://github.com/ESMValGroup/ESMValTool) +> - [Source code (ESMValCore )](https://github.com/ESMValGroup/ESMValCore) +{: .callout} -ESMValTool home page: https://www.esmvaltool.org/ - -Technical description paper: https://doi.org/10.5194/gmd-13-1179-2020 - -Source code (ESMValTool): https://github.com/ESMValGroup/ESMValTool - -Source code (ESMValCore ): https://github.com/ESMValGroup/ESMValCore Additional publications: - Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, K., and Zechlau, S.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for emergent constraints and future projections from Earth system models in CMIP, Geosci. Model Dev. Discuss., https://doi.org/10.5194/gmd-2020-60, in review, 2020. @@ -58,6 +57,10 @@ There are lots of resources available for helping you use ESMValTool. If you get stuck, a great starting point is to create a new issue. [Link to ep 10] +There is also an ESMValTool email list [esmvaltool@listserv.dfn.de](esmvaltool@listserv.dfn.de). + +Everybody can send mail without being subscribed to the group, but note that there is a spam filter. +The email group archive is also [online](https://www.listserv.dfn.de/sympa/arc/esmvaltool/2020-06/). ### What if I find a bug? @@ -66,7 +69,8 @@ If you find a bug, please report it back to the ESMValTool team. This will help us fix it so that you can continue working, but also it means that ESMValTool will be more stable for everyone else as well. -To report a bug, please create a new issue using this page: https://github.com/ESMValGroup/ESMValTool/issues/new/choose +To report a bug, please create a new issue using the +[new issue page](https://github.com/ESMValGroup/ESMValTool/issues/new/choose). In your bug report, please describe the problem as clearly and as completely as possible. You may need to include a recipe or the output log as well. @@ -77,7 +81,24 @@ You may need to include a recipe or the output log as well. Please use the following reference: -Righi, M., Andela, B., Eyring, V., Lauer, A., Predoi, V., Schlund, M., Vegas-Regidor, J., Bock, L., Brötz, B., de Mora, L., Diblen, F., Dreyer, L., Drost, N., Earnshaw, P., Hassler, B., Koldunov, N., Little, B., Loosveldt Tomas, S., and Zimmermann, K.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – technical overview, Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020, 2020. +Please cite ESMValTool as: + +- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., + Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., + Weigel, K., and Zechlau, S.: + Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for + emergent constraints and future projections from Earth system models in CMIP, + Geosci. Model Dev. Discuss., + [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), + in review, 2020. + + +Please cite this tutorial as: + +- ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], + [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), + [DATE]. + The following papers From 77b4b90b747fce029fcb2a17c59693e1d53ec1ef Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 13:26:57 +0100 Subject: [PATCH 195/647] Added an exercise --- _episodes/conclusions.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md index 21f34818..9d8d8402 100644 --- a/_episodes/conclusions.md +++ b/_episodes/conclusions.md @@ -31,6 +31,14 @@ From here, there are lots of ways that you can continue to use ESMValTool. - You can contribute your recipe and diagnostics back into ESMValTool. [Link to ep 10] - You can learn how to prepare observational datasets to be suitable for use by ESMValTool. [ Link to ep 11] +> ## `What's next?` +> +> - Think about what you want to do with ESMValTool. +> - Decide what datasets you want to use. +> - How will you preprocess the data? +> - What will your diagnostic need to do? +> - What will your final figure show? +{: .challenge} ### Where can I get more information on ESMValTool? @@ -57,7 +65,7 @@ There are lots of resources available for helping you use ESMValTool. If you get stuck, a great starting point is to create a new issue. [Link to ep 10] -There is also an ESMValTool email list [esmvaltool@listserv.dfn.de](esmvaltool@listserv.dfn.de). +There is also an ESMValTool email list [esmvaltool@listserv.dfn.de](mailto:esmvaltool@listserv.dfn.de). Everybody can send mail without being subscribed to the group, but note that there is a spam filter. The email group archive is also [online](https://www.listserv.dfn.de/sympa/arc/esmvaltool/2020-06/). @@ -76,11 +84,8 @@ In your bug report, please describe the problem as clearly and as completely as You may need to include a recipe or the output log as well. - ### How do I cite ESMValTool? -Please use the following reference: - Please cite ESMValTool as: - Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., @@ -101,8 +106,6 @@ Please cite this tutorial as: -The following papers - {% include links.md %} From e55b5c49ab433c6d0d776f57b77cf96207af9e07 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 13:35:57 +0100 Subject: [PATCH 196/647] Added minor changes --- _episodes/conclusions.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md index 9d8d8402..2210d7f8 100644 --- a/_episodes/conclusions.md +++ b/_episodes/conclusions.md @@ -31,12 +31,13 @@ From here, there are lots of ways that you can continue to use ESMValTool. - You can contribute your recipe and diagnostics back into ESMValTool. [Link to ep 10] - You can learn how to prepare observational datasets to be suitable for use by ESMValTool. [ Link to ep 11] -> ## `What's next?` +> ## `Exercise: What do you want to do next?` > > - Think about what you want to do with ESMValTool. -> - Decide what datasets you want to use. +> - Decide what datasets and variables you want to use. +> - Is any observational data available? > - How will you preprocess the data? -> - What will your diagnostic need to do? +> - What will your diagnostic script need to do? > - What will your final figure show? {: .challenge} From a1c4d1ac6355970601e89c673fd8dbb8cec9bdf7 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 13:56:00 +0100 Subject: [PATCH 197/647] Added some basic text to the instructors guide --- _extras/guide.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/_extras/guide.md b/_extras/guide.md index 50f266f8..3094ce9c 100644 --- a/_extras/guide.md +++ b/_extras/guide.md @@ -1,6 +1,33 @@ --- title: "Instructor Notes" --- -FIXME + +This page includes some tips, reminders and advice for giving this tutorial. + +## Preparing the meeting. + +Once you've agreed to a date, and attendees have signed up, send them a link to +the pre-tutorial instructions page (setup.md). + +Plan for the tutorial to last two hours. If you do go longer, please include a comfort break. + +Coffee and biscuits always goes down well with participants. + +Remember to email attendees in advacnce to set up conda and work through the set up page. + +Remind people a few days before the meeting about the pre-meeting exercises. + + +## Tips + +- Test all recipes, diagnostics and instructions in advance. + +- Make sure you don't have issues with accessing the compute node via VPN or wifi, + +- Check to copmputing service for any planned downtime or potential interuptnios. + +- Download a local copy of the data, just in case. + +- Decide on one or two advanced mini-tutorials as a stretch goal but don't expect to do all of them. {% include links.md %} From fc891e712f4ce10be48355da3edd6d26a7681db6 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 30 Jun 2020 15:00:07 +0200 Subject: [PATCH 198/647] Fix typo Co-authored-by: Stefan Verhoeven --- _episodes/01-introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index f3edef4f..9131f347 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -91,7 +91,7 @@ ESMValTool is built and maintained by an active community of scientists and soft > ## Challenge: meet ESMValGroup > -> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is our 'organization' GitHub page. Have a look around. How many collaborators are there? Do you know any of them? You should see 2 main repositories: ESMValTool and ESMValCore. Visit each of the repositofires. How many people have contributed to each of them? Can you also find out how many people have contributed to this tutorial? +> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is our 'organization' GitHub page. Have a look around. How many collaborators are there? Do you know any of them? You should see 2 main repositories: ESMValTool and ESMValCore. Visit each of the repositories. How many people have contributed to each of them? Can you also find out how many people have contributed to this tutorial? > > > ## Solution > > From e37103a7aa61eda5e3848ef0548897928cab3622 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Tue, 30 Jun 2020 15:15:05 +0200 Subject: [PATCH 199/647] add DKRZ instructions --- setup.md | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/setup.md b/setup.md index e0671b08..f34a8a82 100644 --- a/setup.md +++ b/setup.md @@ -138,8 +138,92 @@ ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.n Note that the JASMIN is only open to certain locations (mostly universities, and research centres). You may need a VPN if you wish to connect from your home network. -### DLR -FIXME + + +Please request access to the working groups: +- [esmeval working group](https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval) +- [CMIP5 data](https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research) + +Once you have access to the data archive on CEDA, make sure to link your +CEDA and JASMIN accounts. +This can be done by checking the link to CEDA box on +[your JASMIN profile page](https://accounts.jasmin.ac.uk/account/profile/). + +The linking may take a few hours to take effect and is necessary for you to +access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC +are not accessible by default and special permission has to be requested to +access them via [the CEDA catalogue page](https://catalogue.ceda.ac.uk/). + +#### Test your Setup + +Log into jasmin-login: + +~~~ +ssh -X JASMIN-USERNAME@jasmin-login1.ceda.ac.uk +~~~ +{: .language-bash} + +Then log into the sci1 machine: + +~~~ +ssh -X jasmin-sci1 +~~~ +: .language-bash} + +Can you see the following locations: +~~~ +ls /group_workspaces/jasmin4/esmeval/obsdata/Tier2 +ls /badc/cmip5/data/cmip5/output1/MOHC/HadGEM2-ES +ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.nc +~~~ +{: .language-bash} + +Note that the JASMIN is only open to certain locations (mostly universities, and research centres). +You may need a VPN if you wish to connect from your home network. + + +### DKRZ + +If you do not already have an account at the DKRZ, then [register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could find a short introduction how to get started at DKRZ [here](https://www.dkrz.de/up/my-dkrz/getting-started/getting-started-at-dkrz). + +There is also an [user manual](https://www.dkrz.de/up/systems/mistral) for mistral which is DKRZ's current supercomputer. + +#### Join a project + +To use the resources on DKRZ you have to join a project. You could join an existing project by logging into [https://luv.dkrz.de/](https://luv.dkrz.de/) with your account and select 'Join existing project'. Once you are accepted by a project we will turn your web account into a full LDAP account which allows you to log into and use our systems. If you have no access to an existing project here are some instructions [how to apply for resources](https://www.dkrz.de/services/bereitstellung-von-rechenleistung?set_language=en&cl=en). + +#### Access to data on DKRZ + +Availability of CMIP5 and CMIP6 data in this directories: +- CMIP5: /mnt/lustre01/work/kd0956/CMIP5/data/cmip5/output1/ +- CMIP6: /mnt/lustre02/work/ik1017/CMIP6/data/CMIP6/CMIP/ + +#### Test your Setup + +Log into Mistral (DKRZ) + +~~~ +ssh -X user-account@mistral.dkrz.de +~~~ +{: .language-bash} + +#### Additional information + +Login nodes are for compiling and job submission only! For all other tasks, use one of the pre- and post-processing nodes +~~~ +ssh -X @mistralpp.dkrz.de +~~~ +(see also [this](https://www.dkrz.de/up/systems/mistral/hpc-concepts)) + +Data storage: +- Personal data: home directory (24GiB) +- Project data: /work// +- Temporary data: scratch directory on /scratch/*/ will be automatically deleted after 14 days (15TiB) (Please use this directory for tests! Do not use the work directory for tests.) +(see also [this](https://www.dkrz.de/up/systems/mistral/hpc-concepts)) + +Running batch jobs: +Info and examples on SLURM job scheduling system at DKRZ could be found [here](https://www.dkrz.de/up/systems/mistral/running-job). + ### Other computing systems FIXME From 3717977403c40ce71e4219bd8a0b62e18eee631d Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 30 Jun 2020 15:38:33 +0200 Subject: [PATCH 200/647] Render yaml code blocks with syntax highlighting --- _episodes/05-preprocessor.md | 115 +++++++++++++++++------------------ 1 file changed, 56 insertions(+), 59 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index c0e6c686..91c366e1 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -29,17 +29,16 @@ Underneath the hood, each preprocessor is a modular python function that receive Each preprocessor section includes a preprocessor name, a list of preprocessor steps to be executed and any arguments needed by the preprocessor steps. ->~~~YAML -> preprocessors: -> prep_timeseries: -> annual_statistics: -> operator: mean ->~~~ -{: .source} +~~~yaml +preprocessors: + prep_timeseries: + annual_statistics: + operator: mean +~~~ -For instance, the 'annual_statistics' with the 'operation: mean' argument preprocessor receives an iris cube, takes the annual average for each year of data in the cube, and returns the processed cube. +For instance, the 'annual_statistics' with the 'operation: mean' argument preprocessor receives an iris cube, takes the annual average for each year of data in the cube, and returns the processed cube. -You may use one or more of several preprocessors listed in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). The standardised interface between the preprocessors allows them to be used modularly - like lego blocks. Almost any conceivable preprocessing order of operations can be performed using ESMValTool preprocessors. +You may use one or more of several preprocessors listed in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). The standardised interface between the preprocessors allows them to be used modularly - like lego blocks. Almost any conceivable preprocessing order of operations can be performed using ESMValTool preprocessors. > ## The 'custom order' command. > @@ -56,15 +55,15 @@ You may use one or more of several preprocessors listed in the [documentation](h > Changing the order of preprocessors can also speed up your processing. For instance, if you want to extract a two-dimensional layer from a 3D field and re-grid it, the layer extraction should be done first. If you did it the other way around, then the regridding function would be applied to all the layers of your 3D cube and it would take much more time. {: .callout} -Some preprocessor modules are always applied and do not need to be called. This includes the preprocessors that load the data, apply any fixes and save the data file afterwards. These do not need to be explicitly included in recipes. +Some preprocessor modules are always applied and do not need to be called. This includes the preprocessors that load the data, apply any fixes and save the data file afterwards. These do not need to be explicitly included in recipes. > ## Exercise: Adding more preprocessor steps > > Edit the [example recipe](LINK to episode #4) to first change the variable thetao, then add preprocessors to average over the latitude and longitude dimensions and finally average over the depth. Now run the recipe. > >> ## Solution ->> ->>~~~YAML +>> +>>~~~yaml >> preprocessors: >> prep_timeseries: >> annual_statistics: @@ -73,7 +72,7 @@ Some preprocessor modules are always applied and do not need to be called. This >> operator: mean >> depth_integration: >>~~~ ->>{: .source} +>> >{: .solution} {: .challenge} @@ -82,7 +81,7 @@ Some preprocessor modules are always applied and do not need to be called. This You can also define different preprocessors with several preprocessor sections (setting different preprocessor names). In the variable section you call the specific preprocessor which should be applied. > ## Example ->~~~YAML +>~~~yaml > preprocessors: > prep_timeseries_1: > annual_statistics: @@ -95,7 +94,7 @@ You can also define different preprocessors with several preprocessor sections ( > depth_integration: > --- > diagnostics: -> # -------------------------------------------------- +> # -------------------------------------------------- > # Time series diagnostics > # -------------------------------------------------- > diag_timeseries_temperature_1: @@ -105,9 +104,9 @@ You can also define different preprocessors with several preprocessor sections ( > short_name: thetaoga > preprocessor: prep_timeseries_1 > scripts: -> timeseries_diag: +> timeseries_diag: > script: ocean/diagnostic_timeseries.py -> +> > diag_timeseries_temperature_2: > description: simple_time_series > variables: @@ -118,7 +117,6 @@ You can also define different preprocessors with several preprocessor sections ( > timeseries_diag: > script: ocean/diagnostic_timeseries.py >~~~ ->{: .source} {: .solution} >## Challenge : How to write a recipe with multiple preprocessors @@ -126,21 +124,21 @@ You can also define different preprocessors with several preprocessor sections ( > >> ## Recipe >> ->>~~~YAML +>>~~~yaml >> >> datasets: >> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, >> ensemble: r1i1p1f2} #single dataset as an example ->> +>> >> preprocessors: >> prep_map: #preprocessor to just regrid data >> #fill preprocessor details here ->> +>> >> prep_map_land: #preprocessor to mask grid cells and then regrid >> #fill preprocessor details here including ordering ->> +>> >> diagnostics: ->> # -------------------------------------------------- +>> # -------------------------------------------------- >> # Two Simple diagnostics that illustrate the use of >> # different preprocessors >> # -------------------------------------------------- @@ -149,40 +147,40 @@ You can also define different preprocessors with several preprocessor sections ( >> variables: >> # put your variable of choice here >> # apply the first preprocessor i.e. name your preprocessor ->> # edit the following 4 lines for mip, grid and time +>> # edit the following 4 lines for mip, grid and time >> # based on your variable choice >> mip: Amon >> grid: gn #can change for variables from the same model ->> start_year: 1970 +>> start_year: 1970 >> end_year: 2000 >> scripts: null #no scripts called >> diag_land_only_plot: #second diagnostic >> description: #preprocess a variable for a 2D land only plot >> variables: ->> # include a variable and information ->> # as in the previous diagnostic and +>> # include a variable and information +>> # as in the previous diagnostic and >> # include your second preprocessor (masking and regridding) >> scripts: null # no scripts >>~~~ ->>{: .source} +>> >{: .solution} > ->> ## Solution: ->> +>> ## Solution: +>> >> Here is one solution to complete the challenge above using two different preprocessors ->> ->>~~~YAML +>> +>>~~~yaml >> >> datasets: >> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, >> ensemble: r1i1p1f2} #single dataset as an example ->> +>> >> preprocessors: >> prep_map: >> regrid: #apply the preprocessor to regrid >> target_grid: 1x1 # target resolution >> scheme: linear #how to interpolate for regridding ->> +>> >> prep_map_land: >> custom_order: true #ensure that given order of preprocessing is followed >> mask_landsea: #apply a mask @@ -190,9 +188,9 @@ You can also define different preprocessors with several preprocessor sections ( >> regrid: # now apply the preprocessor to regrid >> target_grid: 1x1 # target resolution >> scheme: linear #how to interpolate for regridding ->> +>> >> diagnostics: ->> # -------------------------------------------------- +>> # -------------------------------------------------- >> # Two Simple diagnostics that illustrate the use of >> # different preprocessors >> # -------------------------------------------------- @@ -203,10 +201,10 @@ You can also define different preprocessors with several preprocessor sections ( >> preprocessor: prep_map >> mip: Amon >> grid: gn #can change for variables from the same model ->> start_year: 1970 +>> start_year: 1970 >> end_year: 2000 >> scripts: null ->> +>> >> diag_land_only_plot: >> description: #preprocess a variable for a 2D land only plot >> variables: @@ -214,11 +212,11 @@ You can also define different preprocessors with several preprocessor sections ( >> preprocessor: prep_map_land >> mip: Amon >> grid: gn #can change for variables from the same model ->> start_year: 1970 +>> start_year: 1970 >> end_year: 2000 >> scripts: null >> ~~~ ->> {: .source} +>> > {: .solution} {: .challenge} @@ -227,20 +225,20 @@ You can also define different preprocessors with several preprocessor sections ( Sometimes, we may want to include specific datasets only for certain variables. An example is when we use observations for two different variables in a diagnostic. While the CMIP dataset details for the two variables may be common, the observations will likely not be so. It would be useful to know how to include different datasets for different variables. Here is an example of a simple preprocessor and diagnostic setup for that: > ## Example ->~~~YAML +>~~~yaml > > datasets: -> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, +> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, > ensemble: r1i1p1f2} #common to both variables discussed below -> +> > preprocessors: > prep_regrid: # regrid to get all data to the same resolution > regrid: #apply the preprocessor to regrid > target_grid: 2.5x2.5 # target resolution > scheme: linear #how to interpolate for regridding -> +> > diagnostics: -> # -------------------------------------------------- +> # -------------------------------------------------- > # Simple diagnostic to illustrate use of different > # datasets for different variables > # -------------------------------------------------- @@ -251,14 +249,14 @@ Sometimes, we may want to include specific datasets only for certain variables. > preprocessor: prep_regrid > mip: Amon > grid: gn #can change for variables from the same model -> start_year: 1970 -> end_year: 2000 # start and end years for a 30 year period, +> start_year: 1970 +> end_year: 2000 # start and end years for a 30 year period, > # we assume this is common and exists for all -> # model and obs data +> # model and obs data > additional_datasets: -> - {dataset: GPCP-SG, project: obs4mips, level: L3, +> - {dataset: GPCP-SG, project: obs4mips, level: L3, > version: v2.2, tier: 1} #dataset specific to this variable -> +> > tas: #second variable is surface temperature > preprocessor: prep_regrid > mip: Amon @@ -266,12 +264,12 @@ Sometimes, we may want to include specific datasets only for certain variables. > start_year: 1970 #some 30 year period > end_year: 2000 > additional_datasets: -> - {dataset: HadCRUT4, project: OBS, type: ground, +> - {dataset: HadCRUT4, project: OBS, type: ground, > version: 1, tier: 2} #dataset specific to the temperature variable -> +> > scripts: null >~~~ ->{: .source} +> {: .solution} ## Creating variable groups @@ -279,7 +277,7 @@ Sometimes, we may want to include specific datasets only for certain variables. Variable grouping can be used to preprocess different clusters of data for the same variable. For instance, the example below illustrates how we can compute separate multimodel means for CMIP5 and CMIP6 data given the same variable. Additionally we can also preprocess observed data for evaluation. > ## Example ->~~~YAML +>~~~yaml > >preprocessors: > prep_mmm: @@ -300,8 +298,8 @@ Variable grouping can be used to preprocess different clusters of data for the s > ># note that there is no field called datasets anymore ># note how multiple ensembles are added by using (1:4) ->cmip5_datasets: &cmip5_datasets -> - {dataset: CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5} +>cmip5_datasets: &cmip5_datasets +> - {dataset: CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5} > - {dataset: MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5} > >cmip6_datasets: &cmip6_datasets @@ -330,11 +328,11 @@ Variable grouping can be used to preprocess different clusters of data for the s > - {dataset: HadCRUT4, project: OBS, type: ground, version: 1, tier: 2} > tas_cmip6: > <<: *variable_settings -> tag: TAS_CMIP6 +> tag: TAS_CMIP6 > additional_datasets: *cmip6_datasets #nothing changes from cmip5 except the data set > scripts: null >~~~ ->{: .source} +> {: .solution} You should be able to see the variables grouped under different subdirectories under your output preproc directory. The different groupings can be accessed in your diagnostic by selecting the key name of the field variable_group such as tas_cmip5, tas_cmip6 or tas_obs. @@ -347,4 +345,3 @@ You should be able to see the variables grouped under different subdirectories u > > A full list of all CMIP named variables is available here: [http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html](http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html). {: .callout} - From 17a15e73e4c7faeb68aa2a1085d91e96b6dc32d9 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 30 Jun 2020 15:48:57 +0200 Subject: [PATCH 201/647] Remove 'should' --- _episodes/01-introduction.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 9131f347..92e43b00 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -89,9 +89,9 @@ The figure below shows the different components of ESMValTool. Some of the most ESMValTool is built and maintained by an active community of scientists and software engineers. Many of the interactions take place on GitHub. Here, we briefly introduce you to some of the most important pages. -> ## Challenge: meet ESMValGroup +> ## Meet ESMValGroup > -> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is our 'organization' GitHub page. Have a look around. How many collaborators are there? Do you know any of them? You should see 2 main repositories: ESMValTool and ESMValCore. Visit each of the repositories. How many people have contributed to each of them? Can you also find out how many people have contributed to this tutorial? +> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is our 'organization' GitHub page. Have a look around. How many collaborators are there? Do you know any of them? Near the top of the page there are 2 pinned repositories: ESMValTool and ESMValCore. Visit each of the repositories. How many people have contributed to each of them? Can you also find out how many people have contributed to this tutorial? > > > ## Solution > > @@ -99,9 +99,9 @@ ESMValTool is built and maintained by an active community of scientists and soft > {: .solution} {: .challenge} -> ## Challenge: issues and pull requests +> ## Issues and pull requests > -> Go back to the repository pages of [ESMValTool](https://github.com/ESMValGroup/ESMValTool) or [ESMValCore](https://github.com/ESMValGroup/ESMValCore). You should see tabs for 'issues' and 'pull requests'. You can use the labels to navigate them a bit more. How many open issues are about enhancements of ESMValTool? And how many bugs have been fixed in ESMValCore? There is also an 'insights' tab, where you can see a summary of recent activity. How many issues have been opened and closed in the past month? +> Go back to the repository pages of [ESMValTool](https://github.com/ESMValGroup/ESMValTool) or [ESMValCore](https://github.com/ESMValGroup/ESMValCore). There are tabs for 'issues' and 'pull requests'. You can use the labels to navigate them a bit more. How many open issues are about enhancements of ESMValTool? And how many bugs have been fixed in ESMValCore? There is also an 'insights' tab, where you can see a summary of recent activity. How many issues have been opened and closed in the past month? > > > ## Solution > > @@ -111,6 +111,6 @@ ESMValTool is built and maintained by an active community of scientists and soft ## Conclusion -This concludes the introduction of the tutorial. You should now have a basic knowledge of ESMValTool and our community. The following episodes will walk you through the installation, configuration and running your first recipes. +This concludes the introduction of the tutorial. You now have a basic knowledge of ESMValTool and our community. The following episodes will walk you through the installation, configuration and running your first recipes. {% include links.md %} From 5f18392fcd5d8a792845f833ac58af0dd6e20999 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 14:54:51 +0100 Subject: [PATCH 202/647] Update index.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index 5944e67e..5ad4e825 100644 --- a/index.md +++ b/index.md @@ -5,7 +5,7 @@ permalink: index.html # Is the only page that doesn't follow the pattern /:path date: '`r format(Sys.time(), "%d %B, %Y")`' --- -This tutorial is built to teach you how to use ESMValTool. +This tutorial helps you to use ESMValTool. The Earth System Model Evaluation Tool (ESMValTool) is a community developed software toolkit that aims to facilitate the diagnosis and evaluation of the causes and effects of model biases and inter-model spread within the CMIP model From 9d3a968d0eb361b19824bebec2a026e7c2fcfbb5 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Tue, 30 Jun 2020 15:57:09 +0200 Subject: [PATCH 203/647] add Birgit's suggestions --- setup.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/setup.md b/setup.md index f34a8a82..4296c84e 100644 --- a/setup.md +++ b/setup.md @@ -184,17 +184,17 @@ You may need a VPN if you wish to connect from your home network. ### DKRZ -If you do not already have an account at the DKRZ, then [register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could find a short introduction how to get started at DKRZ [here](https://www.dkrz.de/up/my-dkrz/getting-started/getting-started-at-dkrz). +If you do not already have an account at the DKRZ, then [register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could find a short introduction on how to get started at DKRZ [here](https://www.dkrz.de/up/my-dkrz/getting-started/getting-started-at-dkrz). -There is also an [user manual](https://www.dkrz.de/up/systems/mistral) for mistral which is DKRZ's current supercomputer. +There is also a [user manual](https://www.dkrz.de/up/systems/mistral) for Mistral which is DKRZ's current supercomputer. #### Join a project -To use the resources on DKRZ you have to join a project. You could join an existing project by logging into [https://luv.dkrz.de/](https://luv.dkrz.de/) with your account and select 'Join existing project'. Once you are accepted by a project we will turn your web account into a full LDAP account which allows you to log into and use our systems. If you have no access to an existing project here are some instructions [how to apply for resources](https://www.dkrz.de/services/bereitstellung-von-rechenleistung?set_language=en&cl=en). +To use the resources on DKRZ you have to join a project. One option is to join an existing project by logging into [https://luv.dkrz.de/](https://luv.dkrz.de/) with your account and select 'Join existing project'. Once you are accepted by the manager of your chosen project, your web account will be turned into a full LDAP account which will allow you to log into and use the DKRZ's resources. If you do not have access to an existing project, another option for you would be to apply for resources at DKRZ. Here are some instructions on [how to apply for resources](https://www.dkrz.de/services/bereitstellung-von-rechenleistung?set_language=en&cl=en). #### Access to data on DKRZ -Availability of CMIP5 and CMIP6 data in this directories: +CMIP5 and CMIP6 data are available in these directories: - CMIP5: /mnt/lustre01/work/kd0956/CMIP5/data/cmip5/output1/ - CMIP6: /mnt/lustre02/work/ik1017/CMIP6/data/CMIP6/CMIP/ @@ -218,11 +218,11 @@ ssh -X @mistralpp.dkrz.de Data storage: - Personal data: home directory (24GiB) - Project data: /work// -- Temporary data: scratch directory on /scratch/*/ will be automatically deleted after 14 days (15TiB) (Please use this directory for tests! Do not use the work directory for tests.) +- Temporary data: scratch directory on /scratch/*/ is automatically deleted after 14 days (15TiB) (Please use this directory for all your testing! Do not use the work directory for tests.) (see also [this](https://www.dkrz.de/up/systems/mistral/hpc-concepts)) Running batch jobs: -Info and examples on SLURM job scheduling system at DKRZ could be found [here](https://www.dkrz.de/up/systems/mistral/running-job). +Info and examples on SLURM job scheduling system at DKRZ can be found [here](https://www.dkrz.de/up/systems/mistral/running-job). ### Other computing systems From 0a343bfbdebfb5e7a3b256b51dcb359aedb74520 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 15:16:57 +0100 Subject: [PATCH 204/647] Update _episodes/conclusions.md --- _episodes/conclusions.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md index 2210d7f8..c1a6a3c0 100644 --- a/_episodes/conclusions.md +++ b/_episodes/conclusions.md @@ -53,7 +53,12 @@ From here, there are lots of ways that you can continue to use ESMValTool. Additional publications: -- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, K., and Zechlau, S.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for emergent constraints and future projections from Earth system models in CMIP, Geosci. Model Dev. Discuss., https://doi.org/10.5194/gmd-2020-60, in review, 2020. +- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., Lorenz, R., +Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, K., and Zechlau, S.: +Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics +for emergent constraints and future projections from Earth system models in CMIP, +Geosci. Model Dev. Discuss., +[https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), in review, 2020. - Eyring, V., Bock, L., Lauer, A., Righi, M., Schlund, M., Andela, B., Arnone, E., Bellprat, O., Brötz, B., Caron, L.-P., Carvalhais, N., Cionni, I., Cortesi, N., Crezee, B., Davin, E., Davini, P., Debeire, K., de Mora, L., Deser, C., Docquier, D., Earnshaw, P., Ehbrecht, C., Gier, B. K., Gonzalez-Reviriego, N., Goodman, P., Hagemann, S., Hardiman, S., Hassler, B., Hunter, A., Kadow, C., Kindermann, S., Koirala, S., Koldunov, N. V., Lejeune, Q., Lembo, V., Lovato, T., Lucarini, V., Massonnet, F., Müller, B., Pandde, A., Pérez-Zanón, N., Phillips, A., Predoi, V., Russell, J., Sellar, A., Serva, F., Stacke, T., Swaminathan, R., Torralba, V., Vegas-Regidor, J., von Hardenberg, J., Weigel, K., and Zimmermann, K.: ESMValTool v2.0 – Extended set of large-scale diagnostics for quasi-operational and comprehensive evaluation of Earth system models in CMIP, Geosci. Model Dev. Discuss., https://doi.org/10.5194/gmd-2019-291, in review, 2019. @@ -111,4 +116,3 @@ Please cite this tutorial as: - From e28c14f06cae1c39ec167c6b6796d9a9aa746be3 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 15:17:25 +0100 Subject: [PATCH 205/647] Update _episodes/conclusions.md --- _episodes/conclusions.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md index c1a6a3c0..c1cd3ac7 100644 --- a/_episodes/conclusions.md +++ b/_episodes/conclusions.md @@ -54,7 +54,7 @@ From here, there are lots of ways that you can continue to use ESMValTool. Additional publications: - Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., Lorenz, R., -Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, K., and Zechlau, S.: + Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, K., and Zechlau, S.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for emergent constraints and future projections from Earth system models in CMIP, Geosci. Model Dev. Discuss., @@ -115,4 +115,3 @@ Please cite this tutorial as: {% include links.md %} - From a2db55ef118e137b8bd914fe449470f2c7fb8c40 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 15:18:50 +0100 Subject: [PATCH 206/647] Update _episodes/conclusions.md --- _episodes/conclusions.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md index c1cd3ac7..6d39e598 100644 --- a/_episodes/conclusions.md +++ b/_episodes/conclusions.md @@ -60,7 +60,20 @@ for emergent constraints and future projections from Earth system models in CMIP Geosci. Model Dev. Discuss., [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), in review, 2020. -- Eyring, V., Bock, L., Lauer, A., Righi, M., Schlund, M., Andela, B., Arnone, E., Bellprat, O., Brötz, B., Caron, L.-P., Carvalhais, N., Cionni, I., Cortesi, N., Crezee, B., Davin, E., Davini, P., Debeire, K., de Mora, L., Deser, C., Docquier, D., Earnshaw, P., Ehbrecht, C., Gier, B. K., Gonzalez-Reviriego, N., Goodman, P., Hagemann, S., Hardiman, S., Hassler, B., Hunter, A., Kadow, C., Kindermann, S., Koirala, S., Koldunov, N. V., Lejeune, Q., Lembo, V., Lovato, T., Lucarini, V., Massonnet, F., Müller, B., Pandde, A., Pérez-Zanón, N., Phillips, A., Predoi, V., Russell, J., Sellar, A., Serva, F., Stacke, T., Swaminathan, R., Torralba, V., Vegas-Regidor, J., von Hardenberg, J., Weigel, K., and Zimmermann, K.: ESMValTool v2.0 – Extended set of large-scale diagnostics for quasi-operational and comprehensive evaluation of Earth system models in CMIP, Geosci. Model Dev. Discuss., https://doi.org/10.5194/gmd-2019-291, in review, 2019. +- Eyring, V., Bock, L., Lauer, A., Righi, M., Schlund, M., Andela, B., Arnone, E., + Bellprat, O., Brötz, B., Caron, L.-P., Carvalhais, N., Cionni, I., Cortesi, N., Crezee, B., + Davin, E., Davini, P., Debeire, K., de Mora, L., Deser, C., Docquier, D., Earnshaw, P., + Ehbrecht, C., Gier, B. K., Gonzalez-Reviriego, N., Goodman, P., Hagemann, S., + Hardiman, S., Hassler, B., Hunter, A., Kadow, C., Kindermann, S., Koirala, S., + Koldunov, N. V., Lejeune, Q., Lembo, V., Lovato, T., Lucarini, V., Massonnet, F., + Müller, B., Pandde, A., Pérez-Zanón, N., Phillips, A., Predoi, V., Russell, J., Sellar, A., + Serva, F., Stacke, T., Swaminathan, R., Torralba, V., Vegas-Regidor, J., von Hardenberg, J., + Weigel, K., and Zimmermann, K.: + ESMValTool v2.0 – Extended set of large-scale diagnostics for quasi-operational + and comprehensive evaluation of Earth system models in CMIP, + Geosci. Model Dev. Discuss., + [https://doi.org/10.5194/gmd-2019-291](https://doi.org/10.5194/gmd-2019-291), + in review, 2019. - Eyring, V., Righi, M., Lauer, A., Evaldsson, M., Wenzel, S., Jones, C., Anav, A., Andrews, O., Cionni, I., Davin, E. L., Deser, C., Ehbrecht, C., Friedlingstein, P., Gleckler, P., Gottschaldt, K.-D., Hagemann, S., Juckes, M., Kindermann, S., Krasting, J., Kunert, D., Levine, R., Loew, A., Mäkelä, J., Martin, G., Mason, E., Phillips, A. S., Read, S., Rio, C., Roehrig, R., Senftleben, D., Sterl, A., van Ulft, L. H., Walton, J., Wang, S., and Williams, K. D.: ESMValTool (v1.0) – a community diagnostic and performance metrics tool for routine evaluation of Earth system models in CMIP, Geosci. Model Dev., 9, 1747–1802, https://doi.org/10.5194/gmd-9-1747-2016, 2016. @@ -114,4 +127,3 @@ Please cite this tutorial as: {% include links.md %} - From ea739efceb4adcc892ec26ba765becfd26e11888 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 15:20:03 +0100 Subject: [PATCH 207/647] Update _episodes/conclusions.md --- _episodes/conclusions.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/_episodes/conclusions.md b/_episodes/conclusions.md index 6d39e598..56b4cea2 100644 --- a/_episodes/conclusions.md +++ b/_episodes/conclusions.md @@ -75,7 +75,17 @@ Geosci. Model Dev. Discuss., [https://doi.org/10.5194/gmd-2019-291](https://doi.org/10.5194/gmd-2019-291), in review, 2019. -- Eyring, V., Righi, M., Lauer, A., Evaldsson, M., Wenzel, S., Jones, C., Anav, A., Andrews, O., Cionni, I., Davin, E. L., Deser, C., Ehbrecht, C., Friedlingstein, P., Gleckler, P., Gottschaldt, K.-D., Hagemann, S., Juckes, M., Kindermann, S., Krasting, J., Kunert, D., Levine, R., Loew, A., Mäkelä, J., Martin, G., Mason, E., Phillips, A. S., Read, S., Rio, C., Roehrig, R., Senftleben, D., Sterl, A., van Ulft, L. H., Walton, J., Wang, S., and Williams, K. D.: ESMValTool (v1.0) – a community diagnostic and performance metrics tool for routine evaluation of Earth system models in CMIP, Geosci. Model Dev., 9, 1747–1802, https://doi.org/10.5194/gmd-9-1747-2016, 2016. +- Eyring, V., Righi, M., Lauer, A., Evaldsson, M., Wenzel, S., Jones, C., Anav, A., + Andrews, O., Cionni, I., Davin, E. L., Deser, C., Ehbrecht, C., Friedlingstein, P., + Gleckler, P., Gottschaldt, K.-D., Hagemann, S., Juckes, M., Kindermann, S., + Krasting, J., Kunert, D., Levine, R., Loew, A., Mäkelä, J., Martin, G., Mason, E., + Phillips, A. S., Read, S., Rio, C., Roehrig, R., Senftleben, D., Sterl, A., + van Ulft, L. H., Walton, J., Wang, S., and Williams, K. D.: + ESMValTool (v1.0) – a community diagnostic and performance metrics tool for + routine evaluation of Earth system models in CMIP, + Geosci. Model Dev., 9, 1747–1802, + [https://doi.org/10.5194/gmd-9-1747-2016](https://doi.org/10.5194/gmd-9-1747-2016), + 2016. ### Where can I get more help? @@ -126,4 +136,3 @@ Please cite this tutorial as: {% include links.md %} - From 702adca1704dd4ebc7a6a3c4d7eb13d493dabae5 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 15:29:46 +0100 Subject: [PATCH 208/647] Update setup.md Co-authored-by: Stefan Verhoeven --- setup.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.md b/setup.md index 4296c84e..b0095e71 100644 --- a/setup.md +++ b/setup.md @@ -256,8 +256,7 @@ You don’t need a github account to participate in the tutorial. However, if you want to raise an issue, contribute to the discussions, or share your code, please [create a github account](https://github.com/). -To learn how to use github, please have a look at this [introduction to github] -(https://lab.github.com/githubtraining/introduction-to-github). +To learn how to use github, please have a look at this [introduction to github](https://lab.github.com/githubtraining/introduction-to-github). You may hear a few of the following phrases during the tutorial. Don’t be alarmed, they will make sense eventually. From 7f7748bf5fee7064360dc7e0d003502ac0e2a44d Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Tue, 30 Jun 2020 16:43:06 +0200 Subject: [PATCH 209/647] include review suggetions --- _episodes/first_example_recipe.md | 35 ++++++++++++++++--------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 30fd7d08..854caf77 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -25,14 +25,15 @@ This episode describes how ESMValTool recipes work, how to run a recipe and how Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. - datasets: what datasets you want to use, including - - the time range and time resolution, - - the MIP, ensemble member, + - the time period and temporal resolution, + - the MIP (Model Intercomparison Project, like atmospheric MIP monthly data: amon), + - ensemble member, - the experiment (i.e. historical, ssp125, etc.), - - and the grid type (CMIP6 only). + - and the grid type (necessary for CMIP6 only). - - preprocessors: general operations applied to a dataset before handling it in a diagnostic, listing + - preprocessors: general operations applied to a dataset before handling it in a diagnostic, defining - which preprocessor modules to apply, - - the order to apply them, + - the order in which they are applied, - and the preprocessor arguments. This section can also be optional, if no preprocessing is needed. @@ -42,17 +43,17 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w - the desired diagnostic script to use, - and additional diagnostic script options or arguments, if needed. - Also include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. + It is possible to also include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. - description: a brief description of the recipe, including - who wrote the recipe and who maintains it, - - which project is responsible for it, - - and which publications, references are linked with the recipe. + - which project the recipe was written for, + - and which publications and references are linked with the recipe. - Note that the authors, publications and references are to be named in the config-references.yml + Note that the authors, publications and references need to be included in the `config-references.yml` for the recipe to run successfully. The information you provide in the recipe is not only affecting the processes you are starting, but also the directory names your output will be structured in. -For additional reeds, please have a look at the recipe format description in the [ESMValTool manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). +For additional reads, please have a look at the recipe format description in the [ESMValTool manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). ## How to run ESMValTool @@ -67,7 +68,7 @@ To try your hand with a basic recipe, please work through this episode. ## Introduction to the example recipe The recipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. -Please download the following recipe into your ESMValTool working area with the name: recipe_example.yml LINK +Please download the following recipe into your ESMValTool working directory with the name: recipe_example.yml LINK > ## recipe_example.yml > ~~~YAML @@ -117,7 +118,7 @@ Please download the following recipe into your ESMValTool working area with the {: .solution} > ## Explore the recipe -> Use the command and investigate the sample recipe. +> Use the following command and investigate the sample recipe. > ~~~bash > vim recipe_example.yml > ~~~ @@ -128,10 +129,10 @@ Please note the following sections: The documentation consists of the following information: - description: a short description of the recipe - - authors: a list of authors (linked to esmvaltool/config-references.yml) - - maintainer: a list of maintainers (linked to esmvaltool/config-references.yml) - - references: a list of references (linked to a bibtexfile in esmvaltool/references with the same name) - - projects: a list of projects (linked to esmvaltool/config-references.yml) + - authors: a list of authors (linked to `esmvaltool/config-references.yml`) + - maintainer: a list of maintainers (linked to `esmvaltool/config-references.yml`) + - references: a list of references (linked to a bibtexfile in `esmvaltool/references` with the same name) + - projects: a list of projects (linked to `esmvaltool/config-references.yml`) - datasets: lines 22-23 @@ -144,7 +145,7 @@ Please note the following sections: - ensemble member (key: ensemble) - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) - model grid (for CMIP6 data only, key: grid) - - alias (key: alias; use the alias for e.g. a more human readable name) + - alias (key: alias; use the alias for e.g. a more human readable name for the dataset) - preprocessors: lines 25-28 From 9ea504ef16aabae34bb3c2b0359faba27c7f651b Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 15:57:59 +0100 Subject: [PATCH 210/647] Added Jaros comment --- index.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/index.md b/index.md index 5ad4e825..7d5405ef 100644 --- a/index.md +++ b/index.md @@ -34,15 +34,14 @@ These mini-tutorials can be appended to the main tutorial or worked through inde > ## Prerequisites > -> - Basic understanding of git (optional) -> -> - Basic understanding of your preferred command line interface (ie a bash terminal) -> -> - Access to CMIP data -> -> - Access to a suitable computing system (eg Jasmin, DLR machine) -> -> - Github account (optional) +> *Minimal requirements:* +> - Basic understanding of your preferred command line interface (ie a bash terminal) +> - Laptop/desktop with [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed +> - Access to CMIP data +> *Optional, but useful:* +> - Basic understanding of git +> - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) +> - GitHub account {: .prereq} From 0a4ef5cc032df34e2fbdf70cc5f4e60304485ace Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 17:01:23 +0200 Subject: [PATCH 211/647] Add GitHub actions workflow to run check --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..efbb0a4a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: Jekyll site CI + +on: + push: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup R + uses: r-lib/actions/setup-r@v1 + with: + r-version: '3.5.3' + - name: R deps + run: | + install.packages('knitr', repos = 'https://', dependencies = TRUE) + install.packages('stringr', repos = 'https://cran.rstudio.com', dependencies = TRUE) + install.packages('checkpoint', repos = 'https://cran.rstudio.com', dependencies = TRUE) + install.packages('ggplot2', repos = 'https://cran.rstudio.com', dependencies = TRUE) + shell: Rscript {0} + - name: Setup Ruby + uses: ruby/setup-ruby@v1.38.0 + with: + ruby-version: 2.6 + - name: Ruby deps + run: gem install json kramdown jekyll bundler + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Python deps + run: pip install pyyaml + - name: Check all lessons + run: make lesson-check-all From 8ba22c767436d6dd55df089a7ada423e793b4a27 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 16:05:18 +0100 Subject: [PATCH 212/647] linked a missing link;# --- index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.md b/index.md index 7d5405ef..ea8b3788 100644 --- a/index.md +++ b/index.md @@ -38,6 +38,7 @@ These mini-tutorials can be appended to the main tutorial or worked through inde > - Basic understanding of your preferred command line interface (ie a bash terminal) > - Laptop/desktop with [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed > - Access to CMIP data +> > *Optional, but useful:* > - Basic understanding of git > - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) @@ -48,7 +49,8 @@ These mini-tutorials can be appended to the main tutorial or worked through inde ### Main things you need to know before starting this course 1. This tutorial can be taken online independently or taught by one of our instructors. -2. Please check the common issues page if you get stuck [Link to common issues page]. Otherwise, help is always available from ESMValTool developers via the github issues page. +2. If you get stuck, help is always available from the tutors, from ESMValTool developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) + or via the [ESMValTool email list](mailto:esmvaltool@listserv.dfn.de). 3. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. 4. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. From d0ae46ee7e326c4542c75dc9949adc94c27cd17c Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 16:07:45 +0100 Subject: [PATCH 213/647] fix minor glitch --- index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/index.md b/index.md index ea8b3788..94b3a2f6 100644 --- a/index.md +++ b/index.md @@ -19,7 +19,6 @@ These mini-tutorials can be appended to the main tutorial or worked through inde > ## What will you learn in this course > > - What is ESMValTool -> > - How to install ESMValTool > - How to configure ESMValTool for your local system > - How to run ESMValTool From c38ee3ce3396781d0f8dd4be3aab23508a285044 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 16:10:46 +0100 Subject: [PATCH 214/647] re-ordered a few phrases --- index.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/index.md b/index.md index 94b3a2f6..d5e46dae 100644 --- a/index.md +++ b/index.md @@ -48,24 +48,22 @@ These mini-tutorials can be appended to the main tutorial or worked through inde ### Main things you need to know before starting this course 1. This tutorial can be taken online independently or taught by one of our instructors. -2. If you get stuck, help is always available from the tutors, from ESMValTool developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) +2. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. +3. If you get stuck, help is always available from the tutors, from ESMValTool developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) or via the [ESMValTool email list](mailto:esmvaltool@listserv.dfn.de). -3. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. -4. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. +4. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. -{% include links.md %} - > ## Additional resources: > - [Read the docs page](https://esmvaltool.readthedocs.io/) > - [ESMValTool home page](https://www.esmvaltool.org/) > - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) -> - [Source code (ESMValTool)](https://github.com/ESMValGroup/ESMValTool) -> - [Source code (ESMValCore )](https://github.com/ESMValGroup/ESMValCore) +> - [ESMValTool Source code](https://github.com/ESMValGroup/ESMValTool) +> - [ESMValCore Source code](https://github.com/ESMValGroup/ESMValCore) {: .callout} -## Citation +## How to cite ESMValTool Please cite this tutorial as: @@ -83,3 +81,7 @@ Please cite ESMValTool as: Geosci. Model Dev. Discuss., [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), in review, 2020. + + +{% include links.md %} + From cb34c651111ee3b031d7489fcfa889a613103779 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 17:26:16 +0200 Subject: [PATCH 215/647] Cache R deps + store check message in artifact --- .github/workflows/ci.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index efbb0a4a..ca172d9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,4 +33,16 @@ jobs: - name: Python deps run: pip install pyyaml - name: Check all lessons - run: make lesson-check-all + run: make lesson-check-all | tee check-messages.txt + - name: Build site + run: make --always-make site + - name: Cache R deps + uses: actions/cache@v2 + with: + path: $HOME/.local/share/renv + key: r-${{ hashFiles('renv.lock') }} + restore-keys: r- + - uses: actions/upload-artifact@v2 + with: + name: check-messages + path: check-messages.txt \ No newline at end of file From 266127b1e1a8715148292712a3d02f47c8bc799f Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 16:29:19 +0100 Subject: [PATCH 216/647] testing a link --- setup.md | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/setup.md b/setup.md index b0095e71..2b71f223 100644 --- a/setup.md +++ b/setup.md @@ -5,44 +5,42 @@ title: Preparations for participating in the tutorial This page includes some information on how to prepare for participating in this tutorial. > ## Prerequisites +> > The prerequisites for the tutorial are listed on the > [tutorials home page]({{ page.root}}[% index.md %}) -> and are also eproduced here: -> - Basic understanding of git (optional) -> -> - Basic understanding of your preferred command line interface (ie a bash terminal) -> -> - Access to CMIP data +> and are also reproduced here: > -> - Access to a suitable computing system (eg Jasmin, DLR machine) +> *Minimal requirements:* +> - Basic understanding of your preferred command line interface (ie a bash terminal) +> - Laptop/desktop with [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed +> - Access to CMIP data > -> - Github account (optional) +> *Optional, but useful:* +> - Basic understanding of git +> - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) +> - GitHub account {: .prereq} -## Optional tutorials to be prepared to use ESMValTool - +## Command line & git tutorials We typically use the command line to interact with ESMValTool. While most of us are likely to have experience with the command line, -novices may want to work through this software carpentry unix shell course. +novices may want to work through this software carpentry unix shell course: -- Command line: [https://swcarpentry.github.io/shell-novice/](https://swcarpentry.github.io/shell-novice/) +- Introduction to the unix shell: [https://swcarpentry.github.io/shell-novice/](https://swcarpentry.github.io/shell-novice/) Git is a distributed version-control system for tracking changes in source code during software development. It’s how we distribute, share, and manage the ESMValTool code. -- git: [https://swcarpentry.github.io/git-novice/](https://swcarpentry.github.io/git-novice/) - - +- Introduction to git: [https://swcarpentry.github.io/git-novice/](https://swcarpentry.github.io/git-novice/) ## Access to CMIP and Observational data and a suitable compute cluster -To complete this tutorial and use ESMValTool, you will need access to data in a reasonable format. -Some data will be provided, but there is simply too much data available -for your tutors to make it all available directly. +To complete this tutorial and use ESMValTool, you will need access to data in a reasonable format +and you will need some kind of computer to run ESMValTool. ESMValTool may be run on multiple platforms, from your local machine to large computing clusters. @@ -53,8 +51,7 @@ The benefit of using a compute cluster with an ESGF node is that the is locally stored on disk and accessible directly by the tool. Similarly, observational data would also be available at these sites. -Here are a few options -for compute clusters with ESGF nodes: +Here are a few options for compute clusters with ESGF nodes: - CEDA-Jasmin (UK): - DKRZ (Germany): @@ -62,18 +59,22 @@ for compute clusters with ESGF nodes: A full list of all ESGF nodes is available [here](https://esgf.llnl.gov/nodes.html). - If you're running on a computing cluster without an ESGF node, such as your local machine, or your institue machine, you will most likely have to make a local copy of the data that you need. -If neccesairy, data can be downloaded using the +While some data will be provided by your tutors, there is simply too much data +for your tutors to make it all available directly. + +If you do not have access to an ESGF node, data can be downloaded using the [synda tool](https://prodiguer.github.io/synda/index.html). - ### CEDA-Jasmin +Please skip this section if you are not going to use JASMIN and go [here](Github account (Advanced)). + + If you do not already have an account on JASMIN, then request an account as soon as possible. Please follow [these instructions on how to create a Jasmin account](https://help.jasmin.ac.uk/article/4435-get-a-jasmin-account-portal) From 54e6d7a0300250baaeb1ae11a98611b97c1c91d6 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 16:36:57 +0100 Subject: [PATCH 217/647] adding links here --- setup.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/setup.md b/setup.md index 2b71f223..bf243d45 100644 --- a/setup.md +++ b/setup.md @@ -53,8 +53,8 @@ Similarly, observational data would also be available at these sites. Here are a few options for compute clusters with ESGF nodes: -- CEDA-Jasmin (UK): -- DKRZ (Germany): +- [CEDA-Jasmin (UK)](#CEDA-Jasmin) +- [DKRZ (Germany)](#DKRZ) - ETHZ (Switzerland): A full list of all ESGF nodes is available [here](https://esgf.llnl.gov/nodes.html). @@ -68,11 +68,16 @@ for your tutors to make it all available directly. If you do not have access to an ESGF node, data can be downloaded using the [synda tool](https://prodiguer.github.io/synda/index.html). - + +Depending on which machine you plan to use, you will need to work through one set of the following instructions: +- [CEDA-Jasmin (UK)](#CEDA-Jasmin) +- [DKRZ (Germany)](#DKRZ) +- [Your local machine](#Your-local-machine) + ### CEDA-Jasmin -Please skip this section if you are not going to use JASMIN and go [here](Github account (Advanced)). +Please skip this section if you are not going to use JASMIN and go [here](#Github-account-(Advanced)). If you do not already have an account on JASMIN, then request an account as @@ -183,8 +188,14 @@ Note that the JASMIN is only open to certain locations (mostly universities, and You may need a VPN if you wish to connect from your home network. +Congratulations! Please go here [here](#Github-account-(Advanced)) next. + + + ### DKRZ +Please skip this section if you are not going to use JASMIN and go [here](#Github-account-(Advanced)). + If you do not already have an account at the DKRZ, then [register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could find a short introduction on how to get started at DKRZ [here](https://www.dkrz.de/up/my-dkrz/getting-started/getting-started-at-dkrz). There is also a [user manual](https://www.dkrz.de/up/systems/mistral) for Mistral which is DKRZ's current supercomputer. @@ -226,10 +237,15 @@ Running batch jobs: Info and examples on SLURM job scheduling system at DKRZ can be found [here](https://www.dkrz.de/up/systems/mistral/running-job). +Congratulations! Please go here [here](#Github-account-(Advanced)) next. + + ### Other computing systems FIXME -### Your own machine +### Your local machine + +Please skip this section if you are not going to use ESMValTool on your local machine and go [here](#Github-account-(Advanced)). If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space available to install conda & ESMVAlTool, but also enough to make a copy of some data. From 40ddf79d26cb4cca733e21d448580a7f77a7fd6c Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Tue, 30 Jun 2020 16:46:08 +0100 Subject: [PATCH 218/647] Spelling --- setup.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/setup.md b/setup.md index bf243d45..dd50950e 100644 --- a/setup.md +++ b/setup.md @@ -188,13 +188,13 @@ Note that the JASMIN is only open to certain locations (mostly universities, and You may need a VPN if you wish to connect from your home network. -Congratulations! Please go here [here](#Github-account-(Advanced)) next. +Congratulations! Please go here [here](#GitHub-account-(Advanced)) next. ### DKRZ -Please skip this section if you are not going to use JASMIN and go [here](#Github-account-(Advanced)). +Please skip this section if you are not going to use JASMIN and go [here](#GitHub-account-(Advanced)). If you do not already have an account at the DKRZ, then [register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could find a short introduction on how to get started at DKRZ [here](https://www.dkrz.de/up/my-dkrz/getting-started/getting-started-at-dkrz). @@ -237,7 +237,7 @@ Running batch jobs: Info and examples on SLURM job scheduling system at DKRZ can be found [here](https://www.dkrz.de/up/systems/mistral/running-job). -Congratulations! Please go here [here](#Github-account-(Advanced)) next. +Congratulations! Please go here [here](#GitHub-account-(Advanced)) next. ### Other computing systems @@ -245,7 +245,7 @@ FIXME ### Your local machine -Please skip this section if you are not going to use ESMValTool on your local machine and go [here](#Github-account-(Advanced)). +Please skip this section if you are not going to use ESMValTool on your local machine and go [here](#GitHub-account-(Advanced)). If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space available to install conda & ESMVAlTool, but also enough to make a copy of some data. @@ -267,23 +267,23 @@ available in Windows 10. -## Github account (Advanced) +## GitHub account (Advanced) -You don’t need a github account to participate in the tutorial. +You don’t need a GitHub account to participate in the tutorial. However, if you want to raise an issue, contribute to the discussions, -or share your code, please [create a github account](https://github.com/). +or share your code, please [create a GitHub account](https://github.com/). -To learn how to use github, please have a look at this [introduction to github](https://lab.github.com/githubtraining/introduction-to-github). +To learn how to use GitHub, please have a look at this [introduction to GitHub](https://lab.github.com/githubtraining/introduction-to-github). You may hear a few of the following phrases during the tutorial. Don’t be alarmed, they will make sense eventually. -### github issues -Issues are github’s ticketing system. +### GitHub issues +Issues are GitHub’s ticketing system. They allow users and developers to discuss problems, identify bugs, or to make suggestions. -Each issue is assigned a number and will have it’s own page on github. +Each issue is assigned a number and will have it’s own page on GitHub. -Here’s an explanation of the [github issues](https://guides.github.com/features/issues/). +Here’s an explanation of the [GitHub issues](https://guides.github.com/features/issues/). Raising an issue is the act of creating a new issue. If you are asked to raise an issue, please follow any instructions that you are given, @@ -292,7 +292,7 @@ and also make sure that you read the default issue text. ### pull request -A github pull request is the act of requesting that a branch is merged with another branch. +A GitHub pull request is the act of requesting that a branch is merged with another branch. This is an advanced feature of GitHub, and will generally be performed by the ESMValTool development team. From 4f99e3ac3246c05ebbf45938b07751488c2620fa Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 30 Jun 2020 17:47:27 +0200 Subject: [PATCH 219/647] Enable Ruby cache --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca172d9e..457d55cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,7 @@ jobs: uses: ruby/setup-ruby@v1.38.0 with: ruby-version: 2.6 + bundler-cache: true - name: Ruby deps run: gem install json kramdown jekyll bundler - name: Setup Python From 8d2a9139455733d1f8152999617b5f00078bc499 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 08:48:46 +0200 Subject: [PATCH 220/647] Move R cache up + latest ruby --- .github/workflows/ci.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 457d55cf..23b07fab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,12 @@ jobs: uses: r-lib/actions/setup-r@v1 with: r-version: '3.5.3' + - name: Cache R deps + uses: actions/cache@v2 + with: + path: $HOME/.local/share/renv + key: r-${{ hashFiles('renv.lock') }} + restore-keys: r- - name: R deps run: | install.packages('knitr', repos = 'https://', dependencies = TRUE) @@ -23,7 +29,6 @@ jobs: - name: Setup Ruby uses: ruby/setup-ruby@v1.38.0 with: - ruby-version: 2.6 bundler-cache: true - name: Ruby deps run: gem install json kramdown jekyll bundler @@ -37,13 +42,7 @@ jobs: run: make lesson-check-all | tee check-messages.txt - name: Build site run: make --always-make site - - name: Cache R deps - uses: actions/cache@v2 - with: - path: $HOME/.local/share/renv - key: r-${{ hashFiles('renv.lock') }} - restore-keys: r- - uses: actions/upload-artifact@v2 with: name: check-messages - path: check-messages.txt \ No newline at end of file + path: check-messages.txt From e070ef6706c7e813f3cd6b1528629ffabfbafc6b Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 09:05:43 +0200 Subject: [PATCH 221/647] Disable R + Set ruby version We use *.md instead of *.Rmd Use minimal minor ruby version from Gemfile --- .github/workflows/ci.yml | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23b07fab..df3f55bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,26 +9,27 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Setup R - uses: r-lib/actions/setup-r@v1 - with: - r-version: '3.5.3' - - name: Cache R deps - uses: actions/cache@v2 - with: - path: $HOME/.local/share/renv - key: r-${{ hashFiles('renv.lock') }} - restore-keys: r- - - name: R deps - run: | - install.packages('knitr', repos = 'https://', dependencies = TRUE) - install.packages('stringr', repos = 'https://cran.rstudio.com', dependencies = TRUE) - install.packages('checkpoint', repos = 'https://cran.rstudio.com', dependencies = TRUE) - install.packages('ggplot2', repos = 'https://cran.rstudio.com', dependencies = TRUE) - shell: Rscript {0} + # - name: Setup R + # uses: r-lib/actions/setup-r@v1 + # with: + # r-version: '3.5.3' + # - name: Cache R deps + # uses: actions/cache@v2 + # with: + # path: $HOME/.local/share/renv + # key: r-${{ hashFiles('renv.lock') }} + # restore-keys: r- + # - name: R deps + # run: | + # install.packages('knitr', repos = 'https://', dependencies = TRUE) + # install.packages('stringr', repos = 'https://cran.rstudio.com', dependencies = TRUE) + # install.packages('checkpoint', repos = 'https://cran.rstudio.com', dependencies = TRUE) + # install.packages('ggplot2', repos = 'https://cran.rstudio.com', dependencies = TRUE) + # shell: Rscript {0} - name: Setup Ruby uses: ruby/setup-ruby@v1.38.0 - with: + with: + ruby-version: 2.5 bundler-cache: true - name: Ruby deps run: gem install json kramdown jekyll bundler From 36837c7592e36763d915d19e3914adcfc12d6fe6 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 09:23:04 +0200 Subject: [PATCH 222/647] Use newer Ubuntu --- .github/workflows/ci.yml | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df3f55bb..6b7e667f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,26 +6,9 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - # - name: Setup R - # uses: r-lib/actions/setup-r@v1 - # with: - # r-version: '3.5.3' - # - name: Cache R deps - # uses: actions/cache@v2 - # with: - # path: $HOME/.local/share/renv - # key: r-${{ hashFiles('renv.lock') }} - # restore-keys: r- - # - name: R deps - # run: | - # install.packages('knitr', repos = 'https://', dependencies = TRUE) - # install.packages('stringr', repos = 'https://cran.rstudio.com', dependencies = TRUE) - # install.packages('checkpoint', repos = 'https://cran.rstudio.com', dependencies = TRUE) - # install.packages('ggplot2', repos = 'https://cran.rstudio.com', dependencies = TRUE) - # shell: Rscript {0} - name: Setup Ruby uses: ruby/setup-ruby@v1.38.0 with: @@ -41,9 +24,10 @@ jobs: run: pip install pyyaml - name: Check all lessons run: make lesson-check-all | tee check-messages.txt - - name: Build site - run: make --always-make site - uses: actions/upload-artifact@v2 with: name: check-messages path: check-messages.txt + - name: Build site + run: make --always-make site + From 1580d790bdc28fc1398dbd9a8ae9abacb347a8a6 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Wed, 1 Jul 2020 12:38:48 +0200 Subject: [PATCH 223/647] add results from standard recipe run --- _episodes/first_example_recipe.md | 277 +++++++++++++++++- ...ries_temperature_1859_2005_timeseries_.png | Bin 0 -> 33451 bytes ...ies_temperature_1859_2005_timeseries_0.png | Bin 0 -> 32930 bytes files/recipe_example_output/log.txt | 53 ++++ files/recipe_example_output/main_log.txt | 80 +++++ files/recipe_example_output/metadata.yml | 24 ++ files/recipe_example_output/settings.yml | 14 + 7 files changed, 441 insertions(+), 7 deletions(-) create mode 100644 fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png create mode 100644 fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png create mode 100644 files/recipe_example_output/log.txt create mode 100644 files/recipe_example_output/main_log.txt create mode 100644 files/recipe_example_output/metadata.yml create mode 100644 files/recipe_example_output/settings.yml diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 854caf77..0faccfae 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -211,7 +211,88 @@ Please note the following sections: {: .challenge} > ## Exemplary output -> FIXME +> ~~~ +> 2020-07-01 08:22:58,571 UTC [33433] INFO +> ______________________________________________________________________ +> _____ ____ __ ____ __ _ _____ _ +> | ____/ ___|| \/ \ \ / /_ _| |_ _|__ ___ | | +> | _| \___ \| |\/| |\ \ / / _` | | | |/ _ \ / _ \| | +> | |___ ___) | | | | \ V / (_| | | | | (_) | (_) | | +> |_____|____/|_| |_| \_/ \__,_|_| |_|\___/ \___/|_| +> ______________________________________________________________________ +> +> ESMValTool - Earth System Model Evaluation Tool. +> +> http://www.esmvaltool.org +> +> CORE DEVELOPMENT TEAM AND CONTACTS: +> Veronika Eyring (PI; DLR, Germany - veronika.eyring@dlr.de) +> Bouwe Andela (NLESC, Netherlands - b.andela@esciencecenter.nl) +> Bjoern Broetz (DLR, Germany - bjoern.broetz@dlr.de) +> Lee de Mora (PML, UK - ledm@pml.ac.uk) +> Niels Drost (NLESC, Netherlands - n.drost@esciencecenter.nl) +> Nikolay Koldunov (AWI, Germany - nikolay.koldunov@awi.de) +> Axel Lauer (DLR, Germany - axel.lauer@dlr.de) +> Benjamin Mueller (LMU, Germany - b.mueller@iggf.geo.uni-muenchen.de) +> Valeriu Predoi (URead, UK - valeriu.predoi@ncas.ac.uk) +> Mattia Righi (DLR, Germany - mattia.righi@dlr.de) +> Manuel Schlund (DLR, Germany - manuel.schlund@dlr.de) +> Javier Vegas-Regidor (BSC, Spain - javier.vegas@bsc.es) +> Klaus Zimmermann (SMHI, Sweden - klaus.zimmermann@smhi.se) +> +> For further help, please read the documentation at +> http://esmvaltool.readthedocs.io. Have fun! +> +> 2020-07-01 08:22:58,573 UTC [33433] INFO Using config file /pf/b/b380506/work/config-DKRZ.yml +> 2020-07-01 08:22:58,573 UTC [33433] INFO Writing program log files to: +> /scratch/b/b380506/recipe_example_20200701_082257/run/main_log.txt +> /scratch/b/b380506/recipe_example_20200701_082257/run/main_log_debug.txt +> 2020-07-01 08:22:58,574 UTC [33433] INFO Starting the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:22:58 UTC +> 2020-07-01 08:22:58,574 UTC [33433] INFO ---------------------------------------------------------------------- +> 2020-07-01 08:22:58,574 UTC [33433] INFO RECIPE = /pf/b/b380506/work/recipes/recipe_example.yml +> 2020-07-01 08:22:58,575 UTC [33433] INFO RUNDIR = /scratch/b/b380506/recipe_example_20200701_082257/run +> 2020-07-01 08:22:58,575 UTC [33433] INFO WORKDIR = /scratch/b/b380506/recipe_example_20200701_082257/work +> 2020-07-01 08:22:58,575 UTC [33433] INFO PREPROCDIR = /scratch/b/b380506/recipe_example_20200701_082257/preproc +> 2020-07-01 08:22:58,575 UTC [33433] INFO PLOTDIR = /scratch/b/b380506/recipe_example_20200701_082257/plots +> 2020-07-01 08:22:58,575 UTC [33433] INFO ---------------------------------------------------------------------- +> 2020-07-01 08:22:58,575 UTC [33433] INFO Running tasks using at most 8 processes +> 2020-07-01 08:22:58,575 UTC [33433] INFO If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. +> 2020-07-01 08:22:58,575 UTC [33433] INFO If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. +> 2020-07-01 08:22:58,607 UTC [33433] INFO Creating tasks from recipe +> 2020-07-01 08:22:58,607 UTC [33433] INFO Creating tasks for diagnostic diag_timeseries_temperature +> 2020-07-01 08:22:58,607 UTC [33433] INFO Creating preprocessor task diag_timeseries_temperature/timeseries_variable +> 2020-07-01 08:22:58,608 UTC [33433] INFO Creating preprocessor 'prep_timeseries' task for variable 'thetaoga' +> 2020-07-01 08:22:58,610 UTC [33433] INFO Using input files for variable thetaoga of dataset HadGEM2-ES: +> /mnt/lustre01/work/kd0956/CMIP5/data/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc +> 2020-07-01 08:22:58,617 UTC [33433] INFO PreprocessingTask diag_timeseries_temperature/timeseries_variable created. It will create the files: +> /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> 2020-07-01 08:22:58,617 UTC [33433] INFO Creating diagnostic task diag_timeseries_temperature/timeseries_diag +> 2020-07-01 08:22:58,618 UTC [33433] INFO These tasks will be executed: diag_timeseries_temperature/timeseries_variable, diag_timeseries_temperature/timeseries_diag +> 2020-07-01 08:22:58,621 UTC [33433] INFO Running 2 tasks using 2 processes +> 2020-07-01 08:22:58,641 UTC [39196] INFO Starting task diag_timeseries_temperature/timeseries_variable in process [39196] +> 2020-07-01 08:22:58,735 UTC [33433] INFO Progress: 1 tasks running, 1 tasks waiting for ancestors, 0/2 done +> 2020-07-01 08:23:05,884 UTC [39196] INFO Successfully completed task diag_timeseries_temperature/timeseries_variable (priority 0) in 0:00:07.241490 +> 2020-07-01 08:23:05,963 UTC [33433] INFO Progress: 0 tasks running, 1 tasks waiting for ancestors, 1/2 done +> 2020-07-01 08:23:05,969 UTC [39197] INFO Starting task diag_timeseries_temperature/timeseries_diag in process [39197] +> 2020-07-01 08:23:05,975 UTC [39197] INFO Running command ['/pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python', '/mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py', '/scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml'] +> 2020-07-01 08:23:05,976 UTC [39197] INFO Writing output to /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag +> 2020-07-01 08:23:05,976 UTC [39197] INFO Writing plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag +> 2020-07-01 08:23:05,976 UTC [39197] INFO Writing log to /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/log.txt +> 2020-07-01 08:23:05,977 UTC [39197] INFO To re-run this diagnostic script, run: +> cd /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag; MPLBACKEND="Agg" /pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python /mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml +> 2020-07-01 08:23:06,064 UTC [33433] INFO Progress: 1 tasks running, 0 tasks waiting for ancestors, 1/2 done +> 2020-07-01 08:23:13,312 UTC [39197] INFO Maximum memory used (estimate): 0.2 GB +> 2020-07-01 08:23:13,313 UTC [39197] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +> 2020-07-01 08:23:13,316 UTC [39197] WARNING No provenance information was written to /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/diagnostic_provenance.yml +> 2020-07-01 08:23:13,316 UTC [39197] INFO Successfully completed task diag_timeseries_temperature/timeseries_diag (priority 1) in 0:00:07.347165 +> 2020-07-01 08:23:13,380 UTC [33433] INFO Progress: 0 tasks running, 0 tasks waiting for ancestors, 2/2 done +> 2020-07-01 08:23:13,380 UTC [33433] INFO Successfully completed all tasks. +> 2020-07-01 08:23:13,395 UTC [33433] INFO Ending the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:23:13 UTC +> 2020-07-01 08:23:13,395 UTC [33433] INFO Time for running the recipe was: 0:00:14.820802 +> 2020-07-01 08:23:14,283 UTC [33433] INFO Maximum memory used (estimate): 0.7 GB +> 2020-07-01 08:23:14,284 UTC [33433] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +> 2020-07-01 08:23:14,286 UTC [33433] INFO Run was successful +> ~~~ {: .solution} Each time you run the ESMValTool, it will produce a new output directory within your specified work directory with the name of the recipe and the tagged runtime. This folder should contain four folders: @@ -235,26 +316,208 @@ Each time you run the ESMValTool, it will produce a new output directory within > - The diagnostic log file. {: .checklist} -Exemplary output (depending on the directory paths and package versions that are available) can be found below: +Exemplary output (depending on the directory paths and package versions that are available) can be found below. Note that the timestamps differ. > ## Your output plot(s). -> FIXME (include plots) +> Plot for the dataset(s): +> +> ![single dataset](../fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png "single dataset") +> +> Overlay plot, if multiple datasets are defined: +> +> > ![multiple datasets](../fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png "multiple datasets") {: .solution} > ## Your main output log file. -> FIXME (include example log) +> ~~~ +> INFO [33433] +> ______________________________________________________________________ +> _____ ____ __ ____ __ _ _____ _ +> | ____/ ___|| \/ \ \ / /_ _| |_ _|__ ___ | | +> | _| \___ \| |\/| |\ \ / / _` | | | |/ _ \ / _ \| | +> | |___ ___) | | | | \ V / (_| | | | | (_) | (_) | | +> |_____|____/|_| |_| \_/ \__,_|_| |_|\___/ \___/|_| +> ______________________________________________________________________ +> +> ESMValTool - Earth System Model Evaluation Tool. +> +> http://www.esmvaltool.org +> +> CORE DEVELOPMENT TEAM AND CONTACTS: +> Veronika Eyring (PI; DLR, Germany - veronika.eyring@dlr.de) +> Bouwe Andela (NLESC, Netherlands - b.andela@esciencecenter.nl) +> Bjoern Broetz (DLR, Germany - bjoern.broetz@dlr.de) +> Lee de Mora (PML, UK - ledm@pml.ac.uk) +> Niels Drost (NLESC, Netherlands - n.drost@esciencecenter.nl) +> Nikolay Koldunov (AWI, Germany - nikolay.koldunov@awi.de) +> Axel Lauer (DLR, Germany - axel.lauer@dlr.de) +> Benjamin Mueller (LMU, Germany - b.mueller@iggf.geo.uni-muenchen.de) +> Valeriu Predoi (URead, UK - valeriu.predoi@ncas.ac.uk) +> Mattia Righi (DLR, Germany - mattia.righi@dlr.de) +> Manuel Schlund (DLR, Germany - manuel.schlund@dlr.de) +> Javier Vegas-Regidor (BSC, Spain - javier.vegas@bsc.es) +> Klaus Zimmermann (SMHI, Sweden - klaus.zimmermann@smhi.se) +> +> For further help, please read the documentation at +> http://esmvaltool.readthedocs.io. Have fun! +> +> INFO [33433] Using config file /pf/b/b380506/work/config-DKRZ.yml +> INFO [33433] Writing program log files to: +> /scratch/b/b380506/recipe_example_20200701_082257/run/main_log.txt +> /scratch/b/b380506/recipe_example_20200701_082257/run/main_log_debug.txt +> INFO [33433] Starting the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:22:58 UTC +> INFO [33433] ---------------------------------------------------------------------- +> INFO [33433] RECIPE = /pf/b/b380506/work/recipes/recipe_example.yml +> INFO [33433] RUNDIR = /scratch/b/b380506/recipe_example_20200701_082257/run +> INFO [33433] WORKDIR = /scratch/b/b380506/recipe_example_20200701_082257/work +> INFO [33433] PREPROCDIR = /scratch/b/b380506/recipe_example_20200701_082257/preproc +> INFO [33433] PLOTDIR = /scratch/b/b380506/recipe_example_20200701_082257/plots +> INFO [33433] ---------------------------------------------------------------------- +> INFO [33433] Running tasks using at most 8 processes +> INFO [33433] If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. +> INFO [33433] If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. +> INFO [33433] Creating tasks from recipe +> INFO [33433] Creating tasks for diagnostic diag_timeseries_temperature +> INFO [33433] Creating preprocessor task diag_timeseries_temperature/timeseries_variable +> INFO [33433] Creating preprocessor 'prep_timeseries' task for variable 'thetaoga' +> INFO [33433] Using input files for variable thetaoga of dataset HadGEM2-ES: +> /mnt/lustre01/work/kd0956/CMIP5/data/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc +> INFO [33433] PreprocessingTask diag_timeseries_temperature/timeseries_variable created. It will create the files: +> /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> INFO [33433] Creating diagnostic task diag_timeseries_temperature/timeseries_diag +> INFO [33433] These tasks will be executed: diag_timeseries_temperature/timeseries_variable, diag_timeseries_temperature/timeseries_diag +> INFO [39196] Starting task diag_timeseries_temperature/timeseries_variable in process [39196] +> INFO [33433] Progress: 1 tasks running, 1 tasks waiting for ancestors, 0/2 done +> INFO [39196] Successfully completed task diag_timeseries_temperature/timeseries_variable (priority 0) in 0:00:07.241490 +> INFO [33433] Progress: 0 tasks running, 1 tasks waiting for ancestors, 1/2 done +> INFO [39197] Starting task diag_timeseries_temperature/timeseries_diag in process [39197] +> INFO [39197] Running command ['/pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python', '/mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py', '/scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml'] +> INFO [39197] Writing output to /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag +> INFO [39197] Writing plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag +> INFO [39197] Writing log to /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/log.txt +> INFO [39197] To re-run this diagnostic script, run: +> cd /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag; MPLBACKEND="Agg" /pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python /mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml +> INFO [33433] Progress: 1 tasks running, 0 tasks waiting for ancestors, 1/2 done +> INFO [39197] Maximum memory used (estimate): 0.2 GB +> INFO [39197] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +> WARNING [39197] No provenance information was written to /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/diagnostic_provenance.yml +> INFO [39197] Successfully completed task diag_timeseries_temperature/timeseries_diag (priority 1) in 0:00:07.347165 +> INFO [33433] Progress: 0 tasks running, 0 tasks waiting for ancestors, 2/2 done +> INFO [33433] Successfully completed all tasks. +> INFO [33433] Ending the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:23:13 UTC +> INFO [33433] Time for running the recipe was: 0:00:14.820802 +> INFO [33433] Maximum memory used (estimate): 0.7 GB +> INFO [33433] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +> INFO [33433] Run was successful +> ~~~ +> +> Note: This is the same information as the terminal output, above, but without the time stamps. {: .solution} > ## Your settings.yml file. -> FIXME (include the settings) +> ~~~ +> auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data +> input_files: +> - /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml +> log_level: info +> output_file_type: png +> plot_dir: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag +> profile_diagnostic: false +> recipe: recipe_example.yml +> run_dir: /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag +> script: timeseries_diag +> version: 2.0.0b9 +> work_dir: /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag +> write_netcdf: true +> write_plots: true +> ~~~ {: .solution} > ## A metadata.yml file. -> FIXME (include the metadata) +> ~~~ +> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> : alias: HadGEM2-ES +> dataset: HadGEM2-ES +> diagnostic: diag_timeseries_temperature +> end_year: 2005 +> ensemble: r1i1p1 +> exp: historical +> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> frequency: mon +> institute: +> - INPE +> - MOHC +> long_name: Global Average Sea Water Potential Temperature +> mip: Omon +> modeling_realm: +> - ocean +> preprocessor: prep_timeseries +> project: CMIP5 +> recipe_dataset_index: 0 +> short_name: thetaoga +> standard_name: sea_water_potential_temperature +> start_year: 1859 +> units: K +> variable_group: timeseries_variable +> ~~~ {: .solution} > ## The diagnostic log file. -> FIXME (include the diag log) +> ~~~ +> Starting diagnostic script timeseries_diag with configuration: +> auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data +> input_data: +> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> : alias: HadGEM2-ES +> dataset: HadGEM2-ES +> diagnostic: diag_timeseries_temperature +> end_year: 2005 +> ensemble: r1i1p1 +> exp: historical +> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> frequency: mon +> institute: +> - INPE +> - MOHC +> long_name: Global Average Sea Water Potential Temperature +> mip: Omon +> modeling_realm: +> - ocean +> preprocessor: prep_timeseries +> project: CMIP5 +> recipe_dataset_index: 0 +> short_name: thetaoga +> standard_name: sea_water_potential_temperature +> start_year: 1859 +> units: K +> variable_group: timeseries_variable +> input_files: +> - /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml +> log_level: info +> output_file_type: png +> plot_dir: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag +> profile_diagnostic: false +> recipe: recipe_example.yml +> run_dir: /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag +> script: timeseries_diag +> version: 2.0.0b9 +> work_dir: /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag +> write_netcdf: true +> write_plots: true +> +> Creating /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag +> Creating /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag +> metadata filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml +> No handles with labels found to put in legend. +> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png +> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png +> ----------------- +> model filenames: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png +> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png +> Success +> End of diagnostic script run. +> ~~~ {: .solution} ## Do your first edits diff --git a/fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png b/fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png new file mode 100644 index 0000000000000000000000000000000000000000..29c8ba476b7bb07bd13ea7901a7d76d8e870e3de GIT binary patch literal 33451 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 literal 0 HcmV?d00001 diff --git a/fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png b/fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png new file mode 100644 index 0000000000000000000000000000000000000000..14c3bf0b22ed0b0b7e05ed7b3593db986955328b GIT binary patch literal 32930 zcmdqJbx@UG^gjAh3MkzrA)?Zq5+WsFfPhGcbazRKl$3x7hzimjN;gOeihy*N($Zab z9sPXgH*@FCcjnIh?>ghh5AQkWJ^S5z?PopDv(_f`;eB~LTxwhdLGbP>$fzO+x*vj| zO=DkxD+0aa^Y9O*lk{CRZ20pG`)LULjAO6x#0fzN3{ij4vL&-D;G(dztfuoLJ5y&j zLq`+D#?aZ`+RoY9!id4u#L>yZ&X$jpmy?&B!Q9!|UX+XL|Gds==V-?DhCVzLK^Ty` zGPl*-->pu#X+9b{zqsLseU-3TRq%$b{Y+shS-uOK7Ol(d$zZkCig{jvdR~EsmCbR% zidmD2JXx5wl}eLJSs~LOEL^qQGA5nh4o`1?9eRb__GhTo{}H>uD6}xSU3E47L3h=H zUMQioUkLoky^P^~QA!5>{0hTiAR;1CA^U>)3SP*5X^5@>m(^Oi(U_T-m~xF05Mp>; zoktl7MSYNx#Sir{^~)qu@Nz0^(EmR_&TepewEIedS=jficJPPS{vSLcp$gT4pY81z zB_t%Mf6mR#@p$c7^IHvGCMPH778DE$3%hi3a#C#eg3l9%}_4aM< z-VQ9U z+A~<}`IxO&CpzhS?p+Y&N}45hNhJ3rqksUJ%~-jtr6sFr_dA>i4<6j|J)^C#oshP-=WhP;rMJ}Lr(;;w zqpbUyB}P~dx7x6qUPMu0lXJ>DD zAdljHvIL&Id^>N>@y^mu%XJENO~0O=hY?ODUxM(u($9vPV6BRcT5(zYGhW~rVC}4q z@a?P&5&ZuB`(XQrq`-aQFTn)zGBTLNBqRdA3mz9;87;Tbwx$!X?Dv!YC}m)fqJ{oC zCgyoc3d3a@!OK=dh3ZLWtuM)nKYxCdG+5{5)?c7aq3?TI){T?m?|-|5r%<)kqF)88d;gig$reMqyc*F2+zydy+cdc%JE`&$9V*sndQvX^LY zxj!`afGLxG_UzUh_9v=~Mc-lny~(~NmBeG*#vm-LSzz@GwgeVZ=Bs#!%i@a|z`hB> zqgfummY3JkB11_@XD@cSWm9ug;U~y_j2&4rg#d0SCZB_|A@V8E^F!u4`nJl-OQgUe?3K zXqlOr*q1M>dAlz4T~lBt#>B)l|K_$aeH;FNb>y?Wz}nv07^SH5jn&mv10y4JfGv1> zX`A|!E_|QEUlhv85_H|&-MQq0FJ53OzY`{cefpxRN(A1%F{o`f(-KNTz1!Z_X4L41 z_V5O2@uyGC#fD$(|BQ=7C=nvlCx_c8%!r7ejdpL)4XQs^w|m-FwU5yV!l{(xrf?D1zF$I&}^oE}ub| zc}*>?JYmu_xr=7{F!PfdRq?AUurdkZ)$1^ zBV6pu2-8v;uJzdFcKWT1NEK+6mAVGlj+NuBjg|$#T*AXuyQ~B?oS$hI{5etL|1(|{ z@IlC1|t`BB?2a~%+c1?c5$Lc2qr!lpyx|}Kk1b#S8}gB-(4BX;|#O- znHkY`?ZM%gQv7xzAvy$u%xBZ@29}n%R#sM*DY=p8=xEDd&z?Q&sdO-=mGq&7Fz4pu z`;x$8jLffnfxX$>+p9vhl9lZ9vb2=HEMY6^J4H(E>j|KYjuLe!WGpg+-U4Fwziy(j*k3#qlJkzUi+Lu_;fGzeGajX_tw4)ml&5g zFR6ypOX?Mj!|HB+y`G$+6wf(aW<|lGoZxqUvLIRMv7M<^_39O&LWU|}(dQNiwm8KC z2P-}RO1NY_QLQe(!N7oET)2FL--7kV&6_wBTzWEqdWxi3<&^r?fflfBUn^dNylubO z!x-^rarVWF7mdBWM6g<{z0a^Xv`Vp2cmf|Gq@@j~_c=fVE`-|bwo~;58iD{KkOyQI zy5E;r4RI=exJ6|(nBP>hUZ1CNe`qd)8I}E3hKjySP0(%1FyJ}st5V~-h9GBWXE4$6gM-`8 zstbKhO<6wN@_0_gXKFB1s5@Nk!Y1mxh)7CGT8~$jbh!J~7LF$g+06n7BU>^3UGZFB z0EQN$R(()o2OCGOz(T*&sBeb?t8jR0nfS7DY=NN${M#gR>4Kir5FD3 zPOuTIqh_r;kF>P(^xRy)!jI&Vt zK+tY7JUyLx=g)+;v5)Q#GvI;k{W*^|_r~muVOlk-9IqAX)!}k+akaF!=f!y+Y%m59 z&_}}e%{KaDps1i5~iC@RJ)){MHc}Al8gG<+7@>fN>rnFizHc+;L_aG^s&cep~2C~Nj*6*D2SZONm)5OH@~8y!n{8_ znov3<`l|d(jRGwk#ut^IySWGhP?nY|rv*#|;Ly0nT*f0?X$a7^|u%JW2XTa!Xw|{?^b#*P* z8Ue<2NnT#Q%sb~h1mw-|hzRv|ZNQe6yu+y?h%jny~)nbmOj@f8&8IPPKLBl=s)|Y zQOFGGrWmW35Mmt_koQUJY*f!M~_Opk6qn8JenpZ=%glHB7vqf0hd$f$O9%H0J=}hY6PM@Ix#V{ zH%%U+V`cD`<2?4H#{ykKVq(r(JMa*ut5-41y5FhfHTa&NY0YUts?aJmM@v+`aOch) zN-CQdfanEGOj6I##xNjYhM*TLOMsBw0aOMq ziytWMPtKv09hp>I%uNY={JpR9NPXbV@25HmFqzFA9oTJcZGat(Ighe7e#Pq>&9;OB zMPRvd%iWLYs$8~9LsC*w8a$1#)9-M($HupV@#&=R-^Yh#ADE5*`gCJ&Z*WmBUV+(? zLs4ongP+UwZhSw8w~e#o^)CYh>SY95KNhN2gJXs(?C3!q_GCSvFWa>l%%`HIrR5*2 zc=FlQ-qls3ZhvC~c{N0KJiBXq__NF=c(&UN7)^i-Q`5%GmjNS3dwajEtSmX@!NEbT zBC@FP@D>oEGt<*4qSrmWyfAK@t|b&rZ|d~9BL)Zm#L>3Fq~T7cWMbkiXMNlfxUY_tu_k?qB+u zWenB;k|J=3;WrA2J$vjk(3)&eXoLAr0w7-+FZbtAR~Yx2f`rtpv}de8T4syTj(m3b zE8bF9LBMKIt;V(u6!iin5S&mP5|->q$j)?kf-X0KTz3FXCcTiSk`^>bGWyA+YvXVs z83WO(u+@D!A*(C&dw%`}u(UFZprD{^je@tMr6=A=4eYv6@iD{YHZ%~fJmx(NWh){V z@u*)wE@xzB#)MoI0Bru5w|5CBICjlqL^X#LsFZw?ppBaD0fcbJ*RM^!=g0ad`wiy< zTKY{ZNu@T)>-ER@ki^;nU!$-tk*9d>F27RDNZ>Pz9K{jm;Za$Mihcfbt481STY^9E znMKlg!M(jbO3?kRGvYoc!k#;e{wS9K9_(iC5zM4T z+d4aOL7zQ3<--HZg@$%>*2NFfoB2R487VFnGEre?sAwfgVFEWu5OHDwzXUGBG-Kqb z<>odNn}~{t+|E&(g|(5@OGx%rCfyU~bl1&FOiXOcb|)brdHVF}V!bLCXx+upGB#8Y z15rYGK(D%f!A0}2@--#z_%LF6`Y5v>ADV`THCGm}_TwWWB1Vr-4snz8?8O!xCBmYj zf(cW5E(F1{=hY3BH-OE73Lr2c3}>1Hv-KM!K$8-ZkYGqkHmFWT2DYlA0xtonPX#W@ z$iaaJY{rtqV`gT?^4C^_0@nI*oa9>Tah=OjAC~XQ=0$v3;gss%XdPA_oejHp4X^vh z^LXx{N-2YSHX=h}lYFYC8x&S1G zo1b*zIdxI?!aGS{J&qA}cd>V=^Xs2atV;EErkgO-iu81Cv|zu2yD)J7?cuSQ@7uz5 zrMvS4s|lhmteN-U=k9I;(?IJO8v@>gje~O=P!y#Q^R>zp)dxpMsUd`}%7r(k-;FID z+@H<1Mznmntw&37P=vYb!j@cOL$+3#r54HI^QqVq8*!^a_JhMii-a*$Y%5fe83P)D$6kj--rI3qAtrX0N5Crn9#v-XpOn1q?YXA?=kq1z3RKm11bet0s}5Dv3{Kk-{7cz_apal5k7cyB-ihoi~pc_m$^nM>bY|R z6)S*|>Us2j#1s2Gk|kUR6Ku;`Q_o9YJL|Gyu=o|-IA`$OoF3&eXFCx#6<_(Ldf54@lD z@hYdXHx7=D&tqeMvbF92(nSUd^ z3)4ER#k=?K|EivB6%5`)WsVXMsCTmNzu$n|o(2M!>-5eYrfBnb+*g^H?2mRV%8rEq zVvPZgh21w8V6%UG`$3XgTp#Gn!y-L#ooZ(scs`fVxzMPn#}gWJvQ<@8mEOmKutf|^ zOt6fNjo%OHGetMTW?Q4btE2PoewyF*uj_u>3qOK^y=qa|olPAUEOA914Y?fuj=wql zQdR5t&_n<{L@+moKbc$t;Q2TjWMN@};zVj!1H!a|A!eI;dI;UtCpjGUoegpGlxS?G zOb{?S@8z_pJ_Mn+xl+`?BqT&(SGy^f*st=?Vc|0{OXJPi)`Nv)UvBfBl=$2<=CRGz zQ)5fZ+_$!Nb_9vanGSdMW1dkc8SCl^DI@wSu(=GZt-~4b1WnIHNy^E|T>!Ek2&yVK z?sIuL2qL~>m|B#w!nlYpqpW-xJcF!WENc^!KtO_z50WJ|c6QWih@62YN7741f-wvX z!=lCMc+V!n$_;63ZN=i`hGVkdQE)S5)5&3MtfW%KNbZvm`4kuH@+s32bpt|9wm=*^jdD%WWrK!l+Tum%wfK zd|9q1>WVl@rlBFSk*?+71ice+;s!JR;P^PN8XM3C_4LsQ4GoR)$R`tpd-r4^{2ajZ zMENA*o;wdu`G$7gd)0kbrrPO!!v$?d&7XY$UlPLG;AiH&gN-i)jB$!H>+4adbOQGN z#`bnVMn=ZyEf5$Opb7nirk;_2JMEX0M5C&zYQNA;2kvymaFRQQ$Mv6(cMQPH0Xot4 zJxOR2m`Ezjv}IbKd?alsh)z^0M&($PUl?$a0A)cV{WY7YOngP$GX>};rGOPC3DAVHM!-pR?Pqwd!V?DRP+=hIYY%5keWA z4zn^S9|sBvn#Bfav~+X=av>C%fMSpmhpU{jv?#bLV=o-Xa}iTrit2fK*fSn{3-fyxu zExpL*|NMyr1fBl*KoabKK|#Uc8n>dh48{zTjp-&pC_d19p{Vq1Gg|5o_XY()L{0q? zRXTa^HhHt`$XO)0%x>xmD!-t}G;GT>)Z=#jatAei|HG{u(S7pPuC7Z!z1+`F_fd)o zsH`FAwMyru7`c%X;~8)SZbN)A#3`yv8lVI?upW@<7e9RX0He)kH5`z&$nUa}FS_%P zHRYsN3#RVpkq0WeY+)%*vtp?v0q`e&UKm z=L|1bX*^7;#PwQA%~okdT7ba?5=z51kW+rke-||b2!4p+K(L+{0V+OTWh|@m+AmDt zHF*hW;m-}V2dGx0f@5I>8WOes(m+c($pux{0a5-A4#;$KU!UsE+Sp^AI!|@uI#?*E z3=u-IZ0_$@0|PY#cwh+pZ`mjCf?FfdyE{9HK~AQ^a|FKm`t>Ujz(FeP+FT2$YN*<* z0|zYFmX(za1;ZNK%*@R2=~HHF8=JuR_;}b4A9Iz@cqm9o(|N#f$^@4&2-q|^pgNRR zq*q7FlvYG#<>fDd90CQwNs1e|IMvV~Y(MSSrl1Ix1FRnSHs4y~92}KK=s8CCY+8 z)h8l&`_+MQg19zryBzTYNCqns0`6JfJ+7~N;?E9>%_nQCz;`7=T0jpem41+2TWCfI zL5;GOkAp?pLSt9U_>?yhLJ(y=&Hj))@4q1g#A0TCKE0Z)F>ERpz%>*EBMvB?fqgHq zw`U=F=JI06_y7J`UW7ZQH`+}A{t$_7wKEZJptPp8b{LdlUV`xv5uKI6gR65`k98;{S4`#{yBkXn^Sun+q*Gs{n7B%gydpF!=i;wV8P9Rg9k*+ydr zg+ESZ0Lb^EE-xAy8b&7=Umi7}%0s<{x?+Z4{K5LPf}U$>4Wke^yJ%u+`qE*p4M$sB zn=x9UzuZDqHHK2i_FZvB1qH}`kf-wFuw{Ex8gX!Nw2XUAbXhNj5^C96%gdz8qf9V~ z^Ajf-d3lOa$9pm+#{JnUV5tPRZD;2=8d7i*Ee$-7JjG-vQsMw(6)09~l;l~+%$H!k z!>dfJSD^r{Pz0H{_}QT&d zNdfnU%?VEZHJ|$|;OZ^~6QbX|dDGs}vCm!Rsd^LU2H7q54XL%NBq(?99EF62=6u?x zF+o4T-AW##A|ZJ+&u0P^@$6YJW`bZ-k8W4wQ3JPPXc!x6Zhnp`i}zY(vg+5X3y9VK zEuC}!-%IC1$QvF;Ot8RTB_-vp=a|K;|4%Q#!))|e#SCtK{`|h7G(sYkLql}UpiiGZ zZEVckNzck!5hL})1F7Bwek$zKBmBUS5LOWuKNFc8H73ZRKy>flzYj2Dx`J+HxTOKQrX1WdMU8c4c^Q|FkIy^!4%xe$oSOhXC=&S8#N;-V zD#f4;Ah%`s+rzfum^;<8CDPC{5P0tJKNGB02qgk;mt{5Y;M>qPkimn-j0bkPbc4?+ ze`fICBKR~|%^6x#P($Jd7Y-I31F#1+w;akh_t-X_pP$d}yvs~nPy`{O&LIIs0uVph z10XA(s2@@cWr5VRcXocE!zm9HiejLgMsx3l>^=+%gW0BT0!{_b(+)ym&{Hh2O~68c zuC{`SuIJ(e%UZ{akIq;p3W;XY=h%kdvLBmGBj2y4Mhs-9!`i3-%72NV5efoHo_hiX znI5PJm6>Qhd6HB2_y#GY$?GUz<1INQWeBx^C4;D_mcSb11M|_+o2bYe9vd?TJ9uM% zAD$KK2)xOsc}7hY|@4c9;8q2Rn?K*6@se&+e|_Qr-iiskT`e!Jm}x!N@@<^Vki!Va@9a?92M)dGNI zf%BxYS_@@(U?Vpj-gA8_D+9L}4Jz$T*Bc3m>eBB#p0nRjq-8Qv+W&O5^9y;SH1QE0zMkpvK25ub=eE|+HC9no=S+;IX`SK|!J8s}t1INHjrC8%~TgixsJ_<&? ze@}<95TKqj7sgc&C2s~G){j<2*N00mAlkoxkNA?q3v9xOHB^=A-8(099 za zh-sll>kp}GZLmyFEty-(xN4R%CSzi{er0P{6pogHx*C`Q$Mg$~Z1Z$~D(#=?0V+S2 z)$nJ=SQS*H5kGKqQ-En82+B_p@_pDEhO*&i`!c}|LDfg0NhD0d`zQqjdf*#z*Huc` zoB=3855=wAC4fh40)oeNz9m+`WGaV+!JGlJX=Y_5EbtOVDvojd_~b2U^(b+&N$(^6Zy;@ zf(?f>f_`;a8RP)Efzd&;I0HNvoPBbTovZ`b4WU*UPRWBR_%}gDy2L>NGY+H;Rh(+_ zTCdC6O9Wr({?|;-Ejtp(%{i)1t`Mo1yh%nr9apTXMOwe;)CIe2bIh(`29T*3#2l!p zV9;mk=;mOyf{$$U`&%M7Z`7-6Ynvlx$vM|NpdkrF(H#(lJ@wvR-`)ybg4!??gxY}7 zN56WN;!rmQgr1OsB1`bz$A?m!@m4LB22JSdr=u?d13!Ydfl^7m4Zgkuj^H?j(P78L z#-BNG7ay;AmdR>+?J|sI=sk@_XipK*(QgpDW zaKW6Fi^Xq86-F75oqfZ3We^XF=qU8)DbklLJ09oIttQRM$w8I)r9U=8XbSuZ7=qps zol1K&fVQ&bY7yvQf)*O^&UK78+MwPcVDzNaoJity=TXEGq)6z~*@$fi4?OzAhe+@k z4SQ2%bC-a8V_&+&=6DMH9T!!ov4G6f(b3@t&0N3)xuH~rVj9pWvU`>mCBf=g1)Xmb zIbu=Kd8FAkY{6k=iS=J{N|{sH{}8FlGGD)rl4K~DDlUF_%nlB^ii%3MdLB72zzy8m9;(mvO!dh+;fjj5X2-{!n*>4Q1TTgc>D#;t$Ndv!HQ zuU`I)4&{D@c;9-zLw7%;9kV#x;g!JB%XVBMb(5qY^Wus-9ByL5+KI~|Z#$!K45)Z` zdC?IR#SkI()SahiJ8Z`%Qc>T$#YQ2<*@7TJbt;d3^s3?2Hh&6-xP?491DJ>)Kp&u( zAucaV7EOo_En)6Ei$vg&^MCM>mQfp73v>6I52vlvOxikXaBRjbzAPdvjQFwQFtfgl zi;G)MU}VZw6g-U^Iu+ZApngSNT#^otzp1a7ADR?cn^H6ikMOfPfzIHktKK}XA|WEOC^?)OZ1@vFr!p}v1H+}G#RS?S9Cua3af9J6;EPY`l#AAyV>G{^G2=C?iJC_PvwzrfoATTk_ec=_2tPlRX zT6mg-cnWJRip1mw|LuHSYTflEX$-orjC9fbcf%9%#vp4ncDH|vGH$ZK>cGZHhLA{k z8~p99{Po9Hn)Q=o+`|OQ=GIZQsTnnq|K6(Wwb6jaaN*gBc9rqJw?<+}?fmP|jH@}H zK$rWtppcu%dk>-D(0TzDz@3i|8@s#l!6p0xUc&&Ypj1$lp%jmfptPuYVoFNN<6JK= zUhUo7f}!c8tV{q!gHQ=Mqk$1PoPsR&$7OWeMf02m^S?Kaf}IL@I|JesWub!KTJ5@q zYVc4`god`f|A_qxLw5BA-aA~iP{$R?=w89;7fk1b}{Lp^0y zkC~a7Ur)$^DVjSw8^gE3FHWP1fwMf41QdexF4GIbU+PbwB@bGC>{o|*oL7fctP-Kq zi}BhuEU-*&I*Y)g$%m115E2qT%yqf`ZQ>Pl1z zO?R4q9eS`t-(`hF(1+e559pxUTc3&oTqLg!zeK^waO+lW2QSwn zH%OId>*r?#Z{EBCuZz9+6KqKZx7;6H|7StvYs5S*5F75W4oLKVKC>+82~GN5gjy&WAtb@M<@ zRQa&tK#Qc>{Tf7v>3RwwY5=Gl_y#($TA*Cc5c{>%2P!g7Pz}y#De#pYnE03Y=K$wH z*Na_%f(cB#g>E-E3kDVzIi6M3)o*U#!$hDL*4q%dfuElgWzcoK z6LvrsvYTuHU5BgN4bc4R!v}m{-*eSGZCFT1T~J%#Ku1S6FgMp+EDHqAEe$$vnT&)a z&50Jqh{-JeqwTcC8Idx+9*GRb^RA(jOB-~)zKLSXQ1yQZ6h^uWN_i<@h0E&sQV*7`ejsb~T`PtH=L>52PXjN5-LB>okE@pdzAAYZ3 zyr|&}mk|@Fzv|*A2zgY8F35Sy(-YWN?k5K&-7ZQQs^F1hoF4DXL)7=yxY7{@n}> zU`s{hE~Lde--~|5moyvxHeRb#Rc_hs7kwtX=(qR}Usx#~3nS^x|3S&@mZXP}pY3cj z=EJG~`2g+lWkefcL;ou`)qcafjs7)tn*f@ylK=0Q3pa@D$#DN78SA63R3jmt?=JZ1 zHj-iecj@u@+L=o^Zy?@9KQ-)su%)bf7QBC+Xa4W|6K9cEFaKd<+)aEW$Nj&{GjKWd zFJ#71!R3ViE+6Xe7X^N}`jG;JBlMH=IweN=L9;HZ>0BjIMI2)oKsmZ6?7s^N-5qkw z@XZSUeX~8H(AxU9alI20F6;b1Tuw$*9sb>0HNF{*fsFd!gSgD_{6LUG!OUz^+tdZ~ zY=(c+vdlU8LkZFDFCKJaPRIN2trTg==#XAi{<}?v8t%z=%wp+(5S_ug<-i)l=g7dv z>sON|JvH-+{NE_lbSsmGj)wYMaphDqsmX};aUmq)SmD_Z{yk03(G)_+CN3`>_-}bK zSe85lZ6y`4kkah0EG69`91%AOXU^=&P^&2ZoW6o6aGSeg&qH0#}=i(gt&K2;0K{@+*St# zDw(2H4-HP&z;g_QvM)2}L)ypLzf2IjC9NXo~%$|`!FaMn*(7XFonzdU_+}|IQvZqfSW(EK6*Y>iFxJnf5{>bvDqh&XN z_d7TJT|PZ6*Fxe3-42@5V_U28vpUXy?^Y7CKV-a;W%{wY3TM)>0=_pr?f+Hwi!T%d zFDd!i77n!6q60~U^Z|8(IUw35pLrkwvQlNJPB+Md^CDNChjVrEc)d&|(`y-gsRTeE z6pVmv2@XXHXk!H>rAKid2OA$p*|@n0ft&}ydeHI`&__FKmiYw zo$)#KYD1={4aTcoF4fo9n^fIJePu+z<5~L!6;}4AL6jqt_oikZ;wZczOs!>AQc&;% z35jCM@Yj;#C(z&Y^z>=)76Uo6!1zElrUNo7mi+-Y@gsQ1mA>Z^mi;%*SWt#5be+in zlCiV1J4b>ewCIwhhP!jJiD}!CG5w``cS9xq=m`I=*~z(X_YlHz?HU>ajlQKmSD=Ip zPht!`d4ZgBa0mgE5!a`0UH$L%<)GNr*_kWT#RAFOQo68xPEH5++r7&?ncf^=7hQX* zsYiyx$Za#q4_(!0;G+y`nL>*RI2BMcVRIHiLqh{A)h|B&an9g-Xs7{s;`61?Got^-1ifq^mO~x3N++uon>?1H-#TWDtF_wFHM6h0vpF49365k7MOQb z3yX5*=@sc8$&&5R$FDek^jK$NWMqW$mOD3eb7~aoJXv&vRuN2SnHcCAi2E`T8j`(y zcql_!D4`IPSVC$n)<5VbyhGf14ecGT2`+Rm1VGCZwAY$*ID!8%Uh6?J*A@Z87js>e zg05}o5K$`l1Fboisrj*i(gQKNxuxX?>XY&2&AYoVLqmH-Am^qIy(dKPx??+&hcSeP z#7^a2qNytRkd_*+lBwG$jSVeTSYWouKy$j~0P6|0zn>pcYCS>>l?B;1n;>lp3T$%v z-zT3;)O*u_;se3982mUXA)&FQC4IOWxCko^#A=uKQ1My6IMNtixXaU26X_F>8n2Ow zGY#d{VknzJZIlK#5FL^wg23}9zE>=rVo zQWoQ0TTpDEj#mJ^qNk@978T9agL3#Iwtc8sN@M$jJwjTY57JLqOe_tykd|ZvboxT? za=z09)UJjG0M1w{-Ql=$vd5EZ)mG= z5ceWun^M=$L8?fDZa9ZyJ)cVG!NQ2s4du%`#Tk3rmAxx}`MkJXdH`TLB3`$ zI;**fL60BRQ?8sB6isHnAU-u41V~Cn7Rgh&KF83wP6AXaN>yat`F)lBv|`t8OM5rv z71c*Gl8bO-qElu%GbWOLvXrW(W)z(Ar$G1K-Ei8Wi!`$x=*c zlNQ~7raJ%TKb31GJ3V+W+HVB}ej{9wukg>xiyL$V>|J-s$3rxIm#^@Cf{s+I(=m>5 zuxNyzBwD^t*7Ng|KHHPRxIo_VhgcUWe26 z7xR2ca>-i}qxHP^-!xhutwci}_23FCngJCjkY0lPqB;~UN+ z{7^mPe~Vo_oVAotbIck!p(qsz=Q)oAoumbvNW|skiunFcG1+TE^q=MW%_G^@5kI;6 zUG)S8&ho*Ey{j3ItGc0&Qurs)fi z;r@FmU;Ikwb&Dt9Ahk~m3hdC~t4sfTgjcV_t@9;a2#^hjiVNH^TlxZV5?9nAI>FZt{e)kqcM_wAhy=DTooq;{x8kbYOr zBxoN+tXbuO%OCvO@y2E21eGw3N`Sh*Giim3Nx4%mh zM*{Na{DcCg8bP`>GTq<34ZSLK#c;XYUdK1#GQ)bkZ(Go6dfKPId@uW*j`yqZkYVPI z@XN&=ML3>9F3n%XqBbYnwuk9A2@$|5BYT?1;_`}dbiR6^eB)xLidxW+XUk(V?|*Z0 z$55v{!Vo)gQ*cr^ubZ@!8GBp1P9G;yj*ZE2!TR=NqHwQbiE^VNUfMI9monTLanW1y!^{Gd4e|U85bde97crT zRTGA_l(Iv{16+_8^T6_zm1q(=O=|AfJW}l9wBF&0u1BGJ?sM2xOpDT&2S0?!Xqj@B zpJj1S3*Xow?piw_%@=(We?8>N!ltr#;ptT`Bc5Q7da(cM!X)_uc#be^J~zLxU&=MteHeLGcj1m%_k^B zVx|;+`Bs=W5kYTlkU*Pjc81^s)BBu*ryc}(Q4_77cdQXV8Fc4tZ94run{cgxU&17b zAq3??cS34uZq zfXOIR)#l8{iFM4iAdYUcJhqF5?5=)8L)>N`bzZx|h^cWthAz_Ag=gC4VRLnDMWcP8 z?iPaR(^p1*R(XKTmyrkQgvnR@YA-pM##7&luV9~US!-Y1J9S_eb*DQYvA^=9O3~Ts zX_QBOMCUWz5a(8MDL4>4-F$jIq4dzM<(gSzOAn&IV-ez}UDf>1(oe%ykh1iM|E!Wc zYM`Borzz{Cu;zHCg996F$9fhakiUfZX}gGorxT}}{F=S3df{C`rz=B8vKz6(ujHo* z)OUG4y-yl7yIMEC;r5Mh72nq{G>I$4KLFiVUh#=41rhPCHsJO`>OT57D#CHU1J-U~UY4zmk_pa~JPnUNtRZ&nA)aZSJ6f#3OVR zlBXeukjAkxQ?x;}J_&#E<7o#=^0V65kez&;8=!L5b!k5GJ>yQvxRjfelmcRId5o>t zL7C>6PzTAt_lTJ#%fPa$+P6)2ECUom6t%&X0l!Zgys(cCZy1=F1%n+p1N~^0CU87t zaHuas2@To*Gr?A>{P1B9+W;M$%>vu%BdXh1ff=Pd?OY_+-)sA!n%ovp%G9$vb1EYP<8XsRWHtJ+9|fFL2s+%+9a*9T?xO(P?A#tWES z61xGc>7Y^nKN+cdR^wU!(+l9Hr9}-5@=?%&5kDcvz|{Adj=~rXxigjhQNR#wE9MO( zm|z+769N@Z!~o|JbYQJ(erj-KJblG zIdAJi9gUIu*jszIVn2WUiK+`1h~IY-E!|1f!#IHc>AX7q3R^mqDLd1Q1*R+!0xjwi z%sw#hi~TtymP3Vj2sDyWo1hB1P;jDvqF|BQehAT3*gCv`Z*oGjF{sF;yn78YE$b(1 zT`{K}^Ho2L__<=<9sGLw@mgggEw5X|=lkm%kL#DFNL|+W?Ia&fN!V#UiNc)pT0%oo z9`K9>Wq-OkWQD}WY!$MBWcXhUTp=in?TiK14mNcE*`pq+u;A;>;zSI7WLylnugtaU z?s`TSR)nu}5&5<}6M4p=Tl$7AD!TFfmRIEVezG*v*OefaT*XcfG*W4U(NYUI-Hkyl zWSd|14G!C+JiIZzu<&@%5!Cne%nTYASCJ|lu!0^GX#ddgf?trJCQ_xidLmX7m{%;5 zm(te#W~0#VQU;jIIAhlr0DTGS&xm3y}N)%QXIH}k)R;})2$XVe}Od^(QLP5nQ1^E90Guy^P^W7`2w6m<>* zj@xT2I-*X;!}($GVB#$&s!?arP`^gNGx^=S%a0!qJ=S6&Qh746X}53J@VlFvwdu3Z zSpTQnz)j!P?31n+iUi;pYgyIZ=bDPBd^*r!xPDZw@crBE{yBc&FfFBP@f*JFR~^_S zuoTfQTQ5CtJxyBX7f$_9hYkaG5R<@qPd&UudOX$pfX86hVxD!oI^teL`r^3Bs9Du%+Rwv{|$X6pan7 zv`@H3V)_f%plu(1=RkHH(1cXq58~}JR#C7SD&zV;`G23*_pMLktNC$|-C27+mwcCt8N;7cT6&R=iGhg{ zOO_}vdn}*9ljguNRx{+1vgZD_OWW7+GHMY{l7!=y6{* znmrT%p23+EIIH0Y{S?sl($U$Onx5YBQTO(3v@i;;-~Jb`Wbf)gagh1iwSiGnu*o56 z7oJOqUB4du`ZX!w2#ypS^MWQUXgwOp8e?L*udeZ=HI4pM$|EkKiN|J<#AC)c-_@F? zF-E?~;9>h9>1z$g_3?;rCq@(_Sdnv^XXUo^V^Q-Ys|&4R6}z7$ZFhIK=A)x^pKOms zD^pK~E)DHYw~ig@_k6lRAxa`_xT2!UyM?{8$-KE4z3O9o`N35GMZfsRe^^d;Jn$FD zKifaLfC%CB%o8{~h&aMNfF@HkgZYkV{B^LNlA%gA(x3;8yls?lBKhG;6(lHmI8y|t zNt`3v0VcabNv?A)eul$&mFH*2YwdrkS2&Rm9>1wRc<+rkx!jXUA36Hj;QC46YSbXw zWUbG_H45(!ucYY7Z@G*7B+uCR70G_~wlwN+>dJKH@ZN!kS4`sL=8B~Ow+qQtRa}Nm zW>Hi41ba1$;`UxI#JVvhh7y`)w-oh`9EFf5y@~I7T}6e9GDf2gF@2GIr?I4G?n?ST zr$0Dox!AAvEoZei%$Bof=D3}?GGbw2X%=W~ZEx=iYsyf|`Z!?Ke8yGy&N<)n)##*F z9A|4gRhLb_Z7+(Uv3+y>pf!ol{p6>OCOfxpAEDf!!|HeyrSXC1KF{R6@vcmaDl!)Y7%}*Mcm>dl!wPL&T&(l@Ml9w(CUNLG4 zxU;#Ni!b&y*wMps1Ru%N9ZS32Os}?1%$w^boaPz)`A`a_*PYyFqc6VX~9!&Ne=X<+d&G)$_R7ihb!;NLkP^c|7d6s+|^VlLx&_N&9 zkBRAfkC4~>;r-4C%eevxA;?6u)e<}caZ)2rOMqoj+wqO=xXaz$Fnx4KP+PtT;Clp*v-d&55^(bGyX~- z-@#GHAXqKnTjiC~wR+pj_et_2P|(BC9mV4H z?R)jP4XgaA@v$s-v9Z<5uDpag(Y5@!sWtJh(Y3_SPirgdi&&gP`s2`3;I5xw*W|gH z&dn_~(YWEYOtpU=ERUTN<@0%XF~xHzV&B(=iqU0wz2aJlCi^WHW0xM?(whPO`O?92 z$<~E>-M`?LT)hiDXXcCBzSv@m9-bG-)+DjbSkgVWUuA-LF~p|aJn*e zZaa4zR#;nwUTA;8U9OKQh{4w|ZsIH1Q29JgQln_>s7tAgEw&@DavISDu1M(;5>i>` zd!Eo*(#$Iz@T|(tJxkO(Dk}bBgm`Pw;f#U}c>>S}7W$lOl?i zD;CT1i#T@L*eSN(H=%p4d;jxJO^NvCUg^fZ%kjZ8Z5Cwm19_V+@zQ*!jMkN4NuKk= zAHG|QX;Gix_XPyYL3?%h74f(4-qFGcf2L!-45ux-P3o5N@&OQ z@U`$!X_3!7Dr8D+ey#kwo0wn2K`U2BSJ&L1nsrn7)hs&Ry91R z1Y!2JuLB_=V!euKkf^qL_k)Y6DpR$!s{^q_YG{cZuA=tv{fAmAt*Q5@{NDHwMQ5S{ zdKOdP`UmrZnn<*UWZ@d!?^Q>cmhU%^mm&Nm0oNaF?v2(Vo z-*tY4Q`rnT?Oi+LzbYR<~e~H&KHumQBLn?Egfkrbgu{i@7-z8W3thv$*<6MrM^1 zk(HtDSs07ls`*ilVSncw+jN3R$uEktjH$17F_)RCPbzXgj@$UI%fayg*?W(p%t`8n z>rCHc$dieQED&|UFQtJuN#AHV-gUMz9q&<^c_8za12wb@8+&h^1+R24_O!k+-J z3X_!+{JamBxcmy%bW>in`FL_jDK=`Ec8hQQx^az6-T9JLYX*N>B`_pomD4WWb1s7)VMG zBuUOW7!VW?5y{DbpyVh>8WaUVk{~&ZBoUCD85r)`e&;)New=e}-MV$D@`nsFv-h)~ zr+anx>eXI<|MH)2K>_A#}s{<|1A#arS=-jtA_>3z|WgNfU3S!w$ z>px&vuy&*TV;H)d&-!~|l%}W8Ih)&AoYK;Xp$-+2*K7RtwExjt*{k_|jfK+kvLN5V zP~xJMOpiS+P4-C0oH)*6M(;LQ*A}qLX;0L?1Lf@vpR$LY$Lp?ZMr+3VoGT(0mSo)O zRXG3UP*XflF4^JLTR(g+iCF$&2d$H278S!_*nS->_UHcRD%XUkd^Nc$1ain*8_Qyo zT)c#{ZT@lZikY4B7Z&Vz{!wI&+!Zb3(uUGc(WhR8b2W$8KR)o}S1^93cWvyj_ZT~y zam6;f4c`Da35^hRhl0c?Y~CRO4mfw4nqbH_?X<$lwInpNzRjsd<#u?cwTuHOOw ziMcsLV7?_#YS*va-w?Q0bgX^3kWAYF-`}o1=H}o@{bhFhXRL~_G3^WiQ5K8%!)X;N z27;}ZoZk2c%A8ubv-pozVTzpQsT<$L>nrWtK7Ft{?&2lKX0?Bdo}Y1YPynaM!-CO# zUlhwOtE*S6EK^p927UnI^I#B@z|>`-OrekL2slFZ4Gn1HV7`9+I+!mVFRLlES#cV~ zaDsw^PlL&FXfX@@Ec#lG-3(nWV`z5!{Sob%N~j8hKMB@MbgsvLqP;aNP0l)e)gLQf z9XV5&8S*Og0#9M42(D6De_cE4K-S(Fj#dVJL$`ngZ!dV?inO#py0P;+`BD|g@; zflU7*IoS`iZ!KIYkMr-BQ!!Up=pG%Fs}-btqz<#ziysN|_);#p`k3B2DG}y*cWss% zEWa`rbXY#RcNJRR@HjNg)$=*=blm>IIS2Ltx~ke*rX9QEeleTb+lztS{}Y_yv>C1& z?@d7=^MVvxl2$ByzB@t^VDs!E|FkqA^a1}Qbb5qIA;H1QDzlUVCalZWYxjMQrWTd^ z&i|f1S-s+LYAkE?m%8AV#WNa%+l~8Gt)ioqU-_KNs=Ljs&Z!p$jV9DtA%T`wCI%Y0 zEH)Mdi;A13s-mSr!Qd5foga60n+-o(3$MvyR$5wG>n!M2hHaRkkus}lYik>AvLUc+ zZZfpsT{dUx;O4S%^O3*CC#&%`-CO4&3H81912{Y-(lDklg547#H^dU51C9 zCi@tvroLY$Sndk{N}j6$eVcJ%VPRJF%$YKV#+`irr5vR$l+gh>sjP|g62FY1D9vZM z`lj6ho~X560Ot-|Rj3g)wh-Ddaq;n);1_7rPQgiExp}jyXs+wVSnU&^w_RoX;j_{9 z)J~B@{I2f6Pzx&Vm*(c&n%IMU{%M8vWxOF{I^FR@a$m89m^({re~uQtLpoYU zG>3#7(yRmveX!%htgtw!3q(WT=d!Yxtm=cg9Vd;9jEdw6@M}~$(oq{nQ}92>otz}m zh*gN5N4q~SeU9c-9@q{r|14Ph0&q7aE_TPBU97CkOYWvZ_)6a_1$e^QZK9-0;YYl% zHbj%qy?gim=nW^U2!QcDYmdh(s8txIs_mB3WCOLlpy$sCeGui|3BU@gcC%bIUS92l z+V=pZ*rtW^J-(3Fiw4~bN`*ojH*6?@LQ>~txm9e&IsqQ}{%${ghjTAAi-%V`>$?!8r>4P=wcVwEO2!_nk{nF&l*tP-( zA^uBIc`s_+dmiyapQ`)&S>8PWI-nR%#;z56(?kUV`H;APh5*Bho0l$w@%X1Wc|MUhwrVePxJAmo+qxt zzp>y+2EsA-E}o^aeJL~ieD!K@A#v*S?v(THE3IOrQSvJhHWfL3)!lqO`A65t%SVlt zu4i%*>ppwH>|t@>N9iM(Nm&XT*{qE5O+D9y+&)A)u+OcsZ19{dob**&a?5V;_Bp3V zK#7F&aw=c7gAz+Az0Grd-vc!f&Rj~pApd!W@YD^3MfO5vCBJ36FMi06{Cn}+BUS?t z1_oZOntcA6B%L^p%ZnpC+P)9 z|6Wl;#bXJTNxz$ShM72f5!jS1Hx4VWxOZ1V7_0a-$}$xZPd=5OuV**0zPGh*1fMy5 zeWr>cP~d&+@1GL@K~Z<$`>K#PTy%+JG;mR-_K`05PK@zp<>}XmyJihM$WjPozKnED z$o&t})HGgUMsu#Z7@D$*Vdx&do~G>0QP~_G3T@@@OBXs;y3TYJn(WY{<~rD)w`QS? zNmWFN4!V-%yb)-Tw0O3-OXVj7383Q3aNL;fapi&5h(M;}r-N@*-s5#NULv_m?ry6H zuBaW6cvc&`5`E!Hn-$e%=Uv&G+ZrCa913`8Q*fML1w0a9ql2I0mnE;Yty4BzdNkbh z#4GZMV^5Y@_L}MLeA(`rLrRz0^W?nOcuskFk_+hyA=&MSDyu`EnYAJ02Pt53}G(&uR zejE=v9(Q`)eC#~XxQX`{-JPi}QY4oCO;TBc3y;zqcy}#a=D{wl%GdM!6pNTSp0ux8 z3*o-K!4^`>oc{>N74AbvtT&S)=_9KT56c;oki7~|-|=_j@(tkJRCg^lIIK87WMbRa z$Gjv?;;9yR`Kt0)c3WKA1(h z&v5_U>TBM|ja`!*3~Z{Ca|(-(`9GUHK&1v>7c)ppET+zt1Zx^`|LjfPcv?R02@Xp{ zkx1_fvVJwRm@m37_0Ex8o@}<-mk<{AUPB`;qv-tse>eV16N^JKf?cj*@0xA(#wPe^ zIif+y_pY?9cAQGeyHs=NDlEovy2}wcubuY%k+WLM%Dir5V~^#Z1iH)Hnq&T)!~)=gVO3h=n(USUt2*dZrm@MKKsX>2Zg(k8aR{41pA1|wCSWSVly8k%~ZkE{&KWxDi< zJ*F~iOTNauT+;uvgGfXn5UEdcJDmIZ49xSsVy&1?qj}Uo-9(cx};Qc z8+}WdpRl0PI~Gsz@-sbSy%m6~hhZHrrCyYmKNPa}?zya4gterH_L5R0`ybpTdoyM% zWxcH*Pt48!c!fOWp_BO3l)@fsmZ)SFhYaPWtS15_F@GX`z|kolMdFn?x`EA#0Z+ly zOe%`?c*1)+(L)C}a`&(vcR$at@MW{2Mr6U;Oirv8yXOtvT|}(la}-eB`2Bl>KDrIt zJM+tW>14ICO|EmV%h`3VSB*Tk8-W@gPjztTsc6J2K1VnF{c|2!Zqn;JES@jIOZ+Q1 zN&%-x2*qaS9S5y<^7S0BJsoOL!Ex%snVDTbTYhJiuSDOXu&dFfe=M5oq*EEGD*IOY z39*hXv2E%-H<8|`S5^u2%PVun@BjtH$dQIvbV}Q7cX)4A`LpV0#dhb0v{NH1VBXhH z!XRYX8Z2oeLAF$AqOGGA;JLjk)&85!@>F6br+e1n@Ln%{TUL`V$fuR)W=IqW{`=3PKhQf?NS3Y8*_ygIi$Cqy zm}naRec0M=Z11RkX))I-S7|4Q9-UQgIis;YJ_5upDK`)?mAm4`WLY9M9at3UQ@;}#&NzyI~+W&SVgu8gt+UoGi2Vi)qNM?}7esn|6;H{mNG!8Yo zaox?q*C)x$K>%xnaYOw4ue*`=-$sH~R>jkur~X;HmQPU74^7g65fMXmWx5$Z=AHY4 zRY~YnKb~TS7W13KhWvZ>SWQ)nvqKBvi|#FGR2b$|)YKS2!3mvr1k?bK12aykl(wPo zUbH&xjkdQ=p>*v^tWkEzy?40-a+HdXL0{xGmL08bdiYb>*{rN^1t>m*gUyJh1RY2e zT~kpx0wErBmg`#tg@+H0Ltl<(i?0{D#JD|w|NfoTwlopovHS4hr|5%dT5JU%ONSZqO{LbXA?)=FWI$1&Qj_#S&*HFU;Sz zVI*aZ6|Oe%%ncIQ$QD@E^mbPvBz*?QXOK5Rh@c1R;Z3{7>m&d?iEQ;^S4qGyQFOG^ zl{7R=C5u5nq91y*ao3aDcv-=GosFWig3KIrW$!`|htNJH5p65zEtp3b=JfL}(@>YP z@#Xykt*b@{j^(Uhy+gDh{reqjeO@yOpX!qFR5Q-M=_58IPwL|INK;cuydz!@9{g~W zmXeCxETBR_XN|vwGw65Jw8kH*tgIw~vYJI67#xK73o8Y}ktvj`moNVufA%mKsOm`r z`|(2~KjJS@Y~ni~y77y$&#wx;u99JNb*7W-;{8S9!!~Tx1BzQn{=yKmjYj(&y3JJe zA|XW+i+V^|0I&A269gd@An3v=>*`oEGziIMh;vkh3E%JNxLNt_o73Q%P!vu0L`1U6 z#=;>QrIOT0d;H`{s_OdD-8xBXCFH-unL`mSAz{cTfCRDDi_j%Ile%D<11M%ZUyOsGy?R zrUZzc6I#bHF`{GAga8661S4ta4tH+uz64ug@L9lwQ%33$LU+;k>bX#QRJCVKnR1em z5nMOc#^Pyl$%Fi(nn-O}*490-i?DeyF^82 zqV&dye!a)Oz8~hgT(-xhf}|bv?Ab{zEgsZalW%@_hDuyL6#TZeQx_LEa&i3`f0p0s zy2E>(LGH4?2vQBb;r((=Eu)dsLnMdOx%OLaX#)AVHuLV1B^@(409`{J-Z@1XnWai| zb9hKR|Mo7kk};_>*e#t#B8g91C>cFXyJ~`G6yNwi7SKM6Z+Gn{k$5|Z839%wyYAgv z1uNoOQ{eGmD`_kW#mLhJVzr=pNXF})~)SC&;#xHw$OVYP=F%xu;|rFRm$z> zUwc6y&!X$hq{0CLORhvoKR#O|vz zht?Q}9^`vYrVJ2<2nvjEMWaSK3qslXY1DZOG_Vu-0<^`iB1G2_0Dk4AjWfAKR#jbu zmgPD0XA+s*Qk0TwCC?}y>hN%{+ABhS{#J}uRb=rGO*ZBtccVW~cZ!7awVJFoD{h-y z4VJWS&M~_zF*hiU(oE zjf_lFb>6xEOp=K5q;HvEcKIt*#K+n+ zzO=l1O1wN}Z=w(VVLMy`__2|^BRr=2#F9(f_4Tdm6P!#GkEJb9$pr(hlXZs=4ZC*B zMaEWE3iT(dHeJ>-?tRVlP;1;#fh{oP5}BN{HT~$T$^(&ZDq~+`Zn2ajrQS~8&AZY4 z_V@U8laB?A`iHL%Fd!Z1*le#R*vNd6S72X?_C)n@b^Xmm9On5XA-BNAMA5mZmO9&J z3)p(IY5#+6&7AQp13*7218|wGvDM&4t zUE0iMbrt^I2)R9`#OCR#X$dJKM@Kcsna~W|JKJ?Ugi>!TkDmKtmlU&;HZ!U>b1WbW z;UzWSjdU^p6+7}zRtl!OFS{{~=_1T=bhF#me_iaMJxfMf^gcem(FEnWRa@rXi=`ZU z;QvRNnkl2=VbK*W5oTrKrht4Ko1Duv*Oz6}zCSxZ7bUmERFs~b9Blrmkv1i%fLdsM zrZ4Kfw?FAOnoP?a$rMls3LxsN^#Pl|A55MtO2^4PUwxp@$bF5sjY3OA;Mogjc=UtC zP+V+&eSQ&~*lJ{Gk3L3V_DAAMk?N#R%z##IhN}Ewq7(%HkJ4ar^MKaI&WK38T?@@k zua|Buu*kYOO7MtwxS7^ms7(69E;pK=yh~+eXpfci118~oC5e^R@aic6`@e-Yp6)i& zhh*32nm>)kqA>-Ep5iDZeeTyhii+6h=>4P%ug^&@&pRA{9&DddL;h-+=JPPpYo>2~ z(fl1%F*&YEJ>y9>bKaX%qaxLT)dr5H%17jQ4!*$0uxhn_>7HlTbIuT(kubR$5R^W% z4@Iw!?tiYS?;&dz1`9ddrmIVEJN$hoEjxFyL4eOkLCUL6^yuYY8r(MUd3js*5XmvM zob3Oms4*4*f1p3OAbg?U{LI{X2Q{@e0}<(oR%xOZEA2n#w^G8a?ZgezF7+y{v{m@t8$kN98`9q$Q8re ztkhoc$md)NVvlV%^@IKG66kf@%BMAxwZGWCLXdZ9Q}9IDkPJ(?%1Gs}hJ)UO55n%P zdAe0)>Z|vS7Kg&G`*UI@YG;_{Z(N!A9H2VNQSwxy>7?uJ+p78AIX!TcwCS|yDy`tM z^%kjm_}USTh0O8hP=TdKK3^rV*!QXK9xM!Rf^!b7)NgVvl3pmSb|X1@EYq<>NibZi zO?4Bu5+Wfq{El@C7Ap;v%FLt9>^5-E@cmT(*xAD!85N_3o%TEj-(IDDp!^va>~Ac1 zwL~6vmXK~+mgE&;)yglDBPl!!7%x+GdHePVj-X#{LYc5cygT!0Umu_0tEA_Q*Y!mT zr}bw-^x-kIdnbhy`-fs~`Tb_Qa5}iVHX&D;2x0q9In6sd9j4YO%=dVt-R{>@wYIAr zviDGIE1$^l&WtEJtjmvx_OwI7Wn2lh->YP56eIijRg>sHL}Sz#6Zh#cSUR4XU3 z_rar3)v@mO)L>SNP8lC^^Y~XaG->X|k$$notWt*>=z4FdFw8z>Ds-FEZX!mdSvRH??>eajMtSe4Q^(uTA~W+b;T(>%3icON`4+dmb3jH8}6R`RhD_q@fPP) zajUjT`+(}7p6awjUgZ^gTh^HT42NibV`&>3UV;IT79Y@8MmHk*0nH~v7qI~^YFSC9 zMHM%QjkNL1diGzG*>!Ke|IK&OlKq5OQyfpZ?p^H_Q~QG@qD7yabT0~#2)@dJb}x${ zO??q*+Mo)opnOd6_POTIZhbKan8R*FPEDdLoi!@#I&i z)(>;ODRQUMhfzt;nEl zBX}CJi?ki2+OGPoX}%q`xxx<^s1tQQD_s*Vj`GbK?Tbz>ZDSlUgG!qEeVf|1TGGhd zT^e5I$dR|-a63D3e})N_$#vI+rltE|-v-+PrO5VU{tL*V7@yN%x;*rz(qR5uvx{SI zk_-oZuGYqi^wesL&_~+Zjb167PPTWpe)W87Q+qMSQvEDJI{BR4d%JHFJNHJ*nps0s z7cZ#4@kbfSvia%I2B+(D_Unf0LuRO#tXGy4r~UrnD|qqz$Dg4+H?+t$FRt=eqRGwW zj%==R+!vx=2h`YNExz4uxO-D@i{n(PLc|w|^KjL2`Skm?5~1nb z(z45yEM^4beG6908b3lz2Bzdf%hSzk*KDz<(P^{moS2!EHl)J0MY8@PMdj3*o7$R$ z$T~Bi2!(><6*Z0XD{pm>scANv!J&)tUG?H-Iy_y+^4$7Ak}C3QPlX6{6vK9+=1|fJ z|DnxipS%@vb_wtU&b#bO`t6uyF zuQr&kF0Y8=6?j$D7;u`*b0)MdYs~(`*P~mJqLc4kfeq5X zOtQVo@Md#|)SQb7E$mC%kKT^iCI_sMt0Cy9F?7?r0QShke5Xz;@8K@9;q5BrEvBh8YGn<-`ryQ5EPq`-MoxC z&$d&zHv?s!bs%*MB?{vMA5k9zb<+nFQk~TJ6@9c%lQxiDE5O zUvD+s<)Rgv^Oh00dW;_F!UOqxQ96FzUPAVPz!ON_b}h$#Yzv*`16}RNdymy5A^1Y1 z<+}%Ob>}wE*;?xp7VivQ-TI~eVcTCZF;&9DPt;O}*oOKZYov+<+|A{wVM^TkxT&WW zIi>o2r2IUO4Vyfjg}a?Tr<121&@FO52+`5czyQ>+Ve?%@*(N zER#!*heq0wLuMjBZjkp{oCKF<;HeSG-R-*SCnfI_h_^!IgO1<)QOT_?ony*G3h?_= z`8=sW@&jM9@Jxic-w^ki6_lVuajDkI_|Ur4s#OFLt7PS7S0I1t*gMgoZBIiJnCM>} zeFRpn#vz$i_C#<_Jl##9s#d3S-%GpLXrsalGxdV>`y@DU(u?1>undH3z#fxiXYB5O z=b=ly8fW|Sq->kzQyf^}(!Md^qsZgDMCl!7;OVLtzUi&&{^EIx{|Fc|I|jD=eI*31 z0Dafo4f?Wr!D#|sm#E~(%SQ+^9N#LuGTlj*67t_$ayF>oG@g?ETF*l}mettK8<%IO z{p`9GP1G2XF|@(&f5LN+z*dVQa@QI-);>o)oK;#@r6|gjVH?5;0T^$NHJ4mhvaD)r zZGH9>nbSglDWjxu5i& z1bh-iyy!h2ba>AtDOX(LIcUiW{)D>H5eUDb%m)!4J%}-&f_W?(Wf;+7EvNp?BuG$sYm*?T(0Ws5Rsjw;N?e#5e%x-{Gr5c?NID} z^6Aq_NN^=-)QTX>2vLyFkYgU6{(y8Jv|x^a=-@p^of$3%f3*VYEM^`SD8F`Cmadnc z>#!M+u>e0;B`J7m$rZ|R!`Hrf&3nX}_Gj_3H0&zeyk^1*M_Fv%5X+tySw>s#+<0{G zWF5-PB;?av`33&_gj#A(PY;y8h|YBmJwmeBAix(x`jcTB7B}S{0 zq#aD;{vH+M!~YlAGZSZIP$8bqihk_*`FTQFkVp~YYwwuKVd7G4wP|I&d-m)BkNL%k zQQ8SRQb+nNdgxg~gvASK%iy!TZqG5mpt;2z+HQRV1MS)vEw%p2S;hBURSZ9${cdt} zx>GKT!)+{~n7OVB5BB`Ib369$e}v%_+uDFwJWuU=vLR(XL5`p#QS-#f>Wi)%XQuA!pI7WlB~Uuh_U!wsck z_D!4QRa9o;7?Tk7>NgmivJ3i!&;z>%!DTKSH(g!ba~Ci6-Dj2knbWLg;xnq94ZOuAt?u__)qR3u zB_DSeQ7sHX#FtGrkOc~0;XZa4B$sUg5IsgN=~4?B zLW!=o9b@57ZE;N*-`S|>mn5$4N^~vJ|?+QQSuTe_nN zEi*Hn&yy$i)`V@geu@8reo}L&biZI(bgzX>tEm`T8!liB#}?l=Cu%h>Up{VYdlY*b z!B z2(Anmn-1l=D3d#VrDp%Wr+_l*JTSIy&aa5LICI2ufA7vwmI_JeV+H@b3&-3!LS6pb zx1yLINtB^nsmtWf1j=ZOp(VvVcN0-LCl+n`9|UFpyJgv~45ky*xkZSPDuP>}4)M#f z@a_HiT-=O`B>_Sm=7p_&f823qIn}vLnQWv5!9A$&kK?zC+Ien;i zmcLX~SLZ~w`wc{X@gD1M2Xi5Tf6H4ewP_3#UC0SvK$!z?cmbK}rC;LYopN%NZfU$4 zd!+0z{KmH0-o$0|^UX(%!rXH|54ZjI3^ouVAPr4C5eg+117Rki{&+0g_))W%!wXW2 z4{AWCF|pI;SJk_TdCagOX3b!f*-p@7bh+(?B$o@Y>st zCdih4pqlyJf@j9mq5ynHP*l`KD9bl%xg12jDKppQPe!>~zU_YSWBQ^kKjRdVa!Uk=3}nuuv`Mimv$V z>>p_Dn8Fjpr}nn}O0;FFd-Ol}W)hc_y&rgNF&G{JMaxT$juHe-4i6?HRu8v}4}$Xi z9gi`{(3juIA;w6GI>puuxVp(U7(h=EmQ^RKm5{dA*VhLFYNL^p+aUn~`jXn(T3QTF zIHbd8J-(rJ>aw!(M`$#TnBlk#HmAiFDW$fIMZlM`b8(q!OE+DoYJz_Tz7!#$gY#w> zUA~z*^0+xWpXO5V$!?^o&JU_QB&fJ4VZv3Z-M8lEP>lF#F|q$*5}AY`@fB=95Y#^j z$zxRWFrTR#^A`3(Ma&b*CUoO4JCi@}vl82xfJ@Mk{?n@fejtFP)Nlu+X>aT6i)tDU z{dRR@RD+HrL<+Ob+P6T(41C3%V6$C-B=_AAWO|F7+2BnuJ>hG0^_#-NC@lLUjAR5N zygMYjFh5@xuejZNY&|P$?p(!Y>aq>ylJ$KUi0OUl&67zUNL-E)Guu|`%{qV~mnjp{ zsVx?&h4GCul!7KxHP`M{Cp+RkoA}mcfRFjvbMg4h?l>IoC`Zc_!+0Zi~ z#`!VIk1A2Vtzfpl%yQ zp-#zuuqHFFU7H8>Tmp>MN>BNf3abt~z#c%DQxqq3QL?uG&N3d1hUSWt#b9#|Y%y8^ z%YX!2n=)dXRYN0gOy*QyH@Yv&kJhj53jWyJV7PWT_WF}BzQ7X@0y6bq0235o1n3A! z{L;DE(auOzx9FfGaKhexR((LueQ93ZBUti==3=44m==^oOHoHAv{^~$86`j$s&>9; zQ_Vd+v*7n1g++IF+5Y~1Oh`Op`}^{tqUkFy7AYBchFA`7BrLh5${@u)VsPiyBQY^M`<~b4i#q^qGbTTTLWxnzm4Y2s6RfILfwHM)CMDHgQL5K<*&KI_ z7~$E|r^n%%09I$`YS(F^%A2{;esacc_+oXcvzZM;KK<|An>TO1cI}!(mFxYXj9rGb z3!`YWg iEKpKV*tK^rqbFjIz}VQ@GXL!(<>VEb3sI0=u@T*BH)vyJC0rueo*gH< z64iKT&(WjLq4)=>Yy)a98F$+|GExndo1>7MI&t7E-WE@Z6SI0;U4hgsITRRD zTgNCXv^fG3W7Vn5I#5O;<^)?-yBD;Hjttxxc2Fov<@~QTQ-ICZZbt|)0_0fcnFoi4 z28D$grL{JunH`K^-y4(XkJtoe-xT_=>vgnTMnsAKu<%G5`3W09=Q$qQ-gvyC29#nq zV)#@UY(?SnZ2PQDRg6qK5C{>!MdDtk;FgRGBpyO z<6Q;St(1_VPIc`eyqQw2U!mC-Eb}2vanyW zOk0nDKcR;z{g~wwZ(jEn&|<@Z@+09WKN2uuub5a9I2CQ}c^brquR;TgB80ycot^Vx zlC#M-KTt$pK2)EAAq%lr6p5!To4;$$Im_ep8D=xfeni82Mcmidcf?G~d2o+jjz%?F zQmR0yt%jAmh>fjy;>6t|MTNrmALtoM&Sc}d=%Z%xp;zoDTz1>QAOhWn;h5#zJ1}5~ zDHz6DZZp^QvRb)nL=fw+Z{Dnrqge&X$ST}7*OORjr+NbG?%lWVD@fnrE~6jHF_m2G zx;Qs*3?_qCp*dGkO)U)2<1jtrIti172fuz8>eW!j#Je0zaqpZMv)7QJcXsN>Ri*IE z%p=}5&!0aJ!_h@Iqb~HYsujgMZv%Yy)s;0aYPQeO8(=YJ?SWh(ejsC#LpeAYVQ{f@ zx?qo1^Bt;(4Ib^R7(A2oRFw#{#6DpbX9P&&m8O*9&Ti?06K%g(1j{%YEa%vP{pI66 nG;sX?gUkOfHNZaZ4Kd literal 0 HcmV?d00001 diff --git a/files/recipe_example_output/log.txt b/files/recipe_example_output/log.txt new file mode 100644 index 00000000..55c13f0f --- /dev/null +++ b/files/recipe_example_output/log.txt @@ -0,0 +1,53 @@ +Starting diagnostic script timeseries_diag with configuration: +auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data +input_data: + ? /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc + : alias: HadGEM2-ES + dataset: HadGEM2-ES + diagnostic: diag_timeseries_temperature + end_year: 2005 + ensemble: r1i1p1 + exp: historical + filename: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc + frequency: mon + institute: + - INPE + - MOHC + long_name: Global Average Sea Water Potential Temperature + mip: Omon + modeling_realm: + - ocean + preprocessor: prep_timeseries + project: CMIP5 + recipe_dataset_index: 0 + short_name: thetaoga + standard_name: sea_water_potential_temperature + start_year: 1859 + units: K + variable_group: timeseries_variable +input_files: +- /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml +log_level: info +output_file_type: png +plot_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag +profile_diagnostic: false +recipe: recipe_example.yml +run_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag +script: timeseries_diag +version: 2.0.0b9 +work_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag +write_netcdf: true +write_plots: true + +Creating /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag +Creating /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag +metadata filename: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml +No handles with labels found to put in legend. +Image path will be: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png +Saving plots to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png +----------------- +model filenames: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +Image path will be: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png +Saving plots to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png +Success +End of diagnostic script run. diff --git a/files/recipe_example_output/main_log.txt b/files/recipe_example_output/main_log.txt new file mode 100644 index 00000000..1accd0e7 --- /dev/null +++ b/files/recipe_example_output/main_log.txt @@ -0,0 +1,80 @@ +INFO [33433] +______________________________________________________________________ + _____ ____ __ ____ __ _ _____ _ + | ____/ ___|| \/ \ \ / /_ _| |_ _|__ ___ | | + | _| \___ \| |\/| |\ \ / / _` | | | |/ _ \ / _ \| | + | |___ ___) | | | | \ V / (_| | | | | (_) | (_) | | + |_____|____/|_| |_| \_/ \__,_|_| |_|\___/ \___/|_| +______________________________________________________________________ + +ESMValTool - Earth System Model Evaluation Tool. + +http://www.esmvaltool.org + +CORE DEVELOPMENT TEAM AND CONTACTS: + Veronika Eyring (PI; DLR, Germany - veronika.eyring@dlr.de) + Bouwe Andela (NLESC, Netherlands - b.andela@esciencecenter.nl) + Bjoern Broetz (DLR, Germany - bjoern.broetz@dlr.de) + Lee de Mora (PML, UK - ledm@pml.ac.uk) + Niels Drost (NLESC, Netherlands - n.drost@esciencecenter.nl) + Nikolay Koldunov (AWI, Germany - nikolay.koldunov@awi.de) + Axel Lauer (DLR, Germany - axel.lauer@dlr.de) + Benjamin Mueller (LMU, Germany - b.mueller@iggf.geo.uni-muenchen.de) + Valeriu Predoi (URead, UK - valeriu.predoi@ncas.ac.uk) + Mattia Righi (DLR, Germany - mattia.righi@dlr.de) + Manuel Schlund (DLR, Germany - manuel.schlund@dlr.de) + Javier Vegas-Regidor (BSC, Spain - javier.vegas@bsc.es) + Klaus Zimmermann (SMHI, Sweden - klaus.zimmermann@smhi.se) + +For further help, please read the documentation at +http://esmvaltool.readthedocs.io. Have fun! + +INFO [33433] Using config file /pf/b/b380506/work/config-BM_DKRZ.yml +INFO [33433] Writing program log files to: +/scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/main_log.txt +/scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/main_log_debug.txt +INFO [33433] Starting the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:22:58 UTC +INFO [33433] ---------------------------------------------------------------------- +INFO [33433] RECIPE = /pf/b/b380506/work/recipes/recipe_example.yml +INFO [33433] RUNDIR = /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run +INFO [33433] WORKDIR = /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work +INFO [33433] PREPROCDIR = /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc +INFO [33433] PLOTDIR = /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots +INFO [33433] ---------------------------------------------------------------------- +INFO [33433] Running tasks using at most 8 processes +INFO [33433] If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. +INFO [33433] If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. +INFO [33433] Creating tasks from recipe +INFO [33433] Creating tasks for diagnostic diag_timeseries_temperature +INFO [33433] Creating preprocessor task diag_timeseries_temperature/timeseries_variable +INFO [33433] Creating preprocessor 'prep_timeseries' task for variable 'thetaoga' +INFO [33433] Using input files for variable thetaoga of dataset HadGEM2-ES: +/mnt/lustre01/work/kd0956/CMIP5/data/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc +INFO [33433] PreprocessingTask diag_timeseries_temperature/timeseries_variable created. It will create the files: +/scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +INFO [33433] Creating diagnostic task diag_timeseries_temperature/timeseries_diag +INFO [33433] These tasks will be executed: diag_timeseries_temperature/timeseries_variable, diag_timeseries_temperature/timeseries_diag +INFO [33433] Running 2 tasks using 2 processes +INFO [39196] Starting task diag_timeseries_temperature/timeseries_variable in process [39196] +INFO [33433] Progress: 1 tasks running, 1 tasks waiting for ancestors, 0/2 done +INFO [39196] Successfully completed task diag_timeseries_temperature/timeseries_variable (priority 0) in 0:00:07.241490 +INFO [33433] Progress: 0 tasks running, 1 tasks waiting for ancestors, 1/2 done +INFO [39197] Starting task diag_timeseries_temperature/timeseries_diag in process [39197] +INFO [39197] Running command ['/pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python', '/mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py', '/scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml'] +INFO [39197] Writing output to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag +INFO [39197] Writing plots to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag +INFO [39197] Writing log to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/log.txt +INFO [39197] To re-run this diagnostic script, run: +cd /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag; MPLBACKEND="Agg" /pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python /mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml +INFO [33433] Progress: 1 tasks running, 0 tasks waiting for ancestors, 1/2 done +INFO [39197] Maximum memory used (estimate): 0.2 GB +INFO [39197] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +WARNING [39197] No provenance information was written to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/diagnostic_provenance.yml +INFO [39197] Successfully completed task diag_timeseries_temperature/timeseries_diag (priority 1) in 0:00:07.347165 +INFO [33433] Progress: 0 tasks running, 0 tasks waiting for ancestors, 2/2 done +INFO [33433] Successfully completed all tasks. +INFO [33433] Ending the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:23:13 UTC +INFO [33433] Time for running the recipe was: 0:00:14.820802 +INFO [33433] Maximum memory used (estimate): 0.7 GB +INFO [33433] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +INFO [33433] Run was successful diff --git a/files/recipe_example_output/metadata.yml b/files/recipe_example_output/metadata.yml new file mode 100644 index 00000000..2d3ad5c6 --- /dev/null +++ b/files/recipe_example_output/metadata.yml @@ -0,0 +1,24 @@ +? /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +: alias: HadGEM2-ES + dataset: HadGEM2-ES + diagnostic: diag_timeseries_temperature + end_year: 2005 + ensemble: r1i1p1 + exp: historical + filename: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc + frequency: mon + institute: + - INPE + - MOHC + long_name: Global Average Sea Water Potential Temperature + mip: Omon + modeling_realm: + - ocean + preprocessor: prep_timeseries + project: CMIP5 + recipe_dataset_index: 0 + short_name: thetaoga + standard_name: sea_water_potential_temperature + start_year: 1859 + units: K + variable_group: timeseries_variable diff --git a/files/recipe_example_output/settings.yml b/files/recipe_example_output/settings.yml new file mode 100644 index 00000000..5785249d --- /dev/null +++ b/files/recipe_example_output/settings.yml @@ -0,0 +1,14 @@ +auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data +input_files: +- /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml +log_level: info +output_file_type: png +plot_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag +profile_diagnostic: false +recipe: recipe_example.yml +run_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag +script: timeseries_diag +version: 2.0.0b9 +work_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag +write_netcdf: true +write_plots: true From ce8074a35094c04b4a65393e79c2fddd51d6daec Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 12:43:49 +0200 Subject: [PATCH 224/647] Use old Ubuntu --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b7e667f..a581e784 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - name: Setup Ruby From e369949f124385d88c5f1b20778938fa53ffc277 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 12:54:19 +0200 Subject: [PATCH 225/647] Cache ruby deps --- .github/workflows/ci.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a581e784..c0287b75 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,14 +6,23 @@ on: jobs: build: - runs-on: ubuntu-16.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Setup Ruby uses: ruby/setup-ruby@v1.38.0 with: - ruby-version: 2.5 - bundler-cache: true + ruby-version: 2.7 + - name: Bundle path + run: | + bundle config path .vendor/bundle + - name: Cache Ruby deps + uses: actions/cache@v2 + with: + path: .vendor/bundle + key: ruby-${{ matrix.os }}-${{ matrix.ruby }}-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ruby-${{ matrix.os }}-${{ matrix.ruby }}- - name: Ruby deps run: gem install json kramdown jekyll bundler - name: Setup Python From 3978be5a3a434a4db3e50014ff1aca786a562a40 Mon Sep 17 00:00:00 2001 From: BenMGeo Date: Wed, 1 Jul 2020 14:45:23 +0200 Subject: [PATCH 226/647] add recipe solutions for the suggested edits --- _episodes/first_example_recipe.md | 52 ++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/_episodes/first_example_recipe.md b/_episodes/first_example_recipe.md index 0faccfae..e9575c12 100644 --- a/_episodes/first_example_recipe.md +++ b/_episodes/first_example_recipe.md @@ -26,7 +26,7 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w - datasets: what datasets you want to use, including - the time period and temporal resolution, - - the MIP (Model Intercomparison Project, like atmospheric MIP monthly data: amon), + - the MIP (Model Intercomparison Project, like atmospheric realm of MIP monthly data: Amon), - ensemble member, - the experiment (i.e. historical, ssp125, etc.), - and the grid type (necessary for CMIP6 only). @@ -325,7 +325,7 @@ Exemplary output (depending on the directory paths and package versions that are > > Overlay plot, if multiple datasets are defined: > -> > ![multiple datasets](../fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png "multiple datasets") +> ![multiple datasets](../fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png "multiple datasets") {: .solution} > ## Your main output log file. @@ -524,9 +524,9 @@ Exemplary output (depending on the directory paths and package versions that are > ## Edit the recipe and run again > So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: -> - Land surface average temperature (tsland) -> - Atmospheric surface average temperature (tas) -> - Ocean surface average temperature (tos) +> - Land surface temperature (ts) for dataset HadGEM2-ES for 1901 - 2000 +> - Atmospheric surface average temperature (tas) for datasets HadGEM2-AO and HadGEM2-ES for 1901 - 2000 +> - Ocean surface average temperature (tos) for datasets HadGEM2-AO, HadGEM2-CC and HadGEM2-ES for 1901 - 2000 > > You will need to edit: > - the dataset: @@ -535,7 +535,7 @@ Exemplary output (depending on the directory paths and package versions that are > - These fields are all 2D fields, but thetaoga was a 0D field. This means that we need to take the average over the latitude and longitude dimensions. To do this, add the area_statistics to the preprocessor. > - the diagnostic > - change the short_name value (thetaoga) for another: -> - Land surface average temperature (tsland) +> - Land surface average temperature (ts) > - Atmospheric surface average temperature (tas) > - Ocean surface average temperature (tos) {: .challenge} @@ -543,27 +543,57 @@ Exemplary output (depending on the directory paths and package versions that are The snippets for the edits can be found below: > ## Land surface average temperature -> FIXME (include line numbers, see below) > ~~~YAML > ... -> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} > ... > 27 annual_statistics: > 28 operator: mean +> XX area_statistics: +> XX operator: mean > ... -> 38 short_name: thetaoga +> 38 short_name: ts > 39 preprocessor: prep_timeseries > ~~~~ +> Note: The x-axis in the plot now shows the years 1900 - 2000. {: .solution} > ## Atmospheric surface average temperature -> FIXME +> ~~~YAML +> ... +> 23 - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> XX - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> ... +> 27 annual_statistics: +> 28 operator: mean +> XX area_statistics: +> XX operator: mean +> ... +> 38 short_name: tas +> 39 preprocessor: prep_timeseries +> ~~~~ +> Note: There are now 3 plots in the work directory. One for each dataset and one for the multiple dataset overview. {: .solution} > ## Ocean surface average temperature -> FIXME +> ~~~YAML +> ... +> 23 - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> XX - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> XX - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> ... +> 27 annual_statistics: +> 28 operator: mean +> XX area_statistics: +> XX operator: mean +> ... +> 38 short_name: tos +> 39 preprocessor: prep_timeseries +> ~~~~ +> Note: The unit in the plots is now degrees celsius! There is a plot also for HadGEM2-CC. {: .solution} + > ## Advanced: > If you want to add a different field, please have a look here: > http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html From 5be28269893eb2421e14c470ee4f291c9eb8755d Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 15:16:43 +0200 Subject: [PATCH 227/647] Not a matrix job --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0287b75..6af10f33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,9 +20,9 @@ jobs: uses: actions/cache@v2 with: path: .vendor/bundle - key: ruby-${{ matrix.os }}-${{ matrix.ruby }}-${{ hashFiles('**/Gemfile.lock') }} + key: ruby-deps-${{ hashFiles('**/Gemfile.lock') }} restore-keys: | - ruby-${{ matrix.os }}-${{ matrix.ruby }}- + ruby-deps- - name: Ruby deps run: gem install json kramdown jekyll bundler - name: Setup Python From d0a8f27aef758b64526a354ebda9230a93e672ab Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 16:03:52 +0200 Subject: [PATCH 228/647] Build site timed out after 40m, trying different OS+Ruby version --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6af10f33..654de060 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,13 +6,13 @@ on: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Ruby uses: ruby/setup-ruby@v1.38.0 with: - ruby-version: 2.7 + ruby-version: 2.5 - name: Bundle path run: | bundle config path .vendor/bundle From f6b87d70a77b869898341ecad849613610cb8742 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 16:23:32 +0200 Subject: [PATCH 229/647] Install automake to get missing aclocal --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 654de060..4904eef2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: Install automake + run: sudo apt-get install automake - name: Setup Ruby uses: ruby/setup-ruby@v1.38.0 with: From b172b2026006f6749475be1ac9cc3534bb1fbe31 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 16:43:07 +0200 Subject: [PATCH 230/647] aclocal-1.16 is installed in Ubuntu 20.04 --- .github/workflows/ci.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4904eef2..accb4341 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,15 +6,13 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - - name: Install automake - run: sudo apt-get install automake - name: Setup Ruby uses: ruby/setup-ruby@v1.38.0 with: - ruby-version: 2.5 + ruby-version: 2.6 - name: Bundle path run: | bundle config path .vendor/bundle From 966c4f22d5f803896d40f01e551d7ec3957141c3 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 17:01:22 +0200 Subject: [PATCH 231/647] Install nokokgiri with system libs --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index accb4341..22273195 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: - name: Setup Ruby uses: ruby/setup-ruby@v1.38.0 with: - ruby-version: 2.6 + ruby-version: 2.7 - name: Bundle path run: | bundle config path .vendor/bundle @@ -25,6 +25,8 @@ jobs: ruby-deps- - name: Ruby deps run: gem install json kramdown jekyll bundler + - name: Nokogiri + run: gem install nokogiri -- --use-system-libraries - name: Setup Python uses: actions/setup-python@v2 with: From 878c43488e94bc3b9b3f208f240d66b957ce31e9 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 17:08:48 +0200 Subject: [PATCH 232/647] Add deps for nokogiri --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22273195..dbe2847b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,8 @@ jobs: ruby-deps- - name: Ruby deps run: gem install json kramdown jekyll bundler + - name: Nokogiri deps + run: sudo apt install -y pkg-config libxml2-dev libxslt-dev - name: Nokogiri run: gem install nokogiri -- --use-system-libraries - name: Setup Python From f7cffac2509004b09e78a9d342e07051be379a09 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 1 Jul 2020 17:30:53 +0200 Subject: [PATCH 233/647] Build jekyll straight --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbe2847b..86af8fa3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: restore-keys: | ruby-deps- - name: Ruby deps - run: gem install json kramdown jekyll bundler + run: gem install json kramdown jekyll bundler github-pages - name: Nokogiri deps run: sudo apt install -y pkg-config libxml2-dev libxslt-dev - name: Nokogiri @@ -42,5 +42,5 @@ jobs: name: check-messages path: check-messages.txt - name: Build site - run: make --always-make site + run: jekyll build From 1dc7298b3a4c35db5923a07912ebfc77271d0484 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 2 Jul 2020 09:51:13 +0200 Subject: [PATCH 234/647] Perform commands from Makefile in CI --- .github/workflows/ci.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 86af8fa3..226c41aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,22 +13,15 @@ jobs: uses: ruby/setup-ruby@v1.38.0 with: ruby-version: 2.7 - - name: Bundle path - run: | - bundle config path .vendor/bundle - name: Cache Ruby deps uses: actions/cache@v2 with: - path: .vendor/bundle + path: vendor/bundle key: ruby-deps-${{ hashFiles('**/Gemfile.lock') }} restore-keys: | ruby-deps- - name: Ruby deps - run: gem install json kramdown jekyll bundler github-pages - - name: Nokogiri deps - run: sudo apt install -y pkg-config libxml2-dev libxslt-dev - - name: Nokogiri - run: gem install nokogiri -- --use-system-libraries + run: gem install json kramdown jekyll bundler - name: Setup Python uses: actions/setup-python@v2 with: @@ -41,6 +34,10 @@ jobs: with: name: check-messages path: check-messages.txt + - name: Nokogiri deps + run: sudo apt install -y pkg-config libxml2-dev libxslt-dev + - name: Site deps + run: bundle install - name: Build site - run: jekyll build + run: bundle exec jekyll build From d296482935274d16ad68c592b6f3e568e633f024 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Thu, 2 Jul 2020 09:21:15 +0100 Subject: [PATCH 235/647] addressing codacy issues --- index.md | 91 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/index.md b/index.md index d5e46dae..bb2a9a4c 100644 --- a/index.md +++ b/index.md @@ -11,76 +11,97 @@ The Earth System Model Evaluation Tool (ESMValTool) is a community developed sof the diagnosis and evaluation of the causes and effects of model biases and inter-model spread within the CMIP model ensemble. - This tutorial is structured such that the main body of the tutorial, up to the episode 7, can be done in one sitting. From episode 8, each episode is a mini-tutorial covering an advanced aspect of working with ESMValTool. These mini-tutorials can be appended to the main tutorial or worked through independently. > ## What will you learn in this course > -> - What is ESMValTool -> - How to install ESMValTool -> - How to configure ESMValTool for your local system -> - How to run ESMValTool -> - How to work with ESMValTool's suite of preprocessors -> - How to debug your recipes -> - How to access and deploy recipes from the ESMValTools gallery (Advanced) -> - How to develop your own diagnostics and recipes (Advanced) -> - How to contribute your recipes and diagnostics back into ESMValTool (Advanced) -> - How to include new observational datasets (Advanced) +> - What is ESMValTool +> +> - How to install ESMValTool +> +> - How to configure ESMValTool for your local system +> +> - How to run ESMValTool +> +> - How to work with ESMValTool's suite of preprocessors +> +> - How to debug your recipes +> +> - How to access and deploy recipes from the ESMValTools gallery (Advanced) +> +> - How to develop your own diagnostics and recipes (Advanced) +> +> - How to contribute your recipes and diagnostics back into ESMValTool (Advanced) +> +> - How to include new observational datasets (Advanced) > {: .checklist} > ## Prerequisites > > *Minimal requirements:* -> - Basic understanding of your preferred command line interface (ie a bash terminal) -> - Laptop/desktop with [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed -> - Access to CMIP data +> +> - Basic understanding of your preferred command line interface (ie a bash terminal) +> +> - Laptop/desktop with [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed +> +> - Access to CMIP data > > *Optional, but useful:* -> - Basic understanding of git -> - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) -> - GitHub account +> +> - Basic understanding of git +> +> - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) +> +> - GitHub account +> {: .prereq} - ### Main things you need to know before starting this course -1. This tutorial can be taken online independently or taught by one of our instructors. -2. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. -3. If you get stuck, help is always available from the tutors, from ESMValTool developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) - or via the [ESMValTool email list](mailto:esmvaltool@listserv.dfn.de). -4. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. + 1. This tutorial can be taken online independently or taught by one of our instructors. + + 2. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. + 3. If you get stuck, help is always available from the tutors, from ESMValTool developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) + or via the [ESMValTool email list](mailto:esmvaltool@listserv.dfn.de). + 4. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. -> ## Additional resources: +> ## Additional resources +> > - [Read the docs page](https://esmvaltool.readthedocs.io/) +> > - [ESMValTool home page](https://www.esmvaltool.org/) +> > - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) +> > - [ESMValTool Source code](https://github.com/ESMValGroup/ESMValTool) +> > - [ESMValCore Source code](https://github.com/ESMValGroup/ESMValCore) +> {: .callout} ## How to cite ESMValTool Please cite this tutorial as: -- ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], - [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), - [DATE]. + - ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], + [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), + [DATE]. Please cite ESMValTool as: -- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., - Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., - Weigel, K., and Zechlau, S.: - Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for - emergent constraints and future projections from Earth system models in CMIP, - Geosci. Model Dev. Discuss., - [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), - in review, 2020. + - Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., + Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., + Weigel, K., and Zechlau, S.: + Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for + emergent constraints and future projections from Earth system models in CMIP, + Geosci. Model Dev. Discuss., + [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), + in review, 2020. {% include links.md %} From 1d226413f24414a10e9c57eef25474832475c5e5 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 2 Jul 2020 10:43:41 +0200 Subject: [PATCH 236/647] Make check non-permissive --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c2b18534..7da810b4 100644 --- a/Makefile +++ b/Makefile @@ -132,7 +132,7 @@ lesson-check : lesson-fixme ## * lesson-check-all : validate lesson Markdown, checking line lengths and trailing whitespace lesson-check-all : - @${PYTHON} bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md -l -w --permissive + @${PYTHON} bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md -l -w ## * unittest : run unit tests on checking tools unittest : From 8b32e50746a8a5230b77c7fd26f570e6a070e707 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 2 Jul 2020 10:43:54 +0200 Subject: [PATCH 237/647] Move Markdown check to bottom as it's the most strict check --- .github/workflows/ci.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 226c41aa..b9cf7440 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,16 +28,15 @@ jobs: python-version: '3.x' - name: Python deps run: pip install pyyaml - - name: Check all lessons - run: make lesson-check-all | tee check-messages.txt - - uses: actions/upload-artifact@v2 - with: - name: check-messages - path: check-messages.txt - name: Nokogiri deps run: sudo apt install -y pkg-config libxml2-dev libxslt-dev - name: Site deps run: bundle install - name: Build site run: bundle exec jekyll build - + - name: Check all lessons + run: make lesson-check-all | tee check-messages.txt + - uses: actions/upload-artifact@v2 + with: + name: check-messages + path: check-messages.txt From c769763bd037cb72a53e257d9df9e403650047c5 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Thu, 2 Jul 2020 09:48:09 +0100 Subject: [PATCH 238/647] fixed codacy issues --- index.md | 69 ++++++++++++++++++++++++-------------------------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/index.md b/index.md index bb2a9a4c..56ffa7e4 100644 --- a/index.md +++ b/index.md @@ -17,72 +17,63 @@ These mini-tutorials can be appended to the main tutorial or worked through inde > ## What will you learn in this course > -> - What is ESMValTool -> -> - How to install ESMValTool -> -> - How to configure ESMValTool for your local system -> -> - How to run ESMValTool -> -> - How to work with ESMValTool's suite of preprocessors -> -> - How to debug your recipes -> -> - How to access and deploy recipes from the ESMValTools gallery (Advanced) -> -> - How to develop your own diagnostics and recipes (Advanced) -> -> - How to contribute your recipes and diagnostics back into ESMValTool (Advanced) -> -> - How to include new observational datasets (Advanced) -> -{: .checklist} +> - What is ESMValTool +> - How to install ESMValTool +> - How to configure ESMValTool for your local system +> - How to run ESMValTool +> - How to work with ESMValTool's suite of preprocessors +> - How to debug your recipes +> - How to access and deploy recipes from the ESMValTools gallery (Advanced) +> - How to develop your own diagnostics and recipes (Advanced) +> - How to contribute your recipes and diagnostics back into ESMValTool (Advanced) +> - How to include new observational datasets (Advanced) +> +>{: .checklist} > ## Prerequisites > > *Minimal requirements:* > -> - Basic understanding of your preferred command line interface (ie a bash terminal) +> - Basic understanding of your preferred command line interface (ie a bash terminal) > -> - Laptop/desktop with [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed +> - Laptop/desktop with [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed > -> - Access to CMIP data +> - Access to CMIP data > > *Optional, but useful:* > -> - Basic understanding of git +> - Basic understanding of git > -> - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) +> - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) > -> - GitHub account +> - GitHub account > -{: .prereq} +>{: .prereq} ### Main things you need to know before starting this course - 1. This tutorial can be taken online independently or taught by one of our instructors. +1. This tutorial can be taken online independently or taught by one of our instructors. - 2. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. +2. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. - 3. If you get stuck, help is always available from the tutors, from ESMValTool developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) +3. If you get stuck, help is always available from the tutors, from ESMValTool developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) or via the [ESMValTool email list](mailto:esmvaltool@listserv.dfn.de). - 4. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. +4. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. -> ## Additional resources +> ## Additional Resources > -> - [Read the docs page](https://esmvaltool.readthedocs.io/) +> - [Read the docs page](https://esmvaltool.readthedocs.io/) > -> - [ESMValTool home page](https://www.esmvaltool.org/) +> - [ESMValTool home page](https://www.esmvaltool.org/) > -> - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) +> - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) > -> - [ESMValTool Source code](https://github.com/ESMValGroup/ESMValTool) +> - [ESMValTool Source code](https://github.com/ESMValGroup/ESMValTool) > -> - [ESMValCore Source code](https://github.com/ESMValGroup/ESMValCore) +> - [ESMValCore Source code](https://github.com/ESMValGroup/ESMValCore) > -{: .callout} +> {: .callout} ## How to cite ESMValTool From a50aac9bd0f7e4d390ae2e88f718f2dd46224704 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 2 Jul 2020 10:55:23 +0200 Subject: [PATCH 239/647] Dont store check log in artifact It causes check fail to be swallowed --- .github/workflows/ci.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9cf7440..07c7d702 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,8 +35,4 @@ jobs: - name: Build site run: bundle exec jekyll build - name: Check all lessons - run: make lesson-check-all | tee check-messages.txt - - uses: actions/upload-artifact@v2 - with: - name: check-messages - path: check-messages.txt + run: make lesson-check-all From ef426d44798c51aea65a56620d787ac99ef4436a Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 3 Jul 2020 14:22:56 +0200 Subject: [PATCH 240/647] Address line length and code block yaml errors --- CONTRIBUTING.md | 108 +++++++++------ README.md | 37 +++-- _episodes/01-introduction.md | 121 +++++++++++++---- _episodes/02-installation.md | 107 +++++++++------ _episodes/03-configuration.md | 110 +++++++-------- _episodes/05-preprocessor.md | 156 +++++++++++++++------ _episodes/06-debugging.md | 168 ++++++++++++----------- _episodes/10-development-setup.md | 66 +++++---- setup.md | 219 +++++++++++++++++------------- 9 files changed, 680 insertions(+), 412 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 067d78d4..3377e49d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,68 +1,94 @@ # Contributing to ESMValTool tutorial -[ESMValTool][tutorial-site] tutorial is an open-source project in [ESMValGroup][ESMValTool-site] and we greatly value contributions of all kinds: fixes to this tutorial, bug reports, reviews of pull requests, infrastructure improvements, community help, and outreach. We value the time you invest in contributing and strive to make the process as easy as possible. If you have suggestions for improving the process of contributing, please open an [issue][issues]. To do so, click on `New issue` in the `issues` tab of this repository and choose the `Suggestion` template. +[ESMValTool][tutorial-site] tutorial is an open-source project in +[ESMValGroup][ESMValTool-site] and we greatly value contributions of all kinds: +fixes to this tutorial, bug reports, reviews of pull requests, infrastructure +improvements, community help, and outreach. We value the time you invest in +contributing and strive to make the process as easy as possible. If you have +suggestions for improving the process of contributing, please open an +[issue][issues]. To do so, click on `New issue` in the `issues` tab of this +repository and choose the `Suggestion` template. ## Acknowledgement -The format of this tutorial is based on the [Software Carpentry][swc-site], which is an open-source project. +The format of this tutorial is based on the [Software Carpentry][swc-site], +which is an open-source project. ## Agreement -By contributing, you agree that we may redistribute your work under [our license](LICENSE.md). -In exchange, we will address your issues and/or assess your change proposal as promptly as we can, and help you become a member of our community. -Everyone involved in this [tutorial](tutorial-repo) agrees to abide by our [code of conduct](CODE_OF_CONDUCT.md). +By contributing, you agree that we may redistribute your work under [our +license](LICENSE.md). In exchange, we will address your issues and/or assess +your change proposal as promptly as we can, and help you become a member of our +community. Everyone involved in this [tutorial](tutorial-repo) agrees to abide +by our [code of conduct](CODE_OF_CONDUCT.md). ## How to Contribute There are many ways to contribute: -* If you do not have a [GitHub][github] account, -you can send us comments by [email][email]. -However, -we will be able to respond more quickly when you use one of the other methods described below. - -* If you have a [GitHub][github] account, work in this [repository][tutorial-repo], -which can be viewed at the tutorial [site][tutorial-site]. -You can ask your questions, report problems or suggest improvements by [creating an issue][issues]. -This is the easiest way to tell us about your ideas, and a good way to introduce yourself -and to meet some of our community members. -This allows us to assign the item to someone and to respond to it in a threaded discussion. -To open an issue, click on `New issue` in the `issues` tab of this repository and choose a template from the [list](https://github.com/ESMValGroup/tutorial/issues/new/choose) as described below: +* If you do not have a [GitHub][github] account, you can send us comments by + [email][email]. However, we will be able to respond more quickly when you use + one of the other methods described below. + +* If you have a [GitHub][github] account, work in this + [repository][tutorial-repo], which can be viewed at the tutorial + [site][tutorial-site]. You can ask your questions, report problems or suggest + improvements by [creating an issue][issues]. This is the easiest way to tell + us about your ideas, and a good way to introduce yourself and to meet some of + our community members. This allows us to assign the item to someone and to + respond to it in a threaded discussion. To open an issue, click on `New issue` + in the `issues` tab of this repository and choose a template from the + [list](https://github.com/ESMValGroup/tutorial/issues/new/choose) as described + below: * for asking a question, please use `Question and answer`. * for reporting a bug, please use `Bug reports`. * for developing lesson material, please use `New lesson material`. * for adding a feature to the repository, please use `Suggestion`. -* If you would like to add what is already discussed in an issue, -you can submit a [pull request][PR] and make use of the `pull request checklist`. -Each pull request is reviewed at least by one reviewer who is a community volunteer. -The [maintainers][tutorial-maintainers] have final say over what gets merged into the tutorial. +* If you would like to add what is already discussed in an issue, you can submit + a [pull request][PR] and make use of the `pull request checklist`. Each pull + request is reviewed at least by one reviewer who is a community volunteer. The + [maintainers][tutorial-maintainers] have final say over what gets merged into + the tutorial. ## Tutorial guidelines -This section demonstrates all the instructions for developing a lesson in the [ESMValTool tutorial][tutorial-site]. -The tutorial is a set of lessons (or episodes) that together teach **basic** skills needed to work with [ESMValTool][ESMValTool-doc] in climate-related domains. +This section demonstrates all the instructions for developing a lesson in the +[ESMValTool tutorial][tutorial-site]. The tutorial is a set of lessons (or +episodes) that together teach **basic** skills needed to work with +[ESMValTool][ESMValTool-doc] in climate-related domains. ### Lesson development -The content of this tutorial is mainly developed based on the [Carpentries Curriculum Development Handbook][swc-handbook]. The handbook explains why we teach the way we do, and why our lessons are designed the way they are. -If you are contributing to existing lesson materials, please make sure the content conforms to the concepts provided in the handbook. +The content of this tutorial is mainly developed based on the [Carpentries +Curriculum Development Handbook][swc-handbook]. The handbook explains why we +teach the way we do, and why our lessons are designed the way they are. If you +are contributing to existing lesson materials, please make sure the content +conforms to the concepts provided in the handbook. -We recommend using software to check spelling or grammatical errors. -The following link will guide you through a list of tools for several editors: +We recommend using software to check spelling or grammatical errors. The +following link will guide you through a list of tools for several editors: ### Lesson organization -Each lesson is made up of episodes, which are focused on a particular topic and include time for both teaching and exercises. If you are making a new episode, please make sure the content conforms to the [Carpentries lesson organization][swc-lesson-organization]. +Each lesson is made up of episodes, which are focused on a particular topic and +include time for both teaching and exercises. If you are making a new episode, +please make sure the content conforms to the [Carpentries lesson +organization][swc-lesson-organization]. ### Lesson formatting -Episodes are [Markdown](https://en.wikipedia.org/wiki/Markdown) files. If you are making a new episode or contributing to existing ones, please make sure the content conforms to the [Carpentries lesson formatting][swc-lesson-formatting]. +Episodes are [Markdown](https://en.wikipedia.org/wiki/Markdown) files. If you +are making a new episode or contributing to existing ones, please make sure the +content conforms to the [Carpentries lesson formatting][swc-lesson-formatting]. -We also, recommend using a linter to check errors in Markdown files. -For example, a [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) can be installed as an extension in [Visual Studio Code](https://code.visualstudio.com/). -Alternatively, a linter can be installed with: +We also, recommend using a linter to check errors in Markdown files. For +example, a +[markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) +can be installed as an extension in [Visual Studio +Code](https://code.visualstudio.com/). Alternatively, a linter can be installed +with: ```bash gem install mdl @@ -74,7 +100,10 @@ and can be used as: mdl your_markdown_filename ``` -We use [Codacy](https://app.codacy.com/gh/ESMValGroup/tutorial) as an automated code analysis services. To run the analyis [locally](https://github.com/codacy/codacy-analysis-cli) on Markdown files with Docker use +We use [Codacy](https://app.codacy.com/gh/ESMValGroup/tutorial) as an automated +code analysis services. To run the analyis +[locally](https://github.com/codacy/codacy-analysis-cli) on Markdown files with +Docker use ```bash docker run \ @@ -89,9 +118,9 @@ docker run \ ### Previewing your changes locally -If you are making a new episode or contributing to existing ones, -please preview changes on your machine before submitting a [pull request][PR]. -To do so, you need to install the software described below: +If you are making a new episode or contributing to existing ones, please preview +changes on your machine before submitting a [pull request][PR]. To do so, you +need to install the software described below: ```bash # apt (Ubuntu/Devian) @@ -105,14 +134,15 @@ or sudo dnf install rubygem-bundler ruby-devel ``` -Alternatively, there is an environment file available which can be installed with: +Alternatively, there is an environment file available which can be installed +with: ```bash conda env create -f environment.yml -n esmvaltool_tutorial ``` -To install the required ruby packages, run the following command in the tutorial's -main directory to build and serve the website locally: +To install the required ruby packages, run the following command in the +tutorial's main directory to build and serve the website locally: ```bash make serve diff --git a/README.md b/README.md index dc0335eb..51387256 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,39 @@ # FIXME Lesson title -[![Create a Slack Account with us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/) [![Join the chat at https://gitter.im/ESMValGroup/Tutorial](https://badges.gitter.im/ESMValGroup/Tutorial.svg)](https://gitter.im/ESMValGroup/Tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Create a Slack Account with +us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/) +[![Join the chat at +https://gitter.im/ESMValGroup/Tutorial](https://badges.gitter.im/ESMValGroup/Tutorial.svg)](https://gitter.im/ESMValGroup/Tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -This repository generates the corresponding lesson website from [The Carpentries](https://carpentries.org/) repertoire of lessons. +This repository generates the corresponding lesson website from [The +Carpentries](https://carpentries.org/) repertoire of lessons. ## Contributing -We welcome all contributions to improve the lesson! Maintainers will do their best to help you if you have any -questions, concerns, or experience any difficulties along the way. +We welcome all contributions to improve the lesson! Maintainers will do their +best to help you if you have any questions, concerns, or experience any +difficulties along the way. -We'd like to ask you to familiarize yourself with our [Contribution Guide](CONTRIBUTING.md) and have a look at -the [more detailed guidelines][lesson-example] on proper formatting, ways to render the lesson locally, and even -how to write new episodes. Note that the content of the web page is located in the directory [_episodes](https://github.com/ESMValGroup/tutorial/tree/master/_episodes). +We'd like to ask you to familiarize yourself with our [Contribution +Guide](CONTRIBUTING.md) and have a look at the [more detailed +guidelines][lesson-example] on proper formatting, ways to render the lesson +locally, and even how to write new episodes. Note that the content of the web +page is located in the directory +[_episodes](https://github.com/ESMValGroup/tutorial/tree/master/_episodes). -Please see the current list of [issues][FIXME] for ideas for contributing to this -repository. For making your contribution, we use the GitHub flow, which is -nicely explained in the chapter [Contributing to a Project](http://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project) in Pro Git -by Scott Chacon. -Look for the tag ![good_first_issue](https://img.shields.io/badge/-good%20first%20issue-gold.svg). This indicates that the maintainers will welcome a pull request fixing this issue. +Please see the current list of [issues][FIXME] for ideas for contributing to +this repository. For making your contribution, we use the GitHub flow, which is +nicely explained in the chapter [Contributing to a +Project](http://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project) in Pro +Git by Scott Chacon. Look for the tag +![good_first_issue](https://img.shields.io/badge/-good%20first%20issue-gold.svg). +This indicates that the maintainers will welcome a pull request fixing this +issue. ## Maintainer(s) -Current maintainers of this lesson are +Current maintainers of this lesson are * FIXME * FIXME diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 92e43b00..833eecc2 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -16,14 +16,18 @@ objectives: keypoints: - ESMValTool provides a reliable interface to analyse and evaluate climate data - Using ESMValTool promotes standardization, collaboration, and reuse -- ESMValTool is built and maintained by an active community of scientists and developers -- ESMValTool is written in Python, but supports diagnostic scripts in multiple languages +- ESMValTool is built and maintained by an active community of scientists and + developers +- ESMValTool is written in Python, but supports diagnostic scripts in multiple + languages --- ## What is ESMValTool -EMSValTool is first and foremost a tool to analyse climate data. But you probably already knew that and we like to think there's more to it than that. So let's start with a quick check to synchronize our expectations. +EMSValTool is first and foremost a tool to analyse climate data. But you +probably already knew that and we like to think there's more to it than that. So +let's start with a quick check to synchronize our expectations. > ## Question: what is ESMValTool > @@ -42,75 +46,138 @@ EMSValTool is first and foremost a tool to analyse climate data. But you probabl > > > ## ESMValTool is > > -> > ✓ **A tool to analyse climate data.** It takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. +> > ✓ **A tool to analyse climate data.** It takes care of finding, +> > opening, checking, fixing, concatenating, and preprocessing CMIP data and +> > several other supported datasets. > > -> > ✕ **The easy way out.** If you just want to do an exploratory analysis or quickly hack something together, ESMValTool is probably not the way to go. The tool is intended for robust, repeatable and shareable climate analysis. That *does* require a bit more effort. +> > ✕ **The easy way out.** If you just want to do an exploratory +> > analysis or quickly hack something together, ESMValTool is probably not the +> > way to go. The tool is intended for robust, repeatable and shareable climate +> > analysis. That *does* require a bit more effort. > > -> > ✓ **A community effort.** EMSValTool is developed and maintained by a large team of climate scientists and software engineers. It is an open source project to which anyone can contribute. Its longevity depends on these contributions. +> > ✓ **A community effort.** EMSValTool is developed and maintained by a +> > large team of climate scientists and software engineers. It is an open +> > source project to which anyone can contribute. Its longevity depends on +> > these contributions. > > -> > ✓ **Free.** ESMValTool is licenced under Apache 2.0, which means everyone can use, modify, or share it free of charge. However, we *do* encourage all users to contribute to the community once they get more comfortable with the tool. +> > ✓ **Free.** ESMValTool is licenced under Apache 2.0, which means +> > everyone can use, modify, or share it free of charge. However, we *do* +> > encourage all users to contribute to the community once they get more +> > comfortable with the tool. > > -> > ✓ **A command line tool.** ESMValTool was originally designed for the command line. But, we are working on a user-friendly python interface as well. +> > ✓ **A command line tool.** ESMValTool was originally designed for the +> > command line. But, we are working on a user-friendly python interface as +> > well. > > -> > ✓ **A way to make climate science more [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance information about the data and code that are used to obtain a result. It comes with a readable recipe format that makes climate analysis consistent, reproducible, and easy to share. +> > ✓ **A way to make climate science more +> > [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance +> > information about the data and code that are used to obtain a result. It +> > comes with a readable recipe format that makes climate analysis consistent, +> > reproducible, and easy to share. > > -> > ✕ **Perfect.** Although we are continuously working to improve the tool, you may encounter some bugs or missing features. In the following episodes, you will learn how to troubleshoot, find help, and maybe even contribute to the solution yourself. +> > ✕ **Perfect.** Although we are continuously working to improve the +> > tool, you may encounter some bugs or missing features. In the following +> > episodes, you will learn how to troubleshoot, find help, and maybe even +> > contribute to the solution yourself. > > -> > ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a command line tool. But, we are working on a user-friendly Python interface as well. +> > ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a +> > command line tool. But, we are working on a user-friendly Python interface +> > as well. > {: .solution} {: .challenge} -To learn more about ESMValTool, you can look at the [documentation](https://docs.esmvaltool.org/en/latest/introduction.html), the [official website](https://www.esmvaltool.org/about.html), or the [overview paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific Model Development*. +To learn more about ESMValTool, you can look at the +[documentation](https://docs.esmvaltool.org/en/latest/introduction.html), the +[official website](https://www.esmvaltool.org/about.html), or the [overview +paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific +Model Development*. ## How does ESMValTool work -The figure below shows the different components of ESMValTool. Some of the most important work is done in the 'core', which performs a number of preprocessor steps. Outside of the core we have some configuration files that specify things like *where to find the CMIP data*. The most important file however, is the *recipe* that specifies which preprocessor functions need to be applied to what data. The recipe also points to a diagnostic script that is executed after the preprocessor and performs a more specific analysis on the preprocessed data. +The figure below shows the different components of ESMValTool. Some of the most +important work is done in the 'core', which performs a number of preprocessor +steps. Outside of the core we have some configuration files that specify things +like *where to find the CMIP data*. The most important file however, is the +*recipe* that specifies which preprocessor functions need to be applied to what +data. The recipe also points to a diagnostic script that is executed after the +preprocessor and performs a more specific analysis on the preprocessed data. -![figure showing ESMValTool architecture]({{ page.root }}/fig/esmvaltool_architecture.png) +![figure showing ESMValTool architecture]({{ page.root +}}/fig/esmvaltool_architecture.png) > ## Discussion: (dis)advantages of this approach > -> Discuss or think about the pros and cons of this architecture for a moment. Then unfold the box below to see our answers. +> Discuss or think about the pros and cons of this architecture for a moment. +> Then unfold the box below to see our answers. > > > > ## See our thoughts > > -> > - Streamlining common preprocessing steps ensures consistency in the algorithms being used and the way they are executed. This facilitates comparison and reproducibility. -> > - Provenance and citation information can be tracked through the entire workflow. -> > - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) package, which is quite strict in order to comply with CF conventions and minimize unexpected results. +> > - Streamlining common preprocessing steps ensures consistency in the +> > algorithms being used and the way they are executed. This facilitates +> > comparison and reproducibility. +> > - Provenance and citation information can be tracked through the entire +> > workflow. +> > - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) +> > package, which is quite strict in order to comply with CF conventions and +> > minimize unexpected results. > > - Recipes are easy to read and share. -> > - A collection of recipes and diagnostic scripts is shipped with ESMValTool, ready for re-use. Everyone can add to this collection. -> > - The recipe format takes some getting used to and may be a bit less flexible then working on the datasets directly. -> > - Features or dataset support that are missing from ESMValCore can be a limiting factor. +> > - A collection of recipes and diagnostic scripts is shipped with ESMValTool, +> > ready for re-use. Everyone can add to this collection. +> > - The recipe format takes some getting used to and may be a bit less +> > flexible then working on the datasets directly. +> > - Features or dataset support that are missing from ESMValCore can be a +> > limiting factor. > {: .solution} {: .discussion} ## Community -ESMValTool is built and maintained by an active community of scientists and software engineers. Many of the interactions take place on GitHub. Here, we briefly introduce you to some of the most important pages. +ESMValTool is built and maintained by an active community of scientists and +software engineers. Many of the interactions take place on GitHub. Here, we +briefly introduce you to some of the most important pages. > ## Meet ESMValGroup > -> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is our 'organization' GitHub page. Have a look around. How many collaborators are there? Do you know any of them? Near the top of the page there are 2 pinned repositories: ESMValTool and ESMValCore. Visit each of the repositories. How many people have contributed to each of them? Can you also find out how many people have contributed to this tutorial? +> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is +> our 'organization' GitHub page. Have a look around. How many collaborators are +> there? Do you know any of them? Near the top of the page there are 2 pinned +> repositories: ESMValTool and ESMValCore. Visit each of the repositories. How +> many people have contributed to each of them? Can you also find out how many +> people have contributed to this tutorial? > > > ## Solution > > -> > At the time of making this lesson, there were 138 members of ESMValGroup. 55 of them contributed to ESMValTool, 48 to ESMValCore. 52 (!) people contributed to this tutorial. +> > At the time of making this lesson, there were 138 members of ESMValGroup. 55 +> > of them contributed to ESMValTool, 48 to ESMValCore. 52 (!) people +> > contributed to this tutorial. > {: .solution} {: .challenge} > ## Issues and pull requests > -> Go back to the repository pages of [ESMValTool](https://github.com/ESMValGroup/ESMValTool) or [ESMValCore](https://github.com/ESMValGroup/ESMValCore). There are tabs for 'issues' and 'pull requests'. You can use the labels to navigate them a bit more. How many open issues are about enhancements of ESMValTool? And how many bugs have been fixed in ESMValCore? There is also an 'insights' tab, where you can see a summary of recent activity. How many issues have been opened and closed in the past month? +> Go back to the repository pages of +> [ESMValTool](https://github.com/ESMValGroup/ESMValTool) or +> [ESMValCore](https://github.com/ESMValGroup/ESMValCore). There are tabs for +> 'issues' and 'pull requests'. You can use the labels to navigate them a bit +> more. How many open issues are about enhancements of ESMValTool? And how many +> bugs have been fixed in ESMValCore? There is also an 'insights' tab, where you +> can see a summary of recent activity. How many issues have been opened and +> closed in the past month? > > > ## Solution > > -> > At the time of making this lesson, there were 50 ESMValTool issues (the majority) about enhancement and 31 bugs had been fixed in the Core. 13 ESMValTool issues had been closed in the past month, versus 8 opened: overall good progress. +> > At the time of making this lesson, there were 50 ESMValTool issues (the +> > majority) about enhancement and 31 bugs had been fixed in the Core. 13 +> > ESMValTool issues had been closed in the past month, versus 8 opened: +> > overall good progress. > {: .solution} {: .challenge} ## Conclusion -This concludes the introduction of the tutorial. You now have a basic knowledge of ESMValTool and our community. The following episodes will walk you through the installation, configuration and running your first recipes. +This concludes the introduction of the tutorial. You now have a basic knowledge +of ESMValTool and our community. The following episodes will walk you through +the installation, configuration and running your first recipes. {% include links.md %} diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 2ca58d91..4efb82ea 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -14,22 +14,31 @@ keypoints: --- ## Overview -In this tutorial we will be using the [Conda](https://conda.io/projects/conda/en/latest/index.html) -package manager to install the ESMValTool. -Other installation methods are also available, they can be found in the +In this tutorial we will be using the +[Conda](https://conda.io/projects/conda/en/latest/index.html) package manager to +install the ESMValTool. Other installation methods are also available, they can +be found in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). ESMValTool also contains diagnostics written in [Julia](https://julialang.org/). -Because Julia cannot be installed by Conda, we will install Julia separately. -We will first learn how to install Conda, Julia, and finally the ESMValTool. -We end this chapter by testing that the installation was successful. +Because Julia cannot be installed by Conda, we will install Julia separately. We +will first learn how to install Conda, Julia, and finally the ESMValTool. We end +this chapter by testing that the installation was successful. ## Install Conda -ESMValTool is distributed using [Conda](https://conda.io/). We will be using the Miniconda minimal installer for conda. We suggest a Python 3 based installer, though if you happen to already have Conda installed it should also work with Python 2. For more information about installing conda, see [the conda installation documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). +ESMValTool is distributed using [Conda](https://conda.io/). We will be using the +Miniconda minimal installer for conda. We suggest a Python 3 based installer, +though if you happen to already have Conda installed it should also work with +Python 2. For more information about installing conda, see [the conda +installation +documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). ### Linux -1. Please download Miniconda3 for Linux at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. +1. Please download Miniconda3 for Linux at [the miniconda + page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version + should work on any recent system. If you have problems in the next step(s) + you can alternatively try a 32 bit version. 2. Next, run the installer from the place where you downloaded it @@ -37,11 +46,13 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the bash Miniconda3-latest-Linux-x86_64.sh ``` -3. Follow the instructions in the installer. The defaults should normally suffice. +3. Follow the instructions in the installer. The defaults should normally + suffice. 4. You will need to restart your terminal for the changes to have effect. -5. Verify you have a working conda installation by listing all installed packages +5. Verify you have a working conda installation by listing all installed + packages ```bash conda list @@ -61,7 +72,8 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the ### MacOSX -1. Please download Miniconda3 for MacOSX at [the miniconda page](https://docs.conda.io/en/latest/miniconda.html). +1. Please download Miniconda3 for MacOSX at [the miniconda + page](https://docs.conda.io/en/latest/miniconda.html). 2. Next, run the installer from the place where you downloaded it @@ -69,11 +81,13 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the bash Miniconda3-latest-MacOSX-x86_64.sh ``` -3. Follow the instructions in the installer. The defaults should normally suffice. +3. Follow the instructions in the installer. The defaults should normally + suffice. 4. You will need to restart your terminal for the changes to have effect. -5. Verify you have a working conda installation by listing all installed packages +5. Verify you have a working conda installation by listing all installed + packages ```bash conda list @@ -94,18 +108,23 @@ ESMValTool is distributed using [Conda](https://conda.io/). We will be using the ### Windows -ESMValTool does not directly support Windows, but succesful usage has been reported through the [Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows 10. +ESMValTool does not directly support Windows, but succesful usage has been +reported through the [Windows Subsystem for +Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows +10. -To install the WSL please follow the instructions [on the Windows Documentation page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). +To install the WSL please follow the instructions [on the Windows Documentation +page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). -After installing the WSL, installation can be done using the Linux installation instructions. +After installing the WSL, installation can be done using the Linux installation +instructions. ## Install Julia -Complete instructions for installing Julia can be found on the -[Julia installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). -In this tutorial, we will use the following steps. -First, open a bash terminal and create a directory to install Julia in and cd into it +Complete instructions for installing Julia can be found on the [Julia +installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). +In this tutorial, we will use the following steps. First, open a bash terminal +and create a directory to install Julia in and cd into it ```bash mkdir ~/julia @@ -114,18 +133,20 @@ cd ~/julia Next, download the file [`julia-1.0.5-linux-x86_64.tar.gz`](https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz) -by clicking the link or going to the [Julia downloads page](https://julialang.org/downloads/). -Download the file directly to the `~/julia` directory or move it there after downloading. -To extract the file, you can use the following command: +by clicking the link or going to the [Julia downloads +page](https://julialang.org/downloads/). Download the file directly to the +`~/julia` directory or move it there after downloading. To extract the file, you +can use the following command: ```bash tar -xvzf julia-1.0.5-linux-x86\_64.tar.gz ``` -This will extract the files to a directory named `~/julia/julia-1.0.5`. -To run Julia, you need to add the full path of Julia's `bin` folder to PATH environment variable. -To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. -Open the file in your favorite editor and add a new line as follows at the bottom of the file: +This will extract the files to a directory named `~/julia/julia-1.0.5`. To run +Julia, you need to add the full path of Julia's `bin` folder to PATH environment +variable. To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. +Open the file in your favorite editor and add a new line as follows at the +bottom of the file: ```bash export PATH="$PATH:$HOME/julia/julia-1.0.5/bin" @@ -137,7 +158,8 @@ Finally, for the settings to take effect, either reload your bash profile source ~/.bashrc ``` -(or `source ~/.bash_profile`), or close the bash terminal window and open a new one. +(or `source ~/.bash_profile`), or close the bash terminal window and open a new +one. To check that the Julia executable can be found, run @@ -168,19 +190,26 @@ To install the ESMValTool package, run conda create -n esmvaltool -c conda-forge -c esmvalgroup esmvaltool ``` -This will create a new -[Conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) -called `esmvaltool`, with the ESMValTool package and all of its dependencies installed in it. +This will create a new [Conda +environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) +called `esmvaltool`, with the ESMValTool package and all of its dependencies +installed in it. > ## Conda common problems > > Below are some common problems that could happen while installing. > > - Installation takes long time -> - Downloads and compilations can take several minutes to complete, please be patient. -> - You might have bad luck and the dependencies can not be resolved at the moment, please try again later or [raise an issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose) -> - If you have an old conda installation you could get a `UnsatisfiableError` message. Please install a newer version of conda and try again -> - Downloads fail due to company proxy, see [conda docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to resolve +> - Downloads and compilations can take several minutes to complete, +> please be patient. +> - You might have bad luck and the dependencies can not be resolved at +> the moment, please try again later or [raise an +> issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose) +> - If you have an old conda installation you could get a `UnsatisfiableError` +> message. Please install a newer version of conda and try again +> - Downloads fail due to company proxy, see [conda +> docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to +> resolve > {: .callout} @@ -192,8 +221,9 @@ To test that the installation was successful, run conda activate esmvaltool ``` -to activate the conda environment called `esmvaltool`. -In the shell prompt the active conda environment should have been changed from `(base)` to `(esmvaltool)`. +to activate the conda environment called `esmvaltool`. In the shell prompt the +active conda environment should have been changed from `(base)` to +`(esmvaltool)`. Next, run @@ -209,7 +239,8 @@ to display the command line help. > > > ## Solution > > -> > The `esmvaltool --help` command lists `-v` or `--version` as optional argument to get the version +> > The `esmvaltool --help` command lists `-v` or `--version` as optional +> > argument to get the version > > > > In my case when I run > > ~~~ diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 9ce69945..d8833521 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -19,10 +19,10 @@ keypoints: ## The configuration file -The ``config-user.yml`` configuration file contains all the global level information -needed by ESMValTool to run. This is an -[YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file -can be found in the root directory of the ESMValTool repository: +The ``config-user.yml`` configuration file contains all the global level +information needed by ESMValTool to run. This is an [YAML +file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be +found in the root directory of the ESMValTool repository: [config-user-example.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). First, we make a working directory ``esmvaltool_tutorial``. @@ -33,15 +33,16 @@ In a new terminal, run: cd esmvaltool_tutorial ~~~ -Now, we download the configuration file to our working directory. -To do that, click on -[this link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) -to see a raw version of the file, right-click and press ``save as``, -then you can rename it to ``config-user.yml``and save it into the working directory +Now, we download the configuration file to our working directory. To do that, +click on [this +link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) +to see a raw version of the file, right-click and press ``save as``, then you +can rename it to ``config-user.yml``and save it into the working directory ``esmvaltool_tutorial``. -Now, let's change our working directory in a terminal window to ``esmvaltool_tutorial``. -Then, we run a text editor called Nano to have a look inside the configuration file: +Now, let's change our working directory in a terminal window to +``esmvaltool_tutorial``. Then, we run a text editor called Nano to have a look +inside the configuration file: ~~~bash nano config-user.yml @@ -77,7 +78,7 @@ We can find more information about the projects in the ESMValTool The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. -~~~YAML +```yaml rootpath: CMIP3: [~/cmip3_inputpath1, ~/cmip3_inputpath2] CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2] @@ -89,45 +90,45 @@ rootpath: native6: ~/native6_inputpath RAWOBS: ~/rawobs_inputpath default: ~/default_inputpath -~~~ +``` In this lesson, we will work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). We add the root path of the folder where our/your data is available. -~~~YAML +```yaml rootpath: ... CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2, ~/esmvaltool_tutorial/data] -~~~ +``` > ## Setting the correct rootpath > -> - To get the data (or its correct rootpath), check instruction in -[Setup]({{ page.root }}{% link setup.md %}). +> - To get the data (or its correct rootpath), check instruction in [Setup]({{ +> page.root }}{% link setup.md %}). > - For more information about setting the rootpath, see also the ESMValTool -[documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). +> [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} ## Directory structure for the data from different projects -Input data can be from various models, observations and reanalysis data that adhere -to the [CF/CMOR standard](https://cmor.llnl.gov/). -The ``drs`` setting describes the file structure. -Let's use ``default`` for ``CMIP5`` in our example here: +Input data can be from various models, observations and reanalysis data that +adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). The ``drs`` setting +describes the file structure. Let's use ``default`` for ``CMIP5`` in our example +here: -~~~YAML +```yaml drs: CMIP5: default -~~~ +``` > ## Available drs > -> The ``drs`` setting describes the file structure for several projects -(e.g. ``CMIP6``, ``CMIP5``, ``obs4mips``, ``OBS6``, ``OBS``) on several key machines -(e.g. ``BADC``, ``CP4CDS``, ``DKRZ``, ``ETHZ``, ``SMHI``, ``BSC``). -For more information about ``drs``, you can visit the ESMValTool -[documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html#cmor-drs). +> The ``drs`` setting describes the file structure for several projects (e.g. +> ``CMIP6``, ``CMIP5``, ``obs4mips``, ``OBS6``, ``OBS``) on several key machines +> (e.g. ``BADC``, ``CP4CDS``, ``DKRZ``, ``ETHZ``, ``SMHI``, ``BSC``). For more +> information about ``drs``, you can visit the ESMValTool +> [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html#cmor-drs). {: .callout} ## Number of parallel tasks @@ -137,10 +138,10 @@ You can choose the number of tasks in parallel as 1/2/3/4/... or you can set it to ``null``. That tells ESMValTool to use the maximum number of available CPUs: -~~~YAML +```yaml max_parallel_tasks: null -~~~ +``` > ## Set the number of tasks > @@ -161,9 +162,9 @@ This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ` Let's name our destination directory ``esmvaltool_output`` in the working directory: -~~~YAML +```yaml output_dir: ./esmvaltool_output -~~~ +``` > ## Content of subfolders > @@ -183,23 +184,24 @@ are not plots, e.g. files in NetCDF format (depends on the diagnostic script). ## Auxiliary data directory -The ``auxiliary_data_dir`` setting is the path where any required -additional auxiliary data files are stored. This location allows us to tell -the diagnostic script where to find the files if they can not be downloaded -at runtime. This option should not be used for model or observational datasets, but -for data files (e.g. shape files) used in plotting such as coastline descriptions and so on. +The ``auxiliary_data_dir`` setting is the path where any required additional +auxiliary data files are stored. This location allows us to tell the diagnostic +script where to find the files if they can not be downloaded at runtime. This +option should not be used for model or observational datasets, but for data +files (e.g. shape files) used in plotting such as coastline descriptions and so +on. -~~~YAML +```yaml auxiliary_data_dir: ~/auxiliary_data -~~~ +``` ## Output settings -These settings are used to inform ESMValTool about your preference about specific actions. -You can turn on or off the setting by ``true`` or ``false`` values. -Most of these settings are fairly self-explanatory, ie: +These settings are used to inform ESMValTool about your preference about +specific actions. You can turn on or off the setting by ``true`` or ``false`` +values. Most of these settings are fairly self-explanatory, ie: -~~~YAML +```yaml # Diagnostics create plots? [true]/false write_plots: true # Diagnositcs write NetCDF files? [true]/false @@ -222,26 +224,26 @@ remove_preproc_dir: true # Get profiling information for diagnostics # Only available for Python diagnostics profile_diagnostic: false -~~~ +``` > ## Make your own configuration file > > It is possible to have several configuration files with different purposes, -for example: config-user_formalised_runs.yml, config-user_debugging.yml -{: .callout} +> for example: config-user_formalised_runs.yml, config-user_debugging.yml {: +> .callout} > > ## Saving preprocessed data > -> In the configuration file, which settings are useful to make sure preprocessed data -is stored when ESMValTool is run? +> In the configuration file, which settings are useful to make sure preprocessed +> data is stored when ESMValTool is run? > >> ## Solution >> ->> If the option ``save_intermediary_cubes`` is set to true in -the config-user.yml file, then the intermediary cubes will also be saved -in the folder ``preproc``. Also, if the option ``remove_preproc_dir`` -is set to ``false``, then the ``preproc/`` directory contains all -the preprocessed data and the metadata interface files. +> > If the option ``save_intermediary_cubes`` is set to true in the +> > config-user.yml file, then the intermediary cubes will also be saved in the +> > folder ``preproc``. Also, if the option ``remove_preproc_dir`` is set to +> > ``false``, then the ``preproc/`` directory contains all the preprocessed +> > data and the metadata interface files. > {: .solution} {: .challenge} diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 91c366e1..6d416c72 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -14,56 +14,87 @@ objectives: keypoints: - "A recipe can work with different preprocessors at the same time." - "The setting additional_datasets can be used to add a different dataset." -- "Variable groups are useful for defining different settings for different variables." +- "Variable groups are useful for defining different settings for different + variables." --- ## Preprocessors: What are they and how do they work? -Preprocessing is the process of performing a set of modular operations on the data before applying diagnostics or metrics. In the figure below you see the preprocessor functions in the light blue box on the right. +Preprocessing is the process of performing a set of modular operations on the +data before applying diagnostics or metrics. In the figure below you see the +preprocessor functions in the light blue box on the right. -![figure showing ESMValTool architecture]({{ page.root }}/fig/esmvaltool_architecture.png) +![figure showing ESMValTool architecture]({{ page.root +}}/fig/esmvaltool_architecture.png) -Underneath the hood, each preprocessor is a modular python function that receives an iris cube and sometimes some arguments. The preprocessor applies some mathematical or computational transformation to the input iris cube, then returns the processed iris cube. +Underneath the hood, each preprocessor is a modular python function that +receives an iris cube and sometimes some arguments. The preprocessor applies +some mathematical or computational transformation to the input iris cube, then +returns the processed iris cube. ## Inspect the example preprocessor -Each preprocessor section includes a preprocessor name, a list of preprocessor steps to be executed and any arguments needed by the preprocessor steps. +Each preprocessor section includes a preprocessor name, a list of preprocessor +steps to be executed and any arguments needed by the preprocessor steps. -~~~yaml +```yaml preprocessors: prep_timeseries: annual_statistics: operator: mean -~~~ +``` -For instance, the 'annual_statistics' with the 'operation: mean' argument preprocessor receives an iris cube, takes the annual average for each year of data in the cube, and returns the processed cube. +For instance, the 'annual_statistics' with the 'operation: mean' argument +preprocessor receives an iris cube, takes the annual average for each year of +data in the cube, and returns the processed cube. -You may use one or more of several preprocessors listed in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). The standardised interface between the preprocessors allows them to be used modularly - like lego blocks. Almost any conceivable preprocessing order of operations can be performed using ESMValTool preprocessors. +You may use one or more of several preprocessors listed in the +[documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). +The standardised interface between the preprocessors allows them to be used +modularly - like lego blocks. Almost any conceivable preprocessing order of +operations can be performed using ESMValTool preprocessors. > ## The 'custom order' command. > ->If you do not want your preprocessors to be applied in the [default order](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html), then add the following line to your preprocessor chain: +> If you do not want your preprocessors to be applied in the [default +> order](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html), +> then add the following line to your preprocessor chain: > ->~~~ +>```yaml > custom_order: true ->~~~ +>``` > ->The default preprocessor order is listed in the [ESMValCore preprocessor API page](>https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html). +> The default preprocessor order is listed in the [ESMValCore preprocessor API +> page](>https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html). > -> Also note that preprocessor operations aren't always commutative - meaning that the order of operations matters. For instance, when you run the two preprocessors -- 'extract_volume' to extract the top 100m of the ocean surface and 'volume_statistics' to calculate the volume-weighted mean of the data, your result will differ depending on the order of these two preprocessors. In fact, the 'extract_volume' preprocessor will fail if you try to run it on a 2D dataset. +> Also note that preprocessor operations aren't always commutative - meaning +> that the order of operations matters. For instance, when you run the two +> preprocessors -- 'extract_volume' to extract the top 100m of the ocean +> surface and 'volume_statistics' to calculate the volume-weighted mean of the +> data, your result will differ depending on the order of these two +> preprocessors. In fact, the 'extract_volume' preprocessor will fail if you try +> to run it on a 2D dataset. > -> Changing the order of preprocessors can also speed up your processing. For instance, if you want to extract a two-dimensional layer from a 3D field and re-grid it, the layer extraction should be done first. If you did it the other way around, then the regridding function would be applied to all the layers of your 3D cube and it would take much more time. +> Changing the order of preprocessors can also speed up your processing. For +> instance, if you want to extract a two-dimensional layer from a 3D field and +> re-grid it, the layer extraction should be done first. If you did it the other +> way around, then the regridding function would be applied to all the layers of +> your 3D cube and it would take much more time. {: .callout} -Some preprocessor modules are always applied and do not need to be called. This includes the preprocessors that load the data, apply any fixes and save the data file afterwards. These do not need to be explicitly included in recipes. +Some preprocessor modules are always applied and do not need to be called. This +includes the preprocessors that load the data, apply any fixes and save the data +file afterwards. These do not need to be explicitly included in recipes. > ## Exercise: Adding more preprocessor steps > -> Edit the [example recipe](LINK to episode #4) to first change the variable thetao, then add preprocessors to average over the latitude and longitude dimensions and finally average over the depth. Now run the recipe. +> Edit the [example recipe](LINK to episode #4) to first change the variable +> thetao, then add preprocessors to average over the latitude and longitude +> dimensions and finally average over the depth. Now run the recipe. > >> ## Solution >> ->>~~~yaml +>>```yaml >> preprocessors: >> prep_timeseries: >> annual_statistics: @@ -71,17 +102,20 @@ Some preprocessor modules are always applied and do not need to be called. This >> area_statistics: >> operator: mean >> depth_integration: ->>~~~ +>>``` >> >{: .solution} {: .challenge} ## Using different preprocessors for different variables -You can also define different preprocessors with several preprocessor sections (setting different preprocessor names). In the variable section you call the specific preprocessor which should be applied. +You can also define different preprocessors with several preprocessor sections +(setting different preprocessor names). In the variable section you call the +specific preprocessor which should be applied. > ## Example ->~~~yaml +> +> ```yaml > preprocessors: > prep_timeseries_1: > annual_statistics: @@ -116,15 +150,27 @@ You can also define different preprocessors with several preprocessor sections ( > scripts: > timeseries_diag: > script: ocean/diagnostic_timeseries.py ->~~~ +> ``` +> {: .solution} >## Challenge : How to write a recipe with multiple preprocessors -> We now know that a recipe can have more than one diagnostic, variable or preprocessor. As we saw in the examples so far, we can group preprocessors with a single user defined name and can have more than one such preprocessor group in the recipe as well. Write two different preprocessors - one to regrid the data to a 1x1 resolution and the second preprocessor to mask out sea and ice grid cells before regridding to the same resolution. In the second case, ensure you perform the masking first before regridding (hint: custom order your operations). Now, use the two preprocessors in different diagnostics within the same recipe. You may use any variable(s) of your choice. Once you succeed, try to add new datasets to the same recipe. Placeholders for the different components are provided below: +> +>We now know that a recipe can have more than one diagnostic, variable or +>preprocessor. As we saw in the examples so far, we can group preprocessors with +>a single user defined name and can have more than one such preprocessor group +>in the recipe as well. Write two different preprocessors - one to regrid the +>data to a 1x1 resolution and the second preprocessor to mask out sea and ice +>grid cells before regridding to the same resolution. In the second case, ensure +>you perform the masking first before regridding (hint: custom order your +>operations). Now, use the two preprocessors in different diagnostics within the +>same recipe. You may use any variable(s) of your choice. Once you succeed, try +>to add new datasets to the same recipe. Placeholders for the different +>components are provided below: > >> ## Recipe >> ->>~~~yaml +>> ```yaml >> >> datasets: >> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, @@ -161,15 +207,16 @@ You can also define different preprocessors with several preprocessor sections ( >> # as in the previous diagnostic and >> # include your second preprocessor (masking and regridding) >> scripts: null # no scripts ->>~~~ +>> ``` >> >{: .solution} > >> ## Solution: >> ->> Here is one solution to complete the challenge above using two different preprocessors +>> Here is one solution to complete the challenge above using two different +>> preprocessors >> ->>~~~yaml +>>```yaml >> >> datasets: >> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, @@ -215,17 +262,23 @@ You can also define different preprocessors with several preprocessor sections ( >> start_year: 1970 >> end_year: 2000 >> scripts: null ->> ~~~ +>> ``` >> > {: .solution} {: .challenge} ## Adding different datasets for different variables -Sometimes, we may want to include specific datasets only for certain variables. An example is when we use observations for two different variables in a diagnostic. While the CMIP dataset details for the two variables may be common, the observations will likely not be so. It would be useful to know how to include different datasets for different variables. Here is an example of a simple preprocessor and diagnostic setup for that: +Sometimes, we may want to include specific datasets only for certain variables. +An example is when we use observations for two different variables in a +diagnostic. While the CMIP dataset details for the two variables may be common, +the observations will likely not be so. It would be useful to know how to +include different datasets for different variables. Here is an example of a +simple preprocessor and diagnostic setup for that: > ## Example ->~~~yaml +> +> ```yaml > > datasets: > - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, @@ -245,19 +298,18 @@ Sometimes, we may want to include specific datasets only for certain variables. > diag_diff_datasets: > description: diff_datasets_for_vars > variables: -> pr: #first variable is precipitation +> pr: # first variable is precipitation > preprocessor: prep_regrid > mip: Amon > grid: gn #can change for variables from the same model > start_year: 1970 -> end_year: 2000 # start and end years for a 30 year period, +> end_year: 2000 # start and end years for a 30 year period, > # we assume this is common and exists for all > # model and obs data > additional_datasets: > - {dataset: GPCP-SG, project: obs4mips, level: L3, > version: v2.2, tier: 1} #dataset specific to this variable -> -> tas: #second variable is surface temperature +> tas: # second variable is surface temperature > preprocessor: prep_regrid > mip: Amon > grid: gn #can change for variables from the same model @@ -266,18 +318,20 @@ Sometimes, we may want to include specific datasets only for certain variables. > additional_datasets: > - {dataset: HadCRUT4, project: OBS, type: ground, > version: 1, tier: 2} #dataset specific to the temperature variable -> > scripts: null ->~~~ +> ``` > {: .solution} ## Creating variable groups -Variable grouping can be used to preprocess different clusters of data for the same variable. For instance, the example below illustrates how we can compute separate multimodel means for CMIP5 and CMIP6 data given the same variable. Additionally we can also preprocess observed data for evaluation. +Variable grouping can be used to preprocess different clusters of data for the +same variable. For instance, the example below illustrates how we can compute +separate multimodel means for CMIP5 and CMIP6 data given the same variable. +Additionally we can also preprocess observed data for evaluation. > ## Example ->~~~yaml +>```yaml > >preprocessors: > prep_mmm: @@ -331,17 +385,31 @@ Variable grouping can be used to preprocess different clusters of data for the s > tag: TAS_CMIP6 > additional_datasets: *cmip6_datasets #nothing changes from cmip5 except the data set > scripts: null ->~~~ +>``` > {: .solution} -You should be able to see the variables grouped under different subdirectories under your output preproc directory. The different groupings can be accessed in your diagnostic by selecting the key name of the field variable_group such as tas_cmip5, tas_cmip6 or tas_obs. -> +You should be able to see the variables grouped under different subdirectories +under your output preproc directory. The different groupings can be accessed in +your diagnostic by selecting the key name of the field variable_group such as +tas_cmip5, tas_cmip6 or tas_obs. + > ## How to find what CMIP data is available? > -> [CMIP5](https://pcmdi.llnl.gov/mips/cmip5/index.html) and [CMIP6](https://pcmdi.llnl.gov/CMIP6/Guide/dataUsers.html) data obey the [CF-conventions](http://cfconventions.org/). Available variables can be found under the [CMIP5 data request](https://pcmdi.llnl.gov/mips/cmip5/docs/standard_output.pdf?id=28) and the [CMIP6 Data Request](http://clipc-services.ceda.ac.uk/dreq/index.html). +> [CMIP5](https://pcmdi.llnl.gov/mips/cmip5/index.html) and +> [CMIP6](https://pcmdi.llnl.gov/CMIP6/Guide/dataUsers.html) data obey the +> [CF-conventions](http://cfconventions.org/). Available variables can be found +> under the [CMIP5 data +> request](https://pcmdi.llnl.gov/mips/cmip5/docs/standard_output.pdf?id=28) and +> the [CMIP6 Data Request](http://clipc-services.ceda.ac.uk/dreq/index.html). > -> CMIP data is widely available via the Earth System Grid Federation ([ESGF](https://esgf.llnl.gov/)) and is accessible to users either via download from the ESGF portal or through the ESGF data nodes hosted by large computing facilities (like [CEDA-Jasmin](https://esgf-index1.ceda.ac.uk/), [DKRZ](https://esgf-data.dkrz.de/), etc). The ESGF also hosts observations for Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). +> CMIP data is widely available via the Earth System Grid Federation +> ([ESGF](https://esgf.llnl.gov/)) and is accessible to users either via +> download from the ESGF portal or through the ESGF data nodes hosted by large +> computing facilities (like [CEDA-Jasmin](https://esgf-index1.ceda.ac.uk/), +> [DKRZ](https://esgf-data.dkrz.de/), etc). The ESGF also hosts observations for +> Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). > -> A full list of all CMIP named variables is available here: [http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html](http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html). +> A full list of all CMIP named variables is available here: +> [http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html](http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html). {: .callout} diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index a40072ea..a03d9d6b 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -7,26 +7,28 @@ questions: objectives: - "Fix a broken recipe" keypoints: -- "There are three different kinds of log files: ``main_log.txt``, and ``main_log_debug.txt`` and ``log.txt``." +- "There are three different kinds of log files: ``main_log.txt``, and + ``main_log_debug.txt`` and ``log.txt``." --- Every user encounters errors. Once you know why you get certain types of errors, -they become much easier to fix. -The good news is, ESMValTool creates a record of the output messages and stores them in log files. -They can be used for debugging or monitoring the process. -This lesson helps to understand what the different types of errors are and when you are likely to encounter them. +they become much easier to fix. The good news is, ESMValTool creates a record of +the output messages and stores them in log files. They can be used for debugging +or monitoring the process. This lesson helps to understand what the different +types of errors are and when you are likely to encounter them. ## Log files -Each time we run ESMValTool, it will produce a new output directory. -This directory should contain the ``run`` folder that is automatically generated by ESMValTool. -To examine this, we run a ``recipe_example.yml`` that can be found in -[Setup]({{ page.root }}{% link setup.md %}). -Let's download it to our working directory ``esmvaltool_tutorial`` that was created during -the [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}). +Each time we run ESMValTool, it will produce a new output directory. This +directory should contain the ``run`` folder that is automatically generated by +ESMValTool. To examine this, we run a ``recipe_example.yml`` that can be found +in [Setup]({{ page.root }}{% link setup.md %}). Let's download it to our working +directory ``esmvaltool_tutorial`` that was created during the +[Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}). In a new terminal, go to our working directory ``esmvaltool_tutorial`` where -both files ``user-config.yml`` and ``recipe_example.yml`` are located and run the recipe: +both files ``user-config.yml`` and ``recipe_example.yml`` are located and run +the recipe: ~~~bash cd esmvaltool_tutorial @@ -38,9 +40,9 @@ esmvaltool: command not found ~~~ {: .error} -ESMValTool encounters this error because -the conda environment ``esmvaltool`` has not been activated. -To fix the error, before running the recipe, activate the environment: +ESMValTool encounters this error because the conda environment ``esmvaltool`` +has not been activated. To fix the error, before running the recipe, activate +the environment: ~~~bash conda activate esmvaltool @@ -48,8 +50,8 @@ conda activate esmvaltool > ## conda environment > -> More information about conda environment can be found at -[Installation]({{ page.root }}{% link _episodes/02-installation.md %}) +> More information about conda environment can be found at [Installation]({{ +> page.root }}{% link _episodes/02-installation.md %}) {: .callout} Let's change the working directory to the folder ``run`` and list its files: @@ -64,8 +66,8 @@ diag_timeseries_temperature main_log_debug.txt main_log.txt recipe_example.y ~~~ {: .output} -In the ``main_log_debug.txt`` and ``main_log.txt``, ESMValTool writes the output messages, -warnings and possible errors that might happen during pre-processings. +In the ``main_log_debug.txt`` and ``main_log.txt``, ESMValTool writes the output +messages, warnings and possible errors that might happen during pre-processings. To inspect them, we can look inside the files. For example: ~~~bash @@ -87,10 +89,11 @@ diag_provenance.yml log.txt resource_usage.txt settings.yml In the ``log.txt``, ESMValTool writes the output messages, warnings and possible errors that are related to the diagnostic script. -If you encounter an error and don’t know what it means, it is important to read the log information. -Sometimes knowing where the error occurred is enough to fix it, even if you don’t entirely understand the message. -However, note that you may not always be able to find the error or fix it. -In that case, ESMValTool community helps you figure out what went wrong. +If you encounter an error and don’t know what it means, it is important to read +the log information. Sometimes knowing where the error occurred is enough to fix +it, even if you don’t entirely understand the message. However, note that you +may not always be able to find the error or fix it. In that case, ESMValTool +community helps you figure out what went wrong. > ## Different log files > @@ -99,8 +102,9 @@ What are their differences? > >> ## Solution >> ->> The ``main_log_debug.txt`` contains the output messages from the pre-processor whereas -the ``main_log.txt`` shows general errors and warnings that might happen in running the recipe and diagnostics script. +> > The ``main_log_debug.txt`` contains the output messages from the +> > pre-processor whereas the ``main_log.txt`` shows general errors and warnings +> > that might happen in running the recipe and diagnostics script. > {: .solution} {: .challenge} @@ -123,7 +127,7 @@ and then ctrl + X to exit ``nano``. {: .callout} >## See the recipe_example.yml ->~~~YAML +>```yaml >01 # ESMValTool >02 # recipe_example.yml >03 --- @@ -166,16 +170,18 @@ and then ctrl + X to exit ``nano``. >40 scripts: >41 timeseries_diag: >42 script: ocean/diagnostic_timeseries.py ->~~~ +>``` {: .solution} ## Keys and values in recipe settings -The [ESMValTool pre-processors](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/recipe/preprocessor.html?highlight=preprocessor) cover a broad range of operations on the input data, -like time manipulation, area manipulation, land-sea masking, variable derivation, ... . -Let's add the preprocessor ``extract_region`` to the section ``prep_timeseries``: +The [ESMValTool +pre-processors](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/recipe/preprocessor.html?highlight=preprocessor) +cover a broad range of operations on the input data, like time manipulation, +area manipulation, land-sea masking, variable derivation, ... . Let's add the +preprocessor ``extract_region`` to the section ``prep_timeseries``: -~~~YAML +```yaml 25 preprocessors: 26 prep_timeseries: # For 0D fields 27 annual_statistics: @@ -185,14 +191,14 @@ Let's add the preprocessor ``extract_region`` to the section ``prep_timeseries`` 31 end_longitude: 40 32 start_latitude: 27 33 end_latitude: 70 -~~~ +``` Also, we change the ``projects`` value ``ukesm`` to ``tutorial``: -~~~YAML +```yaml 19 projects: 20 - tutorial -~~~ +``` Then, we save the file and run the recipe: ~~~bash @@ -207,24 +213,26 @@ attach the run/recipe_*.yml and run/main_log_debug.txt files from the output dir ~~~ {: .error} -The values for the keys ``author``, ``maintainer``, ``projects`` and ``references`` in the recipe should -be known by ESMValTool. A list of ESMValTool author, maintainer, references, and projects can be found -in the ``config-references.yml`` that is located in the folder ``references`` -in the ESMValTool installation directory ``path_to_esmvaltool``. To find ``path_to_esmvaltool`` -on your system, see -[Installation]({{ page.root }}{% link _episodes/02-installation.md %}). +The values for the keys ``author``, ``maintainer``, ``projects`` and +``references`` in the recipe should be known by ESMValTool. A list of ESMValTool +author, maintainer, references, and projects can be found in the +``config-references.yml`` that is located in the folder ``references`` in the +ESMValTool installation directory ``path_to_esmvaltool``. To find +``path_to_esmvaltool`` on your system, see [Installation]({{ page.root }}{% link +_episodes/02-installation.md %}). > ## ESMValTool can’t locate the data > -> You are assisting a colleague with ESMValTool. The colleague changes the ``project`` entry to ``CMIP6`` -and runs the recipe. However, ESMValTool encounters an error like: +> You are assisting a colleague with ESMValTool. The colleague changes the +> ``project`` entry to ``CMIP6`` and runs the recipe. However, ESMValTool +> encounters an error like: > -~~~bash -esmvalcore._recipe_checks.RecipeError: Missing data -2020-06-29 17:26:41,303 UTC [43830] INFO If you suspect this is a bug or need help, -please open an issue on https://github.com/ESMValGroup/ESMValTool/issues and -attach the run/recipe_*.yml and run/main_log_debug.txt files from the output directory. -~~~ +> ~~~bash +> esmvalcore._recipe_checks.RecipeError: Missing data +> 2020-06-29 17:26:41,303 UTC [43830] INFO If you suspect this is a bug or need help, +> please open an issue on https://github.com/ESMValGroup/ESMValTool/issues and +> attach the run/recipe_*.yml and run/main_log_debug.txt files from the output directory. +> ~~~ What suggestions would you give the researcher for fixing the error? > >> ## Solution @@ -238,39 +246,40 @@ What suggestions would you give the researcher for fixing the error? ## Check pre-processed data -The setting ``save_intermediary_cubes`` in the configuration file can be used -to save the pre-processed data. More information about this setting can be found at +The setting ``save_intermediary_cubes`` in the configuration file can be used to +save the pre-processed data. More information about this setting can be found at [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}). > ## save_intermediary_cubes > -> Note that this setting should be only used for debugging, as it significantly slows down the recipe -and increases disk usage because a lot of output files need to be stored. +> Note that this setting should be only used for debugging, as it significantly +> slows down the recipe and increases disk usage because a lot of output files +> need to be stored. {: .callout} ## Check diagnostic script path -The result of the pre-processor is passed to the ``diagnostic_timeseries.py`` script, -that is introduced in the recipe as: +The result of the pre-processor is passed to the ``diagnostic_timeseries.py`` +script, that is introduced in the recipe as: -~~~YAML +```yaml 40 scripts: 41 timeseries_diag: 42 script: ocean/diagnostic_timeseries.py -~~~ +``` -The diagnostic scripts are located in the folder ``diag_scripts`` in -the ESMValTool installation directory ``path_to_esmvaltool``. -To find ``path_to_esmvaltool`` on your system, -see [Installation]({{ page.root }}{% link _episodes/02-installation.md %}). +The diagnostic scripts are located in the folder ``diag_scripts`` in the +ESMValTool installation directory ``path_to_esmvaltool``. To find +``path_to_esmvaltool`` on your system, see [Installation]({{ page.root }}{% link +_episodes/02-installation.md %}). let's see if we can change the script path as: -~~~YAML +```yaml 40 scripts: 41 timeseries_diag: 42 script: diag_scripts/ocean/diagnostic_timeseries.py -~~~ +``` ~~~bash esmvaltool -c user-config.yml recipe_example.yml @@ -282,16 +291,17 @@ esmvalcore._task.DiagnosticError: Cannot execute script 'diag_scripts/examples/d ~~~ {: .error} -The script path should be relative to ``diag_scripts`` directory. -It means that the script ``diagnostic_timeseries.py`` is located in ``path_to_esmvaltool/diag_scripts/ocean/``. -Alternatively, the script path can be an absolute path. -To examine this, we change the script path and run the recipe: +The script path should be relative to ``diag_scripts`` directory. It means that +the script ``diagnostic_timeseries.py`` is located in +``path_to_esmvaltool/diag_scripts/ocean/``. Alternatively, the script path can +be an absolute path. To examine this, we change the script path and run the +recipe: -~~~YAML +```yaml 40 scripts: 41 timeseries_diag: 42 script: path_to_esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py -~~~ +``` ~~~bash esmvaltool -c user-config.yml recipe_example.yml @@ -299,10 +309,10 @@ To examine this, we change the script path and run the recipe: > ## Available recipe and diagnostic scripts > -> ESMValTool provides a broad suite of -[recipes and diagnostic](https://docs.esmvaltool.org/en/latest/recipes/index.html) -scripts for different disciplines like atmosphere, climate metrics, future projections, -IPCC, land, ocean, .... +> ESMValTool provides a broad suite of [recipes and +> diagnostic](https://docs.esmvaltool.org/en/latest/recipes/index.html) scripts +> for different disciplines like atmosphere, climate metrics, future +> projections, IPCC, land, ocean, .... {: .callout} > ## Re-running a diagnostic @@ -312,8 +322,8 @@ How to re-run the diagnostic script? > >> ## Solution >> ->> The ``main_log.txt`` file contains information on how to re-run the diagnostic script -without re-running the pre-processors: +> > The ``main_log.txt`` file contains information on how to re-run the +> > diagnostic script without re-running the pre-processors: >> ~~~bash 2020-06-29 20:36:32,844 UTC [52810] INFO To re-run this diagnostic script, run: @@ -325,11 +335,11 @@ without re-running the pre-processors: > ## Memory issues > -> If you run out of memory, try setting ``max_parallel_tasks`` to 1 in the configuration file. -Then, check the amount of memory you need for that by inspecting -the file ``run/resource_usage.txt`` in the output directory. -Using the number there you can increase the number of parallel tasks again to a reasonable number -for the amount of memory available in your system. +> If you run out of memory, try setting ``max_parallel_tasks`` to 1 in the +> configuration file. Then, check the amount of memory you need for that by +> inspecting the file ``run/resource_usage.txt`` in the output directory. Using +> the number there you can increase the number of parallel tasks again to a +> reasonable number for the amount of memory available in your system. {: .callout} {% include links.md %} diff --git a/_episodes/10-development-setup.md b/_episodes/10-development-setup.md index f14a7b02..f389cace 100644 --- a/_episodes/10-development-setup.md +++ b/_episodes/10-development-setup.md @@ -8,17 +8,28 @@ questions: objectives: - "Execute a succesful ESMValTool installation from source" keypoints: -- "ESMValTool is installed from source code that lives in the [GitHub repository](https://github.com/ESMValGroup/ESMValTool)" -- "All the required packages can be installed using conda and the [environment.yml file](https://github.com/ESMValGroup/ESMValTool/blob/master/environment.yml)" -- "You can find more information about installation in the [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html)" +- "ESMValTool is installed from source code that lives in the [GitHub + repository](https://github.com/ESMValGroup/ESMValTool)" +- "All the required packages can be installed using conda and the + [environment.yml + file](https://github.com/ESMValGroup/ESMValTool/blob/master/environment.yml)" +- "You can find more information about installation in the + [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html)" --- -So you want to contribute code to ESMValTool. What follows describes a development installation to help you get going. +So you want to contribute code to ESMValTool. What follows describes a +development installation to help you get going. > ## Attention > -> - This episode is based on the ESMValTool installation instructions, for more information and advanced cases you can visit the ESMValTool [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html). -> - For this episode it is assumed you have knowledge of [git](https://git-scm.com/). You can refresh your knowledge in the corresponding [git carpentries course](http://swcarpentry.github.io/git-novice/). +> - This episode is based on the ESMValTool installation instructions, for +> more information and advanced cases you can visit the ESMValTool +> [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html). +> +> - For this episode it is assumed you have knowledge of +> [git](https://git-scm.com/). You can refresh your knowledge in the +> corresponding [git carpentries +> course](http://swcarpentry.github.io/git-novice/). {: .callout} ## Obtaining the source code @@ -26,43 +37,45 @@ So you want to contribute code to ESMValTool. What follows describes a developme The ESMValTool source code is available on a public GitHub repository: [https://github.com/ESMValGroup/ESMValTool](https://github.com/ESMValGroup/ESMValTool) -The easiest way to obtain it is to clone the repository using git. -To clone the public repository open a terminal window and type: +The easiest way to obtain it is to clone the repository using git. To clone the +public repository open a terminal window and type: ~~~bash git clone https://github.com/ESMValGroup/ESMValTool.git ~~~ By default, this command will create a folder called ESMValTool containing the -source code of the tool. +source code of the tool. -Move into the directory to continue installation. +Move into the directory to continue installation. > ## Attention -> +> > Make sure that the master branch is checked out before continuing intallation: > ~~~bash > git checkout master -> ~~~ +> ~~~ {: .callout} ## Prerequisites -It is recommended to use conda to manage ESMValTool dependencies. -For a minimal conda installation go to [https://conda.io/miniconda.html](https://conda.io/miniconda.html). To -simplify the installation process, an environment definition file is provided -in the repository (``environment.yml`` in the root folder). +It is recommended to use conda to manage ESMValTool dependencies. For a minimal +conda installation go to +[https://conda.io/miniconda.html](https://conda.io/miniconda.html). To simplify +the installation process, an environment definition file is provided in the +repository (``environment.yml`` in the root folder). > ## Attention -> It is preferable to use a local, fully user-controlled conda installation. -> If you have conda installed already, make sure it is up to date by running ``conda update -n base conda``. +> It is preferable to use a local, fully user-controlled conda installation. If +> you have conda installed already, make sure it is up to date by running +> ``conda update -n base conda``. {: .callout} From now on, we will assume that the installation is going to be done through conda. -Ideally, you should create a dedicated conda environment for ESMValTool, so it is -independent from any other Python tools present in the system. +Ideally, you should create a dedicated conda environment for ESMValTool, so it +is independent from any other Python tools present in the system. To create an environment, go to the directory containing the ESMValTool source code (called ESMValTool if you did not choose a different name) and run @@ -79,7 +92,8 @@ the environment using the command: conda activate esmvaltool ~~~ -If you run into trouble, please try recreating the environment. More information can be found in the [conda documentation](https://docs.conda.io/en/latest/). +If you run into trouble, please try recreating the environment. More information +can be found in the [conda documentation](https://docs.conda.io/en/latest/). ## Software installation @@ -90,7 +104,8 @@ the following commands in the directory containing the ESMValTool source code: pip install --editable '.[develop]' ~~~ -This will add the `esmvaltool` directory to the Python path in editable mode and install the developemnt dependencies. +This will add the `esmvaltool` directory to the Python path in editable mode and +install the developemnt dependencies. ## Test the installation @@ -113,8 +128,11 @@ python setup.py test --installation > ## ESMValCore > -> Most core functionality for the ESMValTool is available in the [ESMValCore](https://github.com/ESMValGroup/ESMValCore) Python package. -> If your contribution in ESMValTool needs changes to ESMValCore please follow [its contribution guide](https://github.com/ESMValGroup/ESMValCore/blob/master/CONTRIBUTING.md). +> Most core functionality for the ESMValTool is available in the +> [ESMValCore](https://github.com/ESMValGroup/ESMValCore) Python package. If +> your contribution in ESMValTool needs changes to ESMValCore please follow [its +> contribution +> guide](https://github.com/ESMValGroup/ESMValCore/blob/master/CONTRIBUTING.md). {: .callout} {% include links.md %} diff --git a/setup.md b/setup.md index b0095e71..3056c119 100644 --- a/setup.md +++ b/setup.md @@ -1,11 +1,11 @@ --- -title: Preparations for participating in the tutorial +title: Preparations for participating in the tutorial --- -This page includes some information on how to prepare for participating in this tutorial. +This page includes some information on how to prepare for participating in this tutorial. > ## Prerequisites -> The prerequisites for the tutorial are listed on the +> The prerequisites for the tutorial are listed on the > [tutorials home page]({{ page.root}}[% index.md %}) > and are also eproduced here: > - Basic understanding of git (optional) @@ -23,35 +23,38 @@ This page includes some information on how to prepare for participating in this ## Optional tutorials to be prepared to use ESMValTool -We typically use the command line to interact with ESMValTool. -While most of us are likely to have experience with the command line, -novices may want to work through this software carpentry unix shell course. +We typically use the command line to interact with ESMValTool. While most of us +are likely to have experience with the command line, novices may want to work +through this software carpentry unix shell course. -- Command line: [https://swcarpentry.github.io/shell-novice/](https://swcarpentry.github.io/shell-novice/) +- Command line: + [https://swcarpentry.github.io/shell-novice/](https://swcarpentry.github.io/shell-novice/) - -Git is a distributed version-control system for tracking changes in source code during software development. -It’s how we distribute, share, and manage the ESMValTool code. -- git: [https://swcarpentry.github.io/git-novice/](https://swcarpentry.github.io/git-novice/) +Git is a distributed version-control system for tracking changes in source code +during software development. It’s how we distribute, share, and manage the +ESMValTool code. + +- git: + [https://swcarpentry.github.io/git-novice/](https://swcarpentry.github.io/git-novice/) ## Access to CMIP and Observational data and a suitable compute cluster -To complete this tutorial and use ESMValTool, you will need access to data in a reasonable format. -Some data will be provided, but there is simply too much data available -for your tutors to make it all available directly. +To complete this tutorial and use ESMValTool, you will need access to data in a +reasonable format. Some data will be provided, but there is simply too much data +available for your tutors to make it all available directly. -ESMValTool may be run on multiple platforms, from your local machine to -large computing clusters. -The best option is to use a computing cluster with an -[Earth System Grid Federation (ESGF) node](https://esgf.llnl.gov/nodes.html). -The benefit of using a compute cluster with an ESGF node is that the -[Coupled Model Intercomparison Project (CMIP)](https://en.wikipedia.org/wiki/Coupled_Model_Intercomparison_Project) -is locally stored on disk and accessible directly by the tool. -Similarly, observational data would also be available at these sites. +ESMValTool may be run on multiple platforms, from your local machine to large +computing clusters. The best option is to use a computing cluster with an [Earth +System Grid Federation (ESGF) node](https://esgf.llnl.gov/nodes.html). The +benefit of using a compute cluster with an ESGF node is that the [Coupled Model +Intercomparison Project +(CMIP)](https://en.wikipedia.org/wiki/Coupled_Model_Intercomparison_Project) is +locally stored on disk and accessible directly by the tool. Similarly, +observational data would also be available at these sites. Here are a few options for compute clusters with ESGF nodes: @@ -60,56 +63,60 @@ for compute clusters with ESGF nodes: - DKRZ (Germany): - ETHZ (Switzerland): -A full list of all ESGF nodes is available [here](https://esgf.llnl.gov/nodes.html). +A full list of all ESGF nodes is available +[here](https://esgf.llnl.gov/nodes.html). -If you're running on a computing cluster without an ESGF node, such as -your local machine, or your institue machine, you will most likely -have to make a local copy of the data that you need. +If you're running on a computing cluster without an ESGF node, such as your +local machine, or your institue machine, you will most likely have to make a +local copy of the data that you need. -If neccesairy, data can be downloaded using the +If neccesairy, data can be downloaded using the [synda tool](https://prodiguer.github.io/synda/index.html). - + ### CEDA-Jasmin -If you do not already have an account on JASMIN, then request an account as -soon as possible. -Please follow [these instructions on how to create a Jasmin account](https://help.jasmin.ac.uk/article/4435-get-a-jasmin-account-portal) +If you do not already have an account on JASMIN, then request an account as soon +as possible. Please follow [these instructions on how to create a Jasmin +account](https://help.jasmin.ac.uk/article/4435-get-a-jasmin-account-portal) -During the account creation, you will need an SSH key, which can be generated following -[these instructions](https://help.jasmin.ac.uk/article/185-generate-ssh-key-pair) +During the account creation, you will need an SSH key, which can be generated +following [these +instructions](https://help.jasmin.ac.uk/article/185-generate-ssh-key-pair) -Here are some more [instructions on how to get started with jasmin](https://help.jasmin.ac.uk/article/189-get-started-with-jasmin). +Here are some more [instructions on how to get started with +jasmin](https://help.jasmin.ac.uk/article/189-get-started-with-jasmin). Also note that if you are working from home, JASMIN may not be directly -accessible from your home. You may need to use ssh to connect to a machine -in your institute and then on to JASMIN. Please test your connection before -the tutorial. +accessible from your home. You may need to use ssh to connect to a machine in +your institute and then on to JASMIN. Please test your connection before the +tutorial. #### Jasmin-login -Note that you have only created an account for the web-interface. -To log into the jasmin machine and do work, you'll need to create a -login account too using [this page](https://help.jasmin.ac.uk/article/161-get-login-account). +Note that you have only created an account for the web-interface. To log into +the jasmin machine and do work, you'll need to create a login account too using +[this page](https://help.jasmin.ac.uk/article/161-get-login-account). #### Access to data on JASMIN Please request access to the working groups: -- [esmeval working group](https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval) -- [CMIP5 data](https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research) +- [esmeval working + group](https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval) +- [CMIP5 + data](https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research) -Once you have access to the data archive on CEDA, make sure to link your -CEDA and JASMIN accounts. -This can be done by checking the link to CEDA box on -[your JASMIN profile page](https://accounts.jasmin.ac.uk/account/profile/). +Once you have access to the data archive on CEDA, make sure to link your CEDA +and JASMIN accounts. This can be done by checking the link to CEDA box on [your +JASMIN profile page](https://accounts.jasmin.ac.uk/account/profile/). The linking may take a few hours to take effect and is necessary for you to -access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC -are not accessible by default and special permission has to be requested to -access them via [the CEDA catalogue page](https://catalogue.ceda.ac.uk/). +access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC are not +accessible by default and special permission has to be requested to access them +via [the CEDA catalogue page](https://catalogue.ceda.ac.uk/). #### Test your Setup @@ -135,24 +142,26 @@ ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.n ~~~ {: .language-bash} -Note that the JASMIN is only open to certain locations (mostly universities, and research centres). -You may need a VPN if you wish to connect from your home network. +Note that the JASMIN is only open to certain locations (mostly universities, and +research centres). You may need a VPN if you wish to connect from your home +network. Please request access to the working groups: -- [esmeval working group](https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval) -- [CMIP5 data](https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research) +- [esmeval working + group](https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval) +- [CMIP5 + data](https://services.ceda.ac.uk/cedasite/resreg/application?attributeid=cmip5_research) -Once you have access to the data archive on CEDA, make sure to link your -CEDA and JASMIN accounts. -This can be done by checking the link to CEDA box on +Once you have access to the data archive on CEDA, make sure to link your CEDA +and JASMIN accounts. This can be done by checking the link to CEDA box on [your JASMIN profile page](https://accounts.jasmin.ac.uk/account/profile/). The linking may take a few hours to take effect and is necessary for you to -access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC -are not accessible by default and special permission has to be requested to -access them via [the CEDA catalogue page](https://catalogue.ceda.ac.uk/). +access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC are not +accessible by default and special permission has to be requested to access them +via [the CEDA catalogue page](https://catalogue.ceda.ac.uk/). #### Test your Setup @@ -168,7 +177,7 @@ Then log into the sci1 machine: ~~~ ssh -X jasmin-sci1 ~~~ -: .language-bash} +{: .language-bash} Can you see the following locations: ~~~ @@ -178,19 +187,31 @@ ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.n ~~~ {: .language-bash} -Note that the JASMIN is only open to certain locations (mostly universities, and research centres). -You may need a VPN if you wish to connect from your home network. +Note that the JASMIN is only open to certain locations (mostly universities, and +research centres). You may need a VPN if you wish to connect from your home +network. ### DKRZ -If you do not already have an account at the DKRZ, then [register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could find a short introduction on how to get started at DKRZ [here](https://www.dkrz.de/up/my-dkrz/getting-started/getting-started-at-dkrz). +If you do not already have an account at the DKRZ, then +[register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could +find a short introduction on how to get started at DKRZ +[here](https://www.dkrz.de/up/my-dkrz/getting-started/getting-started-at-dkrz). -There is also a [user manual](https://www.dkrz.de/up/systems/mistral) for Mistral which is DKRZ's current supercomputer. +There is also a [user manual](https://www.dkrz.de/up/systems/mistral) for +Mistral which is DKRZ's current supercomputer. #### Join a project -To use the resources on DKRZ you have to join a project. One option is to join an existing project by logging into [https://luv.dkrz.de/](https://luv.dkrz.de/) with your account and select 'Join existing project'. Once you are accepted by the manager of your chosen project, your web account will be turned into a full LDAP account which will allow you to log into and use the DKRZ's resources. If you do not have access to an existing project, another option for you would be to apply for resources at DKRZ. Here are some instructions on [how to apply for resources](https://www.dkrz.de/services/bereitstellung-von-rechenleistung?set_language=en&cl=en). +To use the resources on DKRZ you have to join a project. One option is to join +an existing project by logging into [https://luv.dkrz.de/](https://luv.dkrz.de/) +with your account and select 'Join existing project'. Once you are accepted by +the manager of your chosen project, your web account will be turned into a full +LDAP account which will allow you to log into and use the DKRZ's resources. If +you do not have access to an existing project, another option for you would be +to apply for resources at DKRZ. Here are some instructions on [how to apply for +resources](https://www.dkrz.de/services/bereitstellung-von-rechenleistung?set_language=en&cl=en). #### Access to data on DKRZ @@ -209,7 +230,8 @@ ssh -X user-account@mistral.dkrz.de #### Additional information -Login nodes are for compiling and job submission only! For all other tasks, use one of the pre- and post-processing nodes +Login nodes are for compiling and job submission only! For all other tasks, use +one of the pre- and post-processing nodes ~~~ ssh -X @mistralpp.dkrz.de ~~~ @@ -218,11 +240,13 @@ ssh -X @mistralpp.dkrz.de Data storage: - Personal data: home directory (24GiB) - Project data: /work// -- Temporary data: scratch directory on /scratch/*/ is automatically deleted after 14 days (15TiB) (Please use this directory for all your testing! Do not use the work directory for tests.) -(see also [this](https://www.dkrz.de/up/systems/mistral/hpc-concepts)) +- Temporary data: scratch directory on /scratch/*/ is + automatically deleted after 14 days (15TiB) (Please use this directory for all + your testing! Do not use the work directory for tests.) (see also + [this](https://www.dkrz.de/up/systems/mistral/hpc-concepts)) -Running batch jobs: -Info and examples on SLURM job scheduling system at DKRZ can be found [here](https://www.dkrz.de/up/systems/mistral/running-job). +Running batch jobs: Info and examples on SLURM job scheduling system at DKRZ can +be found [here](https://www.dkrz.de/up/systems/mistral/running-job). ### Other computing systems @@ -230,7 +254,10 @@ FIXME ### Your own machine -If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space available to install conda & ESMVAlTool, but also enough to make a copy of some data. +If you are planning on running ESMValTool on your own machine, please make sure +that you are able to download CMIP data and that you have several GB of space +available to install conda & ESMVAlTool, but also enough to make a copy of some +data. You will also need to able to use: - git @@ -243,8 +270,8 @@ You will also need to able to use: #### Windows -ESMValTool does not directly support Windows, -but successful usage has been reported through the +ESMValTool does not directly support Windows, +but successful usage has been reported through the [Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows 10. @@ -252,43 +279,47 @@ available in Windows 10. ## Github account (Advanced) -You don’t need a github account to participate in the tutorial. -However, if you want to raise an issue, contribute to the discussions, -or share your code, please [create a github account](https://github.com/). +You don’t need a github account to participate in the tutorial. However, if you +want to raise an issue, contribute to the discussions, or share your code, +please [create a github account](https://github.com/). -To learn how to use github, please have a look at this [introduction to github](https://lab.github.com/githubtraining/introduction-to-github). +To learn how to use github, please have a look at this [introduction to +github](https://lab.github.com/githubtraining/introduction-to-github). -You may hear a few of the following phrases during the tutorial. Don’t be alarmed, they will make sense eventually. +You may hear a few of the following phrases during the tutorial. Don’t be +alarmed, they will make sense eventually. ### github issues -Issues are github’s ticketing system. -They allow users and developers to discuss problems, -identify bugs, or to make suggestions. -Each issue is assigned a number and will have it’s own page on github. +Issues are github’s ticketing system. They allow users and developers to discuss +problems, identify bugs, or to make suggestions. Each issue is assigned a number +and will have it’s own page on github. -Here’s an explanation of the [github issues](https://guides.github.com/features/issues/). +Here’s an explanation of the [github +issues](https://guides.github.com/features/issues/). -Raising an issue is the act of creating a new issue. -If you are asked to raise an issue, please follow any instructions that you are given, -and also make sure that you read the default issue text. +Raising an issue is the act of creating a new issue. If you are asked to raise +an issue, please follow any instructions that you are given, and also make sure +that you read the default issue text. -### pull request +### pull request -A github pull request is the act of requesting that a branch is merged with another branch. +A github pull request is the act of requesting that a branch is merged with +another branch. -This is an advanced feature of GitHub, and will generally be performed by the ESMValTool development team. +This is an advanced feature of GitHub, and will generally be performed by the +ESMValTool development team. ## Install conda -The python package manager Conda (anaconda or miniconda) -needs to be installed on your system before the tutorial starts. -In some cases, your system may have a central version installed already. +The python package manager Conda (anaconda or miniconda) needs to be installed +on your system before the tutorial starts. In some cases, your system may have a +central version installed already. -More details on this process are available in the -[Installation episode]({{ page.root}}[% link _episodes/02-installation.md %}). +More details on this process are available in the [Installation episode]({{ +page.root}}[% link _episodes/02-installation.md %}). From 9a214a5aa8089dc7213a8d206eef92fab6ffeec3 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 3 Jul 2020 14:35:02 +0200 Subject: [PATCH 241/647] Solve remaining problems --- index.md | 112 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/index.md b/index.md index 56ffa7e4..9689b2ae 100644 --- a/index.md +++ b/index.md @@ -5,95 +5,97 @@ permalink: index.html # Is the only page that doesn't follow the pattern /:path date: '`r format(Sys.time(), "%d %B, %Y")`' --- -This tutorial helps you to use ESMValTool. +This tutorial helps you to use ESMValTool. -The Earth System Model Evaluation Tool (ESMValTool) is a community developed software toolkit that aims to facilitate -the diagnosis and evaluation of the causes and effects of model biases and inter-model spread within the CMIP model +The Earth System Model Evaluation Tool (ESMValTool) is a community developed +software toolkit that aims to facilitate the diagnosis and evaluation of the +causes and effects of model biases and inter-model spread within the CMIP model ensemble. -This tutorial is structured such that the main body of the tutorial, up to the episode 7, can be done in one sitting. -From episode 8, each episode is a mini-tutorial covering an advanced aspect of working with ESMValTool. -These mini-tutorials can be appended to the main tutorial or worked through independently. +This tutorial is structured such that the main body of the tutorial, up to the +episode 7, can be done in one sitting. From episode 8, each episode is a +mini-tutorial covering an advanced aspect of working with ESMValTool. These +mini-tutorials can be appended to the main tutorial or worked through +independently. > ## What will you learn in this course > -> - What is ESMValTool -> - How to install ESMValTool -> - How to configure ESMValTool for your local system -> - How to run ESMValTool -> - How to work with ESMValTool's suite of preprocessors -> - How to debug your recipes -> - How to access and deploy recipes from the ESMValTools gallery (Advanced) -> - How to develop your own diagnostics and recipes (Advanced) -> - How to contribute your recipes and diagnostics back into ESMValTool (Advanced) -> - How to include new observational datasets (Advanced) +> - What is ESMValTool +> - How to install ESMValTool +> - How to configure ESMValTool for your local system +> - How to run ESMValTool +> - How to work with ESMValTool's suite of preprocessors +> - How to debug your recipes +> - How to access and deploy recipes from the ESMValTools gallery (Advanced) +> - How to develop your own diagnostics and recipes (Advanced) +> - How to contribute your recipes and diagnostics back into ESMValTool +> (Advanced) +> - How to include new observational datasets (Advanced) > ->{: .checklist} +{: .checklist} > ## Prerequisites > > *Minimal requirements:* > -> - Basic understanding of your preferred command line interface (ie a bash terminal) -> -> - Laptop/desktop with [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed -> -> - Access to CMIP data +> - Basic understanding of your preferred command line interface (ie a bash +> terminal) +> - Laptop/desktop with +> [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed +> - Access to CMIP data > > *Optional, but useful:* > -> - Basic understanding of git -> -> - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) +> - Basic understanding of git +> - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) +> - GitHub account > -> - GitHub account -> ->{: .prereq} +{: .prereq} ### Main things you need to know before starting this course -1. This tutorial can be taken online independently or taught by one of our instructors. +1. This tutorial can be taken online independently or taught by one of our + instructors. -2. Don’t be alarmed if you can’t work through the entire tutorial in one sitting. It may take some time to get used to working with ESMValTool. +2. Don’t be alarmed if you can’t work through the entire tutorial in one + sitting. It may take some time to get used to working with ESMValTool. -3. If you get stuck, help is always available from the tutors, from ESMValTool developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) - or via the [ESMValTool email list](mailto:esmvaltool@listserv.dfn.de). +3. If you get stuck, help is always available from the tutors, from ESMValTool + developers via the [github issues + page](https://github.com/ESMValGroup/ESMValTool/issues) or via the + [ESMValTool email list](mailto:esmvaltool@listserv.dfn.de). -4. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects like “developing your own diagnostic” or “how to include observations”. +4. This tutorial includes several advanced lessons after the conclusion. These + advanced lessons should be treated like “mini-tutorials”, and include aspects + like “developing your own diagnostic” or “how to include observations”. > ## Additional Resources > -> - [Read the docs page](https://esmvaltool.readthedocs.io/) -> -> - [ESMValTool home page](https://www.esmvaltool.org/) +> - [Read the docs page](https://esmvaltool.readthedocs.io/) +> - [ESMValTool home page](https://www.esmvaltool.org/) +> - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) +> - [ESMValTool Source code](https://github.com/ESMValGroup/ESMValTool) +> - [ESMValCore Source code](https://github.com/ESMValGroup/ESMValCore) > -> - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) -> -> - [ESMValTool Source code](https://github.com/ESMValGroup/ESMValTool) -> -> - [ESMValCore Source code](https://github.com/ESMValGroup/ESMValCore) -> -> {: .callout} +{: .callout} ## How to cite ESMValTool Please cite this tutorial as: - - ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], - [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), - [DATE]. +- ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], + [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), + [DATE]. Please cite ESMValTool as: - - Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., - Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., - Weigel, K., and Zechlau, S.: - Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for - emergent constraints and future projections from Earth system models in CMIP, - Geosci. Model Dev. Discuss., - [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), - in review, 2020. - +- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., + Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, + K., and Zechlau, S.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – + diagnostics for emergent constraints and future projections from Earth + system models in CMIP, Geosci. Model Dev. Discuss., + [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), + in review, 2020. {% include links.md %} From b8d4f5f843241da3d86a131afb69ebb606b3d438 Mon Sep 17 00:00:00 2001 From: Jaro Camphuijsen Date: Mon, 6 Jul 2020 11:22:49 +0200 Subject: [PATCH 242/647] Update index.md Remove Rmarkdown for date variable, as this file is not rendered in Rmd. --- index.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/index.md b/index.md index 9689b2ae..6c12896a 100644 --- a/index.md +++ b/index.md @@ -2,7 +2,6 @@ layout: lesson root: . # Is the only page that doesn't follow the pattern /:path/index.html permalink: index.html # Is the only page that doesn't follow the pattern /:path/index.html -date: '`r format(Sys.time(), "%d %B, %Y")`' --- This tutorial helps you to use ESMValTool. @@ -98,4 +97,3 @@ Please cite ESMValTool as: in review, 2020. {% include links.md %} - From b075f05cc549c6ebe802cfd3283828102ebf9bec Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 9 Jul 2020 15:55:47 +0200 Subject: [PATCH 243/647] fix lesson title --- _episodes/03-configuration.md | 2 +- _episodes/{first_example_recipe.md => 04-recipe.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename _episodes/{first_example_recipe.md => 04-recipe.md} (100%) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index d8833521..a504109e 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -179,7 +179,7 @@ resource_usage.txt and temporary files created by the diagnostic scripts. are not plots, e.g. files in NetCDF format (depends on the diagnostic script). > > We explain more about output in the next -[lesson]({{ page.root }}{% link _episodes/04-toy-example.md %}) +[lesson]({{ page.root }}{% link _episodes/04-recipe.md %}) {: .callout} ## Auxiliary data directory diff --git a/_episodes/first_example_recipe.md b/_episodes/04-recipe.md similarity index 100% rename from _episodes/first_example_recipe.md rename to _episodes/04-recipe.md From edb424e8a8ebc3a231b284be36417da1583ddb9a Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 9 Jul 2020 16:19:10 +0200 Subject: [PATCH 244/647] Fix some lint errors --- _episodes/04-recipe.md | 193 ++++++++++++++++++++++++++++------------- 1 file changed, 132 insertions(+), 61 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index e9575c12..0090c61e 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -18,20 +18,27 @@ keypoints: - "The dataset section resembles the filename or directory structure (e.g. CMIP subdirectories)" --- -This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to run your first recipe, look at the recipe output, modify a recipe, explore and run some basic recipe debugging. +This episode describes how ESMValTool recipes work, how to run a recipe and how +to explore the recipe output. By the end of this episode, you should be able to +run your first recipe, look at the recipe output, modify a recipe, explore and +run some basic recipe debugging. ## Introduction to Recipes -Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. +Recipes are the instructions that you give to ESMValTool that tell it what you +want to do. This includes four main sections: datasets, preprocessors, +diagnostics and description. - datasets: what datasets you want to use, including - the time period and temporal resolution, - - the MIP (Model Intercomparison Project, like atmospheric realm of MIP monthly data: Amon), + - the MIP (Model Intercomparison Project, like atmospheric realm of MIP + monthly data: Amon), - ensemble member, - the experiment (i.e. historical, ssp125, etc.), - and the grid type (necessary for CMIP6 only). - - preprocessors: general operations applied to a dataset before handling it in a diagnostic, defining + - preprocessors: general operations applied to a dataset before handling it in + a diagnostic, defining - which preprocessor modules to apply, - the order in which they are applied, - and the preprocessor arguments. @@ -43,35 +50,47 @@ Recipes are the instructions that you give to ESMValTool that tell it what you w - the desired diagnostic script to use, - and additional diagnostic script options or arguments, if needed. - It is possible to also include additional datasets beyond those included in the datasets section mentioned above, for instance variable specific observational data. + It is possible to also include additional datasets beyond those included in + the datasets section mentioned above, for instance variable specific + observational data. - description: a brief description of the recipe, including - who wrote the recipe and who maintains it, - which project the recipe was written for, - and which publications and references are linked with the recipe. - Note that the authors, publications and references need to be included in the `config-references.yml` for the recipe to run successfully. + Note that the authors, publications and references need to be included in + the `config-references.yml` for the recipe to run successfully. -The information you provide in the recipe is not only affecting the processes you are starting, but also the directory names your output will be structured in. -For additional reads, please have a look at the recipe format description in the [ESMValTool manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). +The information you provide in the recipe is not only affecting the processes +you are starting, but also the directory names your output will be structured +in. For additional reads, please have a look at the recipe format description in +the [ESMValTool +manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). ## How to run ESMValTool -Once you’ve set up your conda environment and installed ESMValTool (see episode #2 LINK) and set up your config-user.yml file to correctly match you local environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: +Once you’ve set up your conda environment and installed ESMValTool (see episode +#2 LINK) and set up your config-user.yml file to correctly match you local +environment, (see episode #3 LINK), ESMValTool is invoked using a simple +command: -~~~source +~~~ esmvaltool -c configuration recipe ~~~ +{: .source} To try your hand with a basic recipe, please work through this episode. ## Introduction to the example recipe -The recipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. +The recipe presented here is a simple, basic recipe that takes a single dataset +and produces a time series plot. -Please download the following recipe into your ESMValTool working directory with the name: recipe_example.yml LINK +Please download the following recipe into your ESMValTool working directory with +the name: recipe_example.yml LINK > ## recipe_example.yml -> ~~~YAML +> ```YAML > 1 # ESMValTool > 2 # recipe_example.yml > 3 --- @@ -102,7 +121,7 @@ Please download the following recipe into your ESMValTool working directory with > 28 operator: mean > 29 > 30 diagnostics: -> 31 # -------------------------------------------------- +> 31 # -------------------------------------------------- > 32 # Time series diagnostics > 33 # -------------------------------------------------- > 34 diag_timeseries_temperature: @@ -114,7 +133,7 @@ Please download the following recipe into your ESMValTool working directory with > 40 scripts: > 41 timeseries_diag: > 42 script: ocean/diagnostic_timeseries.py -> ~~~ +> ``` {: .solution} > ## Explore the recipe @@ -125,9 +144,10 @@ Please download the following recipe into your ESMValTool working directory with {: .challenge} Please note the following sections: - - documentation: lines 4-20 - The documentation consists of the following information: + - documentation: lines 4-20. + The documentation consists of the following information: + - description: a short description of the recipe - authors: a list of authors (linked to `esmvaltool/config-references.yml`) - maintainer: a list of maintainers (linked to `esmvaltool/config-references.yml`) @@ -137,7 +157,9 @@ Please note the following sections: - datasets: lines 22-23 - The dataset definition consists of a list of python dictionaries with the information on the datasets. + The dataset definition consists of a list of python dictionaries with the + information on the datasets. + - dataset name (key: dataset) - project (key: project) - experiment (key: exp) @@ -145,30 +167,37 @@ Please note the following sections: - ensemble member (key: ensemble) - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) - model grid (for CMIP6 data only, key: grid) - - alias (key: alias; use the alias for e.g. a more human readable name for the dataset) - + - alias (key: alias; use the alias for e.g. a more human readable name for + the dataset) - preprocessors: lines 25-28 - The definition for different preprocessors or combinations. - If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). - Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). + The definition for different preprocessors or combinations. If no + preprocessing is needed, the preprocessor can be set to an empty python + dictionary (`{}`). Here, we produce annual means. The preprocessor is called + with its name (here: prep_timeseries), later in the diagnostic (line 39). (See episode #5 LINK for more details.) - - diagnostic section: lines 30-42 - The information of which diagnostic script to run with which variables. - The diagnostics section has some indents that are free to call. - - the first indent (here: diag_timeseries_temperature) is the diagnostic’s name (a string without whitespace), used for setting up the respective directories + The information of which diagnostic script to run with which variables. The + diagnostics section has some indents that are free to call. + + - the first indent (here: diag_timeseries_temperature) is the diagnostic’s + name (a string without whitespace), used for setting up the respective + directories - description: a short description of the diagnostic - variables: a definition of all variables that are used in this diagnostic - - the next indent (here: timeseries_variable) is the variables’ names (a string without whitespace) for the diagnostic to use + - the next indent (here: timeseries_variable) is the variables’ names (a + string without whitespace) for the diagnostic to use - short_name: the variable name as listed in the dataset - - preprocessor: the preprocessor(s) applied to the variable before running the diagnostic + - preprocessor: the preprocessor(s) applied to the variable before running + the diagnostic - scripts: a definition of all scripts that are used in this diagnostic - - the next indent (here: timeseries_diag) is the scripts’ names (a string without whitespace) for the script to use - - script: a executable script with a directory relative to the `esmvaltool/diag_scripts/` directory + - the next indent (here: timeseries_diag) is the scripts’ names (a string + without whitespace) for the script to use + - script: a executable script with a directory relative to the + `esmvaltool/diag_scripts/` directory > ## Please answer the following questions: > What is the short_name of the variable being analyzed? @@ -197,7 +226,9 @@ Please note the following sections: {: .solution} > ## Not all parts of the recipe are mandatory -> Some functionalities of the example recipe are mandatory, while others are not. E.g., if you miss any of the documentation information, the call will break. +> Some functionalities of the example recipe are mandatory, while others are +> not. E.g., if you miss any of the documentation information, the call will +> break. {: .callout} > ## Running ESMValTool @@ -207,11 +238,13 @@ Please note the following sections: > esmvaltool -c ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml > ~~~ > -> Follow the terminal guiding you through the subprocesses that are running. Can you find where the preprocessor and the diagnostic are starting? Which one took longer to process? +> Follow the terminal guiding you through the subprocesses that are running. Can +> you find where the preprocessor and the diagnostic are starting? Which one +> took longer to process? {: .challenge} > ## Exemplary output -> ~~~ +> ~~~bash > 2020-07-01 08:22:58,571 UTC [33433] INFO > ______________________________________________________________________ > _____ ____ __ ____ __ _ _____ _ @@ -295,15 +328,20 @@ Please note the following sections: > ~~~ {: .solution} -Each time you run the ESMValTool, it will produce a new output directory within your specified work directory with the name of the recipe and the tagged runtime. This folder should contain four folders: +Each time you run the ESMValTool, it will produce a new output directory within +your specified work directory with the name of the recipe and the tagged +runtime. This folder should contain four folders: - run - work - preproc - plots > ## Inspect the output: -> Now that you have run the esmvaltool command for the first time, please locate your output directory. -> If you’re missing the preproc directory, then your config-user.yml file has the value remove_preproc_dir set to true (this is used to save disk space). Please set this value to false and run the recipe again. +> Now that you have run the esmvaltool command for the first time, please locate +> your output directory. If you’re missing the preproc directory, then your +> config-user.yml file has the value remove_preproc_dir set to true (this is +> used to save disk space). Please set this value to false and run the recipe +> again. > {: .challenge} @@ -316,7 +354,8 @@ Each time you run the ESMValTool, it will produce a new output directory within > - The diagnostic log file. {: .checklist} -Exemplary output (depending on the directory paths and package versions that are available) can be found below. Note that the timestamps differ. +Exemplary output (depending on the directory paths and package versions that are +available) can be found below. Note that the timestamps differ. > ## Your output plot(s). > Plot for the dataset(s): @@ -329,7 +368,7 @@ Exemplary output (depending on the directory paths and package versions that are {: .solution} > ## Your main output log file. -> ~~~ +> ~~~bash > INFO [33433] > ______________________________________________________________________ > _____ ____ __ ____ __ _ _____ _ @@ -415,7 +454,7 @@ Exemplary output (depending on the directory paths and package versions that are {: .solution} > ## Your settings.yml file. -> ~~~ +> ```YAML > auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data > input_files: > - /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml @@ -430,11 +469,11 @@ Exemplary output (depending on the directory paths and package versions that are > work_dir: /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag > write_netcdf: true > write_plots: true -> ~~~ +> ``` {: .solution} > ## A metadata.yml file. -> ~~~ +> ```YAML > ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc > : alias: HadGEM2-ES > dataset: HadGEM2-ES @@ -459,11 +498,11 @@ Exemplary output (depending on the directory paths and package versions that are > start_year: 1859 > units: K > variable_group: timeseries_variable -> ~~~ +> ``` {: .solution} > ## The diagnostic log file. -> ~~~ +> ~~~bash > Starting diagnostic script timeseries_diag with configuration: > auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data > input_data: @@ -523,27 +562,40 @@ Exemplary output (depending on the directory paths and package versions that are ## Do your first edits > ## Edit the recipe and run again -> So far, the example recipe has used global volume-weighted ocean temperature. Please edit this recipe to investigate one of the following fields: +> So far, the example recipe has used global volume-weighted ocean temperature. +> Please edit this recipe to investigate one of the following fields: +> > - Land surface temperature (ts) for dataset HadGEM2-ES for 1901 - 2000 > - Atmospheric surface average temperature (tas) for datasets HadGEM2-AO and HadGEM2-ES for 1901 - 2000 > - Ocean surface average temperature (tos) for datasets HadGEM2-AO, HadGEM2-CC and HadGEM2-ES for 1901 - 2000 > > You will need to edit: +> > - the dataset: +> > - mip, start_year, end_year +> > - the preprocessor: -> - These fields are all 2D fields, but thetaoga was a 0D field. This means that we need to take the average over the latitude and longitude dimensions. To do this, add the area_statistics to the preprocessor. -> - the diagnostic +> +> - These fields are all 2D fields, but thetaoga was a 0D field. This means +> that we need to take the average over the latitude and longitude +> dimensions. To do this, add the area_statistics to the preprocessor. +> +> - the diagnostic: +> > - change the short_name value (thetaoga) for another: +> > - Land surface average temperature (ts) > - Atmospheric surface average temperature (tas) > - Ocean surface average temperature (tos) +> {: .challenge} The snippets for the edits can be found below: > ## Land surface average temperature -> ~~~YAML +> +> ```YAML > ... > 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} > ... @@ -554,12 +606,13 @@ The snippets for the edits can be found below: > ... > 38 short_name: ts > 39 preprocessor: prep_timeseries -> ~~~~ +> ``` +> > Note: The x-axis in the plot now shows the years 1900 - 2000. {: .solution} > ## Atmospheric surface average temperature -> ~~~YAML +> ```YAML > ... > 23 - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} > XX - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} @@ -571,12 +624,12 @@ The snippets for the edits can be found below: > ... > 38 short_name: tas > 39 preprocessor: prep_timeseries -> ~~~~ +> ``` > Note: There are now 3 plots in the work directory. One for each dataset and one for the multiple dataset overview. {: .solution} > ## Ocean surface average temperature -> ~~~YAML +> ```YAML > ... > 23 - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} > XX - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} @@ -589,7 +642,7 @@ The snippets for the edits can be found below: > ... > 38 short_name: tos > 39 preprocessor: prep_timeseries -> ~~~~ +> ``` > Note: The unit in the plots is now degrees celsius! There is a plot also for HadGEM2-CC. {: .solution} @@ -602,25 +655,43 @@ The snippets for the edits can be found below: ## Common issues & tips > ## esmvaltool not found -> Can you run the command “esmvaltool -h”. If no, then it’s possible that the conda environment isn’t activated. Please return to the installation section, episode #2 LINK. +> Can you run the command “esmvaltool -h”. If no, then it’s possible that the +> conda environment isn’t activated. Please return to the installation section, +> episode #2 LINK. {: .solution} -> ## ESMValTool can’t locate the data. The error message is `esmvalcore._recipe_checks.RecipeError: Missing data` -> Which computing machine are you using? Does your user-config.yml file reflect your machine's settings? Is the dataset’s name in the correct order? +> ## The error message is `esmvalcore._recipe_checks.RecipeError: Missing data` +> ESMValTool can’t locate the data. +> +> Which computing machine are you using? Does your user-config.yml file reflect +> your machine's settings? Is the dataset’s name in the correct order? {: .solution} > ## Diagnostic path problems -> The directory path to your diagnostics code is set relative to the esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? Is it spelled correctly? +> The directory path to your diagnostics code is set relative to the +> esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? +> Is it spelled correctly? {: .solution} > ## FX files not found -> There is no FX file for your corresponding dataset. Are your datasets’ names spelled correctly? Is there a FX file for this dataset? +> There is no FX file for your corresponding dataset. Are your datasets’ names +> spelled correctly? Is there a FX file for this dataset? {: .solution} > ## The preprocessor works but the diagnostic fails -> If your preprocessor works fine but your diagnostic script fails, congratulations! A failed diagnostic means that you won’t need to re-run the preprocessor. In your “run/main_log.txt” run output, you should see a line that reads: “To re-run this diagnostic script, run:”, followed by a line with a command that will allow you to re-run your diagnostic script only. Append this line with the “-i” option after the python script you call to re-run your diagnostic. +> If your preprocessor works fine but your diagnostic script fails, +> congratulations! A failed diagnostic means that you won’t need to re-run the +> preprocessor. In your “run/main_log.txt” run output, you should see a line +> that reads: “To re-run this diagnostic script, run:”, followed by a line with +> a command that will allow you to re-run your diagnostic script only. Append +> this line with the “-i” option after the python script you call to re-run your +> diagnostic. {: .solution} -> ## Your recipe’s name/project/reference isn’t recognised by ESMValTool. Error message is `ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml` -> Most likely, you added your own name to the recipe in the description section, but didn’t add it to the esmvaltool/config-references.yml file, where the names are linked to an email address, institute, and ORCID Identity. +> ## `ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml` +> Your recipe’s name/project/reference isn’t recognised by ESMValTool. +> +> Most likely, you added your own name to the recipe in the description section, +> but didn’t add it to the esmvaltool/config-references.yml file, where the +> names are linked to an email address, institute, and ORCID Identity. {: .solution} From 44a9aed4e11a3f32250d6c0231adb6ec5c130ccf Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Fri, 17 Jul 2020 09:48:15 +0100 Subject: [PATCH 245/647] changed end of lines --- _extras/about.md | 97 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 15 deletions(-) diff --git a/_extras/about.md b/_extras/about.md index 6f963b1f..109c048e 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -2,39 +2,106 @@ title: About --- -## ESMValTool - -The Earth System Model Evaluation Tool (ESMValTool) is a community-development that aims at improving diagnosing and understanding of the causes and effects of model biases and inter-model spread. The ESMValTool is open to both users and developers encouraging open exchange of diagnostic source code and evaluation results from the Coupled Model Intercomparison Project (CMIP) ensemble. This will facilitate and improve ESM evaluation beyond the state-of-the-art and aims at supporting the activities within CMIP and at individual modelling centers. We envisage running the ESMValTool routinely on the CMIP model output utilizing observations available through the Earth System Grid Federation (ESGF) in standard formats (obs4MIPs) or made available at ESGF nodes. - -The goal is to develop a benchmarking and evaluation tool that produces well-established analyses as soon as model output from CMIP simulations becomes available, e.g., at one of the central repositories of the ESGF. This is realized through standard recipes that reproduce a certain set of diagnostics and performance metrics that have demonstrated its importance in benchmarking Earth System Models (ESMs) in a paper or assessment report, such as Chapter 9 of the Intergovernmental Panel on Climate Change (IPCC) Fifth Assessment Report (AR5) (Flato et al., 2013). The expectation is that in this way a routine and systematic evaluation of model results can be made more efficient, thereby enabling scientists to focus on developing more innovative methods of analysis rather than constantly having to “reinvent the wheel”. +## ESMValTool + +The Earth System Model Evaluation Tool (ESMValTool) is a community-development +that aims at improving diagnosing and understanding of the causes and effects +of model biases and inter-model spread. The ESMValTool is open to both users +and developers encouraging open exchange of diagnostic source code and +evaluation results from the Coupled Model Intercomparison Project (CMIP) ensemble. +This will facilitate and improve ESM evaluation beyond the state-of-the-art and +aims at supporting the activities within CMIP and at individual modelling centers. +We envisage running the ESMValTool routinely on the CMIP model output utilizing +observations available through the Earth System Grid Federation (ESGF) in standard +formats (obs4MIPs) or made available at ESGF nodes. + +The goal is to develop a benchmarking and evaluation tool that produces +well-established analyses as soon as model output from CMIP simulations becomes +available, e.g., at one of the central repositories of the ESGF. +This is realized through standard recipes that reproduce a certain set of +diagnostics and performance metrics that have demonstrated its importance in +benchmarking Earth System Models (ESMs) in a paper or assessment report, +such as Chapter 9 of the Intergovernmental Panel on Climate Change (IPCC) +Fifth Assessment Report (AR5) (Flato et al., 2013). +The expectation is that in this way a routine and systematic evaluation of +model results can be made more efficient, thereby enabling scientists to +focus on developing more innovative methods of analysis rather than +constantly having to “reinvent the wheel”. ## ESMValTool community. -The ESMValTool community includes scientists and programmers from around the world. +The ESMValTool community includes scientists and programmers from around the world. -ESMValTool has been used to analyse data +ESMValTool has been used to analyse data -## OBS4Mips +## Obs4MIPs -In parallel to standardization of model output, the ESGF also hosts observations for Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). obs4MIPs provides open access data sets of satellite data that are comparable in terms of variables, temporal and spatial frequency, and periods to CMIP model output (Taylor et al., 2012). The ESMValTool utilizes these observations and reanalyses from ana4MIPs plus additionally available observations in order to evaluate the models performance. In many diagnostics and metrics, more than one observational data set or meteorological reanalysis is used to assess uncertainties in observations. +In parallel to standardization of model output, the ESGF also hosts observations +for Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). +Obs4MIPs provides open access data sets of satellite data that are comparable +in terms of variables, temporal and spatial frequency, and periods to CMIP model +output (Taylor et al., 2012). The ESMValTool utilizes these observations and +reanalyses from ana4MIPs plus additionally available observations in order to +evaluate the models performance. In many diagnostics and metrics, more than +one observational data set or meteorological reanalysis is used to assess +uncertainties in observations. -The main idea of the ESMValTool is to provide a broad suite of diagnostics which can be performed easily when new model simulations are run. The suite of diagnostics needs to be broad enough to reflect the diversity and complexity of Earth System Models, but must also be robust enough to be run routinely or semi-operationally. In order the address these challenging objectives the ESMValTool is conceived as a framework which allows community contributions to be bound into a coherent framework. +The main idea of the ESMValTool is to provide a broad suite of diagnostics which +can be performed easily when new model simulations are run. +The suite of diagnostics needs to be broad enough to reflect the diversity and +complexity of Earth System Models, but must also be robust enough to be run +routinely or semi-operationally. In order the address these challenging +objectives the ESMValTool is conceived as a framework which allows community +contributions to be bound into a coherent framework. ## License -The ESMValTool is released under the Apache License, version 2.0. Citation of the ESMValTool paper (“Software Documentation Paper”) is kindly requested upon use, alongside with the software DOI for ESMValTool (doi:10.5281/zenodo.3401363) and ESMValCore (doi:10.5281/zenodo.3387139) and version number: +The ESMValTool is released under the Apache License, version 2.0. Citation of +the ESMValTool paper (“Software Documentation Paper”) is kindly requested upon use, +alongside with the software DOI for ESMValTool (doi:10.5281/zenodo.3401363) +and ESMValCore (doi:10.5281/zenodo.3387139) and version number: ## Citation Please cite ESMValTool using: -Righi, M., Andela, B., Eyring, V., Lauer, A., Predoi, V., Schlund, M., Vegas-Regidor, J., Bock, L., Brötz, B., de Mora, L., Diblen, F., Dreyer, L., Drost, N., Earnshaw, P., Hassler, B., Koldunov, N., Little, B., Loosveldt Tomas, S., and Zimmermann, K.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – technical overview, Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020, 2020. - -Besides the above citation, users are kindly asked to register any journal articles (or other scientific documents) that use the software at the ESMValTool webpage (http://www.esmvaltool.org/). Citing the Software Documentation Paper and registering your paper(s) will serve to document the scientific impact of the Software, which is of vital importance for securing future funding. You should consider this an obligation if you have taken advantage of the ESMValTool, which represents the end product of considerable effort by the development team. +Righi, M., Andela, B., Eyring, V., Lauer, A., Predoi, V., Schlund, M., +Vegas-Regidor, J., Bock, L., Brötz, B., de Mora, L., Diblen, F., Dreyer, L., +Drost, N., Earnshaw, P., Hassler, B., Koldunov, N., Little, B., Loosveldt Tomas, +S., and Zimmermann, K.: +Earth System Model Evaluation Tool (ESMValTool) v2.0 – technical overview, +Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020, +2020. + +Besides the above citation, users are kindly asked to register any journal article + (or other scientific documents) that use the software at the ESMValTool webpage + (http://www.esmvaltool.org/). Citing the Software Documentation Paper and + registering your paper(s) will serve to document the scientific impact of the Software, + which is of vital importance for securing future funding. + You should consider this an obligation if you have taken advantage of the + ESMValTool, which represents the end product of considerable effort by the development team. ## Acknowledgements -The technical development work for ESValTool v2.0 was funded by various projects, in particular (1) the Copernicus Climate Change Service (C3S) “Metrics and Access to Global Indices for Climate Projections (C3S-MAGIC)” project; (2) the European Union's Horizon 2020 Framework Programme for Research and Innovation “Infrastructure for the European Network for Earth System Modelling (IS-ENES3)” project under grant agreement no. 824084; (3) the European Union's Horizon 2020 Framework Programme for Research and Innovation “Coordinated Research in Earth Systems and Climate: Experiments, kNowledge, Dissemination and Outreach (CRESCENDO)” project under grant agreement no. 641816; (4) the the European Union's Horizon 2020 Framework Programme for Research and Innovation “PRocess-based climate sIMulation: AdVances in high-resolution modelling and European climate Risk Assessment (PRIMAVERA)” project under grant agreement no. 641727; (5) the Helmholtz Society project “Advanced Earth System Model Evaluation for CMIP (EVal4CMIP)”; (6) project S1 (Diagnosis and Metrics in Climate Models) of the Collaborative Research Centre TRR 181 “Energy Transfer in Atmosphere and Ocean” funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) project no. 274762653; and (7) National Environmental Research Council (NERC) National Capability Science Multi-Centre (NCSMC) funding for the UK, Earth System Modelling project (grant no. NE/N018036/1). +The technical development work for ESValTool v2.0 was funded by various projects, +in particular (1) the Copernicus Climate Change Service (C3S) “Metrics and Access +to Global Indices for Climate Projections (C3S-MAGIC)” project; (2) the +European Union's Horizon 2020 Framework Programme for Research and Innovation +“Infrastructure for the European Network for Earth System Modelling (IS-ENES3)” +project under grant agreement no. 824084; (3) the European Union's Horizon 2020 +Framework Programme for Research and Innovation “Coordinated Research in Earth +Systems and Climate: Experiments, kNowledge, Dissemination and Outreach (CRESCENDO)” +project under grant agreement no. 641816; (4) the the European Union's Horizon +2020 Framework Programme for Research and Innovation “PRocess-based climate +sIMulation: AdVances in high-resolution modelling and European climate Risk +Assessment (PRIMAVERA)” project under grant agreement no. 641727; (5) the +Helmholtz Society project “Advanced Earth System Model Evaluation for CMIP +(EVal4CMIP)”; (6) project S1 (Diagnosis and Metrics in Climate Models) of +the Collaborative Research Centre TRR 181 “Energy Transfer in Atmosphere and +Ocean” funded by the Deutsche Forschungsgemeinschaft (DFG, German Research +Foundation) project no. 274762653; and (7) National Environmental Research +Council (NERC) National Capability Science Multi-Centre (NCSMC) funding for +the UK, Earth System Modelling project (grant no. NE/N018036/1). {% include escience_academy.html %} From bb0ac2a11cf2ea701bc1c443a4b3d29b2409bc48 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 10:57:30 +0200 Subject: [PATCH 246/647] changed CLI --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 0090c61e..3a37ad22 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -235,7 +235,7 @@ Please note the following sections: > > Use the command: > ~~~bash -> esmvaltool -c ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml +> esmvaltool run --config_file ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml > ~~~ > > Follow the terminal guiding you through the subprocesses that are running. Can From 059831e5e32a1511c83288a7957b9aa43d331154 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 17 Jul 2020 11:09:43 +0200 Subject: [PATCH 247/647] Update 04-recipe.md --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 3a37ad22..1b6a5d55 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -5,8 +5,8 @@ exercises: 25 questions: - "What is a recipe?" - "How can I do the same preprocessing on many different datasets?" -- "What are the files and directories that are created after running a recipe?" - "What happens when I run a recipe?" +- "What are the files and directories that are created after running a recipe?" objectives: - "Run an ESMValTool recipe" - "Understand the purpose of different settings in the recipe" From 0c80a55104cc97acbfb2a0ec039d729d14797673 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 17 Jul 2020 11:13:40 +0200 Subject: [PATCH 248/647] Update 04-recipe.md --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 1b6a5d55..85c49153 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -71,7 +71,7 @@ manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overvie ## How to run ESMValTool Once you’ve set up your conda environment and installed ESMValTool (see episode -#2 LINK) and set up your config-user.yml file to correctly match you local +#2 LINK) and set up your `config-user.yml` file to correctly match you local environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: From 6503cfa5562745a0bc520f9bb28d41759d88c47c Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 17 Jul 2020 11:16:09 +0200 Subject: [PATCH 249/647] Update 04-recipe.md --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 85c49153..4886b237 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -71,7 +71,7 @@ manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overvie ## How to run ESMValTool Once you’ve set up your conda environment and installed ESMValTool (see episode -#2 LINK) and set up your `config-user.yml` file to correctly match you local +#2 LINK) and set up your `config-user.yml` file to correctly match your local environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: From 2999d21ef4bbd792d37d38ad5ff70c39ba877099 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 11:24:18 +0200 Subject: [PATCH 250/647] add text and link --- CODE_OF_CONDUCT.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index c3b96690..11fe015b 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -3,9 +3,7 @@ layout: page title: "Contributor Code of Conduct" --- As contributors and maintainers of this project, -we pledge to follow the [Carpentry Code of Conduct][coc]. - -Instances of abusive, harassing, or otherwise unacceptable behavior -may be reported by following our [reporting guidelines][coc-reporting]. +we pledge to follow the +[ESMValTool Code of Conduct](https://github.com/ESMValGroup/ESMValTool/blob/master/CODE_OF_CONDUCT.md). {% include links.md %} From 901cb2f3069419c7ab5da32e989a947b5287473b Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 17 Jul 2020 11:25:41 +0200 Subject: [PATCH 251/647] Update 04-recipe.md --- _episodes/04-recipe.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 4886b237..2af9c0ec 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -146,7 +146,8 @@ the name: recipe_example.yml LINK Please note the following sections: - documentation: lines 4-20. - The documentation consists of the following information: + + The documentation consists of the following information: - description: a short description of the recipe - authors: a list of authors (linked to `esmvaltool/config-references.yml`) From 239b315a96abf9181f651044fcbe7d11f183bebc Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 17 Jul 2020 11:26:11 +0200 Subject: [PATCH 252/647] Update 04-recipe.md --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 2af9c0ec..9205e252 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -145,7 +145,7 @@ the name: recipe_example.yml LINK Please note the following sections: - - documentation: lines 4-20. + - documentation: lines 4-20 The documentation consists of the following information: From ab316dab03d4f6d17f5179112cd67846631b5c9d Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 17 Jul 2020 11:28:22 +0200 Subject: [PATCH 253/647] Update 04-recipe.md --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 9205e252..06168067 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -173,7 +173,7 @@ Please note the following sections: - preprocessors: lines 25-28 - The definition for different preprocessors or combinations. If no + The definition for different preprocessors or preprocessor combinations. If no preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). From dbf4b4b5140cc7c6ed74d16c391466e02297f544 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 11:33:17 +0200 Subject: [PATCH 254/647] update the text --- CODE_OF_CONDUCT.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 11fe015b..0be60e91 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,9 +1,5 @@ ---- -layout: page -title: "Contributor Code of Conduct" ---- -As contributors and maintainers of this project, +# Contributor Code of Conduct + +As contributors and maintainers of this tutorial, we pledge to follow the [ESMValTool Code of Conduct](https://github.com/ESMValGroup/ESMValTool/blob/master/CODE_OF_CONDUCT.md). - -{% include links.md %} From 3de326ebb37dfc85cdeca9c25dafe6583ba6da55 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 11:35:35 +0200 Subject: [PATCH 255/647] changed CLI --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 4886b237..a11cc25b 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -76,7 +76,7 @@ environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: ~~~ -esmvaltool -c configuration recipe +esmvaltool run --config_file configuration recipe ~~~ {: .source} From 7824c36c03a80d51bac72acd9df557779dec07cd Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 11:49:55 +0200 Subject: [PATCH 256/647] fix linter error --- CODE_OF_CONDUCT.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 0be60e91..e160a917 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,5 +1,5 @@ # Contributor Code of Conduct As contributors and maintainers of this tutorial, -we pledge to follow the -[ESMValTool Code of Conduct](https://github.com/ESMValGroup/ESMValTool/blob/master/CODE_OF_CONDUCT.md). +we pledge to follow the ESMValTool +[Code of Conduct](https://github.com/ESMValGroup/ESMValTool/blob/master/CODE_OF_CONDUCT.md). From fb784b223acdea5fd42adfbe8042d39c495bff53 Mon Sep 17 00:00:00 2001 From: Jaro Camphuijsen Date: Fri, 17 Jul 2020 11:54:44 +0200 Subject: [PATCH 257/647] change tutorial title and life cycle stage --- _config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_config.yml b/_config.yml index 7f6be9ce..a37e81aa 100644 --- a/_config.yml +++ b/_config.yml @@ -11,11 +11,11 @@ carpentry: "ea" # Overall title for pages. -title: "ESMValTool Introduction" +title: "ESMValTool Tutorial" # Life cycle stage of the lesson # possible values: "pre-alpha", "alpha", "beta", "stable" -life_cycle: "pre-alpha" +life_cycle: "beta" #------------------------------------------------------------ # Generic settings (should not need to change). From 6dcec00634084f114f059ea7058f6dc78862726f Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 12:03:35 +0200 Subject: [PATCH 258/647] changed CLI in episode 2 --- _episodes/02-installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 4efb82ea..4b250883 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -244,12 +244,12 @@ to display the command line help. > > > > In my case when I run > > ~~~ -> > esmvaltool --version +> > esmvaltool version > > ~~~ > > {: .bash} > > I get that my installed ESMValTool version is > > ~~~ -> > 2.0.0b9 +> > 2.0.0 > > ~~~ > > {: .output} > {: .solution} From 3bb788e77c9f3ec5dd374c1296d22a238efe490c Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 11:35:35 +0200 Subject: [PATCH 259/647] changed CLI --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 0090c61e..55731e2a 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -76,7 +76,7 @@ environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: ~~~ -esmvaltool -c configuration recipe +esmvaltool run --config_file configuration recipe ~~~ {: .source} From 13b31d149163c2738b1cc0dec27214d43e010c3c Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 10:57:30 +0200 Subject: [PATCH 260/647] changed CLI --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 55731e2a..4d0934dd 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -235,7 +235,7 @@ Please note the following sections: > > Use the command: > ~~~bash -> esmvaltool -c ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml +> esmvaltool run --config_file ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml > ~~~ > > Follow the terminal guiding you through the subprocesses that are running. Can From 8b5010da0dc49231b605a6cd7686ee986cee3c18 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 17 Jul 2020 12:10:05 +0200 Subject: [PATCH 261/647] Update 04-recipe.md --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index b4d8db28..4fc73529 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -182,7 +182,7 @@ Please note the following sections: - diagnostic section: lines 30-42 The information of which diagnostic script to run with which variables. The - diagnostics section has some indents that are free to call. + diagnostics section has some indents that are free to be called. - the first indent (here: diag_timeseries_temperature) is the diagnostic’s name (a string without whitespace), used for setting up the respective From b8f8035f3fd23d380522bcd03edec691ea3e0b6f Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 12:19:21 +0200 Subject: [PATCH 262/647] changed CLI in episode 4 --- _episodes/04-recipe.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 4d0934dd..6a7443fb 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -75,6 +75,13 @@ Once you’ve set up your conda environment and installed ESMValTool (see episod environment, (see episode #3 LINK), ESMValTool is invoked using a simple command: +~~~ +esmvaltool run recipe +~~~ +{: .source} + +If the configuration file is not in the default {HOME}\.esmvaltool\ path you can pass its path explicitly: + ~~~ esmvaltool run --config_file configuration recipe ~~~ @@ -94,7 +101,7 @@ the name: recipe_example.yml LINK > 1 # ESMValTool > 2 # recipe_example.yml > 3 --- -> 4 documentation: +> 4 documentation > 5 description: Demonstrate basic ESMValTool example > 6 > 7 authors: From 7c4fb19936a3c16e642ccedfb2935cc5004c31c8 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 17 Jul 2020 12:19:23 +0200 Subject: [PATCH 263/647] Update 04-recipe.md --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 4fc73529..47537dc9 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -223,7 +223,7 @@ Please note the following sections: {: .solution} > ## What do you think running this recipe will produce? -> A time series plot of thetaoga with increements of 1 year. +> A time series plot of thetaoga with increments of 1 year. {: .solution} > ## Not all parts of the recipe are mandatory From c1a6edd68298f52ad14b3b2128e555418fc02dca Mon Sep 17 00:00:00 2001 From: Jaro Camphuijsen Date: Fri, 17 Jul 2020 12:24:04 +0200 Subject: [PATCH 264/647] add escience academy to checks --- _config.yml | 2 +- bin/lesson_check.py | 2 +- bin/workshop_check.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_config.yml b/_config.yml index a37e81aa..28048592 100644 --- a/_config.yml +++ b/_config.yml @@ -2,7 +2,7 @@ # Values for this lesson. #------------------------------------------------------------ -# Which carpentry is this ("swc", "dc", "lc", or "cp")? +# Which carpentry is this ("swc", "dc", "lc", "cp" or "ea")? # swc: Software Carpentry # dc: Data Carpentry # lc: Library Carpentry diff --git a/bin/lesson_check.py b/bin/lesson_check.py index ee84d849..f3127b32 100644 --- a/bin/lesson_check.py +++ b/bin/lesson_check.py @@ -177,7 +177,7 @@ def check_config(reporter, source_dir): reporter.check_field(config_file, 'configuration', config, 'kind', 'lesson') reporter.check_field(config_file, 'configuration', - config, 'carpentry', ('swc', 'dc', 'lc', 'cp')) + config, 'carpentry', ('swc', 'dc', 'lc', 'cp', 'ea')) reporter.check_field(config_file, 'configuration', config, 'title') reporter.check_field(config_file, 'configuration', config, 'email') diff --git a/bin/workshop_check.py b/bin/workshop_check.py index 2caf5603..a163b2a2 100644 --- a/bin/workshop_check.py +++ b/bin/workshop_check.py @@ -388,7 +388,7 @@ def check_config(reporter, filename): kind) carpentry = config.get('carpentry', None) - reporter.check(carpentry in ('swc', 'dc', 'lc', 'cp'), + reporter.check(carpentry in ('swc', 'dc', 'lc', 'cp', 'ea'), filename, 'Missing or unknown carpentry: {0}', carpentry) From c64553d30db104d442d51ede81cfec35e849eb27 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 12:26:31 +0200 Subject: [PATCH 265/647] changed CLI in epsiode 6 --- _episodes/06-debugging.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index a03d9d6b..e1e6d788 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -32,7 +32,7 @@ the recipe: ~~~bash cd esmvaltool_tutorial - esmvaltool -c user-config.yml recipe_example.yml + esmvaltool run --config_file user-config.yml recipe_example.yml ~~~ ~~~ @@ -202,7 +202,7 @@ Also, we change the ``projects`` value ``ukesm`` to ``tutorial``: Then, we save the file and run the recipe: ~~~bash - esmvaltool -c user-config.yml recipe_example.yml + esmvaltool run --config_file user-config.yml recipe_example.yml ~~~ ~~~ @@ -282,7 +282,7 @@ let's see if we can change the script path as: ``` ~~~bash - esmvaltool -c user-config.yml recipe_example.yml + esmvaltool run --config_file user-config.yml recipe_example.yml ~~~ ~~~ @@ -304,7 +304,7 @@ recipe: ``` ~~~bash - esmvaltool -c user-config.yml recipe_example.yml + esmvaltool run --config_file user-config.yml recipe_example.yml ~~~ > ## Available recipe and diagnostic scripts From 0e87bb0bb1185e85b63f9b27a16a0d8b17222d0e Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 17 Jul 2020 12:28:40 +0200 Subject: [PATCH 266/647] Update 04-recipe.md --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 47537dc9..3342c45b 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -340,7 +340,7 @@ runtime. This folder should contain four folders: > ## Inspect the output: > Now that you have run the esmvaltool command for the first time, please locate > your output directory. If you’re missing the preproc directory, then your -> config-user.yml file has the value remove_preproc_dir set to true (this is +> `config-user.yml` file has the value remove_preproc_dir set to true (this is > used to save disk space). Please set this value to false and run the recipe > again. > From 0e322a5f78b96f70624ef2dc72257537350b5236 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Fri, 17 Jul 2020 11:45:04 +0100 Subject: [PATCH 267/647] removed the too much text --- _extras/about.md | 102 +++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/_extras/about.md b/_extras/about.md index 109c048e..361da411 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -4,56 +4,41 @@ title: About ## ESMValTool -The Earth System Model Evaluation Tool (ESMValTool) is a community-development -that aims at improving diagnosing and understanding of the causes and effects -of model biases and inter-model spread. The ESMValTool is open to both users -and developers encouraging open exchange of diagnostic source code and -evaluation results from the Coupled Model Intercomparison Project (CMIP) ensemble. -This will facilitate and improve ESM evaluation beyond the state-of-the-art and -aims at supporting the activities within CMIP and at individual modelling centers. -We envisage running the ESMValTool routinely on the CMIP model output utilizing -observations available through the Earth System Grid Federation (ESGF) in standard -formats (obs4MIPs) or made available at ESGF nodes. - -The goal is to develop a benchmarking and evaluation tool that produces -well-established analyses as soon as model output from CMIP simulations becomes -available, e.g., at one of the central repositories of the ESGF. -This is realized through standard recipes that reproduce a certain set of -diagnostics and performance metrics that have demonstrated its importance in -benchmarking Earth System Models (ESMs) in a paper or assessment report, -such as Chapter 9 of the Intergovernmental Panel on Climate Change (IPCC) -Fifth Assessment Report (AR5) (Flato et al., 2013). -The expectation is that in this way a routine and systematic evaluation of -model results can be made more efficient, thereby enabling scientists to -focus on developing more innovative methods of analysis rather than -constantly having to “reinvent the wheel”. - -## ESMValTool community. - -The ESMValTool community includes scientists and programmers from around the world. - -ESMValTool has been used to analyse data - - -## Obs4MIPs - -In parallel to standardization of model output, the ESGF also hosts observations -for Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). -Obs4MIPs provides open access data sets of satellite data that are comparable -in terms of variables, temporal and spatial frequency, and periods to CMIP model -output (Taylor et al., 2012). The ESMValTool utilizes these observations and -reanalyses from ana4MIPs plus additionally available observations in order to -evaluate the models performance. In many diagnostics and metrics, more than -one observational data set or meteorological reanalysis is used to assess -uncertainties in observations. - -The main idea of the ESMValTool is to provide a broad suite of diagnostics which -can be performed easily when new model simulations are run. -The suite of diagnostics needs to be broad enough to reflect the diversity and -complexity of Earth System Models, but must also be robust enough to be run -routinely or semi-operationally. In order the address these challenging -objectives the ESMValTool is conceived as a framework which allows community -contributions to be bound into a coherent framework. +The Earth System Model Evaluation Tool, ESMValTool, is a python-based +software toolkit built to evaluate models of the Earths climate. + +ESMVAlTool is made to be: + +- Versatile +- Flexible +- Modular +- Standardised  +- Community driven + +The toolkit is built with a sensible and modern code development process. +Where possible, we follow software development best practices, +including code review & monitoring, unit & integration testing, +and fully transparent design decisions. + +ESMValTool is open source and available on github, and is written +in PEP8-compliant Python3. + +For more details on ESMValTool, please go to: +- [https://esmvaltool.org](ESMValTool home page) +- [https://esmvaltool.readthedocs.io/](ESMValTool Read The Docs page) + + +## ESMValTool_Tutorial + +The ESMValTool tutorial was made to help people learn how to install, use, +and develop ESMValTool. + +The tutorial uses the software carpentry format and tools, and can be +followed both independently and in a taught tutorial environment. + +The tutorial has been produced by the ESMValTool User Engagement team, +and may be forked, developped and rehosted by other groups. + ## License The ESMValTool is released under the Apache License, version 2.0. Citation of @@ -74,12 +59,17 @@ Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020, 2020. Besides the above citation, users are kindly asked to register any journal article - (or other scientific documents) that use the software at the ESMValTool webpage - (http://www.esmvaltool.org/). Citing the Software Documentation Paper and - registering your paper(s) will serve to document the scientific impact of the Software, - which is of vital importance for securing future funding. - You should consider this an obligation if you have taken advantage of the - ESMValTool, which represents the end product of considerable effort by the development team. +(or other scientific documents) that use the software at the ESMValTool webpage +(http://www.esmvaltool.org/). + +Citing the Software Documentation Paper and registering your papers +will serve to document the scientific impact of the Software, +which is of vital importance for securing future funding. + +You should consider this an obligation if you have taken advantage of the +ESMValTool, which represents the end product of considerable effort by the +development teams. + ## Acknowledgements From c9e237a5e4469b38df60d90fd334ef65fbc8b81a Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Fri, 17 Jul 2020 12:00:03 +0100 Subject: [PATCH 268/647] Update _extras/about.md --- _extras/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_extras/about.md b/_extras/about.md index 361da411..2eb1d8d8 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -73,7 +73,7 @@ development teams. ## Acknowledgements -The technical development work for ESValTool v2.0 was funded by various projects, +The technical development work for ESMValTool v2.0 was funded by various projects, in particular (1) the Copernicus Climate Change Service (C3S) “Metrics and Access to Global Indices for Climate Projections (C3S-MAGIC)” project; (2) the European Union's Horizon 2020 Framework Programme for Research and Innovation From 4fb7452ab4730bf1456c9a93b71b5a579c160ed8 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Fri, 17 Jul 2020 12:00:34 +0100 Subject: [PATCH 269/647] Update _extras/about.md --- _extras/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_extras/about.md b/_extras/about.md index 2eb1d8d8..f4a7b7c5 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -86,7 +86,7 @@ project under grant agreement no. 641816; (4) the the European Union's Horizon sIMulation: AdVances in high-resolution modelling and European climate Risk Assessment (PRIMAVERA)” project under grant agreement no. 641727; (5) the Helmholtz Society project “Advanced Earth System Model Evaluation for CMIP -(EVal4CMIP)”; (6) project S1 (Diagnosis and Metrics in Climate Models) of +(Eval4CMIP)”; (6) project S1 (Diagnosis and Metrics in Climate Models) of the Collaborative Research Centre TRR 181 “Energy Transfer in Atmosphere and Ocean” funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) project no. 274762653; and (7) National Environmental Research From 48680fbf05aad65eaf89d79678d5f21f2309432e Mon Sep 17 00:00:00 2001 From: Jaro Camphuijsen Date: Fri, 17 Jul 2020 13:00:59 +0200 Subject: [PATCH 270/647] remove escience academy from checks and change carpentry type to unimplemented value specific to esmvaltool, change life cycle to alpha --- _config.yml | 9 +++++---- bin/lesson_check.py | 2 +- bin/workshop_check.py | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/_config.yml b/_config.yml index 28048592..0a530740 100644 --- a/_config.yml +++ b/_config.yml @@ -2,20 +2,21 @@ # Values for this lesson. #------------------------------------------------------------ -# Which carpentry is this ("swc", "dc", "lc", "cp" or "ea")? +# Which carpentry is this ("swc", "dc", "lc", "cp")? # swc: Software Carpentry # dc: Data Carpentry # lc: Library Carpentry # cp: Carpentries (to use for instructor traning for instance) -# ea: eScience Academy -carpentry: "ea" +# ea: eScience Academy (not implemented) +# et: ESMValTool Tutorial (to be implemented) +carpentry: "et" # Overall title for pages. title: "ESMValTool Tutorial" # Life cycle stage of the lesson # possible values: "pre-alpha", "alpha", "beta", "stable" -life_cycle: "beta" +life_cycle: "alpha" #------------------------------------------------------------ # Generic settings (should not need to change). diff --git a/bin/lesson_check.py b/bin/lesson_check.py index f3127b32..ee84d849 100644 --- a/bin/lesson_check.py +++ b/bin/lesson_check.py @@ -177,7 +177,7 @@ def check_config(reporter, source_dir): reporter.check_field(config_file, 'configuration', config, 'kind', 'lesson') reporter.check_field(config_file, 'configuration', - config, 'carpentry', ('swc', 'dc', 'lc', 'cp', 'ea')) + config, 'carpentry', ('swc', 'dc', 'lc', 'cp')) reporter.check_field(config_file, 'configuration', config, 'title') reporter.check_field(config_file, 'configuration', config, 'email') diff --git a/bin/workshop_check.py b/bin/workshop_check.py index a163b2a2..2caf5603 100644 --- a/bin/workshop_check.py +++ b/bin/workshop_check.py @@ -388,7 +388,7 @@ def check_config(reporter, filename): kind) carpentry = config.get('carpentry', None) - reporter.check(carpentry in ('swc', 'dc', 'lc', 'cp', 'ea'), + reporter.check(carpentry in ('swc', 'dc', 'lc', 'cp'), filename, 'Missing or unknown carpentry: {0}', carpentry) From d5c7606aa914bc265f21ecfed2b8ddfa1e842c40 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 13:18:49 +0200 Subject: [PATCH 271/647] adapt episode 3 to new CLI --- _episodes/03-configuration.md | 232 +++++++++++++++++----------------- 1 file changed, 113 insertions(+), 119 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index a504109e..e5a6fb51 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -22,26 +22,17 @@ keypoints: The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. This is an [YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be -found in the root directory of the ESMValTool repository: -[config-user-example.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/config-user-example.yml). - -First, we make a working directory ``esmvaltool_tutorial``. -In a new terminal, run: +found in the ESMValCore repository: +[config-user-example.yml](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-user.yml). You could download it by typing: ~~~bash - mkdir esmvaltool_tutorial - cd esmvaltool_tutorial + esmvaltool config get_config_user ~~~ -Now, we download the configuration file to our working directory. To do that, -click on [this -link](https://raw.githubusercontent.com/ESMValGroup/ESMValTool/master/config-user-example.yml) -to see a raw version of the file, right-click and press ``save as``, then you -can rename it to ``config-user.yml``and save it into the working directory -``esmvaltool_tutorial``. +It will save the file to: ``{HOME}/.esmvaltool/config-user.yml``. Now, let's change our working directory in a terminal window to -``esmvaltool_tutorial``. Then, we run a text editor called Nano to have a look +``{HOME}/.esmvaltool``. Then, we run a text editor called Nano to have a look inside the configuration file: ~~~bash @@ -50,12 +41,12 @@ inside the configuration file: This file contains the information for: -- Rootpath to input data -- Directory structure for the data from different projects -- Number of tasks that can be run in parallel +- Output settings - Destination directory - Auxiliary data directory -- Output settings +- Number of tasks that can be run in parallel +- Rootpath to input data +- Directory structure for the data from different projects > ## Text editor side note > @@ -67,6 +58,108 @@ This file contains the information for: > and then ctrl + X to exit ``nano``. {: .callout} +## Output settings + +These settings are used to inform ESMValTool about your preference about +specific actions. You can turn on or off the setting by ``true`` or ``false`` +values. Most of these settings are fairly self-explanatory, ie: + +```yaml +# Diagnostics create plots? [true]/false +write_plots: true +# Diagnositcs write NetCDF files? [true]/false +write_netcdf: true +# Set the console log level debug, [info], warning, error +log_level: info +# Exit on warning (only for NCL diagnostic scripts)? true/[false] +exit_on_warning: false +# Plot file format? [png]/pdf/ps/eps/epsi +output_file_type: png + +... + +# Use netCDF compression true/[false] +compress_netcdf: false +# Save intermediary cubes in the preprocessor true/[false] +save_intermediary_cubes: false +# Remove the preproc dir if all fine +remove_preproc_dir: true + +... + +# Path to custom config-developer file, to customise project configurations. +# See config-developer.yml for an example. Set to [null] to use the default + config_developer_file: null +# Get profiling information for diagnostics +# Only available for Python diagnostics +profile_diagnostic: false +``` + +## Destination directory + +The destination directory is the rootpath where ESMValTool will store its output, +i.e. figures, data, logs, etc. With every run, ESMValTool automatically generates +a new output folder determined by recipe name, and date and time using +the format: YYYYMMDD_HHMMSS. +This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. + +Let's name our destination directory ``esmvaltool_output`` in the working directory: + +```yaml +output_dir: ./esmvaltool_output +``` + +> ## Content of subfolders +> +> - ``plots``: the location for all plots, split by individual diagnostics and fields. +> - ``preproc``: this folder contains all the preprocessed data and metadata.yml +interface files. Note that by default this directory will be deleted after +each run because most users will only need the results from the diagnostic scripts. +> - ``run``: this folder includes all log files, a copy of the recipe, +a summary of the resource usage, and the settings.yml interface files, +resource_usage.txt and temporary files created by the diagnostic scripts. +> - ``work``: this folder is a place for any diagnostic script results that +are not plots, e.g. files in NetCDF format (depends on the diagnostic script). +> +> We explain more about output in the next +[lesson]({{ page.root }}{% link _episodes/04-recipe.md %}) +{: .callout} + +## Auxiliary data directory + +The ``auxiliary_data_dir`` setting is the path where any required additional +auxiliary data files are stored. This location allows us to tell the diagnostic +script where to find the files if they can not be downloaded at runtime. This +option should not be used for model or observational datasets, but for data +files (e.g. shape files) used in plotting such as coastline descriptions and so +on. + +```yaml +auxiliary_data_dir: ~/auxiliary_data +``` + +## Number of parallel tasks + +This option enables you to perform parallel processing. +You can choose the number of tasks in parallel as +1/2/3/4/... or you can set it to ``null``. That tells +ESMValTool to use the maximum number of available CPUs: + +```yaml + +max_parallel_tasks: null +``` + +> ## Set the number of tasks +> +> If you run out of memory, try setting ``max_parallel_tasks`` to 1. +Then, check the amount of memory you need for that by inspecting +the file ``run/resource_usage.txt`` in the output directory. +Using the number there you can increase the number of parallel tasks +again to a reasonable number for the amount of memory available in your system. +{: .callout} + + ## Rootpath to input data ESMValTool uses several categories (in ESMValTool, this is referred to as projects) @@ -80,17 +173,13 @@ For each category, you can define either one path or several paths as a list. ```yaml rootpath: - CMIP3: [~/cmip3_inputpath1, ~/cmip3_inputpath2] CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2] - CMIP6: [~/cmip6_inputpath1, ~/cmip6_inputpath2] OBS: ~/obs_inputpath - OBS6: ~/obs6_inputpath - obs4mips: ~/obs4mips_inputpath - ana4mips: ~/ana4mips_inputpath - native6: ~/native6_inputpath RAWOBS: ~/rawobs_inputpath default: ~/default_inputpath + CORDEX: ~/default_inputpath ``` +Site-specific entries for Jasmin, DKRZ and ETHZ are listed at the end of the example configuration file. In this lesson, we will work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). @@ -131,101 +220,6 @@ drs: > [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html#cmor-drs). {: .callout} -## Number of parallel tasks - -This option enables you to perform parallel processing. -You can choose the number of tasks in parallel as -1/2/3/4/... or you can set it to ``null``. That tells -ESMValTool to use the maximum number of available CPUs: - -```yaml - -max_parallel_tasks: null -``` - -> ## Set the number of tasks -> -> If you run out of memory, try setting ``max_parallel_tasks`` to 1. -Then, check the amount of memory you need for that by inspecting -the file ``run/resource_usage.txt`` in the output directory. -Using the number there you can increase the number of parallel tasks -again to a reasonable number for the amount of memory available in your system. -{: .callout} - -## Destination directory - -The destination directory is the rootpath where ESMValTool will store its output, -i.e. figures, data, logs, etc. With every run, ESMValTool automatically generates -a new output folder determined by recipe name, and date and time using -the format: YYYYMMDD_HHMMSS. -This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. - -Let's name our destination directory ``esmvaltool_output`` in the working directory: - -```yaml -output_dir: ./esmvaltool_output -``` - -> ## Content of subfolders -> -> - ``plots``: the location for all plots, split by individual diagnostics and fields. -> - ``preproc``: this folder contains all the preprocessed data and metadata.yml -interface files. Note that by default this directory will be deleted after -each run because most users will only need the results from the diagnostic scripts. -> - ``run``: this folder includes all log files, a copy of the recipe, -a summary of the resource usage, and the settings.yml interface files, -resource_usage.txt and temporary files created by the diagnostic scripts. -> - ``work``: this folder is a place for any diagnostic script results that -are not plots, e.g. files in NetCDF format (depends on the diagnostic script). -> -> We explain more about output in the next -[lesson]({{ page.root }}{% link _episodes/04-recipe.md %}) -{: .callout} - -## Auxiliary data directory - -The ``auxiliary_data_dir`` setting is the path where any required additional -auxiliary data files are stored. This location allows us to tell the diagnostic -script where to find the files if they can not be downloaded at runtime. This -option should not be used for model or observational datasets, but for data -files (e.g. shape files) used in plotting such as coastline descriptions and so -on. - -```yaml -auxiliary_data_dir: ~/auxiliary_data -``` - -## Output settings - -These settings are used to inform ESMValTool about your preference about -specific actions. You can turn on or off the setting by ``true`` or ``false`` -values. Most of these settings are fairly self-explanatory, ie: - -```yaml -# Diagnostics create plots? [true]/false -write_plots: true -# Diagnositcs write NetCDF files? [true]/false -write_netcdf: true -# Set the console log level debug, [info], warning, error -log_level: info -# Exit on warning (only for NCL diagnostic scripts)? true/[false] -exit_on_warning: false -# Plot file format? [png]/pdf/ps/eps/epsi -output_file_type: png -# Use netCDF compression true/[false] -compress_netcdf: false -# Save intermediary cubes in the preprocessor true/[false] -save_intermediary_cubes: false -# Remove the preproc dir if all fine -remove_preproc_dir: true -# Path to custom config-developer file, to customise project configurations. -# See config-developer.yml for an example. Set to [null] to use the default -# config_developer_file: null -# Get profiling information for diagnostics -# Only available for Python diagnostics -profile_diagnostic: false -``` - > ## Make your own configuration file > > It is possible to have several configuration files with different purposes, From b0e1f0000141aab349bc635faadc2e57afbeb08b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 13:31:08 +0200 Subject: [PATCH 272/647] update the content of readme --- README.md | 62 ++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 51387256..494593c0 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,47 @@ -# FIXME Lesson title +# ESMValTool Tutorial -[![Create a Slack Account with -us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/) [![Join the chat at https://gitter.im/ESMValGroup/Tutorial](https://badges.gitter.im/ESMValGroup/Tutorial.svg)](https://gitter.im/ESMValGroup/Tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -This repository generates the corresponding lesson website from [The -Carpentries](https://carpentries.org/) repertoire of lessons. +[ESMValTool Tutorial][tutorial-site] is an open-source project in +[ESMValGroup][ESMValTool-site]. +This tutorial is a set of lessons that together teach skills needed to work +with ESMValTool in climate-related domains. +The Earth System Model Evaluation Tool ([ESMValTool][ESMValTool-site]) is a +community diagnostics and performance metrics tool for the evaluation of +Earth System Models (ESMs) that allows for routine comparison of single or +multiple models. ## Contributing -We welcome all contributions to improve the lesson! Maintainers will do their -best to help you if you have any questions, concerns, or experience any -difficulties along the way. - -We'd like to ask you to familiarize yourself with our [Contribution -Guide](CONTRIBUTING.md) and have a look at the [more detailed -guidelines][lesson-example] on proper formatting, ways to render the lesson -locally, and even how to write new episodes. Note that the content of the web -page is located in the directory -[_episodes](https://github.com/ESMValGroup/tutorial/tree/master/_episodes). - -Please see the current list of [issues][FIXME] for ideas for contributing to -this repository. For making your contribution, we use the GitHub flow, which is -nicely explained in the chapter [Contributing to a -Project](http://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project) in Pro -Git by Scott Chacon. Look for the tag -![good_first_issue](https://img.shields.io/badge/-good%20first%20issue-gold.svg). -This indicates that the maintainers will welcome a pull request fixing this -issue. - +We welcome all contributions to improve the lesson! +We'd like to ask you to familiarize yourself with our guide in +[CONTRIBUTING](CONTRIBUTING) and our [Code of Conduct](CODE_OF_CONDUCT). ## Maintainer(s) -Current maintainers of this lesson are - -* FIXME -* FIXME -* FIXME +Current maintainers of this tutorial are ESMValTool +[User Engagement Team][user-engagement]. +Maintainers will do their +best to help you if you have any questions, concerns, or experience any +difficulties along the way. +If you work or study in climate-related domains and would be interested in +getting involved, you can reach us by email. +Please see the [contact information][contact-info]. ## Authors -A list of contributors to the lesson can be found in [AUTHORS](AUTHORS) +A list of contributors to the lesson can be found in [AUTHORS](AUTHORS). ## Citation -To cite this lesson, please consult with [CITATION](CITATION) +To cite this Tutorial, please consult with [CITATION](CITATION). -[lesson-example]: https://carpentries.github.io/lesson-example +[email]: mailto:TODO_FIX_ME +[ESMValTool-site]: https://www.esmvaltool.org/ +[ESMValTool-doc]: https://esmvaltool.readthedocs.io/en/latest/ +[tutorial-repo]: https://esmvalgroup.github.io/ESMValTool_Tutorial/ +[tutorial-site]: https://esmvalgroup.github.io/ESMValTool_Tutorial +[user-engagement]: https://github.com/orgs/ESMValGroup/teams/userengagementteam +[contact-info]: https://docs.esmvaltool.org/en/latest/community/contact.html From ded307ea75abd4ff8a3134409898246adc99b77e Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 13:31:40 +0200 Subject: [PATCH 273/647] fix broken links, add mailinglist guide --- CONTRIBUTING.md | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3377e49d..95005aa4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -100,10 +100,10 @@ and can be used as: mdl your_markdown_filename ``` -We use [Codacy](https://app.codacy.com/gh/ESMValGroup/tutorial) as an automated -code analysis services. To run the analyis -[locally](https://github.com/codacy/codacy-analysis-cli) on Markdown files with -Docker use +We use [Codacy](https://app.codacy.com/gh/ESMValGroup/ESMValTool_Tutorial) +as an automated code analysis services. To run the analyis +[locally](https://github.com/codacy/codacy-analysis-cli) +on Markdown files with Docker use ```bash docker run \ @@ -118,9 +118,10 @@ docker run \ ### Previewing your changes locally -If you are making a new episode or contributing to existing ones, please preview -changes on your machine before submitting a [pull request][PR]. To do so, you -need to install the software described below: +If you are making a new episode or contributing to existing ones, +please preview changes on your machine before submitting a +[pull request][PR]. To do so, you need to install +the software described below: ```bash # apt (Ubuntu/Devian) @@ -158,20 +159,24 @@ This address can be opened in your browser to preview the tutorial website. ## Other Resources -General discussion of the tutorial happens in `User Engagement Team`. -You can reach us by [email][email]. +General discussion of the tutorial happens in +ESMValTool [User Engagement Team][user-engagement]. +You can reach us by email. +Please see the [contact information][contact-info]. [email]: mailto:TODO_FIX_ME [ESMValTool-site]: https://www.esmvaltool.org/ [ESMValTool-doc]: https://esmvaltool.readthedocs.io/en/latest/ -[tutorial-repo]: https://esmvalgroup.github.io/tutorial/ -[tutorial-site]: https://esmvalgroup.github.io/tutorial -[tutorial-maintainers]: https://github.com/ESMValGroup/tutorial#maintainers +[tutorial-repo]: https://esmvalgroup.github.io/ESMValTool_Tutorial/ +[tutorial-site]: https://esmvalgroup.github.io/ESMValTool_Tutorial +[tutorial-maintainers]: https://github.com/ESMValGroup/ESMValTool_Tutorial#maintainers [github]: https://github.com -[issues]: https://github.com/ESMValGroup/tutorial/issues -[PR]: https://github.com/ESMValGroup/tutorial/pulls +[issues]: https://github.com/ESMValGroup/ESMValTool_Tutorial/issues +[PR]: https://github.com/ESMValGroup/ESMValTool_Tutorial/pulls [swc-site]: https://software-carpentry.org/ [swc-handbook]: https://carpentries.github.io/curriculum-development/ [swc-lesson-organization]: https://carpentries.github.io/lesson-example/03-organization/index.html [swc-lesson-formatting]: https://carpentries.github.io/lesson-example/04-formatting/index.html [ea-site]: https://github.com/escience-academy +[user-engagement]: https://github.com/orgs/ESMValGroup/teams/userengagementteam +[contact-info]: https://docs.esmvaltool.org/en/latest/community/contact.html From 23d972af18d22ea17f894c31e0ce77afa9bd503e Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 13:36:21 +0200 Subject: [PATCH 274/647] adapt episode 6 to changes in episode 3 --- _episodes/06-debugging.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index e1e6d788..6de1d3e3 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -27,12 +27,12 @@ directory ``esmvaltool_tutorial`` that was created during the [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}). In a new terminal, go to our working directory ``esmvaltool_tutorial`` where -both files ``user-config.yml`` and ``recipe_example.yml`` are located and run +the file ``recipe_example.yml`` is located and run the recipe: ~~~bash cd esmvaltool_tutorial - esmvaltool run --config_file user-config.yml recipe_example.yml + esmvaltool run recipe_example.yml ~~~ ~~~ @@ -202,7 +202,7 @@ Also, we change the ``projects`` value ``ukesm`` to ``tutorial``: Then, we save the file and run the recipe: ~~~bash - esmvaltool run --config_file user-config.yml recipe_example.yml + esmvaltool run recipe_example.yml ~~~ ~~~ @@ -216,10 +216,17 @@ attach the run/recipe_*.yml and run/main_log_debug.txt files from the output dir The values for the keys ``author``, ``maintainer``, ``projects`` and ``references`` in the recipe should be known by ESMValTool. A list of ESMValTool author, maintainer, references, and projects can be found in the -``config-references.yml`` that is located in the folder ``references`` in the -ESMValTool installation directory ``path_to_esmvaltool``. To find -``path_to_esmvaltool`` on your system, see [Installation]({{ page.root }}{% link -_episodes/02-installation.md %}). +``config-references.yml``. You could download this file by typing: + +~~~bash + esmvaltool config get_config_reference +~~~ + +It will be saved to: ``{HOME}/.esmvaltool/config-references.yml``. If you modify this file, please add the directory in the ``config-user.yml``: + +```yaml +config_developer_file: {HOME}/.esmvaltool/config_reference.yml +``` > ## ESMValTool can’t locate the data > @@ -282,7 +289,7 @@ let's see if we can change the script path as: ``` ~~~bash - esmvaltool run --config_file user-config.yml recipe_example.yml + esmvaltool run recipe_example.yml ~~~ ~~~ @@ -304,7 +311,7 @@ recipe: ``` ~~~bash - esmvaltool run --config_file user-config.yml recipe_example.yml + esmvaltool run recipe_example.yml ~~~ > ## Available recipe and diagnostic scripts From a6e7a095063527ee9a5b48c6aac6f8ba8a55e28b Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 13:57:54 +0200 Subject: [PATCH 275/647] add links to other episodes --- _episodes/04-recipe.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index b4d8db28..4d777c22 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -70,9 +70,9 @@ manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overvie ## How to run ESMValTool -Once you’ve set up your conda environment and installed ESMValTool (see episode -#2 LINK) and set up your `config-user.yml` file to correctly match your local -environment, (see episode #3 LINK), ESMValTool is invoked using a simple +Once you’ve set up your conda environment and installed ESMValTool (see[ episode +#2]({{ page.root}}{% link _episodes/02-installation.md %})) and set up your `config-user.yml` file to correctly match your local +environment, (see [episode #3]({{ page.root}}{% link _episodes/03-configuration.md %})), ESMValTool is invoked using a simple command: ~~~ @@ -177,7 +177,7 @@ Please note the following sections: preprocessing is needed, the preprocessor can be set to an empty python dictionary (`{}`). Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). - (See episode #5 LINK for more details.) + (See [episode #5]({{ page.root}}{% link _episodes/05-preprocessor.md %}) for more details.) - diagnostic section: lines 30-42 @@ -657,8 +657,8 @@ The snippets for the edits can be found below: > ## esmvaltool not found > Can you run the command “esmvaltool -h”. If no, then it’s possible that the -> conda environment isn’t activated. Please return to the installation section, -> episode #2 LINK. +> conda environment isn’t activated. Please return to the in +> [installation section]({{ page.root }}{% link _episodes/02-installation.md %}). {: .solution} > ## The error message is `esmvalcore._recipe_checks.RecipeError: Missing data` From 062b8e6a56163873b23f504842ad4ad41eb10657 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 13:58:23 +0200 Subject: [PATCH 276/647] remove email --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 494593c0..cb30f609 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,8 @@ A list of contributors to the lesson can be found in [AUTHORS](AUTHORS). ## Citation -To cite this Tutorial, please consult with [CITATION](CITATION). +To cite this tutorial, please consult with [CITATION](CITATION). -[email]: mailto:TODO_FIX_ME [ESMValTool-site]: https://www.esmvaltool.org/ [ESMValTool-doc]: https://esmvaltool.readthedocs.io/en/latest/ [tutorial-repo]: https://esmvalgroup.github.io/ESMValTool_Tutorial/ From 5bb844777caa2af2c850f6bb4b793c7165039d28 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 13:58:46 +0200 Subject: [PATCH 277/647] add a list of authors --- AUTHORS | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 04e1f5ab..3603b5f2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,52 @@ -FIXME: list authors' names and email addresses. \ No newline at end of file +name: Andela, Bouwe + institute: NLeSC, Netherlands + email: b.andela@esciencecenter.nl + orcid: https://orcid.org/0000-0001-9005-8940 + +name: de Mora, Lee + institute: PML, UK + email: ledm@pml.ac.uK + orcid: https://orcid.org/0000-0002-5080-3149 + +name: Drost, Niels + institute: NLeSC, Netherlands + email: n.drost@esciencecenter.nl + orcid: https://orcid.org/0000-0001-9795-7981 + +name: Mueller, Benjamin + institute: LMU, Germany + email: b.mueller@iggf.geo.uni-muenchen.de + orcid: + +name: Predoi, Valeriu + institute: URead, UK + email: valeriu.predoi@ncas.ac.uk + orcid: https://orcid.org/0000-0002-9729-6578 + +name: Alidoost, Sarah + institute: NLeSC, Netherlands + orcid: https://orcid.org/0000-0001-8407-6472 + +name: Bock, Lisa + institute: DLR, Germany + orcid: https://orcid.org/0000-0001-7058-5938 + +name: Camphuijsen, Jaro + institute: NLeSC, Netherlands + orcid: https://orcid.org/0000-0002-8928-7831 + +name: Hassler, Birgit + institute: DLR, Germany + orcid: https://orcid.org/0000-0003-2724-709X + +name: Kalverla, Peter + institute: NLeSC, Netherlands + orcid: https://orcid.org/0000-0002-5025-7862 + +name: Swaminathan, Ranjini + institute: University of Reading, UK + orcid: https://orcid.org/0000-0001-5853-2673 + +name: Verhoeven, Stefan + institute: NLeSC, Netherlands + orcid: https://orcid.org/0000-0002-5821-2060 From 9975c0ec062daf528277a6b6d384bc2775f2d52e Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 17 Jul 2020 13:07:00 +0100 Subject: [PATCH 278/647] updated guide for instructors --- _extras/guide.md | 59 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/_extras/guide.md b/_extras/guide.md index 3094ce9c..c84cb28e 100644 --- a/_extras/guide.md +++ b/_extras/guide.md @@ -3,20 +3,65 @@ title: "Instructor Notes" --- This page includes some tips, reminders and advice for giving this tutorial. +## Tutorial Content -## Preparing the meeting. +Well ahead of the planned tutorial date, please go over the available +tutorial material +in your own time at least once to note specifics such as areas where +your cohort may need extra time, any changes you want to make or +additional examples you would like to include. -Once you've agreed to a date, and attendees have signed up, send them a link to -the pre-tutorial instructions page (setup.md). +If you want to add to or adapt the material, you can create your own copy to +modify by forking the repository. See here for a guide on [how to fork a repository](https://docs.github.com/en/enterprise/2.13/user/articles/fork-a-repo). -Plan for the tutorial to last two hours. If you do go longer, please include a comfort break. +Please use our guide for [Contributing](CONTRIBUTING.md) when creating your +own material just in case you would like to add to the current +repository in the future. -Coffee and biscuits always goes down well with participants. +Once you are satisified with the material you would like to use and have +an estimate of the time required, please proceed with meeting logistics. + +## Meeting Logistics -Remember to email attendees in advacnce to set up conda and work through the set up page. +Decide if the tutorial will be held on site or online. If on site, make +sure of venue availability before finalizing the date. If online, set up connection details. + +Once you have agreed to a date, and attendees have signed up, send them an email +with the following information: + - a link to the [pre-tutorial instructions page](setup.md) + - a contact email address so they can post any questions that arise during setup + - Venue details (if on site) or meeting connection details (if online). + +Also allow for sufficient time to get access to any +accounts etc. which could take more than a few days in some cases (a good +thumb rule is to have the time to send a reminder email a few days after +the first email, +so that participants will still have time after the reminder to complete +setup). + +Plan for the tutorial to last at least two hours (this could vary based on +your choice of modules and any changes you have made to the tutorial). +If you do go longer, please include comfort breaks as needed. + +If more than one person will be conducting the tutorial, discuss ahead +and decide who will handle each component for a smooth flow of material. Remind people a few days before the meeting about the pre-meeting exercises. +If conducting the tutorial on site, confirm room bookings and check for +internet connectivity or firewall issues +at the venue. Coffee and biscuits also usually go down well with participants! + +If conducting the tutorial online, have a backup plan for failed or +poor internet connections. This could involve sending participants +some of the material or previously recorded meeting videos ahead of time. +Establish rules for questions, microphone and video usage before starting the +meeting. Send meeting connection details (Zoom/Teams etc.) ahead of time and +the day before the meeting. + +Have a feedback form ready if you would like attendees to send you feedback. +Request that they do so at the end of the tutorial and send it out as soon after +the tutorial as possible. ## Tips @@ -24,7 +69,7 @@ Remind people a few days before the meeting about the pre-meeting exercises. - Make sure you don't have issues with accessing the compute node via VPN or wifi, -- Check to copmputing service for any planned downtime or potential interuptnios. +- Check with your computing service for any planned downtime or potential interuptions. - Download a local copy of the data, just in case. From b2a6dc35679552c1ea8e4e372be221434700d078 Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 17 Jul 2020 13:44:31 +0100 Subject: [PATCH 279/647] updated guide for instructors with changes suggested by Lee after review --- _extras/guide.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/_extras/guide.md b/_extras/guide.md index c84cb28e..8ca6ce14 100644 --- a/_extras/guide.md +++ b/_extras/guide.md @@ -3,6 +3,7 @@ title: "Instructor Notes" --- This page includes some tips, reminders and advice for giving this tutorial. + ## Tutorial Content Well ahead of the planned tutorial date, please go over the available @@ -30,7 +31,7 @@ Once you have agreed to a date, and attendees have signed up, send them an email with the following information: - a link to the [pre-tutorial instructions page](setup.md) - a contact email address so they can post any questions that arise during setup - - Venue details (if on site) or meeting connection details (if online). + - venue details (if on site) or meeting connection details (if online). Also allow for sufficient time to get access to any accounts etc. which could take more than a few days in some cases (a good @@ -39,12 +40,13 @@ the first email, so that participants will still have time after the reminder to complete setup). -Plan for the tutorial to last at least two hours (this could vary based on +Prepare an estimate for how long the tutorial will last +(this could vary based on your choice of modules and any changes you have made to the tutorial). -If you do go longer, please include comfort breaks as needed. +Do include comfort breaks as needed. If more than one person will be conducting the tutorial, discuss ahead -and decide who will handle each component for a smooth flow of material. +and decide who will handle each component for a smooth flow of the material. Remind people a few days before the meeting about the pre-meeting exercises. @@ -67,9 +69,11 @@ the tutorial as possible. - Test all recipes, diagnostics and instructions in advance. -- Make sure you don't have issues with accessing the compute node via VPN or wifi, +- Make sure you don't have issues with accessing the compute node via VPN +or Wi-Fi. -- Check with your computing service for any planned downtime or potential interuptions. +- Check with your computing service for any planned downtime or potential +interuptions. - Download a local copy of the data, just in case. From 2864673767b5292b2fbc016ab723491fe4f59557 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 14:55:03 +0200 Subject: [PATCH 280/647] add link to example recipe --- _episodes/04-recipe.md | 2 +- _episodes/05-preprocessor.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 9ba98834..2f63b55a 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -87,7 +87,7 @@ The recipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. Please download the following recipe into your ESMValTool working directory with -the name: recipe_example.yml LINK +the name: [recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) > ## recipe_example.yml > ```YAML diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 6d416c72..94809d1b 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -88,7 +88,7 @@ file afterwards. These do not need to be explicitly included in recipes. > ## Exercise: Adding more preprocessor steps > -> Edit the [example recipe](LINK to episode #4) to first change the variable +> Edit the [example recipe](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) to first change the variable > thetao, then add preprocessors to average over the latitude and longitude > dimensions and finally average over the depth. Now run the recipe. > From 3908b97758486917062fdb894621e9e6d75b362c Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 17 Jul 2020 14:45:36 +0100 Subject: [PATCH 281/647] changes to teaching time --- _episodes/01-introduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 833eecc2..0e9e4867 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -1,7 +1,7 @@ --- title: "Introduction" -teaching: 0 -exercises: 25 +teaching: 20 +exercises: 10 questions: - What is ESMValTool and when is it useful? - What are the main components of ESMValTool? From 00ac2817c9c99d6b8ea42591127d1c1c41b8f373 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 15:49:58 +0200 Subject: [PATCH 282/647] add esmvaltool license --- LICENSE | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++ LICENSE.md | 83 ---------------------- 2 files changed, 202 insertions(+), 83 deletions(-) create mode 100644 LICENSE delete mode 100644 LICENSE.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index e6a3398d..00000000 --- a/LICENSE.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -layout: page -title: "Licenses" -root: . ---- -## Instructional Material - -All Software Carpentry, Data Carpentry, and Library Carpentry instructional material is -made available under the [Creative Commons Attribution -license][cc-by-human]. The following is a human-readable summary of -(and not a substitute for) the [full legal text of the CC BY 4.0 -license][cc-by-legal]. - -You are free: - -* to **Share**---copy and redistribute the material in any medium or format -* to **Adapt**---remix, transform, and build upon the material - -for any purpose, even commercially. - -The licensor cannot revoke these freedoms as long as you follow the -license terms. - -Under the following terms: - -* **Attribution**---You must give appropriate credit (mentioning that - your work is derived from work that is Copyright © Software - Carpentry and, where practical, linking to - http://software-carpentry.org/), provide a [link to the - license][cc-by-human], and indicate if changes were made. You may do - so in any reasonable manner, but not in any way that suggests the - licensor endorses you or your use. - -**No additional restrictions**---You may not apply legal terms or -technological measures that legally restrict others from doing -anything the license permits. With the understanding that: - -Notices: - -* You do not have to comply with the license for elements of the - material in the public domain or where your use is permitted by an - applicable exception or limitation. -* No warranties are given. The license may not give you all of the - permissions necessary for your intended use. For example, other - rights such as publicity, privacy, or moral rights may limit how you - use the material. - -## Software - -Except where otherwise noted, the example programs and other software -provided by Software Carpentry and Data Carpentry are made available under the -[OSI][osi]-approved -[MIT license][mit-license]. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -## Trademark - -"Software Carpentry" and "Data Carpentry" and their respective logos -are registered trademarks of [Community Initiatives][CI]. - -[cc-by-human]: https://creativecommons.org/licenses/by/4.0/ -[cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode -[mit-license]: https://opensource.org/licenses/mit-license.html -[ci]: http://communityin.org/ -[osi]: https://opensource.org From cfe71f2b99b9c9917a9c28785381feddd754b064 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Fri, 17 Jul 2020 15:53:03 +0200 Subject: [PATCH 283/647] fix bug --- _episodes/03-configuration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index e5a6fb51..a23221de 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -223,9 +223,9 @@ drs: > ## Make your own configuration file > > It is possible to have several configuration files with different purposes, -> for example: config-user_formalised_runs.yml, config-user_debugging.yml {: -> .callout} -> +> for example: config-user_formalised_runs.yml, config-user_debugging.yml +{: .callout} + > ## Saving preprocessed data > > In the configuration file, which settings are useful to make sure preprocessed From 6c57ac0292778d83cf8e9a9e8b8c48c9d56e5000 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 15:54:16 +0200 Subject: [PATCH 284/647] add citations --- CITATION | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/CITATION b/CITATION index 56ece3c4..947ff8fa 100644 --- a/CITATION +++ b/CITATION @@ -1 +1,15 @@ -FIXME: describe how to cite this lesson. \ No newline at end of file +Please cite this tutorial as: + +- ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], + [https://github.com/ESMValGroup/ESMValTool_tutorial](https://github.com/ESMValGroup/ESMValTool_tutorial), + [DATE]. + +and cite ESMValTool as: + +- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., + Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, + K., and Zechlau, S.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – + diagnostics for emergent constraints and future projections from Earth + system models in CMIP, Geosci. Model Dev. Discuss., + [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), + in review, 2020. From 4673d44f4d6f08853a89bd9dec65410f8f4a089a Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 17 Jul 2020 14:59:54 +0100 Subject: [PATCH 285/647] added teaching times --- _episodes/03-configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index a504109e..32ca21d1 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -1,7 +1,7 @@ --- title: "Configuration" -teaching: 0 -exercises: 0 +teaching: 10 +exercises: 10 questions: - What is the user configuration file and how should I use it? From a8ba361fb85402243083d56cafb1c0c213006a5f Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 17 Jul 2020 15:09:54 +0100 Subject: [PATCH 286/647] changed teaching and ex times --- _episodes/04-recipe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 0090c61e..b3dbf49b 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -1,7 +1,7 @@ --- title: "Running a recipe (First example)" -teaching: 20 -exercises: 25 +teaching: 25 +exercises: 30 questions: - "What is a recipe?" - "How can I do the same preprocessing on many different datasets?" From cd00762017e5d6b3671b27e82f7d31e2da2d99ab Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 17 Jul 2020 15:17:13 +0100 Subject: [PATCH 287/647] changed teaching times --- _episodes/05-preprocessor.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 6d416c72..04a41d25 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -1,7 +1,7 @@ --- title: "Working with preprocessors" -teaching: 20 -exercises: 20 +teaching: 15 +exercises: 45 questions: - "How do I set up a preprocessor?" - "Can I use different preprocessors for different variables?" From 78d8a790c57baa7a69c5f496ebe16fa4234bf074 Mon Sep 17 00:00:00 2001 From: Lee de Mora Date: Fri, 17 Jul 2020 15:19:52 +0100 Subject: [PATCH 288/647] minor edits --- setup.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/setup.md b/setup.md index 7ff1a293..48e23b92 100644 --- a/setup.md +++ b/setup.md @@ -6,7 +6,7 @@ This page includes some information on how to prepare for participating in this > ## Prerequisites > -> The prerequisites for the tutorial are listed on the +> The prerequisites for the tutorial are listed on the > [tutorials home page]({{ page.root}}[% index.md %}) > and are also reproduced here: > @@ -74,7 +74,6 @@ If neccesairy, data can be downloaded using the [synda tool](https://prodiguer.github.io/synda/index.html). - ### CEDA-Jasmin Please skip this section if you are not going to use JASMIN and go [here](#Github-account-(Advanced)). @@ -149,7 +148,6 @@ research centres). You may need a VPN if you wish to connect from your home network. - Please request access to the working groups: - [esmeval working group](https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval) @@ -165,6 +163,7 @@ access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC are not accessible by default and special permission has to be requested to access them via [the CEDA catalogue page](https://catalogue.ceda.ac.uk/). + #### Test your Setup Log into jasmin-login: @@ -193,13 +192,13 @@ Note that the JASMIN is only open to certain locations (mostly universities, and research centres). You may need a VPN if you wish to connect from your home network. - -Congratulations! Please go here [here](#GitHub-account-(Advanced)) next. - +Congratulations! Please go here [here](#gitHub-account-(advanced)) next. ### DKRZ +Please skip this section if you are not going to use DKRZ and go [here](#github-account-(advanced)). + If you do not already have an account at the DKRZ, then [register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could find a short introduction on how to get started at DKRZ @@ -246,7 +245,7 @@ ssh -X @mistralpp.dkrz.de Data storage: - Personal data: home directory (24GiB) - Project data: /work// -- Temporary data: scratch directory on /scratch/*/ is +- Temporary data: scratch directory on /scratch/\*/ is automatically deleted after 14 days (15TiB) (Please use this directory for all your testing! Do not use the work directory for tests.) (see also [this](https://www.dkrz.de/up/systems/mistral/hpc-concepts)) @@ -258,12 +257,15 @@ be found [here](https://www.dkrz.de/up/systems/mistral/running-job). Congratulations! Please go here [here](#GitHub-account-(Advanced)) next. -### Other computing systems -FIXME + + ### Your local machine -Please skip this section if you are not going to use ESMValTool on your local machine and go [here](#GitHub-account-(Advanced)). +Please skip this section if you are not going to use ESMValTool on your +local machine and go [here](#gitHub-account-(advanced)). If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space @@ -277,8 +279,14 @@ You will also need to able to use: #### Linux/unix +ESMValTool is easilly installable in Linux/unix, please follow +the installation instructions in epiode 2. + #### Mac OSx +Installing ESMValTool in a Mac OSx environment is possible, but not +directly supported. + #### Windows ESMValTool does not directly support Windows, @@ -287,7 +295,6 @@ but successful usage has been reported through the available in Windows 10. - ## GitHub account (Advanced) You don’t need a github account to participate in the tutorial. However, if you @@ -314,7 +321,7 @@ an issue, please follow any instructions that you are given, and also make sure that you read the default issue text. -### pull request +### GitHub pull requests A GitHub pull request is the act of requesting that a branch is merged with another branch. @@ -322,7 +329,6 @@ This is an advanced feature of GitHub, and will generally be performed by the ESMValTool development team. - ## Install conda The python package manager Conda (anaconda or miniconda) needs to be installed From e17b11cd3b2e2240de8b79091254fc0087f75832 Mon Sep 17 00:00:00 2001 From: Jaro Camphuijsen Date: Fri, 17 Jul 2020 16:58:35 +0200 Subject: [PATCH 289/647] Apply suggestions from code review Add some minor changes --- _episodes/02-installation.md | 2 +- _episodes/03-configuration.md | 6 ++++-- _episodes/04-recipe.md | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 4b250883..d6a34e66 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -249,7 +249,7 @@ to display the command line help. > > {: .bash} > > I get that my installed ESMValTool version is > > ~~~ -> > 2.0.0 +> > ESMValCore: 2.0.0 > > ~~~ > > {: .output} > {: .solution} diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index a23221de..1fbd7bb3 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -23,7 +23,9 @@ The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. This is an [YAML file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be found in the ESMValCore repository: -[config-user-example.yml](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-user.yml). You could download it by typing: +[config-user-example.yml](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-user.yml). + +You can generate the default configuration file by running: ~~~bash esmvaltool config get_config_user @@ -97,7 +99,7 @@ profile_diagnostic: false ## Destination directory -The destination directory is the rootpath where ESMValTool will store its output, +The destination directory is the rootpath where ESMValTool will store its output folders containing i.e. figures, data, logs, etc. With every run, ESMValTool automatically generates a new output folder determined by recipe name, and date and time using the format: YYYYMMDD_HHMMSS. diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 6a7443fb..650455bf 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -101,7 +101,7 @@ the name: recipe_example.yml LINK > 1 # ESMValTool > 2 # recipe_example.yml > 3 --- -> 4 documentation +> 4 documentation: > 5 description: Demonstrate basic ESMValTool example > 6 > 7 authors: From 8aa1adb23c78c08f059b6950b47e97114553ac32 Mon Sep 17 00:00:00 2001 From: Jaro Camphuijsen Date: Fri, 17 Jul 2020 17:11:59 +0200 Subject: [PATCH 290/647] Rename LICENSE to LICENSE.md --- LICENSE => LICENSE.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LICENSE => LICENSE.md (100%) diff --git a/LICENSE b/LICENSE.md similarity index 100% rename from LICENSE rename to LICENSE.md From 7e93854b1759684198f7f775d7ec602411983a4d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 17 Jul 2020 17:43:08 +0200 Subject: [PATCH 291/647] remove one empty episode, rename two episodes --- _episodes/{conclusions.md => 07-conclusions.md} | 0 _episodes/07-contributing-to-esmvaltool.md | 15 --------------- ...velopment-setup.md => 08-development-setup.md} | 0 3 files changed, 15 deletions(-) rename _episodes/{conclusions.md => 07-conclusions.md} (100%) delete mode 100644 _episodes/07-contributing-to-esmvaltool.md rename _episodes/{10-development-setup.md => 08-development-setup.md} (100%) diff --git a/_episodes/conclusions.md b/_episodes/07-conclusions.md similarity index 100% rename from _episodes/conclusions.md rename to _episodes/07-conclusions.md diff --git a/_episodes/07-contributing-to-esmvaltool.md b/_episodes/07-contributing-to-esmvaltool.md deleted file mode 100644 index 7dce2d5a..00000000 --- a/_episodes/07-contributing-to-esmvaltool.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: "Contributing to ESMValTool" -teaching: 0 -exercises: 0 -questions: -- "Key question (FIXME)" -objectives: -- "First learning objective. (FIXME)" -keypoints: -- "First key point. Brief Answer to questions. (FIXME)" ---- -FIXME - -{% include links.md %} - diff --git a/_episodes/10-development-setup.md b/_episodes/08-development-setup.md similarity index 100% rename from _episodes/10-development-setup.md rename to _episodes/08-development-setup.md From ba466bf5e5ce3f480d01c8b0c0c91ec7df9740c1 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 10:54:57 +0200 Subject: [PATCH 292/647] Fix typo Fixes #84 --- _episodes/02-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index d6a34e66..812ccb33 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -7,7 +7,7 @@ questions: - "How do I confirm that the installation was successful?" objectives: - "Install ESMValTool" -- "Demonstate that the installation was successful" +- "Demonstrate that the installation was successful" keypoints: - "All the required packages can be installed using conda" - "You can find more information about installation in the documentation" From e21b7f1b1c674dded14ffb303e62f9e53e77029f Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 10:57:55 +0200 Subject: [PATCH 293/647] Update `esmvaltool version` description and output Fixes #92 --- _episodes/02-installation.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 812ccb33..40c9785f 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -239,8 +239,8 @@ to display the command line help. > > > ## Solution > > -> > The `esmvaltool --help` command lists `-v` or `--version` as optional -> > argument to get the version +> > The `esmvaltool --help` command lists `version` as a +> > command to get the version > > > > In my case when I run > > ~~~ @@ -250,6 +250,7 @@ to display the command line help. > > I get that my installed ESMValTool version is > > ~~~ > > ESMValCore: 2.0.0 +> > ESMValTool: 2.0.0 > > ~~~ > > {: .output} > {: .solution} From deb72a01d1674b212a7c5d549dd11694ba359198 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 11:22:00 +0200 Subject: [PATCH 294/647] Use nano in installation episode Refs #77 --- _episodes/02-installation.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 40c9785f..6d9378de 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -145,7 +145,13 @@ tar -xvzf julia-1.0.5-linux-x86\_64.tar.gz This will extract the files to a directory named `~/julia/julia-1.0.5`. To run Julia, you need to add the full path of Julia's `bin` folder to PATH environment variable. To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. -Open the file in your favorite editor and add a new line as follows at the +Open the file in a text editor called Nano: + +```bash +nano ~/.bashrc +``` + +and add a new line as follows at the bottom of the file: ```bash @@ -182,6 +188,16 @@ julia to start the interactive Julia interpreter. Press `Ctrl+D` to exit. +> ## Text editor side note +> +> No matter what editor you use, you will need to know where it searches +> for and saves files. If you start it from the shell, it will (probably) +> use your current working directory as its default location. We use ``nano`` +> in examples here because it is one of the least complex text editors. +> Press ctrl + O to save the file, +> and then ctrl + X to exit ``nano``. +{: .callout} + ## Install the ESMValTool package To install the ESMValTool package, run From c6f961c6d5d7a4d453247fc7686270b09743fee3 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 11:48:22 +0200 Subject: [PATCH 295/647] Use nano to look at recipy Also added shortcut for line numbers to help section description --- _episodes/04-recipe.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index a8ff0de3..93c3daab 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -146,10 +146,21 @@ the name: [recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutoria > ## Explore the recipe > Use the following command and investigate the sample recipe. > ~~~bash -> vim recipe_example.yml +> nano recipe_example.yml > ~~~ {: .challenge} +> ## Text editor side note +> +> No matter what editor you use, you will need to know where it searches +> for and saves files. If you start it from the shell, it will (probably) +> use your current working directory as its default location. We use ``nano`` +> in examples here because it is one of the least complex text editors. +> Press ctrl + O to save the file, +> and then ctrl + X to exit ``nano``. +> The line numbers can be shown by pressing alt + shift + 3. +{: .callout} + Please note the following sections: - documentation: lines 4-20 From f60d93407435153a0cf1fa52501a413ce85d63ed Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 11:55:15 +0200 Subject: [PATCH 296/647] Qoute nano same as other episodes --- _episodes/02-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 6d9378de..29b73584 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -145,7 +145,7 @@ tar -xvzf julia-1.0.5-linux-x86\_64.tar.gz This will extract the files to a directory named `~/julia/julia-1.0.5`. To run Julia, you need to add the full path of Julia's `bin` folder to PATH environment variable. To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. -Open the file in a text editor called Nano: +Open the file in a text editor called ``nano``: ```bash nano ~/.bashrc From ab3f74a36711ae35ce78a3abb299910da3eddd63 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 11:55:46 +0200 Subject: [PATCH 297/647] Qoute nano same as other episodes --- _episodes/03-configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 113629cf..77b86319 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -34,7 +34,7 @@ You can generate the default configuration file by running: It will save the file to: ``{HOME}/.esmvaltool/config-user.yml``. Now, let's change our working directory in a terminal window to -``{HOME}/.esmvaltool``. Then, we run a text editor called Nano to have a look +``{HOME}/.esmvaltool``. Then, we run a text editor called ``nano`` to have a look inside the configuration file: ~~~bash From f156a26bd1d3d261b1378782f939762d35c66fb7 Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 31 Jul 2020 12:16:25 +0200 Subject: [PATCH 298/647] Fix links and clarify --- _episodes/03-configuration.md | 39 +++++++++++++++------------ _episodes/04-recipe.md | 50 ++++++++++++++++++++++++----------- _episodes/06-debugging.md | 4 +-- 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 113629cf..eeca53a0 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -31,14 +31,15 @@ You can generate the default configuration file by running: esmvaltool config get_config_user ~~~ -It will save the file to: ``{HOME}/.esmvaltool/config-user.yml``. +It will save the file to: `~/.esmvaltool/config-user.yml`, where `~` is the +path to your home directory. Note that files and directories starting with a +period are "hidden", to see the `.esmvaltool` directory in the terminal use +`ls -la ~`. -Now, let's change our working directory in a terminal window to -``{HOME}/.esmvaltool``. Then, we run a text editor called Nano to have a look -inside the configuration file: +We run a text editor called Nano to have a look inside the configuration file: ~~~bash - nano config-user.yml + nano ~/.esmvaltool/config-user.yml ~~~ This file contains the information for: @@ -91,12 +92,14 @@ remove_preproc_dir: true # Path to custom config-developer file, to customise project configurations. # See config-developer.yml for an example. Set to [null] to use the default - config_developer_file: null +config_developer_file: null # Get profiling information for diagnostics # Only available for Python diagnostics profile_diagnostic: false ``` +In general there is no need to change the settings listed above. + ## Destination directory The destination directory is the rootpath where ESMValTool will store its output folders containing @@ -169,7 +172,7 @@ for input data based on their source. The current categories in the configuratio file are mentioned below. For example, CMIP is used for a dataset from the climate model intercomparison project whereas OBS is used for an observational dataset. We can find more information about the projects in the ESMValTool -[documentation](https://docs.esmvaltool.org/en/latest/input.html). +[documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html). The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. @@ -181,7 +184,7 @@ rootpath: default: ~/default_inputpath CORDEX: ~/default_inputpath ``` -Site-specific entries for Jasmin, DKRZ and ETHZ are listed at the end of the example configuration file. +Site-specific entries for Jasmin, DKRZ and ETHZ are listed at the end of the example configuration file. In this lesson, we will work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). @@ -195,10 +198,10 @@ We add the root path of the folder where our/your data is available. > ## Setting the correct rootpath > -> - To get the data (or its correct rootpath), check instruction in [Setup]({{ -> page.root }}{% link setup.md %}). +> - To get the data (or its correct rootpath), check instruction in +> [Setup]({{ page.root }}{% link setup.md %}). > - For more information about setting the rootpath, see also the ESMValTool -> [documentation](https://esmvaltool.readthedocs.io/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). +> [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). {: .callout} ## Directory structure for the data from different projects @@ -225,7 +228,7 @@ drs: > ## Make your own configuration file > > It is possible to have several configuration files with different purposes, -> for example: config-user_formalised_runs.yml, config-user_debugging.yml +> for example: config-user_formalised_runs.yml, config-user_debugging.yml {: .callout} > ## Saving preprocessed data @@ -235,11 +238,13 @@ drs: > >> ## Solution >> -> > If the option ``save_intermediary_cubes`` is set to true in the -> > config-user.yml file, then the intermediary cubes will also be saved in the -> > folder ``preproc``. Also, if the option ``remove_preproc_dir`` is set to -> > ``false``, then the ``preproc/`` directory contains all the preprocessed -> > data and the metadata interface files. +> > If the option ``remove_preproc_dir`` is set to ``false``, then the +> > ``preproc/`` directory contains all the pre-processed data and the +> > metadata interface files. +> > If the option ``save_intermediary_cubes`` is set to ``true`` +> > then data will also be saved after each preprocessor step in the folder +> > ``preproc``. Note that saving all intermediate results to file will result +> > in a considerable slowdown. > {: .solution} {: .challenge} diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index a8ff0de3..8e1630c8 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -70,20 +70,31 @@ manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overvie ## How to run ESMValTool -Once you’ve set up your conda environment and installed ESMValTool (see[ episode -#2]({{ page.root}}{% link _episodes/02-installation.md %})) and set up your `config-user.yml` file to correctly match your local -environment, (see [episode #3]({{ page.root}}{% link _episodes/03-configuration.md %})), ESMValTool is invoked using a simple -command: - -~~~ -esmvaltool run recipe +Once you’ve set up your conda environment and installed ESMValTool (see +[episode #2]({{ page.root}}{% link _episodes/02-installation.md %}) +) and set up your `config-user.yml` file to correctly match your local +environment, (see +[episode #3]({{ page.root}}{% link _episodes/03-configuration.md %}) +), ESMValTool is invoked using the command: + +~~~bash +esmvaltool run /path/to/recipe_example.yml ~~~ {: .source} -If the configuration file is not in the default {HOME}\.esmvaltool\ path you can pass its path explicitly: +If the configuration file is not in the default location +`~/.esmvaltool/config-user.yml`, you can pass its path explicitly: +~~~bash +esmvaltool run --config_file /path/to/config-user.yml /path/to/recipe_example.yml ~~~ -esmvaltool run --config_file configuration recipe +{: .source} + +Note that the path to the recipe can be either a path to a recipe file or it can +be the name of an installed recipe. +To view the list of installed recipes, run +~~~bash +esmvaltool recipes list ~~~ {: .source} @@ -93,8 +104,13 @@ To try your hand with a basic recipe, please work through this episode. The recipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. -Please download the following recipe into your ESMValTool working directory with -the name: [recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) +Please download [recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) +into your ESMValTool working directory: + +~~~bash +wget https://raw.githubusercontent.com/ESMValGroup/ESMValTool_Tutorial/master/data/recipe_example.yml +~~~ +{: .source} > ## recipe_example.yml > ```YAML @@ -153,7 +169,7 @@ the name: [recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutoria Please note the following sections: - documentation: lines 4-20 - + The documentation consists of the following information: - description: a short description of the recipe @@ -204,8 +220,11 @@ Please note the following sections: - scripts: a definition of all scripts that are used in this diagnostic - the next indent (here: timeseries_diag) is the scripts’ names (a string without whitespace) for the script to use - - script: a executable script with a directory relative to the - `esmvaltool/diag_scripts/` directory + - script: a script that will produce the plots. The path can be either + relative the ESMValTool installation with subdirectory + [`esmvaltool/diag_scripts/`](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/diag_scripts) + or an absolute path. In this case, it is a diagnostic script that is + installed with ESMValTool. > ## Please answer the following questions: > What is the short_name of the variable being analyzed? @@ -222,7 +241,8 @@ Please note the following sections: {: .solution} > ## What is the diagnostic script being used? -> `ocean/diagnostic_timeseries.py` +> The installed copy of +> [`ocean/diagnostic_timeseries.py`](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py) {: .solution} > ## How many years of data are being analyzed? diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 6de1d3e3..59122c4e 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -50,8 +50,8 @@ conda activate esmvaltool > ## conda environment > -> More information about conda environment can be found at [Installation]({{ -> page.root }}{% link _episodes/02-installation.md %}) +> More information about the conda environment can be found at +> [Installation]({{ page.root }}{% link _episodes/02-installation.md %}). {: .callout} Let's change the working directory to the folder ``run`` and list its files: From 92f5a1a743b96bc84a1e5275a44460323d66fc07 Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Fri, 31 Jul 2020 12:33:57 +0200 Subject: [PATCH 299/647] Fix some linter errors --- _episodes/03-configuration.md | 9 +++++---- _episodes/04-recipe.md | 31 ++++++++++++++++--------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index eeca53a0..35849f35 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -20,9 +20,9 @@ keypoints: ## The configuration file The ``config-user.yml`` configuration file contains all the global level -information needed by ESMValTool to run. This is an [YAML -file](https://yaml.org/spec/1.2/spec.html). An example configuration file can be -found in the ESMValCore repository: +information needed by ESMValTool to run. +This is a [YAML file](https://yaml.org/spec/1.2/spec.html). +An example configuration file can be found in the ESMValCore repository: [config-user-example.yml](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-user.yml). You can generate the default configuration file by running: @@ -184,7 +184,8 @@ rootpath: default: ~/default_inputpath CORDEX: ~/default_inputpath ``` -Site-specific entries for Jasmin, DKRZ and ETHZ are listed at the end of the example configuration file. +Site-specific entries for Jasmin, DKRZ and ETHZ are listed at the end of the +example configuration file. In this lesson, we will work with data from [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 8e1630c8..ac0bf0b6 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -64,9 +64,9 @@ diagnostics and description. The information you provide in the recipe is not only affecting the processes you are starting, but also the directory names your output will be structured -in. For additional reads, please have a look at the recipe format description in -the [ESMValTool -manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). +in. +For additional reads, please have a look at the recipe format description in the +[ESMValTool manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). ## How to run ESMValTool @@ -80,7 +80,6 @@ environment, (see ~~~bash esmvaltool run /path/to/recipe_example.yml ~~~ -{: .source} If the configuration file is not in the default location `~/.esmvaltool/config-user.yml`, you can pass its path explicitly: @@ -88,7 +87,6 @@ If the configuration file is not in the default location ~~~bash esmvaltool run --config_file /path/to/config-user.yml /path/to/recipe_example.yml ~~~ -{: .source} Note that the path to the recipe can be either a path to a recipe file or it can be the name of an installed recipe. @@ -96,7 +94,6 @@ To view the list of installed recipes, run ~~~bash esmvaltool recipes list ~~~ -{: .source} To try your hand with a basic recipe, please work through this episode. @@ -104,13 +101,13 @@ To try your hand with a basic recipe, please work through this episode. The recipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. -Please download [recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) +Please download +[recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) into your ESMValTool working directory: ~~~bash wget https://raw.githubusercontent.com/ESMValGroup/ESMValTool_Tutorial/master/data/recipe_example.yml ~~~ -{: .source} > ## recipe_example.yml > ```YAML @@ -174,9 +171,12 @@ Please note the following sections: - description: a short description of the recipe - authors: a list of authors (linked to `esmvaltool/config-references.yml`) - - maintainer: a list of maintainers (linked to `esmvaltool/config-references.yml`) - - references: a list of references (linked to a bibtexfile in `esmvaltool/references` with the same name) - - projects: a list of projects (linked to `esmvaltool/config-references.yml`) + - maintainer: a list of maintainers (linked to + `esmvaltool/config-references.yml`) + - references: a list of references (linked to a bibtexfile in + `esmvaltool/references` with the same name) + - projects: a list of projects (linked to + `esmvaltool/config-references.yml`) - datasets: lines 22-23 @@ -196,11 +196,12 @@ Please note the following sections: - preprocessors: lines 25-28 - The definition for different preprocessors or preprocessor combinations. If no - preprocessing is needed, the preprocessor can be set to an empty python - dictionary (`{}`). Here, we produce annual means. The preprocessor is called + The definition for different preprocessors or preprocessor combinations. + If no preprocessing is needed, the preprocessor can be set to an empty + map (`{}`). Here, we produce annual means. The preprocessor is called with its name (here: prep_timeseries), later in the diagnostic (line 39). - (See [episode #5]({{ page.root}}{% link _episodes/05-preprocessor.md %}) for more details.) + (See [episode #5]({{ page.root}}{% link _episodes/05-preprocessor.md %}) + for more details.) - diagnostic section: lines 30-42 From 75058a8f3e5a61b150232d62eb6037ddb522af6d Mon Sep 17 00:00:00 2001 From: lopeztarifa Date: Fri, 31 Jul 2020 13:31:23 +0200 Subject: [PATCH 300/647] Fix setup.md issues #80 . --- setup.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/setup.md b/setup.md index 3056c119..343bee11 100644 --- a/setup.md +++ b/setup.md @@ -71,7 +71,7 @@ If you're running on a computing cluster without an ESGF node, such as your local machine, or your institue machine, you will most likely have to make a local copy of the data that you need. -If neccesairy, data can be downloaded using the +If necessary, data can be downloaded using the [synda tool](https://prodiguer.github.io/synda/index.html). @@ -249,14 +249,11 @@ Running batch jobs: Info and examples on SLURM job scheduling system at DKRZ can be found [here](https://www.dkrz.de/up/systems/mistral/running-job). -### Other computing systems -FIXME - -### Your own machine +### Using your own machine If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space -available to install conda & ESMVAlTool, but also enough to make a copy of some +available to install conda & ESMValTool, but also enough to make a copy of some data. You will also need to able to use: @@ -264,10 +261,16 @@ You will also need to able to use: - conda - synda -#### Linux/unix +#### Linux/Unix + +For Linux/Unix systems, follow the instructions of the [Installation episode]({{ +page.root}}{% link _episodes/02-installation.md %}). #### Mac OSx +Also, for Mac OSx systems, follow the instructions of the [Installation episode]({{ +page.root}}{% link _episodes/02-installation.md %}). + #### Windows ESMValTool does not directly support Windows, @@ -319,8 +322,9 @@ on your system before the tutorial starts. In some cases, your system may have a central version installed already. More details on this process are available in the [Installation episode]({{ -page.root}}[% link _episodes/02-installation.md %}). +page.root}}{% link _episodes/02-installation.md %}). {% include links.md %} + From 57c74ae626df3c7b0cb71478a418e3b4501d0f9a Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 14:05:27 +0200 Subject: [PATCH 301/647] Update _episodes/04-recipe.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 75264e2d..51a4a9ef 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -157,7 +157,7 @@ wget https://raw.githubusercontent.com/ESMValGroup/ESMValTool_Tutorial/master/da {: .solution} > ## Explore the recipe -> Use the following command and investigate the sample recipe. +> We use the text editor ``nano`` to investigate the sample recipe. > ~~~bash > nano recipe_example.yml > ~~~ From 254594f38fe3c0fca4226e99e361eb6776e4398b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 31 Jul 2020 15:07:02 +0200 Subject: [PATCH 302/647] move Prerequisites from index to serup, remove conda Prerequisites from setup --- index.md | 15 ++------------- setup.md | 6 ------ 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/index.md b/index.md index 6c12896a..0ef8bff0 100644 --- a/index.md +++ b/index.md @@ -35,19 +35,8 @@ independently. > ## Prerequisites > -> *Minimal requirements:* -> -> - Basic understanding of your preferred command line interface (ie a bash -> terminal) -> - Laptop/desktop with -> [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed -> - Access to CMIP data -> -> *Optional, but useful:* -> -> - Basic understanding of git -> - Access to a suitable computing system (eg CEDA-Jasmin, DKRZ-Mistral) -> - GitHub account +> The prerequisites for the tutorial are listed on the +> [tutorial setup page]({{ page.root }}{% link setup.md %}). > {: .prereq} diff --git a/setup.md b/setup.md index 07b4d49d..3b2f5814 100644 --- a/setup.md +++ b/setup.md @@ -6,13 +6,8 @@ This page includes some information on how to prepare for participating in this > ## Prerequisites > -> The prerequisites for the tutorial are listed on the -> [tutorials home page]({{ page.root}}[% index.md %}) -> and are also reproduced here: -> > *Minimal requirements:* > - Basic understanding of your preferred command line interface (ie a bash terminal) -> - Laptop/desktop with [(mini)conda](https://docs.conda.io/en/latest/miniconda.html) installed > - Access to CMIP data > > *Optional, but useful:* @@ -60,7 +55,6 @@ Here are a few options for compute clusters with ESGF nodes: - [CEDA-Jasmin (UK)](#CEDA-Jasmin) - [DKRZ (Germany)](#DKRZ) -- ETHZ (Switzerland): A full list of all ESGF nodes is available [here](https://esgf.llnl.gov/nodes.html). From 866429c28a344f1201eabd207e522248cceb52d9 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 31 Jul 2020 15:15:57 +0200 Subject: [PATCH 303/647] fix minor things --- setup.md | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/setup.md b/setup.md index 3b2f5814..9bf86336 100644 --- a/setup.md +++ b/setup.md @@ -53,26 +53,23 @@ observational data would also be available at these sites. Here are a few options for compute clusters with ESGF nodes: -- [CEDA-Jasmin (UK)](#CEDA-Jasmin) -- [DKRZ (Germany)](#DKRZ) +- [CEDA-Jasmin (UK)](#ceda-jasmin) +- [DKRZ (Germany)](#dkrz) A full list of all ESGF nodes is available [here](https://esgf.llnl.gov/nodes.html). - If you're running on a computing cluster without an ESGF node, such as your -local machine, or your institue machine, you will most likely have to make a +local machine, or your institute machine, you will most likely have to make a local copy of the data that you need. If necessary, data can be downloaded using the [synda tool](https://prodiguer.github.io/synda/index.html). - ### CEDA-Jasmin Please skip this section if you are not going to use JASMIN and go [here](#Github-account-(Advanced)). - If you do not already have an account on JASMIN, then request an account as soon as possible. Please follow [these instructions on how to create a Jasmin account](https://help.jasmin.ac.uk/article/4435-get-a-jasmin-account-portal) @@ -95,7 +92,6 @@ Note that you have only created an account for the web-interface. To log into the jasmin machine and do work, you'll need to create a login account too using [this page](https://help.jasmin.ac.uk/article/161-get-login-account). - #### Access to data on JASMIN Please request access to the working groups: @@ -266,15 +262,13 @@ You will also need to able to use: #### Linux/Unix -For Linux/Unix systems, follow the instructions of the [Installation episode]({{ +For Linux/Unix systems, please follow the instructions of the [Installation episode]({{ page.root}}{% link _episodes/02-installation.md %}). -ESMValTool is easilly installable in Linux/unix, please follow -the installation instructions in epiode 2. #### Mac OSx -Also, for Mac OSx systems, follow the instructions of the [Installation episode]({{ +Also, for Mac OSx systems, please follow the instructions of the [Installation episode]({{ page.root}}{% link _episodes/02-installation.md %}). #### Windows From cfa8bb116ae366cdad2cccd479a2b4d946f28578 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 15:30:03 +0200 Subject: [PATCH 304/647] Started explaining how to download data file Refs #54 --- Makefile | 2 +- setup.md | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 7da810b4..087e5708 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ site : lesson-md docker-serve : docker run --rm -it --volume ${PWD}:/srv/jekyll \ --volume=${PWD}/.docker-vendor/bundle:/usr/local/bundle \ - -p 127.0.0.1:4000:4000 \ + -p 0.0.0.0:4000:4000 \ jekyll/jekyll:${JEKYLL_VERSION} \ bin/run-make-docker-serve.sh diff --git a/setup.md b/setup.md index 9bf86336..fcbeb2f7 100644 --- a/setup.md +++ b/setup.md @@ -255,17 +255,21 @@ that you are able to download CMIP data and that you have several GB of space available to install conda & ESMValTool, but also enough to make a copy of some data. +For this tutorial you can download the required data files by +1. Going to https://esgf-data.dkrz.de/projects/esgf-dkrz/ +2. Performing the following search + * +3. Download the NetCDF file to a ~/ + You will also need to able to use: - git - conda -- synda #### Linux/Unix For Linux/Unix systems, please follow the instructions of the [Installation episode]({{ page.root}}{% link _episodes/02-installation.md %}). - #### Mac OSx Also, for Mac OSx systems, please follow the instructions of the [Installation episode]({{ From a3ea827fe2899dd05eb559576ce93472771a1f0c Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Fri, 31 Jul 2020 16:01:57 +0200 Subject: [PATCH 305/647] Fix citation information, contact info and broken links in episode 07 (#93) * replace links to undeveloped episodes with those in the documentation * replace refrence with a link to citation, fix some links * remove citation information * update the references, add more papers * fix email address * fix how to cite sections * try to fix some linter errors * Update CITATION Co-authored-by: Bouwe Andela * Update _episodes/07-conclusions.md Co-authored-by: Bouwe Andela * Update _episodes/07-conclusions.md Co-authored-by: Bouwe Andela * Update _episodes/07-conclusions.md Co-authored-by: Bouwe Andela * Update _extras/about.md Co-authored-by: Bouwe Andela * Update index.md Co-authored-by: Bouwe Andela * Update index.md Co-authored-by: Bouwe Andela * replace additional resources with the link to esmvaltool reference list * fix mailing list info * fix broken links Co-authored-by: Bouwe Andela --- CITATION | 16 +++-- CONTRIBUTING.md | 9 +-- README.md | 4 +- _config.yml | 2 +- _episodes/01-introduction.md | 8 +-- _episodes/07-conclusions.md | 120 ++++++++++++----------------------- _extras/about.md | 25 ++------ index.md | 27 +++----- 8 files changed, 72 insertions(+), 139 deletions(-) diff --git a/CITATION b/CITATION index 947ff8fa..e67c89b1 100644 --- a/CITATION +++ b/CITATION @@ -6,10 +6,12 @@ Please cite this tutorial as: and cite ESMValTool as: -- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., - Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, - K., and Zechlau, S.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – - diagnostics for emergent constraints and future projections from Earth - system models in CMIP, Geosci. Model Dev. Discuss., - [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), - in review, 2020. +- Righi, M., Andela, B., Eyring, V., Lauer, A., Predoi, V., Schlund, M., + Vegas-Regidor, J., Bock, L., Brötz, B., de Mora, L., Diblen, F., Dreyer, L., + Drost, N., Earnshaw, P., Hassler, B., Koldunov, N., Little, B., Loosveldt Tomas, + S., and Zimmermann, K.: + Earth System Model Evaluation Tool (ESMValTool) v2.0 – technical overview, + Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020,2020. + +See additional resources at https://www.esmvaltool.org/references.html. + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 95005aa4..14fe2003 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,7 @@ by our [code of conduct](CODE_OF_CONDUCT.md). There are many ways to contribute: * If you do not have a [GitHub][github] account, you can send us comments by - [email][email]. However, we will be able to respond more quickly when you use + [email][contact-info]. However, we will be able to respond more quickly when you use one of the other methods described below. * If you have a [GitHub][github] account, work in this @@ -161,10 +161,8 @@ This address can be opened in your browser to preview the tutorial website. General discussion of the tutorial happens in ESMValTool [User Engagement Team][user-engagement]. -You can reach us by email. -Please see the [contact information][contact-info]. +Please see [information][contact-info] on how to subscribe to user mailing list. -[email]: mailto:TODO_FIX_ME [ESMValTool-site]: https://www.esmvaltool.org/ [ESMValTool-doc]: https://esmvaltool.readthedocs.io/en/latest/ [tutorial-repo]: https://esmvalgroup.github.io/ESMValTool_Tutorial/ @@ -177,6 +175,5 @@ Please see the [contact information][contact-info]. [swc-handbook]: https://carpentries.github.io/curriculum-development/ [swc-lesson-organization]: https://carpentries.github.io/lesson-example/03-organization/index.html [swc-lesson-formatting]: https://carpentries.github.io/lesson-example/04-formatting/index.html -[ea-site]: https://github.com/escience-academy [user-engagement]: https://github.com/orgs/ESMValGroup/teams/userengagementteam -[contact-info]: https://docs.esmvaltool.org/en/latest/community/contact.html +[contact-info]: https://docs.esmvaltool.org/en/latest/community/contact.html#user-mailing-list diff --git a/README.md b/README.md index cb30f609..50c844e8 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ difficulties along the way. If you work or study in climate-related domains and would be interested in getting involved, you can reach us by email. -Please see the [contact information][contact-info]. +Please see [information][contact-info] on how to subscribe to user mailing list. ## Authors @@ -43,4 +43,4 @@ To cite this tutorial, please consult with [CITATION](CITATION). [tutorial-repo]: https://esmvalgroup.github.io/ESMValTool_Tutorial/ [tutorial-site]: https://esmvalgroup.github.io/ESMValTool_Tutorial [user-engagement]: https://github.com/orgs/ESMValGroup/teams/userengagementteam -[contact-info]: https://docs.esmvaltool.org/en/latest/community/contact.html +[contact-info]: https://docs.esmvaltool.org/en/latest/community/contact.html#user-mailing-list diff --git a/_config.yml b/_config.yml index 0a530740..496c642f 100644 --- a/_config.yml +++ b/_config.yml @@ -31,7 +31,7 @@ kind: "lesson" repository: / # Email address, no mailto: -email: "team@carpentries.org" +email: "esmvaltool@listserv.dfn.de" # Sites. amy_site: "https://amy.carpentries.org/workshops" diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 0e9e4867..9d7a854c 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -86,11 +86,9 @@ let's start with a quick check to synchronize our expectations. > {: .solution} {: .challenge} -To learn more about ESMValTool, you can look at the -[documentation](https://docs.esmvaltool.org/en/latest/introduction.html), the -[official website](https://www.esmvaltool.org/about.html), or the [overview -paper](https://gmd.copernicus.org/articles/13/1179/2020/) in *Geoscientific -Model Development*. +To learn more about ESMValTool, you can look at the section +``Where can I get more information on ESMValTool?`` in the lesson +[Conclusion of the basic tutorial]({{ page.root }}{% link _episodes/07-conclusions.md %}). ## How does ESMValTool work diff --git a/_episodes/07-conclusions.md b/_episodes/07-conclusions.md index 56b4cea2..44ffc3bb 100644 --- a/_episodes/07-conclusions.md +++ b/_episodes/07-conclusions.md @@ -13,23 +13,35 @@ objectives: - "breathe - you're finished now!" - "Congratulations & Thanks!" - "Find out about the mini-tutorials, and what to do next." + +keypoints: +- "Individual mini-tutorials help work through a specific issue (not developed yet)." +- "We are constantly improving this tutorial." --- ## Congratulations! -Congratulations on completing the ESMValTool tutorial! You should be now ready to go and start using ESMValTool independently. - -The rest of this tutorial contains individual mini-tutorials to help work through a specific issue. +Congratulations on completing the ESMValTool tutorial! +You should be now ready to go and start using ESMValTool independently. +The rest of this tutorial contains individual mini-tutorials +to help work through a specific issue (not developed yet). ### What next? From here, there are lots of ways that you can continue to use ESMValTool. -- You can start from the list of existing recipes and run one of those. [LINK to ep 8] -- You can learn how to write your own diagnostics and recipes. [LINK to ep 9] -- You can contribute your recipe and diagnostics back into ESMValTool. [Link to ep 10] -- You can learn how to prepare observational datasets to be suitable for use by ESMValTool. [ Link to ep 11] +- You can start from the list of +[existing recipes](https://docs.esmvaltool.org/en/latest/recipes/index.html) +and run one of those. +- You can learn how to +[write your own diagnostics and recipes](https://docs.esmvaltool.org/en/latest/develop/index.html). +- You can +[contribute your recipe and diagnostics](https://docs.esmvaltool.org/en/latest/community/index.html) +back into ESMValTool. +- You can learn how to prepare +[observational datasets](https://docs.esmvaltool.org/en/latest/input.html#observations) +to be suitable for use by ESMValTool. > ## `Exercise: What do you want to do next?` > @@ -38,101 +50,47 @@ From here, there are lots of ways that you can continue to use ESMValTool. > - Is any observational data available? > - How will you preprocess the data? > - What will your diagnostic script need to do? -> - What will your final figure show? +> - What will your final figure show? {: .challenge} ### Where can I get more information on ESMValTool? -> ## Additional resources: -> - [Read the docs page](https://esmvaltool.readthedocs.io/) +> ## Additional resources: +> +> - [Documenation](https://docs.esmvaltool.org) > - [ESMValTool home page](https://www.esmvaltool.org/) -> - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) +> - [Papers](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION) > - [Source code (ESMValTool)](https://github.com/ESMValGroup/ESMValTool) > - [Source code (ESMValCore )](https://github.com/ESMValGroup/ESMValCore) {: .callout} -Additional publications: -- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., Lorenz, R., - Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, K., and Zechlau, S.: -Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics -for emergent constraints and future projections from Earth system models in CMIP, -Geosci. Model Dev. Discuss., -[https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), in review, 2020. - -- Eyring, V., Bock, L., Lauer, A., Righi, M., Schlund, M., Andela, B., Arnone, E., - Bellprat, O., Brötz, B., Caron, L.-P., Carvalhais, N., Cionni, I., Cortesi, N., Crezee, B., - Davin, E., Davini, P., Debeire, K., de Mora, L., Deser, C., Docquier, D., Earnshaw, P., - Ehbrecht, C., Gier, B. K., Gonzalez-Reviriego, N., Goodman, P., Hagemann, S., - Hardiman, S., Hassler, B., Hunter, A., Kadow, C., Kindermann, S., Koirala, S., - Koldunov, N. V., Lejeune, Q., Lembo, V., Lovato, T., Lucarini, V., Massonnet, F., - Müller, B., Pandde, A., Pérez-Zanón, N., Phillips, A., Predoi, V., Russell, J., Sellar, A., - Serva, F., Stacke, T., Swaminathan, R., Torralba, V., Vegas-Regidor, J., von Hardenberg, J., - Weigel, K., and Zimmermann, K.: - ESMValTool v2.0 – Extended set of large-scale diagnostics for quasi-operational - and comprehensive evaluation of Earth system models in CMIP, - Geosci. Model Dev. Discuss., - [https://doi.org/10.5194/gmd-2019-291](https://doi.org/10.5194/gmd-2019-291), - in review, 2019. - -- Eyring, V., Righi, M., Lauer, A., Evaldsson, M., Wenzel, S., Jones, C., Anav, A., - Andrews, O., Cionni, I., Davin, E. L., Deser, C., Ehbrecht, C., Friedlingstein, P., - Gleckler, P., Gottschaldt, K.-D., Hagemann, S., Juckes, M., Kindermann, S., - Krasting, J., Kunert, D., Levine, R., Loew, A., Mäkelä, J., Martin, G., Mason, E., - Phillips, A. S., Read, S., Rio, C., Roehrig, R., Senftleben, D., Sterl, A., - van Ulft, L. H., Walton, J., Wang, S., and Williams, K. D.: - ESMValTool (v1.0) – a community diagnostic and performance metrics tool for - routine evaluation of Earth system models in CMIP, - Geosci. Model Dev., 9, 1747–1802, - [https://doi.org/10.5194/gmd-9-1747-2016](https://doi.org/10.5194/gmd-9-1747-2016), - 2016. - - ### Where can I get more help? -There are lots of resources available for helping you use ESMValTool. - -If you get stuck, a great starting point is to create a new issue. [Link to ep 10] - -There is also an ESMValTool email list [esmvaltool@listserv.dfn.de](mailto:esmvaltool@listserv.dfn.de). +There are lots of resources available for helping you use ESMValTool. -Everybody can send mail without being subscribed to the group, but note that there is a spam filter. -The email group archive is also [online](https://www.listserv.dfn.de/sympa/arc/esmvaltool/2020-06/). +If you get stuck, a great starting point is to create a +[new issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose). +There is also an ESMValTool email list. +Please see +[information](https://docs.esmvaltool.org/en/latest/community/contact.html#user-mailing-list) +on how to subscribe to user mailing list. -### What if I find a bug? +### What if I find a bug? -If you find a bug, please report it back to the ESMValTool team. -This will help us fix it so that you can continue working, -but also it means that ESMValTool will be more stable for everyone else as well. +If you find a bug, please report it back to the ESMValTool team. +This will help us fix it, so that you can continue working, +but also it means that ESMValTool will be more stable for everyone else as well. -To report a bug, please create a new issue using the +To report a bug, please create a new issue using the [new issue page](https://github.com/ESMValGroup/ESMValTool/issues/new/choose). -In your bug report, please describe the problem as clearly and as completely as possible. +In your bug report, please describe the problem as clearly and as completely as possible. You may need to include a recipe or the output log as well. +### How do I cite the Tutorial and ESMValTool? -### How do I cite ESMValTool? - -Please cite ESMValTool as: - -- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., - Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., - Weigel, K., and Zechlau, S.: - Earth System Model Evaluation Tool (ESMValTool) v2.0 – diagnostics for - emergent constraints and future projections from Earth system models in CMIP, - Geosci. Model Dev. Discuss., - [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), - in review, 2020. - - -Please cite this tutorial as: - -- ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], - [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), - [DATE]. - - +Please see [citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION). {% include links.md %} diff --git a/_extras/about.md b/_extras/about.md index f4a7b7c5..f0f105b6 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -24,8 +24,9 @@ ESMValTool is open source and available on github, and is written in PEP8-compliant Python3. For more details on ESMValTool, please go to: -- [https://esmvaltool.org](ESMValTool home page) -- [https://esmvaltool.readthedocs.io/](ESMValTool Read The Docs page) + +- [ESMValTool home page](https://esmvaltool.org) +- [ESMValTool Documentation page](https://docs.esmvaltool.org) ## ESMValTool_Tutorial @@ -39,28 +40,17 @@ followed both independently and in a taught tutorial environment. The tutorial has been produced by the ESMValTool User Engagement team, and may be forked, developped and rehosted by other groups. - ## License + The ESMValTool is released under the Apache License, version 2.0. Citation of the ESMValTool paper (“Software Documentation Paper”) is kindly requested upon use, alongside with the software DOI for ESMValTool (doi:10.5281/zenodo.3401363) -and ESMValCore (doi:10.5281/zenodo.3387139) and version number: +and ESMValCore (doi:10.5281/zenodo.3387139) and version number. ## Citation -Please cite ESMValTool using: - -Righi, M., Andela, B., Eyring, V., Lauer, A., Predoi, V., Schlund, M., -Vegas-Regidor, J., Bock, L., Brötz, B., de Mora, L., Diblen, F., Dreyer, L., -Drost, N., Earnshaw, P., Hassler, B., Koldunov, N., Little, B., Loosveldt Tomas, -S., and Zimmermann, K.: -Earth System Model Evaluation Tool (ESMValTool) v2.0 – technical overview, -Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020, -2020. - -Besides the above citation, users are kindly asked to register any journal article -(or other scientific documents) that use the software at the ESMValTool webpage -(http://www.esmvaltool.org/). +Please see +[citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION). Citing the Software Documentation Paper and registering your papers will serve to document the scientific impact of the Software, @@ -70,7 +60,6 @@ You should consider this an obligation if you have taken advantage of the ESMValTool, which represents the end product of considerable effort by the development teams. - ## Acknowledgements The technical development work for ESMValTool v2.0 was funded by various projects, diff --git a/index.md b/index.md index 0ef8bff0..644e3239 100644 --- a/index.md +++ b/index.md @@ -51,7 +51,9 @@ independently. 3. If you get stuck, help is always available from the tutors, from ESMValTool developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) or via the - [ESMValTool email list](mailto:esmvaltool@listserv.dfn.de). + ESMValTool email list. Please see + [information](https://docs.esmvaltool.org/en/latest/community/contact.html#user-mailing-list) + on how to subscribe to user mailing list. 4. This tutorial includes several advanced lessons after the conclusion. These advanced lessons should be treated like “mini-tutorials”, and include aspects @@ -59,30 +61,17 @@ independently. > ## Additional Resources > -> - [Read the docs page](https://esmvaltool.readthedocs.io/) +> - [Documentation](https://docs.esmvaltool.org) > - [ESMValTool home page](https://www.esmvaltool.org/) -> - [Technical description paper](https://doi.org/10.5194/gmd-13-1179-2020) +> - [Papers](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION) > - [ESMValTool Source code](https://github.com/ESMValGroup/ESMValTool) > - [ESMValCore Source code](https://github.com/ESMValGroup/ESMValCore) > {: .callout} -## How to cite ESMValTool +## How to cite the Tutorial and ESMValTool -Please cite this tutorial as: - -- ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], - [https://github.com/ESMValGroup/tutorial](https://github.com/ESMValGroup/tutorial), - [DATE]. - -Please cite ESMValTool as: - -- Lauer, A., Eyring, V., Bellprat, O., Bock, L., Gier, B. K., Hunter, A., - Lorenz, R., Pérez-Zanón, N., Righi, M., Schlund, M., Senftleben, D., Weigel, - K., and Zechlau, S.: Earth System Model Evaluation Tool (ESMValTool) v2.0 – - diagnostics for emergent constraints and future projections from Earth - system models in CMIP, Geosci. Model Dev. Discuss., - [https://doi.org/10.5194/gmd-2020-60](https://doi.org/10.5194/gmd-2020-60), - in review, 2020. +Please see +[citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION). {% include links.md %} From fa911e6db7dde6bc37daa823b2d2d1ba5093cc2f Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 16:04:24 +0200 Subject: [PATCH 306/647] Add some steps to search esgf --- setup.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/setup.md b/setup.md index fcbeb2f7..93332f08 100644 --- a/setup.md +++ b/setup.md @@ -256,10 +256,18 @@ available to install conda & ESMValTool, but also enough to make a copy of some data. For this tutorial you can download the required data files by -1. Going to https://esgf-data.dkrz.de/projects/esgf-dkrz/ -2. Performing the following search - * -3. Download the NetCDF file to a ~/ +1. Going to https://esgf-data.dkrz.de/search/cmip5-dkrz/ +2. Performing the following search constraints + * Model = HadGEM2-ES + * Experiment = historical + * Time frequency = mon + * Ensemble = r1i1p1 + * Variable = thetaoga +3. Press search button +4. On single single search result press `Show files` +5. Click on more files +6. Find the thetaoga datafile in the list +7. Download the NetCDF file to a ~/ You will also need to able to use: - git From 5ad5adb47e93d35964cb7172c916dbddc5985f3a Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 16:12:16 +0200 Subject: [PATCH 307/647] Layout --- setup.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/setup.md b/setup.md index 93332f08..02798d8e 100644 --- a/setup.md +++ b/setup.md @@ -258,16 +258,18 @@ data. For this tutorial you can download the required data files by 1. Going to https://esgf-data.dkrz.de/search/cmip5-dkrz/ 2. Performing the following search constraints - * Model = HadGEM2-ES - * Experiment = historical - * Time frequency = mon - * Ensemble = r1i1p1 - * Variable = thetaoga + + * Model = HadGEM2-ES + * Experiment = historical + * Time frequency = mon + * Ensemble = r1i1p1 + * Variable = thetaoga + 3. Press search button 4. On single single search result press `Show files` -5. Click on more files -6. Find the thetaoga datafile in the list -7. Download the NetCDF file to a ~/ +5. Click on `Show All Files` at bottom of page +6. Find the `thetaoga` datafile in the list +7. Use `HTTP Download` link to download the NetCDF file to `~/default_inputpath/` directory You will also need to able to use: - git From c5f2d3b00cc08ed65e9c30f86145ea004a8e2b83 Mon Sep 17 00:00:00 2001 From: lopeztarifa Date: Fri, 31 Jul 2020 16:15:26 +0200 Subject: [PATCH 308/647] Adding glossary. --- _extras/glossary.md | 20 ++++++++++++++++++++ reference.md | 4 ---- 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 _extras/glossary.md diff --git a/_extras/glossary.md b/_extras/glossary.md new file mode 100644 index 00000000..d57ee456 --- /dev/null +++ b/_extras/glossary.md @@ -0,0 +1,20 @@ +--- +title: Glossary +--- + +## ESMValTool Glossary + +Here, there are some definitions used throughout this tutorial: + +- **Diagnostics**: + +- **CMIP**: The Coupled Model Intercomparison Project (CMIP) aims at better understanding past, present and future climate changes arising from natural, unforced variability or in response to changes in radiative forcing in a multi-model context. For more information, check the [WCR-Climate webpage](https://www.wcrp-climate.org/). + +- **CMOR**: + +- **Recipe**: Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. + +For more details on ESMValTool, please go to: +Additional info can be found in [ESMValTool home page](https://esmvaltool.org) +and [https://esmvaltool.readthedocs.io/](ESMValTool Read The Docs page). + diff --git a/reference.md b/reference.md index 8c826167..c5bcdd84 100644 --- a/reference.md +++ b/reference.md @@ -2,8 +2,4 @@ layout: reference --- -## Glossary - -FIXME - {% include links.md %} From 96c8476b8c516fcf37f52f070464597f6dacf06f Mon Sep 17 00:00:00 2001 From: lopeztarifa Date: Fri, 31 Jul 2020 16:15:26 +0200 Subject: [PATCH 309/647] Adding glossary. --- _extras/glossary.md | 20 ++++++++++++++++++++ reference.md | 4 ---- 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 _extras/glossary.md diff --git a/_extras/glossary.md b/_extras/glossary.md new file mode 100644 index 00000000..d57ee456 --- /dev/null +++ b/_extras/glossary.md @@ -0,0 +1,20 @@ +--- +title: Glossary +--- + +## ESMValTool Glossary + +Here, there are some definitions used throughout this tutorial: + +- **Diagnostics**: + +- **CMIP**: The Coupled Model Intercomparison Project (CMIP) aims at better understanding past, present and future climate changes arising from natural, unforced variability or in response to changes in radiative forcing in a multi-model context. For more information, check the [WCR-Climate webpage](https://www.wcrp-climate.org/). + +- **CMOR**: + +- **Recipe**: Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. + +For more details on ESMValTool, please go to: +Additional info can be found in [ESMValTool home page](https://esmvaltool.org) +and [https://esmvaltool.readthedocs.io/](ESMValTool Read The Docs page). + diff --git a/reference.md b/reference.md index 8c826167..c5bcdd84 100644 --- a/reference.md +++ b/reference.md @@ -2,8 +2,4 @@ layout: reference --- -## Glossary - -FIXME - {% include links.md %} From 7c99f04638f9ed4cd2667d463a29d2e57bb8f9d7 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 31 Jul 2020 16:18:12 +0200 Subject: [PATCH 310/647] english --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index 02798d8e..18a2cb02 100644 --- a/setup.md +++ b/setup.md @@ -268,7 +268,7 @@ For this tutorial you can download the required data files by 3. Press search button 4. On single single search result press `Show files` 5. Click on `Show All Files` at bottom of page -6. Find the `thetaoga` datafile in the list +6. Find the datafile which starts with `thetaoga` in the list 7. Use `HTTP Download` link to download the NetCDF file to `~/default_inputpath/` directory You will also need to able to use: From 5b998d3add63eeb02d68e6e30ebee5a3af3ecfce Mon Sep 17 00:00:00 2001 From: lopeztarifa Date: Fri, 31 Jul 2020 16:42:25 +0200 Subject: [PATCH 311/647] Adding glossary definitions. --- _extras/glossary.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index d57ee456..117111aa 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -10,9 +10,9 @@ Here, there are some definitions used throughout this tutorial: - **CMIP**: The Coupled Model Intercomparison Project (CMIP) aims at better understanding past, present and future climate changes arising from natural, unforced variability or in response to changes in radiative forcing in a multi-model context. For more information, check the [WCR-Climate webpage](https://www.wcrp-climate.org/). -- **CMOR**: +- **CMOR**: CMOR stands for [“Climate Model Output Rewriter” library](https://pcmdi.github.io/cmor-site/index.html). It comprises a set of C-based functions, with bindings to both Python and FORTRAN 90, that can be used to produce CF-compliant netCDF files that fulfill the requirements of many of the climate community's standard model experiments. -- **Recipe**: Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. +- **Recipe**: A recipe contains the instructions that you give to ESMValTool describing what you want it to do. This includes four main sections: datasets, preprocessors, diagnostics and description. For more details on ESMValTool, please go to: Additional info can be found in [ESMValTool home page](https://esmvaltool.org) From 7495b594a797551019bff1cbad72eae9b565994a Mon Sep 17 00:00:00 2001 From: lopeztarifa Date: Fri, 31 Jul 2020 16:49:51 +0200 Subject: [PATCH 312/647] Adding glossary definitions. --- _extras/glossary.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index 59c35e3a..358bdca6 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -12,11 +12,7 @@ Here, there are some definitions used throughout this tutorial: - **CMOR**: CMOR stands for [“Climate Model Output Rewriter” library](https://pcmdi.github.io/cmor-site/index.html). It comprises a set of C-based functions, with bindings to both Python and FORTRAN 90, that can be used to produce CF-compliant netCDF files that fulfill the requirements of many of the climate community's standard model experiments. -- **Recipe**: A recipe contains the instructions that you give to ESMValTool describing what you want it to do. This includes four main sections: datasets, preprocessors, diagnostics and description. -======= -- **CMOR**: - -- **Recipe**: Recipes are the instructions that you give to ESMValTool that tell it what you want to do. This includes four main sections: datasets, preprocessors, diagnostics and description. +- **Recipe**: A recipe contains the instructions to be carried out by the ESMValTool. This includes four main sections: datasets, preprocessors, diagnostics and description. For more details on ESMValTool, please go to: Additional info can be found in [ESMValTool home page](https://esmvaltool.org) From 7691d83cc0bebddccd27192767ac424f59487b3d Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 09:56:46 +0200 Subject: [PATCH 313/647] Prep for more urls --- setup.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/setup.md b/setup.md index 18a2cb02..e1d433e0 100644 --- a/setup.md +++ b/setup.md @@ -255,23 +255,29 @@ that you are able to download CMIP data and that you have several GB of space available to install conda & ESMValTool, but also enough to make a copy of some data. -For this tutorial you can download the required data files by -1. Going to https://esgf-data.dkrz.de/search/cmip5-dkrz/ +For this tutorial you can download the required data files by + +1. Going to [the CMIP5 search page on the DKRZ ESGF node](https://esgf-data.dkrz.de/search/cmip5-dkrz/) 2. Performing the following search constraints - * Model = HadGEM2-ES - * Experiment = historical - * Time frequency = mon - * Ensemble = r1i1p1 - * Variable = thetaoga + - Model = HadGEM2-ES + - Experiment = historical + - Time frequency = mon + - Ensemble = r1i1p1 + - Variable = thetaoga 3. Press search button -4. On single single search result press `Show files` -5. Click on `Show All Files` at bottom of page +4. On single single search result press `List files` +5. At bottom of page click on `Show All Files` 6. Find the datafile which starts with `thetaoga` in the list -7. Use `HTTP Download` link to download the NetCDF file to `~/default_inputpath/` directory +7. Use `HTTP Download` link to download the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc)) file to `~/default_inputpath/` directory + +The tutorial also needs the following data files, we will use deep links instead of going through the search form. Please download all the links below to `~/default_inputpath/` directory: + +- TODO complete list of urls You will also need to able to use: + - git - conda From 4668e8e597d7b07aeb7373ceb0bb3198ad43873d Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 11:37:58 +0200 Subject: [PATCH 314/647] More links and use wget to download all --- data/dataset.urls | 10 ++++++++++ setup.md | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 data/dataset.urls diff --git a/data/dataset.urls b/data/dataset.urls new file mode 100644 index 00000000..325bde26 --- /dev/null +++ b/data/dataset.urls @@ -0,0 +1,10 @@ +# Dataset urls required fo tutorial, described at https://esmvalgroup.github.io/ESMValTool_Tutorial/setup.html#using-your-own-machine +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc diff --git a/setup.md b/setup.md index e1d433e0..23911fb9 100644 --- a/setup.md +++ b/setup.md @@ -274,7 +274,40 @@ For this tutorial you can download the required data files by The tutorial also needs the following data files, we will use deep links instead of going through the search form. Please download all the links below to `~/default_inputpath/` directory: -- TODO complete list of urls +- Variable = ts, model = HadGEM2-ES + - [ts_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc) + - [ts_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc) + - [ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc) + - [ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc) +- Variable = tas, model = HadGEM2-AO + - TODO add links +- Variable = tas, model = HadGEM2-ES + - [tas_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc) + - [tas_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc) + - [tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc) + - [tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc) +- Variable = tos, model = HadGEM2-AO + - TODO add links +- Variable = tos, model = HadGEM2-CC + - TODO add links +- Variable = tos, model = HadGEM2-ES + - TODO add links +- Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = pr and tas + - TODO add links +- Model = CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5, variable = tas + - TODO add links +- Model = MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5, variable = tas + - TODO add links +- Model = UKESM1-0-LL, ensemble: "r(1:4)i1p1f2", grid: gn, project: CMIP6, variable = tas + - TODO add links +- Model = CanESM5, ensemble: "r(1:4)i1p2f1", grid: gn, project: CMIP6, variable = tas + - TODO add links + +To download all these files at once use the [dataset.urls](https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/recipe_example.yml) file and wget + +~~~shell +wget --input-file dataset.urls --no-clobber --directory-prefix $HOME/default_inputpath/ +~~~ You will also need to able to use: From a2878f81a75770b7c96a196b91fe14604e572bde Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 11:44:52 +0200 Subject: [PATCH 315/647] Move list of dataset urls to text file --- data/dataset.urls | 23 +++++++++++++++++++++++ setup.md | 39 ++++----------------------------------- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/data/dataset.urls b/data/dataset.urls index 325bde26..75667846 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -1,10 +1,33 @@ # Dataset urls required fo tutorial, described at https://esmvalgroup.github.io/ESMValTool_Tutorial/setup.html#using-your-own-machine +# For Running a recipe episode +# Variable = thetaoga, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc +# Variable = ts, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc +# Variable = tas, model = HadGEM2-AO +# TODO add links +# Variable = tas, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc +# Variable = tos, model = HadGEM2-AO +# TODO add links +# Variable = tos, model = HadGEM2-CC +# TODO add links +# Variable = tos, model = HadGEM2-ES +# TODO add links +# For Working with preprocessors episode +# Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = pr and tas +# TODO add links +# Model = CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5, variable = tas +# TODO add links +# Model = MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5, variable = tas +# TODO add links +# Model = UKESM1-0-LL, ensemble: "r(1:4)i1p1f2", grid: gn, project: CMIP6, variable = tas +# TODO add links +# Model = CanESM5, ensemble: "r(1:4)i1p2f1", grid: gn, project: CMIP6, variable = tas +# TODO add links diff --git a/setup.md b/setup.md index 23911fb9..f54b94a6 100644 --- a/setup.md +++ b/setup.md @@ -270,43 +270,12 @@ For this tutorial you can download the required data files by 4. On single single search result press `List files` 5. At bottom of page click on `Show All Files` 6. Find the datafile which starts with `thetaoga` in the list -7. Use `HTTP Download` link to download the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc)) file to `~/default_inputpath/` directory - -The tutorial also needs the following data files, we will use deep links instead of going through the search form. Please download all the links below to `~/default_inputpath/` directory: - -- Variable = ts, model = HadGEM2-ES - - [ts_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc) - - [ts_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc) - - [ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc) - - [ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc) -- Variable = tas, model = HadGEM2-AO - - TODO add links -- Variable = tas, model = HadGEM2-ES - - [tas_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc) - - [tas_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc) - - [tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc) - - [tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc) -- Variable = tos, model = HadGEM2-AO - - TODO add links -- Variable = tos, model = HadGEM2-CC - - TODO add links -- Variable = tos, model = HadGEM2-ES - - TODO add links -- Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = pr and tas - - TODO add links -- Model = CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5, variable = tas - - TODO add links -- Model = MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5, variable = tas - - TODO add links -- Model = UKESM1-0-LL, ensemble: "r(1:4)i1p1f2", grid: gn, project: CMIP6, variable = tas - - TODO add links -- Model = CanESM5, ensemble: "r(1:4)i1p2f1", grid: gn, project: CMIP6, variable = tas - - TODO add links - -To download all these files at once use the [dataset.urls](https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/recipe_example.yml) file and wget +7. Use `HTTP Download` link to download the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc)) file to + +The tutorial needs the more data files, we will use deep links instead of going through the search form. To download all dataset files to `~/default_inputpath/` directory use the [dataset.urls](https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/recipe_example.yml) file and [wget](https://en.wikipedia.org/wiki/Wget): ~~~shell -wget --input-file dataset.urls --no-clobber --directory-prefix $HOME/default_inputpath/ +wget --input-file https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/recipe_example.yml --no-clobber --directory-prefix $HOME/default_inputpath/ ~~~ You will also need to able to use: From bb193f6a894dd191ff7102565f078d6cc7c06a6c Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 12:01:54 +0200 Subject: [PATCH 316/647] Describe dataset.urls later --- setup.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/setup.md b/setup.md index f54b94a6..239b73ef 100644 --- a/setup.md +++ b/setup.md @@ -257,7 +257,7 @@ data. For this tutorial you can download the required data files by -1. Going to [the CMIP5 search page on the DKRZ ESGF node](https://esgf-data.dkrz.de/search/cmip5-dkrz/) +1. Going to the [CMIP5 search page on the DKRZ ESGF node](https://esgf-data.dkrz.de/search/cmip5-dkrz/) 2. Performing the following search constraints - Model = HadGEM2-ES @@ -269,15 +269,17 @@ For this tutorial you can download the required data files by 3. Press search button 4. On single single search result press `List files` 5. At bottom of page click on `Show All Files` -6. Find the datafile which starts with `thetaoga` in the list +6. Find the file which starts with `thetaoga` in the list 7. Use `HTTP Download` link to download the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc)) file to -The tutorial needs the more data files, we will use deep links instead of going through the search form. To download all dataset files to `~/default_inputpath/` directory use the [dataset.urls](https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/recipe_example.yml) file and [wget](https://en.wikipedia.org/wiki/Wget): +The tutorial needs more data files. All of the data files should be downloaded to `~/default_inputpath/` directory and [wget](https://en.wikipedia.org/wiki/Wget): ~~~shell -wget --input-file https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/recipe_example.yml --no-clobber --directory-prefix $HOME/default_inputpath/ +wget --input-file https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls --no-clobber --directory-prefix $HOME/default_inputpath/ ~~~ +The [dataset.urls](https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/rdataset.urls) file contains all data set urls and in comments the used search constraints. + You will also need to able to use: - git From f04aca66c9b717bb7babad07931d2abe2e4cba80 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 12:02:04 +0200 Subject: [PATCH 317/647] Undo list on all interfaces To discourage hosting `make docker-serve` on Internet. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 087e5708..7da810b4 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ site : lesson-md docker-serve : docker run --rm -it --volume ${PWD}:/srv/jekyll \ --volume=${PWD}/.docker-vendor/bundle:/usr/local/bundle \ - -p 0.0.0.0:4000:4000 \ + -p 127.0.0.1:4000:4000 \ jekyll/jekyll:${JEKYLL_VERSION} \ bin/run-make-docker-serve.sh From 589397870ff8929bfceb770a0096e3b971d313e0 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 12:40:08 +0200 Subject: [PATCH 318/647] Complete sentence --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index 239b73ef..77dedbb3 100644 --- a/setup.md +++ b/setup.md @@ -270,7 +270,7 @@ For this tutorial you can download the required data files by 4. On single single search result press `List files` 5. At bottom of page click on `Show All Files` 6. Find the file which starts with `thetaoga` in the list -7. Use `HTTP Download` link to download the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc)) file to +7. Use `HTTP Download` link to download the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc)) file to `~/default_inputpath/` directory. The tutorial needs more data files. All of the data files should be downloaded to `~/default_inputpath/` directory and [wget](https://en.wikipedia.org/wiki/Wget): From 65c22989fc06660aabc77d24bc19e46cd06bebf6 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 12:42:38 +0200 Subject: [PATCH 319/647] English --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index 77dedbb3..d3e691f6 100644 --- a/setup.md +++ b/setup.md @@ -272,7 +272,7 @@ For this tutorial you can download the required data files by 6. Find the file which starts with `thetaoga` in the list 7. Use `HTTP Download` link to download the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc)) file to `~/default_inputpath/` directory. -The tutorial needs more data files. All of the data files should be downloaded to `~/default_inputpath/` directory and [wget](https://en.wikipedia.org/wiki/Wget): +The tutorial needs more data files. All of the data files should be downloaded to `~/default_inputpath/` directory with [wget](https://en.wikipedia.org/wiki/Wget): ~~~shell wget --input-file https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls --no-clobber --directory-prefix $HOME/default_inputpath/ From 5ce360ae800254c80c5bb9b22d69f55ffa6cdfe9 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 13:33:34 +0200 Subject: [PATCH 320/647] More dataset links --- data/dataset.urls | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/data/dataset.urls b/data/dataset.urls index 75667846..206e8da9 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -8,26 +8,38 @@ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc # Variable = tas, model = HadGEM2-AO -# TODO add links +http://aims3.llnl.gov/thredds/fileServer/cmip5_css02_data/cmip5/output1/NIMR-KMA/HadGEM2-AO/historical/mon/atmos/Amon/r1i1p1/tas/1/tas_Amon_HadGEM2-AO_historical_r1i1p1_186001-200512.nc # Variable = tas, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc # Variable = tos, model = HadGEM2-AO -# TODO add links +http://aims3.llnl.gov/thredds/fileServer/cmip5_css02_data/cmip5/output1/NIMR-KMA/HadGEM2-AO/historical/mon/ocean/Omon/r1i1p1/tos/1/tos_Omon_HadGEM2-AO_historical_r1i1p1_186001-200512.nc # Variable = tos, model = HadGEM2-CC -# TODO add links +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-CC/historical/mon/ocean/Omon/r1i1p1/v20110930/tos/tos_Omon_HadGEM2-CC_historical_r1i1p1_185912-195911.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-CC/historical/mon/ocean/Omon/r1i1p1/v20110930/tos/tos_Omon_HadGEM2-CC_historical_r1i1p1_195912-200511.nc # Variable = tos, model = HadGEM2-ES -# TODO add links +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_185912-195911.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_195912-200512.nc # For Working with preprocessors episode -# Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = pr and tas -# TODO add links +# Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = pr and tas, 1970-2000 +http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Amon/tas/gn/v20190406/tas_Amon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-201412.nc +http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Amon/pr/gn/v20190406/pr_Amon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-201412.nc # Model = CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5, variable = tas -# TODO add links +http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r1i1p1/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc +http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r2i1p1/tas_Amon_CanESM2_historical_r2i1p1_185001-200512.nc +http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r3i1p1/tas_Amon_CanESM2_historical_r3i1p1_185001-200512.nc +http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r4i1p1/tas_Amon_CanESM2_historical_r4i1p1_185001-200512.nc # Model = MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5, variable = tas -# TODO add links +http://esgf1.dkrz.de/thredds/fileServer/cmip5/cmip5/output1/MPI-M/MPI-ESM-LR/historical/mon/atmos/Amon/r1i1p1/v20120315/tas/tas_Amon_MPI-ESM-LR_historical_r1i1p1_185001-200512.nc +http://esgf1.dkrz.de/thredds/fileServer/cmip5/cmip5/output1/MPI-M/MPI-ESM-LR/historical/mon/atmos/Amon/r2i1p1/v20120315/tas/tas_Amon_MPI-ESM-LR_historical_r2i1p1_185001-200512.nc # Model = UKESM1-0-LL, ensemble: "r(1:4)i1p1f2", grid: gn, project: CMIP6, variable = tas -# TODO add links +http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r2i1p1f2/Amon/tas/gn/v20190502/tas_Amon_UKESM1-0-LL_historical_r2i1p1f2_gn_195001-201412.nc +http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r3i1p1f2/Amon/tas/gn/v20190502/tas_Amon_UKESM1-0-LL_historical_r3i1p1f2_gn_195001-201412.nc +http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r4i1p1f2/Amon/tas/gn/v20190502/tas_Amon_UKESM1-0-LL_historical_r4i1p1f2_gn_195001-201412.nc # Model = CanESM5, ensemble: "r(1:4)i1p2f1", grid: gn, project: CMIP6, variable = tas -# TODO add links +http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r1i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r1i1p2f1_gn_185001-201412.nc +http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r2i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r2i1p2f1_gn_185001-201412.nc +http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r3i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r3i1p2f1_gn_185001-201412.nc +http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r4i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r4i1p2f1_gn_185001-201412.nc From 82f59e6bc1330323a7353d52a28fca85298f2d83 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 14:04:39 +0200 Subject: [PATCH 321/647] Test recipe in CI --- .github/workflows/recipes.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/recipes.yml diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml new file mode 100644 index 00000000..982caea3 --- /dev/null +++ b/.github/workflows/recipes.yml @@ -0,0 +1,33 @@ +name: Test recipes + +on: + push: + pull_request: + +jobs: + build: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install esmvaltool + run: conda create -n esmvaltool -c esmvalgroup -c conda-forge esmvaltool-python + - name: Activate esmvaltool conda env + run: conda activate esmvaltool + - name: Setup config + run: | + esmvaltool config get_config_user + patch ~/.esmvaltool/config-user.yml << EOF + 44c44 + < #rootpath: + --- + > rootpath: + 48c48 + < # default: ~/default_inputpath + --- + > default: ~/default_inputpath + EOF + - name: Download dataset files for data/recipe_example.yml + run: | + head -4 data/dataset.urls |grep -v '#' | wget --input-file - --no-clobber --directory-prefix $HOME/default_inputpath/ + - name: Run data/recipe_example.yml + run: esmvaltool run $PWD/data/recipe_example.yml From dd32da4365cfaa5e730540c527d950183e1580c8 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 14:19:30 +0200 Subject: [PATCH 322/647] Use action to setup conda --- .github/workflows/recipes.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 982caea3..682a1f70 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -9,10 +9,9 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 + - uses: goanpeca/setup-miniconda@v1 - name: Install esmvaltool - run: conda create -n esmvaltool -c esmvalgroup -c conda-forge esmvaltool-python - - name: Activate esmvaltool conda env - run: conda activate esmvaltool + run: conda install -c esmvalgroup -c conda-forge esmvaltool-python - name: Setup config run: | esmvaltool config get_config_user From c35c18c94d3159c9ea78830918e3774e67b4eb68 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 14:35:50 +0200 Subject: [PATCH 323/647] More cache + debug step --- .github/workflows/recipes.yml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 682a1f70..03014169 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -9,9 +9,23 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 + - name: Cache conda + uses: actions/cache@v1 + env: + # Increase this value to reset cache if data/recipe_example.yml has not changed + CACHE_NUMBER: 0 + with: + path: ~/conda_pkgs_dir + key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/recipe_example.yml') }} - uses: goanpeca/setup-miniconda@v1 - name: Install esmvaltool - run: conda install -c esmvalgroup -c conda-forge esmvaltool-python + run: conda install -y -c esmvalgroup -c conda-forge esmvaltool-python + - name: Debug + run: + echo $CONDA + echo $PATH + ls $CONDA/envs/test/bin + which esmvaltool - name: Setup config run: | esmvaltool config get_config_user @@ -25,6 +39,14 @@ jobs: --- > default: ~/default_inputpath EOF + - name: Cache datasets + uses: actions/cache@v1 + env: + # Increase this value to reset cache if data/dataset.urls has not changed + CACHE_NUMBER: 0 + with: + path: ~/default_inputpath + key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} - name: Download dataset files for data/recipe_example.yml run: | head -4 data/dataset.urls |grep -v '#' | wget --input-file - --no-clobber --directory-prefix $HOME/default_inputpath/ From 393c1436f81712616eecbd9c22cab9df0268e89f Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 14:40:28 +0200 Subject: [PATCH 324/647] More debug --- .github/workflows/recipes.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 03014169..0de90d4c 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -18,10 +18,12 @@ jobs: path: ~/conda_pkgs_dir key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/recipe_example.yml') }} - uses: goanpeca/setup-miniconda@v1 + with: + activate-environment: esmvaltool - name: Install esmvaltool run: conda install -y -c esmvalgroup -c conda-forge esmvaltool-python - name: Debug - run: + run: | echo $CONDA echo $PATH ls $CONDA/envs/test/bin From 3803be60017ae16ff5d4c11c0ad4b42b919ad090 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 14:46:18 +0200 Subject: [PATCH 325/647] bin dir of env is not added to PATH so use absolute paths --- .github/workflows/recipes.yml | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 0de90d4c..ca73c064 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -18,19 +18,11 @@ jobs: path: ~/conda_pkgs_dir key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/recipe_example.yml') }} - uses: goanpeca/setup-miniconda@v1 - with: - activate-environment: esmvaltool - name: Install esmvaltool run: conda install -y -c esmvalgroup -c conda-forge esmvaltool-python - - name: Debug - run: | - echo $CONDA - echo $PATH - ls $CONDA/envs/test/bin - which esmvaltool - name: Setup config run: | - esmvaltool config get_config_user + $CONDA/envs/test/bin/esmvaltool config get_config_user patch ~/.esmvaltool/config-user.yml << EOF 44c44 < #rootpath: @@ -51,6 +43,6 @@ jobs: key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} - name: Download dataset files for data/recipe_example.yml run: | - head -4 data/dataset.urls |grep -v '#' | wget --input-file - --no-clobber --directory-prefix $HOME/default_inputpath/ + head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --directory-prefix $HOME/default_inputpath/ - name: Run data/recipe_example.yml - run: esmvaltool run $PWD/data/recipe_example.yml + run: $CONDA/envs/test/bin/esmvaltool run $PWD/data/recipe_example.yml From a18bc04177d710b723614f45c563ee78c3a0532b Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 14:52:18 +0200 Subject: [PATCH 326/647] Install tool in right env --- .github/workflows/recipes.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index ca73c064..56aab046 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -19,7 +19,10 @@ jobs: key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/recipe_example.yml') }} - uses: goanpeca/setup-miniconda@v1 - name: Install esmvaltool - run: conda install -y -c esmvalgroup -c conda-forge esmvaltool-python + run: conda install -n test -y -c esmvalgroup -c conda-forge esmvaltool-python + - name: Debug + run: | + ls -R $CONDA/envs - name: Setup config run: | $CONDA/envs/test/bin/esmvaltool config get_config_user From ea001f9f41bcfcc1e4acc9433a0390bf292a4cf0 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 14:56:00 +0200 Subject: [PATCH 327/647] CI green, Drop debug --- .github/workflows/recipes.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 56aab046..4315f292 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -20,9 +20,6 @@ jobs: - uses: goanpeca/setup-miniconda@v1 - name: Install esmvaltool run: conda install -n test -y -c esmvalgroup -c conda-forge esmvaltool-python - - name: Debug - run: | - ls -R $CONDA/envs - name: Setup config run: | $CONDA/envs/test/bin/esmvaltool config get_config_user From 9610c61670e5f35f4a405796ce0277d2eb64f6bc Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 3 Aug 2020 15:02:01 +0200 Subject: [PATCH 328/647] Added recipe solutions and use unified diff Fixed #107 --- _episodes/04-recipe.md | 126 +++++++++++++++++++++++++----------- data/recipe_example_tas.yml | 45 +++++++++++++ data/recipe_example_tos.yml | 46 +++++++++++++ data/recipe_example_ts.yml | 44 +++++++++++++ 4 files changed, 224 insertions(+), 37 deletions(-) create mode 100644 data/recipe_example_tas.yml create mode 100644 data/recipe_example_tos.yml create mode 100644 data/recipe_example_ts.yml diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 51a4a9ef..5f8ad11b 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -635,58 +635,110 @@ The snippets for the edits can be found below: > ## Land surface average temperature > -> ```YAML -> ... -> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} -> ... -> 27 annual_statistics: -> 28 operator: mean -> XX area_statistics: -> XX operator: mean -> ... -> 38 short_name: ts -> 39 preprocessor: prep_timeseries +> ```diff +> --- data/recipe_example.yml 2020-07-31 14:43:48.976660742 +0200 +> +++ data/recipe_example_ts.yml 2020-08-03 14:57:45.962391097 +0200 +> @@ -20,12 +20,14 @@ +> - ukesm +> +> datasets: +> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> +> preprocessors: +> prep_timeseries: # For 0D fields +> annual_statistics: +> operator: mean +> + area_statistics: +> + operator: mean +> +> diagnostics: +> # -------------------------------------------------- +> @@ -35,7 +37,7 @@ +> description: simple_time_series +> variables: +> timeseries_variable: +> - short_name: thetaoga +> + short_name: ts +> preprocessor: prep_timeseries +> scripts: +> timeseries_diag: > ``` > > Note: The x-axis in the plot now shows the years 1900 - 2000. {: .solution} > ## Atmospheric surface average temperature -> ```YAML -> ... -> 23 - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} -> XX - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} -> ... -> 27 annual_statistics: -> 28 operator: mean -> XX area_statistics: -> XX operator: mean -> ... -> 38 short_name: tas -> 39 preprocessor: prep_timeseries +> +> ```diff +> --- data/recipe_example.yml 2020-07-31 14:43:48.976660742 +0200 +> +++ data/recipe_example_tas.yml 2020-08-03 14:58:22.981947194 +0200 +> @@ -20,12 +20,15 @@ +> - ukesm +> +> datasets: +> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> + - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> +> preprocessors: +> prep_timeseries: # For 0D fields +> annual_statistics: +> operator: mean +> + area_statistics: +> + operator: mean +> +> diagnostics: +> # -------------------------------------------------- +> @@ -35,7 +38,7 @@ +> description: simple_time_series +> variables: +> timeseries_variable: +> - short_name: thetaoga +> + short_name: tas +> preprocessor: prep_timeseries +> scripts: +> timeseries_diag: > ``` > Note: There are now 3 plots in the work directory. One for each dataset and one for the multiple dataset overview. {: .solution} > ## Ocean surface average temperature -> ```YAML -> ... -> 23 - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} -> XX - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} -> XX - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} -> ... -> 27 annual_statistics: -> 28 operator: mean -> XX area_statistics: -> XX operator: mean -> ... -> 38 short_name: tos -> 39 preprocessor: prep_timeseries +> +> ```diff +> --- data/recipe_example.yml 2020-07-31 14:43:48.976660742 +0200 +> +++ data/recipe_example_tos.yml 2020-08-03 14:11:33.721000000 +0200 +> @@ -20,12 +20,16 @@ +> - ukesm +> +> datasets: +> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> + - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> + - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> +> preprocessors: +> prep_timeseries: # For 0D fields +> annual_statistics: +> operator: mean +> + area_statistics: +> + operator: mean +> +> diagnostics: +> # -------------------------------------------------- +> @@ -35,7 +39,7 @@ +> description: simple_time_series +> variables: +> timeseries_variable: +> - short_name: thetaoga +> + short_name: tos +> preprocessor: prep_timeseries +> scripts: +> timeseries_diag: > ``` > Note: The unit in the plots is now degrees celsius! There is a plot also for HadGEM2-CC. {: .solution} - > ## Advanced: > If you want to add a different field, please have a look here: > http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html diff --git a/data/recipe_example_tas.yml b/data/recipe_example_tas.yml new file mode 100644 index 00000000..8bb3b40d --- /dev/null +++ b/data/recipe_example_tas.yml @@ -0,0 +1,45 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +datasets: + - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} + +preprocessors: + prep_timeseries: # For 0D fields + annual_statistics: + operator: mean + area_statistics: + operator: mean + +diagnostics: + # -------------------------------------------------- + # Time series diagnostics + # -------------------------------------------------- + diag_timeseries_temperature: + description: simple_time_series + variables: + timeseries_variable: + short_name: tas + preprocessor: prep_timeseries + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py diff --git a/data/recipe_example_tos.yml b/data/recipe_example_tos.yml new file mode 100644 index 00000000..98171eea --- /dev/null +++ b/data/recipe_example_tos.yml @@ -0,0 +1,46 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +datasets: + - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} + - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} + +preprocessors: + prep_timeseries: # For 0D fields + annual_statistics: + operator: mean + area_statistics: + operator: mean + +diagnostics: + # -------------------------------------------------- + # Time series diagnostics + # -------------------------------------------------- + diag_timeseries_temperature: + description: simple_time_series + variables: + timeseries_variable: + short_name: tos + preprocessor: prep_timeseries + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py diff --git a/data/recipe_example_ts.yml b/data/recipe_example_ts.yml new file mode 100644 index 00000000..74359c43 --- /dev/null +++ b/data/recipe_example_ts.yml @@ -0,0 +1,44 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +datasets: + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} + +preprocessors: + prep_timeseries: # For 0D fields + annual_statistics: + operator: mean + area_statistics: + operator: mean + +diagnostics: + # -------------------------------------------------- + # Time series diagnostics + # -------------------------------------------------- + diag_timeseries_temperature: + description: simple_time_series + variables: + timeseries_variable: + short_name: ts + preprocessor: prep_timeseries + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py From 2b35ffabff2c5d591b2bbcb0d900e21a792ce255 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 Aug 2020 09:17:10 +0200 Subject: [PATCH 329/647] Fix identation --- _episodes/05-preprocessor.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 1cc8a30c..7c447170 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -256,11 +256,11 @@ specific preprocessor which should be applied. >> description: #preprocess a variable for a 2D land only plot >> variables: >> tas: # surface temperature ->> preprocessor: prep_map_land ->> mip: Amon ->> grid: gn #can change for variables from the same model ->> start_year: 1970 ->> end_year: 2000 +>> preprocessor: prep_map_land +>> mip: Amon +>> grid: gn #can change for variables from the same model +>> start_year: 1970 +>> end_year: 2000 >> scripts: null >> ``` >> From 55a46c85d17b75da43000d36a6119d5f40247b96 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 Aug 2020 12:19:32 +0200 Subject: [PATCH 330/647] Removed timestamps from diffs + Add download link for solution recipes --- _episodes/04-recipe.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 5f8ad11b..1f67ddfd 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -636,8 +636,8 @@ The snippets for the edits can be found below: > ## Land surface average temperature > > ```diff -> --- data/recipe_example.yml 2020-07-31 14:43:48.976660742 +0200 -> +++ data/recipe_example_ts.yml 2020-08-03 14:57:45.962391097 +0200 +> --- data/recipe_example.yml +> +++ data/recipe_example_ts.yml > @@ -20,12 +20,14 @@ > - ukesm > @@ -666,13 +666,15 @@ The snippets for the edits can be found below: > ``` > > Note: The x-axis in the plot now shows the years 1900 - 2000. +> +> Complete recipe can be downloaded as [recipe_example_ts.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_ts.yml) {: .solution} > ## Atmospheric surface average temperature > > ```diff -> --- data/recipe_example.yml 2020-07-31 14:43:48.976660742 +0200 -> +++ data/recipe_example_tas.yml 2020-08-03 14:58:22.981947194 +0200 +> --- data/recipe_example.yml +> +++ data/recipe_example_tas.yml > @@ -20,12 +20,15 @@ > - ukesm > @@ -701,13 +703,15 @@ The snippets for the edits can be found below: > timeseries_diag: > ``` > Note: There are now 3 plots in the work directory. One for each dataset and one for the multiple dataset overview. +> +> Complete recipe can be downloaded as [recipe_example_tas.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_tas.yml) {: .solution} > ## Ocean surface average temperature > > ```diff -> --- data/recipe_example.yml 2020-07-31 14:43:48.976660742 +0200 -> +++ data/recipe_example_tos.yml 2020-08-03 14:11:33.721000000 +0200 +> --- data/recipe_example.yml +> +++ data/recipe_example_tos.yml > @@ -20,12 +20,16 @@ > - ukesm > @@ -737,6 +741,8 @@ The snippets for the edits can be found below: > timeseries_diag: > ``` > Note: The unit in the plots is now degrees celsius! There is a plot also for HadGEM2-CC. +> +> Complete recipe can be downloaded as [recipe_example_tos.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_tos.yml) {: .solution} > ## Advanced: From a6b556c426a483e6ae604a30e0bae9f02db5884e Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 Aug 2020 12:29:35 +0200 Subject: [PATCH 331/647] Link to complete recipe --- _episodes/05-preprocessor.md | 1 + data/recipe_example_multi_preprocessors.yml | 65 +++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 data/recipe_example_multi_preprocessors.yml diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 7c447170..7d4e7bf6 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -264,6 +264,7 @@ specific preprocessor which should be applied. >> scripts: null >> ``` >> +>> Complete recipe can be downloaded [here](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_multi_preprocessors.yml). > {: .solution} {: .challenge} diff --git a/data/recipe_example_multi_preprocessors.yml b/data/recipe_example_multi_preprocessors.yml new file mode 100644 index 00000000..e65d6c16 --- /dev/null +++ b/data/recipe_example_multi_preprocessors.yml @@ -0,0 +1,65 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +datasets: + - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, + ensemble: r1i1p1f2} #single dataset as an example + +preprocessors: + prep_map: + regrid: #apply the preprocessor to regrid + target_grid: 1x1 # target resolution + scheme: linear #how to interpolate for regridding + + prep_map_land: + custom_order: true #ensure that given order of preprocessing is followed + mask_landsea: #apply a mask + mask_out: sea #mask out sea grid cells + regrid: # now apply the preprocessor to regrid + target_grid: 1x1 # target resolution + scheme: linear #how to interpolate for regridding + +diagnostics: + # -------------------------------------------------- + # Two Simple diagnostics that illustrate the use of + # different preprocessors + # -------------------------------------------------- + diag_simple_plot: + description: # preprocess a variable for a simple 2D plot + variables: + tas: # surface temperature + preprocessor: prep_map + mip: Amon + grid: gn #can change for variables from the same model + start_year: 1970 + end_year: 2000 + scripts: null + + diag_land_only_plot: + description: #preprocess a variable for a 2D land only plot + variables: + tas: # surface temperature + preprocessor: prep_map_land + mip: Amon + grid: gn #can change for variables from the same model + start_year: 1970 + end_year: 2000 + scripts: null From 44bad5f49e7fdf46fc6c38ad9ee1244be794c206 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 Aug 2020 18:00:28 +0200 Subject: [PATCH 332/647] Update _episodes/04-recipe.md Co-authored-by: Peter Kalverla --- _episodes/04-recipe.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 1f67ddfd..cf3e5a93 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -635,6 +635,8 @@ The snippets for the edits can be found below: > ## Land surface average temperature > +> In the `diff` file below you will see the changes we have made to the file. The top 2 lines are the filenames and the lines like @@ -20,12 +20,14 @@ indicate the line numbers in the original and modified file, respectively. For more info on this format, see [here](https://en.wikipedia.org/wiki/Diff#Unified_format) +> > ```diff > --- data/recipe_example.yml > +++ data/recipe_example_ts.yml From badbe0cda870a4d96131e4f52c08175f3370bd40 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 09:23:52 +0200 Subject: [PATCH 333/647] Added thetao data sets --- data/dataset.urls | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/dataset.urls b/data/dataset.urls index 206e8da9..a3cde59d 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -23,7 +23,9 @@ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_185912-195911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_195912-200512.nc # For Working with preprocessors episode -# Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = pr and tas, 1970-2000 +# Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = thetao, pr and tas, 1970-2000 +http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Omon/thetao/gn/v20190627/thetao_Omon_UKESM1-0-LL_historical_r1i1p1f2_gn_200001-201412.nc +http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Omon/thetao/gn/v20190627/thetao_Omon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-199912.nc http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Amon/tas/gn/v20190406/tas_Amon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-201412.nc http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Amon/pr/gn/v20190406/pr_Amon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-201412.nc # Model = CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5, variable = tas From f065655efb1440223f9051e6f3ca75fc6050010f Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 09:26:58 +0200 Subject: [PATCH 334/647] The thetao datasets are quite big 8.3Gb, add size to md --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index d3e691f6..51a59f1a 100644 --- a/setup.md +++ b/setup.md @@ -253,7 +253,7 @@ local machine and go [here](#gitHub-account-(advanced)). If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space available to install conda & ESMValTool, but also enough to make a copy of some -data. +data (12Gb). For this tutorial you can download the required data files by From 357c177d983fa2a8a6ecd57b53d59b1a405c2ba2 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 10:00:31 +0200 Subject: [PATCH 335/647] Clear conda cache in CI --- .github/workflows/recipes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 4315f292..2e54e637 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -13,7 +13,7 @@ jobs: uses: actions/cache@v1 env: # Increase this value to reset cache if data/recipe_example.yml has not changed - CACHE_NUMBER: 0 + CACHE_NUMBER: 1 with: path: ~/conda_pkgs_dir key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/recipe_example.yml') }} From 6ac4568a196541bdab565bf8d86e3b3b6eda2d1f Mon Sep 17 00:00:00 2001 From: Pablo Lopez Tarifa Date: Wed, 5 Aug 2020 11:47:52 +0200 Subject: [PATCH 336/647] Update _extras/glossary.md Co-authored-by: Stefan Verhoeven --- _extras/glossary.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index 358bdca6..00d8b704 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -6,7 +6,7 @@ title: Glossary Here, there are some definitions used throughout this tutorial: -- **Diagnostics**: +- **Diagnostics**: A diagnostic script is the last step in a recipe to convert the pre-processed input data to the desired output like plots or NetCDF files. - **CMIP**: The Coupled Model Intercomparison Project (CMIP) aims at better understanding past, present and future climate changes arising from natural, unforced variability or in response to changes in radiative forcing in a multi-model context. For more information, check the [WCR-Climate webpage](https://www.wcrp-climate.org/). @@ -17,4 +17,3 @@ Here, there are some definitions used throughout this tutorial: For more details on ESMValTool, please go to: Additional info can be found in [ESMValTool home page](https://esmvaltool.org) and [https://esmvaltool.readthedocs.io/](ESMValTool Read The Docs page). - From 9f003c0183328a02024ab94dff3f3e5702250a0c Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 13:59:00 +0200 Subject: [PATCH 337/647] Reduce line lengths --- setup.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/setup.md b/setup.md index 51a59f1a..a90ad8a8 100644 --- a/setup.md +++ b/setup.md @@ -68,7 +68,8 @@ If necessary, data can be downloaded using the ### CEDA-Jasmin -Please skip this section if you are not going to use JASMIN and go [here](#Github-account-(Advanced)). +Please skip this section if you are not going to use JASMIN +and go [here](#Github-account-(Advanced)). If you do not already have an account on JASMIN, then request an account as soon as possible. Please follow [these instructions on how to create a Jasmin @@ -257,7 +258,7 @@ data (12Gb). For this tutorial you can download the required data files by -1. Going to the [CMIP5 search page on the DKRZ ESGF node](https://esgf-data.dkrz.de/search/cmip5-dkrz/) +1. Going to the [CMIP5 search page on the DKRZ ESGF node](cmip5-search) 2. Performing the following search constraints - Model = HadGEM2-ES @@ -270,15 +271,20 @@ For this tutorial you can download the required data files by 4. On single single search result press `List files` 5. At bottom of page click on `Show All Files` 6. Find the file which starts with `thetaoga` in the list -7. Use `HTTP Download` link to download the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc)) file to `~/default_inputpath/` directory. +7. Use `HTTP Download` link to download + the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](theatoga.nc) file + to `~/default_inputpath/` directory. -The tutorial needs more data files. All of the data files should be downloaded to `~/default_inputpath/` directory with [wget](https://en.wikipedia.org/wiki/Wget): +The tutorial needs more data files. All of the data files should be downloaded +to `~/default_inputpath/` directory with [wget](https://en.wikipedia.org/wiki/Wget): ~~~shell -wget --input-file https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls --no-clobber --directory-prefix $HOME/default_inputpath/ +wget --no-clobber --input-file \ + https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls \ + --directory-prefix $HOME/default_inputpath/ ~~~ -The [dataset.urls](https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/rdataset.urls) file contains all data set urls and in comments the used search constraints. +The [dataset.urls](ds) file contains all data set urls and in comments the used search constraints. You will also need to able to use: @@ -344,3 +350,7 @@ More details on this process are available in the [Installation episode]({{ page.root}}{% link _episodes/02-installation.md %}). {% include links.md %} + +[cmip5-search]: https://esgf-data.dkrz.de/search/cmip5-dkrz/ +[theatoga.nc]: http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc +[ds]: https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls From de7af0c3ac4798ad0883da785124adbcdb35d348 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 14:01:55 +0200 Subject: [PATCH 338/647] Correct brackets --- setup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.md b/setup.md index a90ad8a8..8c5e35f0 100644 --- a/setup.md +++ b/setup.md @@ -258,7 +258,7 @@ data (12Gb). For this tutorial you can download the required data files by -1. Going to the [CMIP5 search page on the DKRZ ESGF node](cmip5-search) +1. Going to the [CMIP5 search page on the DKRZ ESGF node][cmip5-search] 2. Performing the following search constraints - Model = HadGEM2-ES @@ -272,7 +272,7 @@ For this tutorial you can download the required data files by 5. At bottom of page click on `Show All Files` 6. Find the file which starts with `thetaoga` in the list 7. Use `HTTP Download` link to download - the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc](theatoga.nc) file + the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc][theatoga.nc] file to `~/default_inputpath/` directory. The tutorial needs more data files. All of the data files should be downloaded @@ -284,7 +284,7 @@ wget --no-clobber --input-file \ --directory-prefix $HOME/default_inputpath/ ~~~ -The [dataset.urls](ds) file contains all data set urls and in comments the used search constraints. +The [dataset.urls][ds] file contains all data set urls and in comments the used search constraints. You will also need to able to use: From 295163ed5620ac74e8f670fefbdf9e76d42ff935 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 15:55:00 +0200 Subject: [PATCH 339/647] Apply suggestions from code review Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- setup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.md b/setup.md index 8c5e35f0..166fbbee 100644 --- a/setup.md +++ b/setup.md @@ -256,10 +256,10 @@ that you are able to download CMIP data and that you have several GB of space available to install conda & ESMValTool, but also enough to make a copy of some data (12Gb). -For this tutorial you can download the required data files by +We can download a single data file following the instructions as described below: -1. Going to the [CMIP5 search page on the DKRZ ESGF node][cmip5-search] -2. Performing the following search constraints +1. Go to the [CMIP5 search page on the DKRZ ESGF node][cmip5-search] +2. Perform the following search constraints - Model = HadGEM2-ES - Experiment = historical @@ -268,7 +268,7 @@ For this tutorial you can download the required data files by - Variable = thetaoga 3. Press search button -4. On single single search result press `List files` +4. On single search result press `List files` 5. At bottom of page click on `Show All Files` 6. Find the file which starts with `thetaoga` in the list 7. Use `HTTP Download` link to download From 0b3da6a8588b1625d16418718206d319d5ff909f Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 15:57:27 +0200 Subject: [PATCH 340/647] Update setup.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index 166fbbee..372c779f 100644 --- a/setup.md +++ b/setup.md @@ -275,7 +275,7 @@ We can download a single data file following the instructions as described below the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc][theatoga.nc] file to `~/default_inputpath/` directory. -The tutorial needs more data files. All of the data files should be downloaded +However, the tutorial needs more data files. The [dataset.urls][ds] file contains all data set URLs and in comments the used search constraints. All of the data files should be downloaded to `~/default_inputpath/` directory with [wget](https://en.wikipedia.org/wiki/Wget): ~~~shell From 6057799e34dd14e5345fa8a512c2b467224b4db2 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 16:00:04 +0200 Subject: [PATCH 341/647] Apply suggestions from code review Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- setup.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.md b/setup.md index 372c779f..8ecdaf7d 100644 --- a/setup.md +++ b/setup.md @@ -276,7 +276,9 @@ We can download a single data file following the instructions as described below to `~/default_inputpath/` directory. However, the tutorial needs more data files. The [dataset.urls][ds] file contains all data set URLs and in comments the used search constraints. All of the data files should be downloaded -to `~/default_inputpath/` directory with [wget](https://en.wikipedia.org/wiki/Wget): +to `~/default_inputpath/` directory. + +To download the data, run the following command using [wget](https://en.wikipedia.org/wiki/Wget): ~~~shell wget --no-clobber --input-file \ @@ -284,7 +286,6 @@ wget --no-clobber --input-file \ --directory-prefix $HOME/default_inputpath/ ~~~ -The [dataset.urls][ds] file contains all data set urls and in comments the used search constraints. You will also need to able to use: From 7843ac1590e97211e694a2a323388d6967bb4d8b Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 16:04:20 +0200 Subject: [PATCH 342/647] Remove local installation links, they are part of installation episode --- setup.md | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/setup.md b/setup.md index 8ecdaf7d..305793a3 100644 --- a/setup.md +++ b/setup.md @@ -276,7 +276,7 @@ We can download a single data file following the instructions as described below to `~/default_inputpath/` directory. However, the tutorial needs more data files. The [dataset.urls][ds] file contains all data set URLs and in comments the used search constraints. All of the data files should be downloaded -to `~/default_inputpath/` directory. +to `~/default_inputpath/` directory. To download the data, run the following command using [wget](https://en.wikipedia.org/wiki/Wget): @@ -286,29 +286,6 @@ wget --no-clobber --input-file \ --directory-prefix $HOME/default_inputpath/ ~~~ - -You will also need to able to use: - -- git -- conda - -#### Linux/Unix - -For Linux/Unix systems, please follow the instructions of the [Installation episode]({{ -page.root}}{% link _episodes/02-installation.md %}). - -#### Mac OSx - -Also, for Mac OSx systems, please follow the instructions of the [Installation episode]({{ -page.root}}{% link _episodes/02-installation.md %}). - -#### Windows - -ESMValTool does not directly support Windows, -but successful usage has been reported through the -[Windows Subsystem for Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), -available in Windows 10. - ## GitHub account (Advanced) You don’t need a github account to participate in the tutorial. However, if you From 97bf717858ab3cc76d01f17ae75e0f3bf8cd6765 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 Aug 2020 16:06:09 +0200 Subject: [PATCH 343/647] Dont mention conda in setup We will explain it in the install episode --- setup.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/setup.md b/setup.md index 305793a3..ac38ae81 100644 --- a/setup.md +++ b/setup.md @@ -318,15 +318,6 @@ A GitHub pull request is the act of requesting that a branch is merged with anot This is an advanced feature of GitHub, and will generally be performed by the ESMValTool development team. -## Install conda - -The python package manager Conda (anaconda or miniconda) needs to be installed -on your system before the tutorial starts. In some cases, your system may have a -central version installed already. - -More details on this process are available in the [Installation episode]({{ -page.root}}{% link _episodes/02-installation.md %}). - {% include links.md %} [cmip5-search]: https://esgf-data.dkrz.de/search/cmip5-dkrz/ From 9cfce62a6cf48c8047973a1a9862512d6e50aebb Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 10:44:12 +0200 Subject: [PATCH 344/647] replace apache with cc license for tutorial, add more info --- LICENSE.md | 266 +++++++++++++---------------------------------------- 1 file changed, 65 insertions(+), 201 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index d6456956..3a360ebc 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,202 +1,66 @@ +--- +layout: page +title: "Licenses" +root: . +--- +## Instructional Material - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +All ESMValTool instructional material is +made available under the [Creative Commons Attribution +license][cc-by-human]. The following is a human-readable summary of +(and not a substitute for) the [full legal text of the CC BY 4.0 +license][cc-by-legal]. + +You are free: + +* to **Share**---copy and redistribute the material in any medium or format +* to **Adapt**---remix, transform, and build upon the material + +for any purpose, even commercially. + +The licensor cannot revoke these freedoms as long as you follow the +license terms. + +Under the following terms: + +* **Attribution**---You must give appropriate credit (mentioning that + your work is derived from ESMValTool tutorial, provide a [link to the + license][cc-by-human], and indicate if changes were made. You may do + so in any reasonable manner, but not in any way that suggests the + licensor endorses you or your use. + +**No additional restrictions**---You may not apply legal terms or +technological measures that legally restrict others from doing +anything the license permits. With the understanding that: + +Notices: + +* You do not have to comply with the license for elements of the + material in the public domain or where your use is permitted by an + applicable exception or limitation. +* No warranties are given. The license may not give you all of the + permissions necessary for your intended use. For example, other + rights such as publicity, privacy, or moral rights may limit how you + use the material. + +## Software + +Except where otherwise noted, the example programs and other software +provided by ESMValTool tutorial are made available under the +[Apache License, version 2.0][Apache-license]. + +Citation of the +[ESMValTool paper](https://doi.org/10.5194/gmd-13-1179-2020,2020) +is kindly requested upon use, alongside with the software DOI for +ESMValTool (doi:10.5281/zenodo.3401363) +and ESMValCore (doi:10.5281/zenodo.3387139) and version number. + +## Style + +Using the [Carpentries style][style] version [9.5.3][version]. + +[cc-by-human]: https://creativecommons.org/licenses/by/4.0/ +[cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode +[Apache-license]: http://www.apache.org/licenses/LICENSE-2.0 +[style]: https://github.com/carpentries/styles/ +[version]: https://github.com/carpentries/styles/releases/tag/v9.5.3 From e7e0396b5fb4981c28559142db04aaedbfb8101d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 10:45:00 +0200 Subject: [PATCH 345/647] fix text in license section by providing a link to license.md --- _extras/about.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/_extras/about.md b/_extras/about.md index f0f105b6..1af187c0 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -42,10 +42,8 @@ and may be forked, developped and rehosted by other groups. ## License -The ESMValTool is released under the Apache License, version 2.0. Citation of -the ESMValTool paper (“Software Documentation Paper”) is kindly requested upon use, -alongside with the software DOI for ESMValTool (doi:10.5281/zenodo.3401363) -and ESMValCore (doi:10.5281/zenodo.3387139) and version number. +Please see +[license information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/LICENSE.md). ## Citation From 0fc04f83001e71267b908f5e0bffa24f3d59603e Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 10:49:33 +0200 Subject: [PATCH 346/647] revise a sentence --- LICENSE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index 3a360ebc..d9c49a5c 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -57,7 +57,8 @@ and ESMValCore (doi:10.5281/zenodo.3387139) and version number. ## Style -Using the [Carpentries style][style] version [9.5.3][version]. +ESMValTool tutorial uses +the [Carpentries style][style] version [9.5.3][version]. [cc-by-human]: https://creativecommons.org/licenses/by/4.0/ [cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode From e107256cbdfa36349c02b4ce7916df24c4d018b2 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 11:06:43 +0200 Subject: [PATCH 347/647] replace reference entry with bibtex format, add esmvaltool and core citation, update the text --- CITATION | 53 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/CITATION b/CITATION index e67c89b1..5c974682 100644 --- a/CITATION +++ b/CITATION @@ -1,17 +1,46 @@ Please cite this tutorial as: -- ESMValTool 2.0 tutorial, ESMValTool developers, version [ADD VERSION], - [https://github.com/ESMValGroup/ESMValTool_tutorial](https://github.com/ESMValGroup/ESMValTool_tutorial), - [DATE]. - -and cite ESMValTool as: - -- Righi, M., Andela, B., Eyring, V., Lauer, A., Predoi, V., Schlund, M., - Vegas-Regidor, J., Bock, L., Brötz, B., de Mora, L., Diblen, F., Dreyer, L., - Drost, N., Earnshaw, P., Hassler, B., Koldunov, N., Little, B., Loosveldt Tomas, - S., and Zimmermann, K.: - Earth System Model Evaluation Tool (ESMValTool) v2.0 – technical overview, - Geosci. Model Dev., 13, 1179–1199, https://doi.org/10.5194/gmd-13-1179-2020,2020. +- ESMValTool tutorial authors, "ESMValTool 2.0 tutorial", version [ADD VERSION], + August, 2020, + [https://github.com/ESMValGroup/ESMValTool_tutorial](https://github.com/ESMValGroup/ESMValTool_tutorial). + +and cite ESMValTool paper as: + +@article{Righi2020, + doi = {10.5194/gmd-13-1179-2020}, + url = {https://doi.org/10.5194/gmd-13-1179-2020}, + year = {2020}, + month = mar, + publisher = {Copernicus {GmbH}}, + volume = {13}, + number = {3}, + pages = {1179--1199}, + author = {Mattia Righi and Bouwe Andela and Veronika Eyring and Axel Lauer and Valeriu Predoi and Manuel Schlund and Javier Vegas-Regidor and Lisa Bock and Bj\"{o}rn Br\"{o}tz and Lee de Mora and Faruk Diblen and Laura Dreyer and Niels Drost and Paul Earnshaw and Birgit Hassler and Nikolay Koldunov and Bill Little and Saskia Loosveldt Tomas and Klaus Zimmermann}, + title = {Earth System Model Evaluation Tool ({ESMValTool}) v2.0 {\textendash} technical overview}, + journal = {Geoscientific Model Development} +} + +and cite ESMValTool and ESMValCore software as: + +@misc{https://doi.org/10.5281/zenodo.3401363, + doi = {10.5281/ZENODO.3401363}, + url = {https://zenodo.org/record/3401363}, + author = {Andela, Bouwe and Broetz, Bjoern and de Mora, Lee and Drost, Niels and Eyring, Veronika and Koldunov, Nikolay and Lauer, Axel and Mueller, Benjamin and Predoi, Valeriu and Righi, Mattia and Schlund, Manuel and Vegas-Regidor, Javier and Zimmermann, Klaus and Adeniyi, Kemisola and Arnone, Enrico and Bellprat, Omar and Berg, Peter and Bock, Lisa and Caron, Louis-Philippe and Carvalhais, Nuno and Cionni, Irene and Cortesi, Nicola and Corti, Susanna and Crezee, Bas and Davin, Edouard Leopold and Davini, Paolo and Deser, Clara and Diblen, Faruk and Docquier, David and Dreyer, Laura and Ehbrecht, Carsten and Earnshaw, Paul and Gier, Bettina and Gonzalez-Reviriego, Nube and Goodman, Paul and Hagemann, Stefan and von Hardenberg, Jost and Hassler, Birgit and Hunter, Alasdair and Kadow, Christopher and Kindermann, Stephan and Koirala, Sujan and Lledó, Lloren\c{c} and Lejeune, Quentin and Lembo, Valerio and Little, Bill and Loosveldt-Tomas, Saskia and Lorenz, Ruth and Lovato, Tomas and Lucarini, Valerio and Massonnet, Fran\c{c}ois and Mohr, Christian Wilhelm and Amarjiit, Pandde and Pérez-Zanón, Núria and Phillips, Adam and Russell, Joellen and Sandstad, Marit and Sellar, Alistair and Senftleben, Daniel and Serva, Federico and Sillmann, Jana and Stacke, Tobias and Swaminathan, Ranjini and Torralba, Verónica and Weigel, Katja}, + title = {ESMValTool}, + publisher = {Zenodo}, + year = {2020}, + copyright = {Apache License 2.0} +} + +@misc{https://doi.org/10.5281/zenodo.3387139, + doi = {10.5281/ZENODO.3387139}, + url = {https://zenodo.org/record/3387139}, + author = {Andela, Bouwe and Broetz, Bjoern and de Mora, Lee and Drost, Niels and Eyring, Veronika and Koldunov, Nikolay and Lauer, Axel and Predoi, Valeriu and Righi, Mattia and Schlund, Manuel and Vegas-Regidor, Javier and Zimmermann, Klaus and Bock, Lisa and Diblen, Faruk and Dreyer, Laura and Earnshaw, Paul and Hassler, Birgit and Little, Bill and Loosveldt-Tomas, Saskia}, + title = {ESMValCore}, + publisher = {Zenodo}, + year = {2020}, + copyright = {Apache License 2.0} +} See additional resources at https://www.esmvaltool.org/references.html. From b3a76dbf5530880ff44538a81a5f4d98215da150 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 14:07:50 +0200 Subject: [PATCH 348/647] update the text --- LICENSE.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index d9c49a5c..4fe4a577 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -24,7 +24,9 @@ license terms. Under the following terms: * **Attribution**---You must give appropriate credit (mentioning that - your work is derived from ESMValTool tutorial, provide a [link to the + your work is derived from work that is + Copyright © [ESMValTool Development Team][Development_Team], + provide a [link to the license][cc-by-human], and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. @@ -51,9 +53,8 @@ provided by ESMValTool tutorial are made available under the Citation of the [ESMValTool paper](https://doi.org/10.5194/gmd-13-1179-2020,2020) -is kindly requested upon use, alongside with the software DOI for -ESMValTool (doi:10.5281/zenodo.3401363) -and ESMValCore (doi:10.5281/zenodo.3387139) and version number. +is kindly requested upon use, alongside with the software license for +[ESMValTool and ESMValCore][ESMValTool-ESMValCore-license]. ## Style @@ -62,6 +63,8 @@ the [Carpentries style][style] version [9.5.3][version]. [cc-by-human]: https://creativecommons.org/licenses/by/4.0/ [cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode +[Development_Team]: https://www.esmvaltool.org/team.html [Apache-license]: http://www.apache.org/licenses/LICENSE-2.0 +[ESMValTool-ESMValCore-license]: https://docs.esmvaltool.org/en/latest/introduction.html#license [style]: https://github.com/carpentries/styles/ [version]: https://github.com/carpentries/styles/releases/tag/v9.5.3 From d025b5d6b7e3e6aa958e2de6299c4c7963334229 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 15:05:07 +0200 Subject: [PATCH 349/647] make citation.cff, fix broken links --- AUTHORS | 52 --------------------- CITATION | 46 ------------------ CITATION.cff | 79 +++++++++++++++++++++++++++++++ README.md | 6 +-- _episodes/07-conclusions.md | 6 +-- _extras/about.md | 93 +++++++++++++++++++++++++++---------- index.md | 7 +-- 7 files changed, 156 insertions(+), 133 deletions(-) delete mode 100644 AUTHORS delete mode 100644 CITATION create mode 100644 CITATION.cff diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 3603b5f2..00000000 --- a/AUTHORS +++ /dev/null @@ -1,52 +0,0 @@ -name: Andela, Bouwe - institute: NLeSC, Netherlands - email: b.andela@esciencecenter.nl - orcid: https://orcid.org/0000-0001-9005-8940 - -name: de Mora, Lee - institute: PML, UK - email: ledm@pml.ac.uK - orcid: https://orcid.org/0000-0002-5080-3149 - -name: Drost, Niels - institute: NLeSC, Netherlands - email: n.drost@esciencecenter.nl - orcid: https://orcid.org/0000-0001-9795-7981 - -name: Mueller, Benjamin - institute: LMU, Germany - email: b.mueller@iggf.geo.uni-muenchen.de - orcid: - -name: Predoi, Valeriu - institute: URead, UK - email: valeriu.predoi@ncas.ac.uk - orcid: https://orcid.org/0000-0002-9729-6578 - -name: Alidoost, Sarah - institute: NLeSC, Netherlands - orcid: https://orcid.org/0000-0001-8407-6472 - -name: Bock, Lisa - institute: DLR, Germany - orcid: https://orcid.org/0000-0001-7058-5938 - -name: Camphuijsen, Jaro - institute: NLeSC, Netherlands - orcid: https://orcid.org/0000-0002-8928-7831 - -name: Hassler, Birgit - institute: DLR, Germany - orcid: https://orcid.org/0000-0003-2724-709X - -name: Kalverla, Peter - institute: NLeSC, Netherlands - orcid: https://orcid.org/0000-0002-5025-7862 - -name: Swaminathan, Ranjini - institute: University of Reading, UK - orcid: https://orcid.org/0000-0001-5853-2673 - -name: Verhoeven, Stefan - institute: NLeSC, Netherlands - orcid: https://orcid.org/0000-0002-5821-2060 diff --git a/CITATION b/CITATION deleted file mode 100644 index 5c974682..00000000 --- a/CITATION +++ /dev/null @@ -1,46 +0,0 @@ -Please cite this tutorial as: - -- ESMValTool tutorial authors, "ESMValTool 2.0 tutorial", version [ADD VERSION], - August, 2020, - [https://github.com/ESMValGroup/ESMValTool_tutorial](https://github.com/ESMValGroup/ESMValTool_tutorial). - -and cite ESMValTool paper as: - -@article{Righi2020, - doi = {10.5194/gmd-13-1179-2020}, - url = {https://doi.org/10.5194/gmd-13-1179-2020}, - year = {2020}, - month = mar, - publisher = {Copernicus {GmbH}}, - volume = {13}, - number = {3}, - pages = {1179--1199}, - author = {Mattia Righi and Bouwe Andela and Veronika Eyring and Axel Lauer and Valeriu Predoi and Manuel Schlund and Javier Vegas-Regidor and Lisa Bock and Bj\"{o}rn Br\"{o}tz and Lee de Mora and Faruk Diblen and Laura Dreyer and Niels Drost and Paul Earnshaw and Birgit Hassler and Nikolay Koldunov and Bill Little and Saskia Loosveldt Tomas and Klaus Zimmermann}, - title = {Earth System Model Evaluation Tool ({ESMValTool}) v2.0 {\textendash} technical overview}, - journal = {Geoscientific Model Development} -} - -and cite ESMValTool and ESMValCore software as: - -@misc{https://doi.org/10.5281/zenodo.3401363, - doi = {10.5281/ZENODO.3401363}, - url = {https://zenodo.org/record/3401363}, - author = {Andela, Bouwe and Broetz, Bjoern and de Mora, Lee and Drost, Niels and Eyring, Veronika and Koldunov, Nikolay and Lauer, Axel and Mueller, Benjamin and Predoi, Valeriu and Righi, Mattia and Schlund, Manuel and Vegas-Regidor, Javier and Zimmermann, Klaus and Adeniyi, Kemisola and Arnone, Enrico and Bellprat, Omar and Berg, Peter and Bock, Lisa and Caron, Louis-Philippe and Carvalhais, Nuno and Cionni, Irene and Cortesi, Nicola and Corti, Susanna and Crezee, Bas and Davin, Edouard Leopold and Davini, Paolo and Deser, Clara and Diblen, Faruk and Docquier, David and Dreyer, Laura and Ehbrecht, Carsten and Earnshaw, Paul and Gier, Bettina and Gonzalez-Reviriego, Nube and Goodman, Paul and Hagemann, Stefan and von Hardenberg, Jost and Hassler, Birgit and Hunter, Alasdair and Kadow, Christopher and Kindermann, Stephan and Koirala, Sujan and Lledó, Lloren\c{c} and Lejeune, Quentin and Lembo, Valerio and Little, Bill and Loosveldt-Tomas, Saskia and Lorenz, Ruth and Lovato, Tomas and Lucarini, Valerio and Massonnet, Fran\c{c}ois and Mohr, Christian Wilhelm and Amarjiit, Pandde and Pérez-Zanón, Núria and Phillips, Adam and Russell, Joellen and Sandstad, Marit and Sellar, Alistair and Senftleben, Daniel and Serva, Federico and Sillmann, Jana and Stacke, Tobias and Swaminathan, Ranjini and Torralba, Verónica and Weigel, Katja}, - title = {ESMValTool}, - publisher = {Zenodo}, - year = {2020}, - copyright = {Apache License 2.0} -} - -@misc{https://doi.org/10.5281/zenodo.3387139, - doi = {10.5281/ZENODO.3387139}, - url = {https://zenodo.org/record/3387139}, - author = {Andela, Bouwe and Broetz, Bjoern and de Mora, Lee and Drost, Niels and Eyring, Veronika and Koldunov, Nikolay and Lauer, Axel and Predoi, Valeriu and Righi, Mattia and Schlund, Manuel and Vegas-Regidor, Javier and Zimmermann, Klaus and Bock, Lisa and Diblen, Faruk and Dreyer, Laura and Earnshaw, Paul and Hassler, Birgit and Little, Bill and Loosveldt-Tomas, Saskia}, - title = {ESMValCore}, - publisher = {Zenodo}, - year = {2020}, - copyright = {Apache License 2.0} -} - -See additional resources at https://www.esmvaltool.org/references.html. - diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 00000000..6480797e --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,79 @@ +# YAML 1.2 +--- +abstract: "ESMValTool 2.0 Tutorial." + +authors: + - + affiliation: "NLeSC, Netherlands" + family-names: Alidoost + given-names: Fakhereh + orcid: "https://orcid.org/0000-0001-8407-6472" + - + affiliation: "NLeSC, Netherlands" + family-names: Andela + given-names: Bouwe + orcid: "https://orcid.org/0000-0001-9005-8940" + - + affiliation: "DLR, Germany" + family-names: Bock + given-names: Lisa + orcid: "https://orcid.org/0000-0001-7058-5938" + - + affiliation: "NLeSC, Netherlands" + family-names: Camphuijsen + given-names: Jaro + orcid: "https://orcid.org/0000-0002-8928-7831" + - + affiliation: "NLeSC, Netherlands" + family-names: Drost + given-names: Niels + orcid: "https://orcid.org/0000-0001-9795-7981" + - + affiliation: "DLR, Germany" + family-names: Hassler + given-names: Birgit + orcid: "https://orcid.org/0000-0003-2724-709X" + - + affiliation: "NLeSC, Netherlands" + family-names: Kalverla + given-names: Peter + orcid: "https://orcid.org/0000-0002-5025-7862" + - + affiliation: "NLeSC, Netherlands" + family-names: López-Tarifa + given-names: Pablo + orcid: "https://orcid.org/0000-0002-4136-1860" + - + affiliation: "PML, UK" + name-particle: de + family-names: Mora + given-names: Lee + orcid: "https://orcid.org/0000-0002-5080-3149" + - + affiliation: "LMU, Germany" + family-names: Mueller + given-names: Benjamin + - + affiliation: "URead, UK" + family-names: Predoi + given-names: Valeriu + orcid: "https://orcid.org/0000-0002-9729-6578" + - + affiliation: "URead, UK" + family-names: Swaminathan + given-names: Ranjini + orcid: "https://orcid.org/0000-0001-5853-2673" + - + affiliation: "NLeSC, Netherlands" + family-names: Verhoeven + given-names: Stefan + orcid: "https://orcid.org/0000-0002-5821-2060" +cff-version: "1.0.3" +date-released: 2020-08-06 +doi: "" +license: "CC-BY-4.0" +message: "If you use this tutorial, please cite it using these metadata." +repository-code: "https://github.com/ESMValGroup/ESMValTool_Tutorial/" +title: "ESMValTool Tutorial" +version: "v1.0.0" +... diff --git a/README.md b/README.md index 50c844e8..432cdefb 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,9 @@ If you work or study in climate-related domains and would be interested in getting involved, you can reach us by email. Please see [information][contact-info] on how to subscribe to user mailing list. -## Authors - -A list of contributors to the lesson can be found in [AUTHORS](AUTHORS). - ## Citation -To cite this tutorial, please consult with [CITATION](CITATION). +To cite this tutorial, please consult with [CITATION](CITATION.cff). [ESMValTool-site]: https://www.esmvaltool.org/ [ESMValTool-doc]: https://esmvaltool.readthedocs.io/en/latest/ diff --git a/_episodes/07-conclusions.md b/_episodes/07-conclusions.md index 44ffc3bb..bc344f84 100644 --- a/_episodes/07-conclusions.md +++ b/_episodes/07-conclusions.md @@ -59,7 +59,7 @@ to be suitable for use by ESMValTool. > > - [Documenation](https://docs.esmvaltool.org) > - [ESMValTool home page](https://www.esmvaltool.org/) -> - [Papers](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION) +> - [Papers](https://www.esmvaltool.org/references.html) > - [Source code (ESMValTool)](https://github.com/ESMValGroup/ESMValTool) > - [Source code (ESMValCore )](https://github.com/ESMValGroup/ESMValCore) {: .callout} @@ -89,8 +89,8 @@ To report a bug, please create a new issue using the In your bug report, please describe the problem as clearly and as completely as possible. You may need to include a recipe or the output log as well. -### How do I cite the Tutorial and ESMValTool? +### How do I cite the Tutorial? -Please see [citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION). +Please see [citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION.cff) {% include links.md %} diff --git a/_extras/about.md b/_extras/about.md index f0f105b6..eddbd1af 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -50,37 +50,82 @@ and ESMValCore (doi:10.5281/zenodo.3387139) and version number. ## Citation Please see -[citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION). +[citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION.cff). -Citing the Software Documentation Paper and registering your papers +## Acknowledgements + +Citing the ESMValTool paper and registering your papers will serve to document the scientific impact of the Software, which is of vital importance for securing future funding. - You should consider this an obligation if you have taken advantage of the ESMValTool, which represents the end product of considerable effort by the development teams. -## Acknowledgements - -The technical development work for ESMValTool v2.0 was funded by various projects, -in particular (1) the Copernicus Climate Change Service (C3S) “Metrics and Access -to Global Indices for Climate Projections (C3S-MAGIC)” project; (2) the -European Union's Horizon 2020 Framework Programme for Research and Innovation -“Infrastructure for the European Network for Earth System Modelling (IS-ENES3)” -project under grant agreement no. 824084; (3) the European Union's Horizon 2020 -Framework Programme for Research and Innovation “Coordinated Research in Earth -Systems and Climate: Experiments, kNowledge, Dissemination and Outreach (CRESCENDO)” -project under grant agreement no. 641816; (4) the the European Union's Horizon -2020 Framework Programme for Research and Innovation “PRocess-based climate -sIMulation: AdVances in high-resolution modelling and European climate Risk -Assessment (PRIMAVERA)” project under grant agreement no. 641727; (5) the -Helmholtz Society project “Advanced Earth System Model Evaluation for CMIP -(Eval4CMIP)”; (6) project S1 (Diagnosis and Metrics in Climate Models) of -the Collaborative Research Centre TRR 181 “Energy Transfer in Atmosphere and -Ocean” funded by the Deutsche Forschungsgemeinschaft (DFG, German Research -Foundation) project no. 274762653; and (7) National Environmental Research -Council (NERC) National Capability Science Multi-Centre (NCSMC) funding for -the UK, Earth System Modelling project (grant no. NE/N018036/1). +Please cite ESMValTool paper as: + +@article{Righi2020, + doi = {10.5194/gmd-13-1179-2020}, + url = {https://doi.org/10.5194/gmd-13-1179-2020}, + year = {2020}, + month = mar, + publisher = {Copernicus {GmbH}}, + volume = {13}, + number = {3}, + pages = {1179--1199}, + author = {Mattia Righi and Bouwe Andela and Veronika Eyring and Axel Lauer and Valeriu Predoi + and Manuel Schlund and Javier Vegas-Regidor and Lisa Bock and Bj\"{o}rn Br\"{o}tz and + Lee de Mora and Faruk Diblen and Laura Dreyer and Niels Drost and Paul Earnshaw and + Birgit Hassler and Nikolay Koldunov and Bill Little and Saskia Loosveldt Tomas and Klaus Zimmermann}, + title = {Earth System Model Evaluation Tool ({ESMValTool}) v2.0 {\textendash} technical overview}, + journal = {Geoscientific Model Development} +} + +and cite ESMValTool and ESMValCore software as: + +@misc{https://doi.org/10.5281/zenodo.3401363, + doi = {10.5281/ZENODO.3401363}, + url = {https://zenodo.org/record/3401363}, + author = {Andela, Bouwe and Broetz, Bjoern and de Mora, Lee and Drost, Niels and + Eyring, Veronika and Koldunov, Nikolay and Lauer, Axel and Mueller, Benjamin and + Predoi, Valeriu and Righi, Mattia and Schlund, Manuel and Vegas-Regidor, Javier and + Zimmermann, Klaus and Adeniyi, Kemisola and Arnone, Enrico and Bellprat, Omar and + Berg, Peter and Bock, Lisa and Caron, Louis-Philippe and Carvalhais, Nuno and + Cionni, Irene and Cortesi, Nicola and Corti, Susanna and Crezee, Bas and + Davin, Edouard Leopold and Davini, Paolo and Deser, Clara and Diblen, Faruk and + Docquier, David and Dreyer, Laura and Ehbrecht, Carsten and Earnshaw, Paul and + Gier, Bettina and Gonzalez-Reviriego, Nube and Goodman, Paul and Hagemann, Stefan and + von Hardenberg, Jost and Hassler, Birgit and Hunter, Alasdair and Kadow, Christopher and + Kindermann, Stephan and Koirala, Sujan and Lledó, Lloren\c{c} and Lejeune, Quentin and + Lembo, Valerio and Little, Bill and Loosveldt-Tomas, Saskia and Lorenz, Ruth + and Lovato, Tomas and Lucarini, Valerio and Massonnet, Fran\c{c}ois + and Mohr, Christian Wilhelm and Amarjiit, Pandde and Pérez-Zanón, Núria + and Phillips, Adam and Russell, Joellen and Sandstad, Marit and Sellar, Alistair + and Senftleben, Daniel and Serva, Federico and Sillmann, Jana and Stacke, Tobias + and Swaminathan, Ranjini and Torralba, Verónica and Weigel, Katja}, + title = {ESMValTool}, + publisher = {Zenodo}, + year = {2020}, + copyright = {Apache License 2.0} +} + +@misc{https://doi.org/10.5281/zenodo.3387139, + doi = {10.5281/ZENODO.3387139}, + url = {https://zenodo.org/record/3387139}, + author = {Andela, Bouwe and Broetz, Bjoern and de Mora, Lee and Drost, Niels and + Eyring, Veronika and Koldunov, Nikolay and Lauer, Axel and Predoi, Valeriu and + Righi, Mattia and Schlund, Manuel and Vegas-Regidor, Javier and Zimmermann, Klaus and + Bock, Lisa and Diblen, Faruk and Dreyer, Laura and Earnshaw, Paul and + Hassler, Birgit and Little, Bill and Loosveldt-Tomas, Saskia}, + title = {ESMValCore}, + publisher = {Zenodo}, + year = {2020}, + copyright = {Apache License 2.0} +} + +See additional resources at https://www.esmvaltool.org/references.html. + +The technical development work for ESMValTool v2.0 was funded by +[various projects](https://www.esmvaltool.org/acknowledgements.html). {% include escience_academy.html %} diff --git a/index.md b/index.md index 644e3239..a056c73a 100644 --- a/index.md +++ b/index.md @@ -63,15 +63,16 @@ independently. > > - [Documentation](https://docs.esmvaltool.org) > - [ESMValTool home page](https://www.esmvaltool.org/) -> - [Papers](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION) +> - [Papers](https://www.esmvaltool.org/references.html) > - [ESMValTool Source code](https://github.com/ESMValGroup/ESMValTool) > - [ESMValCore Source code](https://github.com/ESMValGroup/ESMValCore) +> - [ESMValTool Citation info](https://esmvalgroup.github.io/ESMValTool_Tutorial/about/index.html) > {: .callout} -## How to cite the Tutorial and ESMValTool +## How to cite the Tutorial Please see -[citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION). +[citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION.cff). {% include links.md %} From 947bc689642813f398e8c9f18dcd52f5eb7b483d Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 6 Aug 2020 15:06:32 +0200 Subject: [PATCH 350/647] Update LICENSE.md Co-authored-by: Peter Kalverla --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index 4fe4a577..66b47308 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -31,7 +31,7 @@ Under the following terms: so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. -**No additional restrictions**---You may not apply legal terms or +* **No additional restrictions**---You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. With the understanding that: From 4a9fabe0236b7da2816071bbaae091b8c0245bf3 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 15:09:33 +0200 Subject: [PATCH 351/647] remove citation info from license --- LICENSE.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 66b47308..4cc470db 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -51,11 +51,6 @@ Except where otherwise noted, the example programs and other software provided by ESMValTool tutorial are made available under the [Apache License, version 2.0][Apache-license]. -Citation of the -[ESMValTool paper](https://doi.org/10.5194/gmd-13-1179-2020,2020) -is kindly requested upon use, alongside with the software license for -[ESMValTool and ESMValCore][ESMValTool-ESMValCore-license]. - ## Style ESMValTool tutorial uses From 363b62fab81fda7a452cb90b994adcdfd4f73a45 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 15:31:30 +0200 Subject: [PATCH 352/647] add zenodo file --- .zenodo.json | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ CITATION.cff | 3 ++ 2 files changed, 95 insertions(+) create mode 100644 .zenodo.json diff --git a/.zenodo.json b/.zenodo.json new file mode 100644 index 00000000..2463548d --- /dev/null +++ b/.zenodo.json @@ -0,0 +1,92 @@ +{ + "creators": [ + { + "affiliation": "NLeSC, Netherlands", + "name": "Alidoost, Fakhereh", + "orcid": "0000-0001-8407-6472" + }, + { + "affiliation": "NLeSC, Netherlands", + "name": "Andela, Bouwe", + "orcid": "0000-0001-9005-8940" + }, + { + "affiliation": "DLR, Germany", + "name": "Bock, Lisa", + "orcid": "0000-0001-7058-5938" + }, + { + "affiliation": "NLeSC, Netherlands", + "name": "Camphuijsen, Jaro", + "orcid": "0000-0002-8928-7831" + }, + { + "affiliation": "NLeSC, Netherlands", + "name": "Drost, Niels", + "orcid": "0000-0001-9795-7981" + }, + { + "affiliation": "DLR, Germany", + "name": "Hassler, Birgit", + "orcid": "0000-0003-2724-709X" + }, + { + "affiliation": "NLeSC, Netherlands", + "name": "Kalverla, Peter", + "orcid": "0000-0002-5025-7862" + }, + { + "affiliation": "NLeSC, Netherlands", + "name": "López-Tarifa, Pablo", + "orcid": "0000-0002-4136-1860" + }, + { + "affiliation": "PML, UK", + "name": "de Mora, Lee", + "orcid": "0000-0002-5080-3149" + }, + { + "affiliation": "LMU, Germany", + "name": "Mueller, Benjamin" + }, + { + "affiliation": "URead, UK", + "name": "Predoi, Valeriu", + "orcid": "0000-0002-9729-6578" + }, + { + "affiliation": "URead, UK", + "name": "Swaminathan, Ranjini", + "orcid": "0000-0001-5853-2673" + }, + { + "affiliation": "NLeSC, Netherlands", + "name": "Verhoeven, Stefan", + "orcid": "0000-0002-5821-2060" + } + ], + "description": "ESMValTool 2.0 Tutorial.", + "license": { + "id": "CC-BY-4.0" + }, + "title": "ESMValTool Tutorial", + "communities": [ + { + "identifier": "is-enes3" + }, + { + "identifier": "dlr_de" + }, + { + "identifier": "nlesc" + } + ], + "grants": [ + { + "id": "10.13039/501100000780::641727" + }, + { + "id": "10.13039/501100000780::824084" + } + ] +} diff --git a/CITATION.cff b/CITATION.cff index 6480797e..221d1505 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -75,5 +75,8 @@ license: "CC-BY-4.0" message: "If you use this tutorial, please cite it using these metadata." repository-code: "https://github.com/ESMValGroup/ESMValTool_Tutorial/" title: "ESMValTool Tutorial" +keyword: + - Earth System Model Validation + - Climate Science version: "v1.0.0" ... From 26c0edf1ded0c8911b64f17b33abc03970a69529 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 6 Aug 2020 15:32:17 +0200 Subject: [PATCH 353/647] Update README.md Co-authored-by: Peter Kalverla --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 432cdefb..a5ef6471 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Please see [information][contact-info] on how to subscribe to user mailing list. ## Citation -To cite this tutorial, please consult with [CITATION](CITATION.cff). +To cite this tutorial, please use the information available [here](CITATION.cff). [ESMValTool-site]: https://www.esmvaltool.org/ [ESMValTool-doc]: https://esmvaltool.readthedocs.io/en/latest/ From 9c9484af86d78ef7e72760412495f871a4529c42 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 6 Aug 2020 15:34:49 +0200 Subject: [PATCH 354/647] Update CITATION.cff Co-authored-by: Peter Kalverla --- CITATION.cff | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CITATION.cff b/CITATION.cff index 221d1505..838d05cb 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -75,7 +75,7 @@ license: "CC-BY-4.0" message: "If you use this tutorial, please cite it using these metadata." repository-code: "https://github.com/ESMValGroup/ESMValTool_Tutorial/" title: "ESMValTool Tutorial" -keyword: +keywords: - Earth System Model Validation - Climate Science version: "v1.0.0" From f8151f1179ced8a568c268070db0567ace6d5e3a Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 6 Aug 2020 15:34:57 +0200 Subject: [PATCH 355/647] Update CITATION.cff Co-authored-by: Peter Kalverla --- CITATION.cff | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 838d05cb..6a579cab 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -76,7 +76,7 @@ message: "If you use this tutorial, please cite it using these metadata." repository-code: "https://github.com/ESMValGroup/ESMValTool_Tutorial/" title: "ESMValTool Tutorial" keywords: - - Earth System Model Validation - - Climate Science + - "Earth System Model Validation" + - "Climate Science" version: "v1.0.0" ... From 13dbc5d93df3ae9efc194888fa13044d26c3617d Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 6 Aug 2020 15:52:36 +0200 Subject: [PATCH 356/647] Update lesson_footer.html Change to .cff citation file --- _includes/lesson_footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/lesson_footer.html b/_includes/lesson_footer.html index 03091a7c..ad8cdda0 100644 --- a/_includes/lesson_footer.html +++ b/_includes/lesson_footer.html @@ -40,7 +40,7 @@ / Source / - Cite + Cite / Contact From 07255244f3768efc8dd6535ae5e2f7341210aaf2 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 6 Aug 2020 16:01:42 +0200 Subject: [PATCH 357/647] replace alpha with beta --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 496c642f..60e980e3 100644 --- a/_config.yml +++ b/_config.yml @@ -16,7 +16,7 @@ title: "ESMValTool Tutorial" # Life cycle stage of the lesson # possible values: "pre-alpha", "alpha", "beta", "stable" -life_cycle: "alpha" +life_cycle: "beta" #------------------------------------------------------------ # Generic settings (should not need to change). From 612b6bd7ede0b4d3d16b52ace10bf2778da22964 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 6 Aug 2020 16:24:59 +0200 Subject: [PATCH 358/647] Add DOI badge --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a5ef6471..455993aa 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ [![Join the chat at https://gitter.im/ESMValGroup/Tutorial](https://badges.gitter.im/ESMValGroup/Tutorial.svg)](https://gitter.im/ESMValGroup/Tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3974592.svg)](https://doi.org/10.5281/zenodo.3974592) + + [ESMValTool Tutorial][tutorial-site] is an open-source project in [ESMValGroup][ESMValTool-site]. This tutorial is a set of lessons that together teach skills needed to work From d0cf81b54d68a24ce356c97d0826e77e6c393bc5 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 6 Aug 2020 16:26:08 +0200 Subject: [PATCH 359/647] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 455993aa..cbf50403 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ [![Join the chat at https://gitter.im/ESMValGroup/Tutorial](https://badges.gitter.im/ESMValGroup/Tutorial.svg)](https://gitter.im/ESMValGroup/Tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3974592.svg)](https://doi.org/10.5281/zenodo.3974592) From cf6c9185a1f9c0f54ddd08bb1d0daacef9d1b824 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 6 Aug 2020 16:38:20 +0200 Subject: [PATCH 360/647] Update EUCP grant (used wrong number) --- .zenodo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.zenodo.json b/.zenodo.json index 2463548d..9d4a03c8 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -83,7 +83,7 @@ ], "grants": [ { - "id": "10.13039/501100000780::641727" + "id": "10.13039/501100000780::776613" }, { "id": "10.13039/501100000780::824084" From 994b2337949da5bed87cd3a6db3903828b3ae923 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 6 Aug 2020 16:55:25 +0200 Subject: [PATCH 361/647] Add eWaterCycle II grant information --- .zenodo.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.zenodo.json b/.zenodo.json index 9d4a03c8..2be51800 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -87,6 +87,9 @@ }, { "id": "10.13039/501100000780::824084" + }, + { + "id": "10.13039/501100003246::2300185259" } ] } From 68bfa3497f48c30f2f46b0ff367cdd58828c1910 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 17:18:59 +0200 Subject: [PATCH 362/647] add zenodo link for citation of the tutorial --- README.md | 3 ++- _episodes/07-conclusions.md | 3 ++- _extras/about.md | 4 ++-- index.md | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cbf50403..d1f0198e 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,8 @@ Please see [information][contact-info] on how to subscribe to user mailing list. ## Citation -To cite this tutorial, please use the information available [here](CITATION.cff). +To cite this tutorial, please use the information available at +[http://doi.org/10.5281/zenodo.3974592](http://doi.org/10.5281/zenodo.3974592). [ESMValTool-site]: https://www.esmvaltool.org/ [ESMValTool-doc]: https://esmvaltool.readthedocs.io/en/latest/ diff --git a/_episodes/07-conclusions.md b/_episodes/07-conclusions.md index bc344f84..0ed72db9 100644 --- a/_episodes/07-conclusions.md +++ b/_episodes/07-conclusions.md @@ -91,6 +91,7 @@ You may need to include a recipe or the output log as well. ### How do I cite the Tutorial? -Please see [citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION.cff) +Please use citation information available at +[http://doi.org/10.5281/zenodo.3974592](http://doi.org/10.5281/zenodo.3974592). {% include links.md %} diff --git a/_extras/about.md b/_extras/about.md index ef0bb5f5..38361193 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -47,8 +47,8 @@ Please see ## Citation -Please see -[citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION.cff). +Please use citation information available at +[http://doi.org/10.5281/zenodo.3974592](http://doi.org/10.5281/zenodo.3974592). ## Acknowledgements diff --git a/index.md b/index.md index a056c73a..10032e6b 100644 --- a/index.md +++ b/index.md @@ -72,7 +72,7 @@ independently. ## How to cite the Tutorial -Please see -[citation information](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/CITATION.cff). +Please use citation information available at +[http://doi.org/10.5281/zenodo.3974592](http://doi.org/10.5281/zenodo.3974592). {% include links.md %} From 330bd9fe03ad250ceaac52e74224e481bb35691d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 17:21:33 +0200 Subject: [PATCH 363/647] add zenodo doi to citation file --- CITATION.cff | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CITATION.cff b/CITATION.cff index 6a579cab..cd470908 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -70,7 +70,7 @@ authors: orcid: "https://orcid.org/0000-0002-5821-2060" cff-version: "1.0.3" date-released: 2020-08-06 -doi: "" +doi: "10.5281/zenodo.3974592" license: "CC-BY-4.0" message: "If you use this tutorial, please cite it using these metadata." repository-code: "https://github.com/ESMValGroup/ESMValTool_Tutorial/" From 85fddd9aa270c8a28f69ba211e524397113fec2f Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 6 Aug 2020 17:28:44 +0200 Subject: [PATCH 364/647] fix a link --- _extras/about.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_extras/about.md b/_extras/about.md index 38361193..d5e11a3c 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -120,7 +120,8 @@ and cite ESMValTool and ESMValCore software as: copyright = {Apache License 2.0} } -See additional resources at https://www.esmvaltool.org/references.html. +See additional resources at +[https://www.esmvaltool.org/references.html](https://www.esmvaltool.org/references.html). The technical development work for ESMValTool v2.0 was funded by [various projects](https://www.esmvaltool.org/acknowledgements.html). From cdfd66869125ab78a6271460a2a17f556fdb6e03 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 7 Aug 2020 09:06:18 +0200 Subject: [PATCH 365/647] add zenodo link for Cite --- _includes/lesson_footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/lesson_footer.html b/_includes/lesson_footer.html index ad8cdda0..e18ef5a0 100644 --- a/_includes/lesson_footer.html +++ b/_includes/lesson_footer.html @@ -40,7 +40,7 @@ / Source / - Cite + Cite / Contact From 62de036db88f2544cb9cfba2f98b3ad520305d33 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 7 Aug 2020 09:28:05 +0200 Subject: [PATCH 366/647] replace specific doi with general one --- CITATION.cff | 2 +- README.md | 2 +- _episodes/07-conclusions.md | 2 +- _extras/about.md | 2 +- _includes/lesson_footer.html | 2 +- index.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index cd470908..4061aa7e 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -70,7 +70,7 @@ authors: orcid: "https://orcid.org/0000-0002-5821-2060" cff-version: "1.0.3" date-released: 2020-08-06 -doi: "10.5281/zenodo.3974592" +doi: "10.5281/zenodo.3974591" license: "CC-BY-4.0" message: "If you use this tutorial, please cite it using these metadata." repository-code: "https://github.com/ESMValGroup/ESMValTool_Tutorial/" diff --git a/README.md b/README.md index d1f0198e..854bfea8 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Please see [information][contact-info] on how to subscribe to user mailing list. ## Citation To cite this tutorial, please use the information available at -[http://doi.org/10.5281/zenodo.3974592](http://doi.org/10.5281/zenodo.3974592). +[https://doi.org/10.5281/zenodo.3974591](https://doi.org/10.5281/zenodo.3974591). [ESMValTool-site]: https://www.esmvaltool.org/ [ESMValTool-doc]: https://esmvaltool.readthedocs.io/en/latest/ diff --git a/_episodes/07-conclusions.md b/_episodes/07-conclusions.md index 0ed72db9..b1f6183f 100644 --- a/_episodes/07-conclusions.md +++ b/_episodes/07-conclusions.md @@ -92,6 +92,6 @@ You may need to include a recipe or the output log as well. ### How do I cite the Tutorial? Please use citation information available at -[http://doi.org/10.5281/zenodo.3974592](http://doi.org/10.5281/zenodo.3974592). +[https://doi.org/10.5281/zenodo.3974591](https://doi.org/10.5281/zenodo.3974591). {% include links.md %} diff --git a/_extras/about.md b/_extras/about.md index d5e11a3c..dcab29e0 100644 --- a/_extras/about.md +++ b/_extras/about.md @@ -48,7 +48,7 @@ Please see ## Citation Please use citation information available at -[http://doi.org/10.5281/zenodo.3974592](http://doi.org/10.5281/zenodo.3974592). +[https://doi.org/10.5281/zenodo.3974591](https://doi.org/10.5281/zenodo.3974591). ## Acknowledgements diff --git a/_includes/lesson_footer.html b/_includes/lesson_footer.html index e18ef5a0..e2a5ca95 100644 --- a/_includes/lesson_footer.html +++ b/_includes/lesson_footer.html @@ -40,7 +40,7 @@ / Source / - Cite + Cite / Contact diff --git a/index.md b/index.md index 10032e6b..565112d7 100644 --- a/index.md +++ b/index.md @@ -73,6 +73,6 @@ independently. ## How to cite the Tutorial Please use citation information available at -[http://doi.org/10.5281/zenodo.3974592](http://doi.org/10.5281/zenodo.3974592). +[https://doi.org/10.5281/zenodo.3974591](https://doi.org/10.5281/zenodo.3974591). {% include links.md %} From 82faeb091a21d4e0fda896971d4824b81375938b Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 10 Aug 2020 17:09:49 +0200 Subject: [PATCH 367/647] Add missing data sets (Fixes #123) --- data/dataset.urls | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/dataset.urls b/data/dataset.urls index a3cde59d..150f436b 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -5,6 +5,7 @@ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/ # Variable = ts, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_193412-195911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc # Variable = tas, model = HadGEM2-AO @@ -12,6 +13,7 @@ http://aims3.llnl.gov/thredds/fileServer/cmip5_css02_data/cmip5/output1/NIMR-KMA # Variable = tas, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_193412-195911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc # Variable = tos, model = HadGEM2-AO From 5b48dba56c3b92a092599f663959f9b589dd3dc6 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 10 Aug 2020 17:16:45 +0200 Subject: [PATCH 368/647] Fix some typos and formatting --- _episodes/01-introduction.md | 6 +++--- _episodes/02-installation.md | 2 +- _episodes/03-configuration.md | 2 +- _episodes/04-recipe.md | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 9d7a854c..22d480ea 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -23,9 +23,9 @@ keypoints: --- -## What is ESMValTool +## What is ESMValTool? -EMSValTool is first and foremost a tool to analyse climate data. But you +ESMValTool is first and foremost a tool to analyse climate data. But you probably already knew that and we like to think there's more to it than that. So let's start with a quick check to synchronize our expectations. @@ -55,7 +55,7 @@ let's start with a quick check to synchronize our expectations. > > way to go. The tool is intended for robust, repeatable and shareable climate > > analysis. That *does* require a bit more effort. > > -> > ✓ **A community effort.** EMSValTool is developed and maintained by a +> > ✓ **A community effort.** ESMValTool is developed and maintained by a > > large team of climate scientists and software engineers. It is an open > > source project to which anyone can contribute. Its longevity depends on > > these contributions. diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 29b73584..131a7e0a 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -91,7 +91,7 @@ documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install ```bash conda list - ```` + ``` Should output something like diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index b5005e47..8a0f7a12 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -103,7 +103,7 @@ In general there is no need to change the settings listed above. ## Destination directory The destination directory is the rootpath where ESMValTool will store its output folders containing -i.e. figures, data, logs, etc. With every run, ESMValTool automatically generates +e.g. figures, data, logs, etc. With every run, ESMValTool automatically generates a new output folder determined by recipe name, and date and time using the format: YYYYMMDD_HHMMSS. This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index cf3e5a93..64b825e1 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -34,7 +34,7 @@ diagnostics and description. - the MIP (Model Intercomparison Project, like atmospheric realm of MIP monthly data: Amon), - ensemble member, - - the experiment (i.e. historical, ssp125, etc.), + - the experiment (e.g. historical, ssp125), - and the grid type (necessary for CMIP6 only). - preprocessors: general operations applied to a dataset before handling it in @@ -613,7 +613,7 @@ available) can be found below. Note that the timestamps differ. > > - the dataset: > -> - mip, start_year, end_year +> - `mip`, `start_year`, `end_year` > > - the preprocessor: > @@ -635,7 +635,7 @@ The snippets for the edits can be found below: > ## Land surface average temperature > -> In the `diff` file below you will see the changes we have made to the file. The top 2 lines are the filenames and the lines like @@ -20,12 +20,14 @@ indicate the line numbers in the original and modified file, respectively. For more info on this format, see [here](https://en.wikipedia.org/wiki/Diff#Unified_format) +> In the `diff` file below you will see the changes we have made to the file. The top 2 lines are the filenames and the lines like @@ -20,12 +20,14 @@ indicate the line numbers in the original and modified file, respectively. For more info on this format, see [here](https://en.wikipedia.org/wiki/Diff#Unified_format). > > ```diff > --- data/recipe_example.yml @@ -755,7 +755,7 @@ The snippets for the edits can be found below: ## Common issues & tips > ## esmvaltool not found -> Can you run the command “esmvaltool -h”. If no, then it’s possible that the +> Can you run the command `esmvaltool -h`. If no, then it’s possible that the > conda environment isn’t activated. Please return to the in > [installation section]({{ page.root }}{% link _episodes/02-installation.md %}). {: .solution} @@ -763,13 +763,13 @@ The snippets for the edits can be found below: > ## The error message is `esmvalcore._recipe_checks.RecipeError: Missing data` > ESMValTool can’t locate the data. > -> Which computing machine are you using? Does your user-config.yml file reflect +> Which computing machine are you using? Does your `user-config.yml` file reflect > your machine's settings? Is the dataset’s name in the correct order? {: .solution} > ## Diagnostic path problems > The directory path to your diagnostics code is set relative to the -> esmvaltool/diag_scripts subdirectory. Is the code placed in this subdirectory? +> `esmvaltool/diag_scripts` subdirectory. Is the code placed in this subdirectory? > Is it spelled correctly? {: .solution} @@ -781,7 +781,7 @@ The snippets for the edits can be found below: > ## The preprocessor works but the diagnostic fails > If your preprocessor works fine but your diagnostic script fails, > congratulations! A failed diagnostic means that you won’t need to re-run the -> preprocessor. In your “run/main_log.txt” run output, you should see a line +> preprocessor. In your `run/main_log.txt` run output, you should see a line > that reads: “To re-run this diagnostic script, run:”, followed by a line with > a command that will allow you to re-run your diagnostic script only. Append > this line with the “-i” option after the python script you call to re-run your From bb9361755ef9930fb7d6a3b8aee7419b9c4865cd Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 10 Aug 2020 17:17:06 +0200 Subject: [PATCH 369/647] Add download instructions using wget --- _episodes/02-installation.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 131a7e0a..1c81aeb7 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -40,6 +40,10 @@ documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install should work on any recent system. If you have problems in the next step(s) you can alternatively try a 32 bit version. + ```bash + wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh + ``` + 2. Next, run the installer from the place where you downloaded it ```bash @@ -135,10 +139,10 @@ Next, download the file [`julia-1.0.5-linux-x86_64.tar.gz`](https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz) by clicking the link or going to the [Julia downloads page](https://julialang.org/downloads/). Download the file directly to the -`~/julia` directory or move it there after downloading. To extract the file, you -can use the following command: +`~/julia` directory or move it there after downloading. To download and extract the file, you can use the following commands: ```bash +wget https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz tar -xvzf julia-1.0.5-linux-x86\_64.tar.gz ``` From 53f7aecd21b39c03ceb6546a7b742028cc3f81ad Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 10 Aug 2020 17:17:29 +0200 Subject: [PATCH 370/647] Remove specification of redundant config directory --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 64b825e1..bb8e30a0 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -275,7 +275,7 @@ Please note the following sections: > > Use the command: > ~~~bash -> esmvaltool run --config_file ./path_to_file/user-config.yml ./path_to_file/recipe_example.yml +> esmvaltool run ./path_to_file/recipe_example.yml > ~~~ > > Follow the terminal guiding you through the subprocesses that are running. Can From 7fc2826f53f38323fc97f2c134bcee9102268083 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 10 Aug 2020 17:17:43 +0200 Subject: [PATCH 371/647] Add file locations --- _episodes/04-recipe.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index bb8e30a0..8719c2db 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -398,16 +398,20 @@ Exemplary output (depending on the directory paths and package versions that are available) can be found below. Note that the timestamps differ. > ## Your output plot(s). -> Plot for the dataset(s): -> +> Plots for the dataset(s) are located in `./recipe_example_#_#/diag_timeseries_temperature/timeseries_diag/` +> +> For a single dataset: +> > ![single dataset](../fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png "single dataset") > -> Overlay plot, if multiple datasets are defined: +> Or an overlay plot, if multiple datasets are defined: > > ![multiple datasets](../fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png "multiple datasets") {: .solution} > ## Your main output log file. +> The main output file is located at `./recipe_example_#_#/run/main_log.txt/` +> > ~~~bash > INFO [33433] > ______________________________________________________________________ @@ -494,6 +498,8 @@ available) can be found below. Note that the timestamps differ. {: .solution} > ## Your settings.yml file. +> This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/settings.yaml`. +> > ```YAML > auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data > input_files: @@ -513,6 +519,9 @@ available) can be found below. Note that the timestamps differ. {: .solution} > ## A metadata.yml file. +> +> This file is located at `./recipe_example_#_#/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml`. +> > ```YAML > ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc > : alias: HadGEM2-ES @@ -542,6 +551,8 @@ available) can be found below. Note that the timestamps differ. {: .solution} > ## The diagnostic log file. +> This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/log.txt` +> > ~~~bash > Starting diagnostic script timeseries_diag with configuration: > auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data From 201d7cb899fbedfe55a8fc47beba992136679b23 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 11 Aug 2020 14:04:52 +0200 Subject: [PATCH 372/647] Add a more interesting example for the diagnostic script path --- _episodes/06-debugging.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 59122c4e..169d5156 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -300,20 +300,28 @@ esmvalcore._task.DiagnosticError: Cannot execute script 'diag_scripts/examples/d The script path should be relative to ``diag_scripts`` directory. It means that the script ``diagnostic_timeseries.py`` is located in -``path_to_esmvaltool/diag_scripts/ocean/``. Alternatively, the script path can -be an absolute path. To examine this, we change the script path and run the -recipe: +``/diag_scripts/ocean/``. Alternatively, the script path can +be an absolute path. To examine this, we create a small python script `hello.py`: + +```python +with open('hello_world.txt', 'w') as f: + print('Fello from ESMValTool!', file=f) +``` + +Change and run the recipe: ```yaml 40 scripts: 41 timeseries_diag: -42 script: path_to_esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py +42 script: ~/esmvaltool_tutorial/hello.py ``` ~~~bash esmvaltool run recipe_example.yml ~~~ +Now examine `./esmvaltool_output/recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/` to see if it worked! Of course, this is a simple example, but it shows how you can customize diagnostic scripts or even make your own. Have a look through the scripts available in the [ESMValTool repository](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/). + > ## Available recipe and diagnostic scripts > > ESMValTool provides a broad suite of [recipes and From a9bab912a4549292c38890175f2bf4a1029b6231 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 11 Aug 2020 14:05:30 +0200 Subject: [PATCH 373/647] Add full dictionary path to avoid confusion with `projects` keyword --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 169d5156..bf76bc2c 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -231,7 +231,7 @@ config_developer_file: {HOME}/.esmvaltool/config_reference.yml > ## ESMValTool can’t locate the data > > You are assisting a colleague with ESMValTool. The colleague changes the -> ``project`` entry to ``CMIP6`` and runs the recipe. However, ESMValTool +> ``datasets/project`` entry to ``CMIP6`` and runs the recipe. However, ESMValTool > encounters an error like: > > ~~~bash From 73d3c36970d33150bc526c50094613fa119dee98 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 11 Aug 2020 14:06:01 +0200 Subject: [PATCH 374/647] Change bash command to be run from any directory --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index bf76bc2c..c8e84580 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -112,7 +112,7 @@ Let's change some settings in the recipe to run a regional pre-processor. We use a text editor called ``nano`` to open the recipe file: ~~~bash - cd esmvaltool_tutorial + cd ~/esmvaltool_tutorial nano recipe_example.yml ~~~ From de07f96ab2870b13a1c0f86d1ee0baa83c2105eb Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 11 Aug 2020 14:07:52 +0200 Subject: [PATCH 375/647] Use relative path --- _episodes/06-debugging.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index c8e84580..d671e979 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -57,7 +57,7 @@ conda activate esmvaltool Let's change the working directory to the folder ``run`` and list its files: ~~~bash - cd path_to_output_directory/run + cd esmvaltool_output/recipe_example_#_#/run ls ~~~ @@ -77,7 +77,7 @@ To inspect them, we can look inside the files. For example: Now, let's have a look inside the folder ``diag_timeseries_temperature``: ~~~bash - cd path_to_output_directory/run/diag_timeseries_temperature + cd diag_timeseries_temperature/timeseries_diag ls ~~~ From 2679b4bbaa2665aabcc6f2b59bd415fb6d7ecff9 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 11 Aug 2020 14:08:44 +0200 Subject: [PATCH 376/647] Small formatting/text changes --- _episodes/05-preprocessor.md | 89 ++++++++++++++++++------------------ _episodes/06-debugging.md | 12 ++--- 2 files changed, 50 insertions(+), 51 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 7d4e7bf6..07f181fa 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -13,7 +13,7 @@ objectives: - "Run a recipe with variables from different datasets" keypoints: - "A recipe can work with different preprocessors at the same time." -- "The setting additional_datasets can be used to add a different dataset." +- "The setting `additional_datasets` can be used to add a different dataset." - "Variable groups are useful for defining different settings for different variables." --- @@ -44,14 +44,14 @@ preprocessors: operator: mean ``` -For instance, the 'annual_statistics' with the 'operation: mean' argument +For instance, the `annual_statistics` with the `operation: mean` argument preprocessor receives an iris cube, takes the annual average for each year of data in the cube, and returns the processed cube. You may use one or more of several preprocessors listed in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). The standardised interface between the preprocessors allows them to be used -modularly - like lego blocks. Almost any conceivable preprocessing order of +modularly -- like lego blocks. Almost any conceivable preprocessing order of operations can be performed using ESMValTool preprocessors. > ## The 'custom order' command. @@ -174,14 +174,14 @@ specific preprocessor which should be applied. >> >> datasets: >> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, ->> ensemble: r1i1p1f2} #single dataset as an example +>> ensemble: r1i1p1f2} # single dataset as an example >> >> preprocessors: ->> prep_map: #preprocessor to just regrid data ->> #fill preprocessor details here +>> prep_map: # preprocessor to just regrid data +>> # fill preprocessor details here >> ->> prep_map_land: #preprocessor to mask grid cells and then regrid ->> #fill preprocessor details here including ordering +>> prep_map_land: # preprocessor to mask grid cells and then regrid +>> # fill preprocessor details here including ordering >> >> diagnostics: >> # -------------------------------------------------- @@ -189,24 +189,24 @@ specific preprocessor which should be applied. >> # different preprocessors >> # -------------------------------------------------- >> diag_simple_plot: ->> description: # preprocess a variable for a simple 2D plot +>> description: # preprocess a variable for a simple 2D plot >> variables: >> # put your variable of choice here >> # apply the first preprocessor i.e. name your preprocessor >> # edit the following 4 lines for mip, grid and time >> # based on your variable choice >> mip: Amon ->> grid: gn #can change for variables from the same model +>> grid: gn # can change for variables from the same model >> start_year: 1970 >> end_year: 2000 ->> scripts: null #no scripts called ->> diag_land_only_plot: #second diagnostic ->> description: #preprocess a variable for a 2D land only plot +>> scripts: null # no scripts called +>> diag_land_only_plot: # second diagnostic +>> description: # preprocess a variable for a 2D land only plot >> variables: >> # include a variable and information >> # as in the previous diagnostic and >> # include your second preprocessor (masking and regridding) ->> scripts: null # no scripts +>> scripts: null # no scripts >> ``` >> >{: .solution} @@ -214,27 +214,27 @@ specific preprocessor which should be applied. >> ## Solution: >> >> Here is one solution to complete the challenge above using two different ->> preprocessors +>> preprocessors: >> >>```yaml >> >> datasets: >> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, ->> ensemble: r1i1p1f2} #single dataset as an example +>> ensemble: r1i1p1f2} # single dataset as an example >> >> preprocessors: >> prep_map: ->> regrid: #apply the preprocessor to regrid ->> target_grid: 1x1 # target resolution ->> scheme: linear #how to interpolate for regridding +>> regrid: # apply the preprocessor to regrid +>> target_grid: 1x1 # target resolution +>> scheme: linear # how to interpolate for regridding >> >> prep_map_land: ->> custom_order: true #ensure that given order of preprocessing is followed ->> mask_landsea: #apply a mask ->> mask_out: sea #mask out sea grid cells ->> regrid: # now apply the preprocessor to regrid ->> target_grid: 1x1 # target resolution ->> scheme: linear #how to interpolate for regridding +>> custom_order: true # ensure that given order of preprocessing is followed +>> mask_landsea: # apply a mask +>> mask_out: sea # mask out sea grid cells +>> regrid: # now apply the preprocessor to regrid +>> target_grid: 1x1 # target resolution +>> scheme: linear # how to interpolate for regridding >> >> diagnostics: >> # -------------------------------------------------- @@ -242,23 +242,23 @@ specific preprocessor which should be applied. >> # different preprocessors >> # -------------------------------------------------- >> diag_simple_plot: ->> description: # preprocess a variable for a simple 2D plot +>> description: # preprocess a variable for a simple 2D plot >> variables: >> tas: # surface temperature >> preprocessor: prep_map >> mip: Amon ->> grid: gn #can change for variables from the same model +>> grid: gn # can change for variables from the same model >> start_year: 1970 >> end_year: 2000 >> scripts: null >> >> diag_land_only_plot: ->> description: #preprocess a variable for a 2D land only plot +>> description: # preprocess a variable for a 2D land only plot >> variables: >> tas: # surface temperature >> preprocessor: prep_map_land >> mip: Amon ->> grid: gn #can change for variables from the same model +>> grid: gn # can change for variables from the same model >> start_year: 1970 >> end_year: 2000 >> scripts: null @@ -283,13 +283,13 @@ simple preprocessor and diagnostic setup for that: > > datasets: > - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, -> ensemble: r1i1p1f2} #common to both variables discussed below +> ensemble: r1i1p1f2} # common to both variables discussed below > > preprocessors: > prep_regrid: # regrid to get all data to the same resolution -> regrid: #apply the preprocessor to regrid -> target_grid: 2.5x2.5 # target resolution -> scheme: linear #how to interpolate for regridding +> regrid: # apply the preprocessor to regrid +> target_grid: 2.5x2.5 # target resolution +> scheme: linear # how to interpolate for regridding > > diagnostics: > # -------------------------------------------------- @@ -302,23 +302,23 @@ simple preprocessor and diagnostic setup for that: > pr: # first variable is precipitation > preprocessor: prep_regrid > mip: Amon -> grid: gn #can change for variables from the same model +> grid: gn # can change for variables from the same model > start_year: 1970 > end_year: 2000 # start and end years for a 30 year period, > # we assume this is common and exists for all > # model and obs data > additional_datasets: > - {dataset: GPCP-SG, project: obs4mips, level: L3, -> version: v2.2, tier: 1} #dataset specific to this variable -> tas: # second variable is surface temperature +> version: v2.2, tier: 1} # dataset specific to this variable +> tas: # second variable is surface temperature > preprocessor: prep_regrid > mip: Amon -> grid: gn #can change for variables from the same model -> start_year: 1970 #some 30 year period +> grid: gn # can change for variables from the same model +> start_year: 1970 # some 30 year period > end_year: 2000 > additional_datasets: > - {dataset: HadCRUT4, project: OBS, type: ground, -> version: 1, tier: 2} #dataset specific to the temperature variable +> version: 1, tier: 2} # dataset specific to the temperature variable > scripts: null > ``` > @@ -366,14 +366,14 @@ Additionally we can also preprocess observed data for evaluation. > diag_variable_groups: > description: Demonstrate the use of variable groups. > variables: -> tas_cmip5: &variable_settings # need a key name for the grouping -> short_name: tas # specify variable to look for +> tas_cmip5: &variable_settings # need a key name for the grouping +> short_name: tas # specify variable to look for > preprocessor: prep_mmm > mip: Amon > exp: historical > start_year: 2000 > end_year: 2005 -> tag: TAS_CMIP5 #tag is optional if you are using these settings just once +> tag: TAS_CMIP5 # tag is optional if you are using these settings just once > additional_datasets: *cmip5_datasets > tas_obs: > <<: *variable_settings @@ -384,7 +384,7 @@ Additionally we can also preprocess observed data for evaluation. > tas_cmip6: > <<: *variable_settings > tag: TAS_CMIP6 -> additional_datasets: *cmip6_datasets #nothing changes from cmip5 except the data set +> additional_datasets: *cmip6_datasets # nothing changes from cmip5 except the data set > scripts: null >``` > @@ -392,8 +392,7 @@ Additionally we can also preprocess observed data for evaluation. You should be able to see the variables grouped under different subdirectories under your output preproc directory. The different groupings can be accessed in -your diagnostic by selecting the key name of the field variable_group such as -tas_cmip5, tas_cmip6 or tas_obs. +your diagnostic by selecting the key name of the field `variable_group` such as `tas_cmip5`, `tas_cmip6` or `tas_obs`. > ## How to find what CMIP data is available? > diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index d671e979..25b569ce 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -153,7 +153,7 @@ and then ctrl + X to exit ``nano``. >23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} >24 >25 preprocessors: ->26 prep_timeseries: # For 0D fields +>26 prep_timeseries: # For 0D fields >27 annual_statistics: >28 operator: mean >29 @@ -178,12 +178,12 @@ and then ctrl + X to exit ``nano``. The [ESMValTool pre-processors](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/recipe/preprocessor.html?highlight=preprocessor) cover a broad range of operations on the input data, like time manipulation, -area manipulation, land-sea masking, variable derivation, ... . Let's add the +area manipulation, land-sea masking, variable derivation, etc. Let's add the preprocessor ``extract_region`` to the section ``prep_timeseries``: ```yaml 25 preprocessors: -26 prep_timeseries: # For 0D fields +26 prep_timeseries: # For 0D fields 27 annual_statistics: 28 operator: mean 29 extract_region: @@ -276,11 +276,11 @@ script, that is introduced in the recipe as: ``` The diagnostic scripts are located in the folder ``diag_scripts`` in the -ESMValTool installation directory ``path_to_esmvaltool``. To find -``path_to_esmvaltool`` on your system, see [Installation]({{ page.root }}{% link +ESMValTool installation directory ````. To find +where ESMValTool is located on your system, see [Installation]({{ page.root }}{% link _episodes/02-installation.md %}). -let's see if we can change the script path as: +Let's see what happens if we can change the script path as: ```yaml 40 scripts: From 4eed456d1ba5e9765647411e70c5fb0c04a6c7b7 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 11 Aug 2020 14:21:19 +0200 Subject: [PATCH 377/647] Remove missing file --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 25b569ce..41c11515 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -82,7 +82,7 @@ Now, let's have a look inside the folder ``diag_timeseries_temperature``: ~~~ ~~~ -diag_provenance.yml log.txt resource_usage.txt settings.yml +log.txt resource_usage.txt settings.yml ~~~ {: .output} From 56998b7984bdd00ad07c2bbd2e8d18ee7b6f7adc Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 11 Aug 2020 15:43:43 +0200 Subject: [PATCH 378/647] Use consistent data path (Fixes #122) --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index ac38ae81..7fabf383 100644 --- a/setup.md +++ b/setup.md @@ -283,7 +283,7 @@ To download the data, run the following command using [wget](https://en.wikipedi ~~~shell wget --no-clobber --input-file \ https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls \ - --directory-prefix $HOME/default_inputpath/ + --directory-prefix $HOME/esmvaltool_tutorial/data/ ~~~ ## GitHub account (Advanced) From 9b6ed5673ef54176165e61af7643964ecf5e5c7c Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 4 Sep 2020 10:22:42 +0200 Subject: [PATCH 379/647] Address review comments --- _episodes/02-installation.md | 13 ++++--------- _episodes/04-recipe.md | 2 +- _episodes/06-debugging.md | 4 ++-- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 1c81aeb7..2f845abe 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -35,15 +35,14 @@ documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install ### Linux -1. Please download Miniconda3 for Linux at [the miniconda - page](https://docs.conda.io/en/latest/miniconda.html). The 64 bit version - should work on any recent system. If you have problems in the next step(s) - you can alternatively try a 32 bit version. +1. Please download Miniconda3 by running: ```bash wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh ``` +It is also possible to download Miniconda3 for Linux on the [miniconda page](https://docs.conda.io/en/latest/miniconda.html). If you have problems with the 64 bit version in the next step(s) you can alternatively try a 32 bit version. + 2. Next, run the installer from the place where you downloaded it ```bash @@ -135,11 +134,7 @@ mkdir ~/julia cd ~/julia ``` -Next, download the file -[`julia-1.0.5-linux-x86_64.tar.gz`](https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz) -by clicking the link or going to the [Julia downloads -page](https://julialang.org/downloads/). Download the file directly to the -`~/julia` directory or move it there after downloading. To download and extract the file, you can use the following commands: +Next, to download and extract the file `julia-1.0.5-linux-x86_64.tar.gz`, you can use the following commands:: ```bash wget https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 8719c2db..83bbedca 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -398,7 +398,7 @@ Exemplary output (depending on the directory paths and package versions that are available) can be found below. Note that the timestamps differ. > ## Your output plot(s). -> Plots for the dataset(s) are located in `./recipe_example_#_#/diag_timeseries_temperature/timeseries_diag/` +> Plots for the dataset(s) are located in `./recipe_example_#_#/plots/timeseries_diag/` > > For a single dataset: > diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 41c11515..1edb307b 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -230,8 +230,8 @@ config_developer_file: {HOME}/.esmvaltool/config_reference.yml > ## ESMValTool can’t locate the data > -> You are assisting a colleague with ESMValTool. The colleague changes the -> ``datasets/project`` entry to ``CMIP6`` and runs the recipe. However, ESMValTool +> You are assisting a colleague with ESMValTool. The colleague replaces the +> ``CMIP5`` entry in ``project: CMIP5`` to ``CMIP6`` and runs the recipe. However, ESMValTool > encounters an error like: > > ~~~bash From f4c57b28e4bff954a2163be0b22fc6bcdde239f7 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 4 Sep 2020 08:23:30 +0000 Subject: [PATCH 380/647] Update _episodes/06-debugging.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 1edb307b..461dacde 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -320,7 +320,7 @@ Change and run the recipe: esmvaltool run recipe_example.yml ~~~ -Now examine `./esmvaltool_output/recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/` to see if it worked! Of course, this is a simple example, but it shows how you can customize diagnostic scripts or even make your own. Have a look through the scripts available in the [ESMValTool repository](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/). +Now examine `./esmvaltool_output/recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/` to see if it worked! > ## Available recipe and diagnostic scripts > From 7ec1af5a3b8c575da3930bd5178831187be53c85 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 4 Sep 2020 08:23:41 +0000 Subject: [PATCH 381/647] Update _episodes/06-debugging.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/06-debugging.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 461dacde..cd78d4d5 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -301,14 +301,8 @@ esmvalcore._task.DiagnosticError: Cannot execute script 'diag_scripts/examples/d The script path should be relative to ``diag_scripts`` directory. It means that the script ``diagnostic_timeseries.py`` is located in ``/diag_scripts/ocean/``. Alternatively, the script path can -be an absolute path. To examine this, we create a small python script `hello.py`: - -```python -with open('hello_world.txt', 'w') as f: - print('Fello from ESMValTool!', file=f) -``` - -Change and run the recipe: +be an absolute path. To examine this, we change the script path and run the +recipe: ```yaml 40 scripts: From 33e9b9e7a9885f18023f25908f6e51af676aa692 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 4 Sep 2020 08:23:55 +0000 Subject: [PATCH 382/647] Update _episodes/06-debugging.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index cd78d4d5..2a819205 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -307,7 +307,7 @@ recipe: ```yaml 40 scripts: 41 timeseries_diag: -42 script: ~/esmvaltool_tutorial/hello.py +42 script: /diag_scripts/ocean/diagnostic_timeseries.py ``` ~~~bash From 68a01f6a6e901109e2e7453ff5709fd13ee6b63a Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 4 Sep 2020 11:13:00 +0200 Subject: [PATCH 383/647] Improve absolute path example --- _episodes/06-debugging.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 2a819205..303356f8 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -300,14 +300,25 @@ esmvalcore._task.DiagnosticError: Cannot execute script 'diag_scripts/examples/d The script path should be relative to ``diag_scripts`` directory. It means that the script ``diagnostic_timeseries.py`` is located in -``/diag_scripts/ocean/``. Alternatively, the script path can -be an absolute path. To examine this, we change the script path and run the -recipe: +``/diag_scripts/ocean/``. +Alternatively, the script path can be an absolute path. To examine this, we can download the script from the ``ESMValTool`` repository: + +```bash +wget https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py +``` + +One way to get the absolute path is to run: + +```bash +readlink -f diagnostic_timeseries.py +``` + +Then we can update the script path and run the recipe: ```yaml 40 scripts: 41 timeseries_diag: -42 script: /diag_scripts/ocean/diagnostic_timeseries.py +42 script: /diagnostic_timeseries.py ``` ~~~bash From 20b22856f39a48094b436682bc8f458507b1b40b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 4 Sep 2020 13:27:29 +0200 Subject: [PATCH 384/647] fixing missing cmip5 thetao and example recipe in episode 5 --- _episodes/05-preprocessor.md | 46 ++++++++++++++++++++++++++-------- data/dataset.urls | 2 ++ data/recipe_example_thetao.yml | 45 +++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 data/recipe_example_thetao.yml diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 07f181fa..6143e4d3 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -88,22 +88,46 @@ file afterwards. These do not need to be explicitly included in recipes. > ## Exercise: Adding more preprocessor steps > -> Edit the [example recipe](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) to first change the variable -> thetao, then add preprocessors to average over the latitude and longitude +> Edit the [example recipe](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) to first change the variable to +> `thetao`, then add preprocessors to average over the latitude and longitude > dimensions and finally average over the depth. Now run the recipe. > >> ## Solution >> ->>```yaml ->> preprocessors: ->> prep_timeseries: ->> annual_statistics: ->> operator: mean ->> area_statistics: ->> operator: mean ->> depth_integration: ->>``` +>> In the `diff` file below you will see the changes we have made to the file. The top 2 lines are the filenames and the lines like @@ -20,12 +20,15 @@ indicate the line numbers in the original and modified file, respectively. For more info on this format, see [here](https://en.wikipedia.org/wiki/Diff#Unified_format). +>> +>>```diff +>> --- data/recipe_example.yml +>> --- data/recipe_example_thetao.yml +>> @@ -20,12 +20,15 @@ +>> - ukesm +>> +>> datasets: +>> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +>> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} +>> +>> preprocessors: +>> prep_timeseries: # For 0D fields +>> annual_statistics: +>> operator: mean +>> + area_statistics: +>> + operator: mean +>> + depth_integration: +>> +>> diagnostics: +>> # -------------------------------------------------- +>> @@ -35,7 +38,7 @@ +>> description: simple_time_series +>> variables: +>> timeseries_variable: +>> - short_name: thetaoga +>> + short_name: thetao +>> preprocessor: prep_timeseries +>> scripts: +>> timeseries_diag: +>> ``` >> +>> Complete recipe can be downloaded as [recipe_example_thetao.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_thetao.yml) >{: .solution} {: .challenge} diff --git a/data/dataset.urls b/data/dataset.urls index 150f436b..55b688ee 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -25,6 +25,8 @@ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_185912-195911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_195912-200512.nc # For Working with preprocessors episode +# Variable = thetao, model = HadGEM2-ES +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetao/thetao_Omon_HadGEM2-ES_historical_r1i1p1_199912-200512.nc # Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = thetao, pr and tas, 1970-2000 http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Omon/thetao/gn/v20190627/thetao_Omon_UKESM1-0-LL_historical_r1i1p1f2_gn_200001-201412.nc http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Omon/thetao/gn/v20190627/thetao_Omon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-199912.nc diff --git a/data/recipe_example_thetao.yml b/data/recipe_example_thetao.yml new file mode 100644 index 00000000..6afe3f1f --- /dev/null +++ b/data/recipe_example_thetao.yml @@ -0,0 +1,45 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +datasets: + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} + +preprocessors: + prep_timeseries: # For 0D fields + annual_statistics: + operator: mean + area_statistics: + operator: mean + depth_integration: + +diagnostics: + # -------------------------------------------------- + # Time series diagnostics + # -------------------------------------------------- + diag_timeseries_temperature: + description: simple_time_series + variables: + timeseries_variable: + short_name: thetao + preprocessor: prep_timeseries + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py From 9e8c643a397f32e4a063508ac41365f72eac9143 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 4 Sep 2020 13:46:27 +0200 Subject: [PATCH 385/647] fix missing data in example episode 5 --- _episodes/05-preprocessor.md | 4 ++ data/recipe_example_thetao_thetaoga.yml | 57 +++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 data/recipe_example_thetao_thetaoga.yml diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 6143e4d3..dccbe202 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -140,6 +140,9 @@ specific preprocessor which should be applied. > ## Example > > ```yaml +>datasets: +> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} +> > preprocessors: > prep_timeseries_1: > annual_statistics: @@ -176,6 +179,7 @@ specific preprocessor which should be applied. > script: ocean/diagnostic_timeseries.py > ``` > +> Complete recipe can be downloaded as [recipe_example_thetao_thetaoga.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_thetao_thetaoga.yml) {: .solution} >## Challenge : How to write a recipe with multiple preprocessors diff --git a/data/recipe_example_thetao_thetaoga.yml b/data/recipe_example_thetao_thetaoga.yml new file mode 100644 index 00000000..58185194 --- /dev/null +++ b/data/recipe_example_thetao_thetaoga.yml @@ -0,0 +1,57 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +datasets: + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} + +preprocessors: + prep_timeseries_1: + annual_statistics: + operator: mean + prep_timeseries_2: # For 0D fields + annual_statistics: + operator: mean + area_statistics: + operator: mean + depth_integration: + +diagnostics: + # -------------------------------------------------- + # Time series diagnostics + # -------------------------------------------------- + diag_timeseries_temperature_1: + description: simple_time_series + variables: + timeseries_variable: + short_name: thetaoga + preprocessor: prep_timeseries_1 + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py + diag_timeseries_temperature_2: + description: simple_time_series + variables: + timeseries_variable: + short_name: thetao + preprocessor: prep_timeseries_2 + scripts: + timeseries_diag: + script: ocean/diagnostic_timeseries.py From 6ad39a42cc6f0f9dc773b35a60562d1b26e3cef8 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 4 Sep 2020 14:24:25 +0200 Subject: [PATCH 386/647] fix missing obs4mips dataset, remove OBS dataset from episode 5 --- _episodes/05-preprocessor.md | 19 ++++--------------- data/dataset.urls | 2 ++ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index dccbe202..29bccea1 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -331,9 +331,8 @@ simple preprocessor and diagnostic setup for that: > preprocessor: prep_regrid > mip: Amon > grid: gn # can change for variables from the same model -> start_year: 1970 -> end_year: 2000 # start and end years for a 30 year period, -> # we assume this is common and exists for all +> start_year: 1979 +> end_year: 2000 # we assume this exists for all > # model and obs data > additional_datasets: > - {dataset: GPCP-SG, project: obs4mips, level: L3, @@ -342,11 +341,8 @@ simple preprocessor and diagnostic setup for that: > preprocessor: prep_regrid > mip: Amon > grid: gn # can change for variables from the same model -> start_year: 1970 # some 30 year period +> start_year: 1979 > end_year: 2000 -> additional_datasets: -> - {dataset: HadCRUT4, project: OBS, type: ground, -> version: 1, tier: 2} # dataset specific to the temperature variable > scripts: null > ``` > @@ -357,7 +353,6 @@ simple preprocessor and diagnostic setup for that: Variable grouping can be used to preprocess different clusters of data for the same variable. For instance, the example below illustrates how we can compute separate multimodel means for CMIP5 and CMIP6 data given the same variable. -Additionally we can also preprocess observed data for evaluation. > ## Example >```yaml @@ -403,12 +398,6 @@ Additionally we can also preprocess observed data for evaluation. > end_year: 2005 > tag: TAS_CMIP5 # tag is optional if you are using these settings just once > additional_datasets: *cmip5_datasets -> tas_obs: -> <<: *variable_settings -> preprocessor: prep_obs -> tag: TAS_OBS -> additional_datasets: -> - {dataset: HadCRUT4, project: OBS, type: ground, version: 1, tier: 2} > tas_cmip6: > <<: *variable_settings > tag: TAS_CMIP6 @@ -420,7 +409,7 @@ Additionally we can also preprocess observed data for evaluation. You should be able to see the variables grouped under different subdirectories under your output preproc directory. The different groupings can be accessed in -your diagnostic by selecting the key name of the field `variable_group` such as `tas_cmip5`, `tas_cmip6` or `tas_obs`. +your diagnostic by selecting the key name of the field `variable_group` such as `tas_cmip5`, or `tas_cmip6`. > ## How to find what CMIP data is available? > diff --git a/data/dataset.urls b/data/dataset.urls index 55b688ee..9e3935a2 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -49,3 +49,5 @@ http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCC http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r2i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r2i1p2f1_gn_185001-201412.nc http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r3i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r3i1p2f1_gn_185001-201412.nc http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r4i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r4i1p2f1_gn_185001-201412.nc +# Variable = pr, model = GPCP-SG, project= obs4mips +https://dpesgf03.nccs.nasa.gov/thredds/fileServer/obs4MIPs/observations/NASA-GSFC/Obs-GPCP/GPCP/V2.2/atmos/pr/pr_GPCP-SG_L3_v2.2_197901-201312.nc From 3959d437e2d9a9ebaf50a0cdc2e2d47a29dcb1dd Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 4 Sep 2020 14:49:20 +0200 Subject: [PATCH 387/647] fix how to get config_references --- _episodes/06-debugging.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 303356f8..ac388e2c 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -216,18 +216,12 @@ attach the run/recipe_*.yml and run/main_log_debug.txt files from the output dir The values for the keys ``author``, ``maintainer``, ``projects`` and ``references`` in the recipe should be known by ESMValTool. A list of ESMValTool author, maintainer, references, and projects can be found in the -``config-references.yml``. You could download this file by typing: +``config-references.yml``. You could download this file: ~~~bash - esmvaltool config get_config_reference + wget https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml ~~~ -It will be saved to: ``{HOME}/.esmvaltool/config-references.yml``. If you modify this file, please add the directory in the ``config-user.yml``: - -```yaml -config_developer_file: {HOME}/.esmvaltool/config_reference.yml -``` - > ## ESMValTool can’t locate the data > > You are assisting a colleague with ESMValTool. The colleague replaces the @@ -300,7 +294,7 @@ esmvalcore._task.DiagnosticError: Cannot execute script 'diag_scripts/examples/d The script path should be relative to ``diag_scripts`` directory. It means that the script ``diagnostic_timeseries.py`` is located in -``/diag_scripts/ocean/``. +``/diag_scripts/ocean/``. Alternatively, the script path can be an absolute path. To examine this, we can download the script from the ``ESMValTool`` repository: ```bash From 8e569e107fefdc80840dac08c573b19c961c28a6 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 4 Sep 2020 15:17:41 +0200 Subject: [PATCH 388/647] remove duplicate text --- _episodes/05-preprocessor.md | 17 +------------ setup.md | 49 ++++++++---------------------------- 2 files changed, 12 insertions(+), 54 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 29bccea1..b6968be2 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -413,20 +413,5 @@ your diagnostic by selecting the key name of the field `variable_group` such as > ## How to find what CMIP data is available? > -> [CMIP5](https://pcmdi.llnl.gov/mips/cmip5/index.html) and -> [CMIP6](https://pcmdi.llnl.gov/CMIP6/Guide/dataUsers.html) data obey the -> [CF-conventions](http://cfconventions.org/). Available variables can be found -> under the [CMIP5 data -> request](https://pcmdi.llnl.gov/mips/cmip5/docs/standard_output.pdf?id=28) and -> the [CMIP6 Data Request](http://clipc-services.ceda.ac.uk/dreq/index.html). -> -> CMIP data is widely available via the Earth System Grid Federation -> ([ESGF](https://esgf.llnl.gov/)) and is accessible to users either via -> download from the ESGF portal or through the ESGF data nodes hosted by large -> computing facilities (like [CEDA-Jasmin](https://esgf-index1.ceda.ac.uk/), -> [DKRZ](https://esgf-data.dkrz.de/), etc). The ESGF also hosts observations for -> Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). -> -> A full list of all CMIP named variables is available here: -> [http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html](http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html). +> Please see section "Access to CMIP and Observational data" in [Setup]({{ page.root }}{% link setup.md %}). {: .callout} diff --git a/setup.md b/setup.md index 7fabf383..e7325ec8 100644 --- a/setup.md +++ b/setup.md @@ -35,7 +35,6 @@ ESMValTool code. [https://swcarpentry.github.io/git-novice/](https://swcarpentry.github.io/git-novice/) - ## Access to CMIP and Observational data and a suitable compute cluster To complete this tutorial and use ESMValTool, you will need access to data in a @@ -50,21 +49,25 @@ Intercomparison Project (CMIP)](https://en.wikipedia.org/wiki/Coupled_Model_Intercomparison_Project) is locally stored on disk and accessible directly by the tool. Similarly, observational data would also be available at these sites. +The ESGF also hosts observations for Model Intercomparison Projects (obs4MIPs) and reanalyses data (ana4MIPs). Here are a few options for compute clusters with ESGF nodes: - [CEDA-Jasmin (UK)](#ceda-jasmin) - [DKRZ (Germany)](#dkrz) -A full list of all ESGF nodes is available -[here](https://esgf.llnl.gov/nodes.html). +For more information see: + +- [CMIP5](https://pcmdi.llnl.gov/mips/cmip5/index.html) and +[CMIP6](https://pcmdi.llnl.gov/CMIP6/Guide/dataUsers.html) data obey the +[CF-conventions](http://cfconventions.org/). Available variables can be found +under the [CMIP5 data request](https://pcmdi.llnl.gov/mips/cmip5/docs/standard_output.pdf?id=28) +and the [CMIP6 Data Request](http://clipc-services.ceda.ac.uk/dreq/index.html). -If you're running on a computing cluster without an ESGF node, such as your -local machine, or your institute machine, you will most likely have to make a -local copy of the data that you need. +- A full list of all +[CMIP named variables](http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html). -If necessary, data can be downloaded using the -[synda tool](https://prodiguer.github.io/synda/index.html). +- A full list of [all ESGF nodes](https://esgf.llnl.gov/nodes.html). ### CEDA-Jasmin @@ -138,7 +141,6 @@ Note that the JASMIN is only open to certain locations (mostly universities, and research centres). You may need a VPN if you wish to connect from your home network. - Please request access to the working groups: - [esmeval working group](https://accounts.jasmin.ac.uk/services/group_workspaces/esmeval) @@ -154,35 +156,6 @@ access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC are not accessible by default and special permission has to be requested to access them via [the CEDA catalogue page](https://catalogue.ceda.ac.uk/). - -#### Test your Setup - -Log into jasmin-login: - -~~~ -ssh -X JASMIN-USERNAME@jasmin-login1.ceda.ac.uk -~~~ -{: .language-bash} - -Then log into the sci1 machine: - -~~~ -ssh -X jasmin-sci1 -~~~ -{: .language-bash} - -Can you see the following locations: -~~~ -ls /group_workspaces/jasmin4/esmeval/obsdata/Tier2 -ls /badc/cmip5/data/cmip5/output1/MOHC/HadGEM2-ES -ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.nc -~~~ -{: .language-bash} - -Note that the JASMIN is only open to certain locations (mostly universities, and -research centres). You may need a VPN if you wish to connect from your home -network. - Congratulations! Please go here [here](#gitHub-account-(advanced)) next. From 1afa69f57131e9ba1a9b0af8b6080d3f20d0ec77 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 4 Sep 2020 15:19:07 +0200 Subject: [PATCH 389/647] fix time estimation for exercises --- _episodes/02-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 2f845abe..1cefe292 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -1,7 +1,7 @@ --- title: "Installation" teaching: 10 -exercises: 20 +exercises: 10 questions: - "What are the prerequisites for installing ESMValTool?" - "How do I confirm that the installation was successful?" From dd72f7e2fe89995ad228b58d777248d072cde09b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 4 Sep 2020 15:42:12 +0200 Subject: [PATCH 390/647] fix the link to config_references --- _episodes/04-recipe.md | 38 +++++++++++++++++++++++--------------- _episodes/06-debugging.md | 5 ++++- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 83bbedca..e85b7034 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -181,14 +181,22 @@ Please note the following sections: The documentation consists of the following information: - description: a short description of the recipe - - authors: a list of authors (linked to `esmvaltool/config-references.yml`) - - maintainer: a list of maintainers (linked to - `esmvaltool/config-references.yml`) - - references: a list of references (linked to a bibtexfile in - `esmvaltool/references` with the same name) - - projects: a list of projects (linked to - `esmvaltool/config-references.yml`) + - authors: a list of authors + - maintainer: a list of maintainers + - references: a list of references + - projects: a list of projects +> ## config-references.yml and references +> +> The values for the keys ``author``, ``maintainer``, ``projects`` and +> ``references`` in the recipe should be known by ESMValTool. A list of ESMValTool +> author, maintainer, and projects are mentioned in the file ``config-references.yml`` +> that can be found in +> [ESMValTool/esmvaltool](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml). +> +> ESMValTool references in `BibTeX` format can be found in +> [ESMValTool/esmvaltool/references](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references). +{: .callout} - datasets: lines 22-23 @@ -399,9 +407,9 @@ available) can be found below. Note that the timestamps differ. > ## Your output plot(s). > Plots for the dataset(s) are located in `./recipe_example_#_#/plots/timeseries_diag/` -> +> > For a single dataset: -> +> > ![single dataset](../fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png "single dataset") > > Or an overlay plot, if multiple datasets are defined: @@ -410,8 +418,8 @@ available) can be found below. Note that the timestamps differ. {: .solution} > ## Your main output log file. -> The main output file is located at `./recipe_example_#_#/run/main_log.txt/` -> +> The main output file is located at `./recipe_example_#_#/run/main_log.txt/` +> > ~~~bash > INFO [33433] > ______________________________________________________________________ @@ -499,7 +507,7 @@ available) can be found below. Note that the timestamps differ. > ## Your settings.yml file. > This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/settings.yaml`. -> +> > ```YAML > auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data > input_files: @@ -519,9 +527,9 @@ available) can be found below. Note that the timestamps differ. {: .solution} > ## A metadata.yml file. -> +> > This file is located at `./recipe_example_#_#/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml`. -> +> > ```YAML > ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc > : alias: HadGEM2-ES @@ -552,7 +560,7 @@ available) can be found below. Note that the timestamps differ. > ## The diagnostic log file. > This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/log.txt` -> +> > ~~~bash > Starting diagnostic script timeseries_diag with configuration: > auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index ac388e2c..8595abd6 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -215,13 +215,16 @@ attach the run/recipe_*.yml and run/main_log_debug.txt files from the output dir The values for the keys ``author``, ``maintainer``, ``projects`` and ``references`` in the recipe should be known by ESMValTool. A list of ESMValTool -author, maintainer, references, and projects can be found in the +author, maintainer, and projects can be found in the ``config-references.yml``. You could download this file: ~~~bash wget https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml ~~~ +And ESMValTool references in `BibTeX` format can be found +[here](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references). + > ## ESMValTool can’t locate the data > > You are assisting a colleague with ESMValTool. The colleague replaces the From f191ce65dd498f57a7664809762922549c03f18c Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Mon, 7 Sep 2020 11:06:45 +0200 Subject: [PATCH 391/647] Update total data size --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index e7325ec8..c8d56cbf 100644 --- a/setup.md +++ b/setup.md @@ -227,7 +227,7 @@ local machine and go [here](#gitHub-account-(advanced)). If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space available to install conda & ESMValTool, but also enough to make a copy of some -data (12Gb). +data (13Gb). We can download a single data file following the instructions as described below: From ec805548827f838b6fdf6a12333baa29e9e6c0c7 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 7 Sep 2020 14:12:17 +0200 Subject: [PATCH 392/647] Update _episodes/06-debugging.md Co-authored-by: Stefan Verhoeven --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 8595abd6..9fbe92f8 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -223,7 +223,7 @@ author, maintainer, and projects can be found in the ~~~ And ESMValTool references in `BibTeX` format can be found -[here](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references). +[ESMValTool/esmvaltool/references](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) directory. > ## ESMValTool can’t locate the data > From cef0c11ff5bf51a69de1ce79f8ed09ac555abe61 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Sep 2020 14:24:03 +0200 Subject: [PATCH 393/647] reduce data --- _episodes/04-recipe.md | 71 +++++++++++++++---------------------- data/dataset.urls | 15 ++------ data/recipe_example.yml | 2 +- data/recipe_example_tas.yml | 3 +- data/recipe_example_tos.yml | 5 ++- data/recipe_example_ts.yml | 2 +- 6 files changed, 36 insertions(+), 62 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 83bbedca..dd488b11 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -133,7 +133,7 @@ wget https://raw.githubusercontent.com/ESMValGroup/ESMValTool_Tutorial/master/da > 20 - ukesm > 21 > 22 datasets: -> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} +> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} > 24 > 25 preprocessors: > 26 prep_timeseries: # For 0D fields @@ -200,7 +200,7 @@ Please note the following sections: - experiment (key: exp) - mip (for CMIP data, key: mip) - ensemble member (key: ensemble) - - time range (e.g. key-value-pair: start_year: 1982, end_year: 1990) + - time range (e.g. key-value-pair: start_year: 1970, end_year: 2000) - model grid (for CMIP6 data only, key: grid) - alias (key: alias; use the alias for e.g. a more human readable name for the dataset) @@ -258,7 +258,7 @@ Please note the following sections: {: .solution} > ## How many years of data are being analyzed? -> 1859 to 2005, that is 147 years. +> 1970 to 2000. {: .solution} > ## What do you think running this recipe will produce? @@ -399,9 +399,9 @@ available) can be found below. Note that the timestamps differ. > ## Your output plot(s). > Plots for the dataset(s) are located in `./recipe_example_#_#/plots/timeseries_diag/` -> +> > For a single dataset: -> +> > ![single dataset](../fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png "single dataset") > > Or an overlay plot, if multiple datasets are defined: @@ -410,8 +410,8 @@ available) can be found below. Note that the timestamps differ. {: .solution} > ## Your main output log file. -> The main output file is located at `./recipe_example_#_#/run/main_log.txt/` -> +> The main output file is located at `./recipe_example_#_#/run/main_log.txt/` +> > ~~~bash > INFO [33433] > ______________________________________________________________________ @@ -499,7 +499,7 @@ available) can be found below. Note that the timestamps differ. > ## Your settings.yml file. > This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/settings.yaml`. -> +> > ```YAML > auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data > input_files: @@ -511,7 +511,7 @@ available) can be found below. Note that the timestamps differ. > recipe: recipe_example.yml > run_dir: /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag > script: timeseries_diag -> version: 2.0.0b9 +> version: 2.0.0 > work_dir: /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag > write_netcdf: true > write_plots: true @@ -519,18 +519,18 @@ available) can be found below. Note that the timestamps differ. {: .solution} > ## A metadata.yml file. -> +> > This file is located at `./recipe_example_#_#/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml`. -> +> > ```YAML -> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1970-2000.nc > : alias: HadGEM2-ES > dataset: HadGEM2-ES > diagnostic: diag_timeseries_temperature -> end_year: 2005 +> end_year: 2000 > ensemble: r1i1p1 > exp: historical -> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1970-2000.nc > frequency: mon > institute: > - INPE @@ -544,7 +544,7 @@ available) can be found below. Note that the timestamps differ. > recipe_dataset_index: 0 > short_name: thetaoga > standard_name: sea_water_potential_temperature -> start_year: 1859 +> start_year: 1970 > units: K > variable_group: timeseries_variable > ``` @@ -552,19 +552,19 @@ available) can be found below. Note that the timestamps differ. > ## The diagnostic log file. > This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/log.txt` -> +> > ~~~bash > Starting diagnostic script timeseries_diag with configuration: > auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data > input_data: -> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1970-2000.nc > : alias: HadGEM2-ES > dataset: HadGEM2-ES > diagnostic: diag_timeseries_temperature > end_year: 2005 > ensemble: r1i1p1 > exp: historical -> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc +> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1970-2000.nc > frequency: mon > institute: > - INPE @@ -599,12 +599,12 @@ available) can be found below. Note that the timestamps differ. > Creating /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag > metadata filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml > No handles with labels found to put in legend. -> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png -> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png +> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1970-2000_timeseries_.png +> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1970-2000_timeseries_.png > ----------------- > model filenames: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc -> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png -> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png +> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1970-2000_timeseries_0.png +> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1970-2000_timeseries_0.png > Success > End of diagnostic script run. > ~~~ @@ -616,9 +616,9 @@ available) can be found below. Note that the timestamps differ. > So far, the example recipe has used global volume-weighted ocean temperature. > Please edit this recipe to investigate one of the following fields: > -> - Land surface temperature (ts) for dataset HadGEM2-ES for 1901 - 2000 -> - Atmospheric surface average temperature (tas) for datasets HadGEM2-AO and HadGEM2-ES for 1901 - 2000 -> - Ocean surface average temperature (tos) for datasets HadGEM2-AO, HadGEM2-CC and HadGEM2-ES for 1901 - 2000 +> - Land surface temperature (ts) for dataset HadGEM2-ES for 1970-2000 +> - Atmospheric surface average temperature (tas) for dataset HadGEM2-ES for 1970-2000 +> - Ocean surface average temperature (tos) for dataset HadGEM2-ES for 1970-2000 > > You will need to edit: > @@ -652,11 +652,6 @@ The snippets for the edits can be found below: > --- data/recipe_example.yml > +++ data/recipe_example_ts.yml > @@ -20,12 +20,14 @@ -> - ukesm -> -> datasets: -> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} -> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} > > preprocessors: > prep_timeseries: # For 0D fields @@ -678,7 +673,7 @@ The snippets for the edits can be found below: > timeseries_diag: > ``` > -> Note: The x-axis in the plot now shows the years 1900 - 2000. +> Note: The x-axis in the plot now shows the years 1970 - 2000. > > Complete recipe can be downloaded as [recipe_example_ts.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_ts.yml) {: .solution} @@ -689,12 +684,6 @@ The snippets for the edits can be found below: > --- data/recipe_example.yml > +++ data/recipe_example_tas.yml > @@ -20,12 +20,15 @@ -> - ukesm -> -> datasets: -> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} -> + - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} -> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} > > preprocessors: > prep_timeseries: # For 0D fields @@ -729,10 +718,8 @@ The snippets for the edits can be found below: > - ukesm > > datasets: -> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} -> + - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} -> + - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} -> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} +> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} +> + - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} > > preprocessors: > prep_timeseries: # For 0D fields @@ -753,7 +740,7 @@ The snippets for the edits can be found below: > scripts: > timeseries_diag: > ``` -> Note: The unit in the plots is now degrees celsius! There is a plot also for HadGEM2-CC. +> Note: The unit in the plots is now degrees celsius! There are now 3 plots in the work directory. One for each dataset and one for the multiple dataset overview. > > Complete recipe can be downloaded as [recipe_example_tos.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_tos.yml) {: .solution} diff --git a/data/dataset.urls b/data/dataset.urls index 150f436b..7620e28e 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -3,27 +3,16 @@ # Variable = thetaoga, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc # Variable = ts, model = HadGEM2-ES -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_193412-195911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc -# Variable = tas, model = HadGEM2-AO -http://aims3.llnl.gov/thredds/fileServer/cmip5_css02_data/cmip5/output1/NIMR-KMA/HadGEM2-AO/historical/mon/atmos/Amon/r1i1p1/tas/1/tas_Amon_HadGEM2-AO_historical_r1i1p1_186001-200512.nc # Variable = tas, model = HadGEM2-ES -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_188412-190911.nc -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_190912-193411.nc -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_193412-195911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc -# Variable = tos, model = HadGEM2-AO -http://aims3.llnl.gov/thredds/fileServer/cmip5_css02_data/cmip5/output1/NIMR-KMA/HadGEM2-AO/historical/mon/ocean/Omon/r1i1p1/tos/1/tos_Omon_HadGEM2-AO_historical_r1i1p1_186001-200512.nc -# Variable = tos, model = HadGEM2-CC -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-CC/historical/mon/ocean/Omon/r1i1p1/v20110930/tos/tos_Omon_HadGEM2-CC_historical_r1i1p1_185912-195911.nc +# Variable = tos, model = HadGEM2-CC http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-CC/historical/mon/ocean/Omon/r1i1p1/v20110930/tos/tos_Omon_HadGEM2-CC_historical_r1i1p1_195912-200511.nc # Variable = tos, model = HadGEM2-ES -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_185912-195911.nc http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_195912-200512.nc +# # For Working with preprocessors episode # Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = thetao, pr and tas, 1970-2000 http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Omon/thetao/gn/v20190627/thetao_Omon_UKESM1-0-LL_historical_r1i1p1f2_gn_200001-201412.nc diff --git a/data/recipe_example.yml b/data/recipe_example.yml index 67cee8b9..21f3983c 100644 --- a/data/recipe_example.yml +++ b/data/recipe_example.yml @@ -20,7 +20,7 @@ documentation: - ukesm datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} preprocessors: prep_timeseries: # For 0D fields diff --git a/data/recipe_example_tas.yml b/data/recipe_example_tas.yml index 8bb3b40d..1fc6c34e 100644 --- a/data/recipe_example_tas.yml +++ b/data/recipe_example_tas.yml @@ -20,8 +20,7 @@ documentation: - ukesm datasets: - - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} preprocessors: prep_timeseries: # For 0D fields diff --git a/data/recipe_example_tos.yml b/data/recipe_example_tos.yml index 98171eea..718e6fda 100644 --- a/data/recipe_example_tos.yml +++ b/data/recipe_example_tos.yml @@ -20,9 +20,8 @@ documentation: - ukesm datasets: - - {dataset: HadGEM2-AO, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} - - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} + - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} preprocessors: prep_timeseries: # For 0D fields diff --git a/data/recipe_example_ts.yml b/data/recipe_example_ts.yml index 74359c43..03cb81b2 100644 --- a/data/recipe_example_ts.yml +++ b/data/recipe_example_ts.yml @@ -20,7 +20,7 @@ documentation: - ukesm datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1901, end_year: 2000} + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} preprocessors: prep_timeseries: # For 0D fields From 3447abef2e10e6ad9439aca777b46efcb61caee0 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Sep 2020 15:20:06 +0200 Subject: [PATCH 394/647] fix abs4mips --- _episodes/03-configuration.md | 4 +++- _episodes/05-preprocessor.md | 2 +- setup.md | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 8a0f7a12..84f3973e 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -188,13 +188,15 @@ Site-specific entries for Jasmin, DKRZ and ETHZ are listed at the end of the example configuration file. In this lesson, we will work with data from -[CMIP5](https://esgf-node.llnl.gov/projects/cmip5/). +[CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) +and [obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/). We add the root path of the folder where our/your data is available. ```yaml rootpath: ... CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2, ~/esmvaltool_tutorial/data] + obs4mips: ~/esmvaltool_tutorial/data ``` > ## Setting the correct rootpath diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index b6968be2..f9bbde69 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -299,7 +299,7 @@ specific preprocessor which should be applied. ## Adding different datasets for different variables Sometimes, we may want to include specific datasets only for certain variables. -An example is when we use observations for two different variables in a +An example is when we use observations for variables in a diagnostic. While the CMIP dataset details for the two variables may be common, the observations will likely not be so. It would be useful to know how to include different datasets for different variables. Here is an example of a diff --git a/setup.md b/setup.md index c8d56cbf..34e35b5e 100644 --- a/setup.md +++ b/setup.md @@ -257,6 +257,9 @@ To download the data, run the following command using [wget](https://en.wikipedi wget --no-clobber --input-file \ https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls \ --directory-prefix $HOME/esmvaltool_tutorial/data/ +cd $HOME/esmvaltool_tutorial/data/ +mkdir -p Tier1/GPCP-SG +mv pr_GPCP-SG_*.nc Tier1/GPCP-SG/ ~~~ ## GitHub account (Advanced) From d83eaae6917599cdb2e4fd511eabdf1e8df1c736 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 7 Sep 2020 15:20:46 +0200 Subject: [PATCH 395/647] Update _episodes/06-debugging.md Co-authored-by: Stefan Verhoeven --- _episodes/06-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index 9fbe92f8..d70ee3cf 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -216,7 +216,7 @@ attach the run/recipe_*.yml and run/main_log_debug.txt files from the output dir The values for the keys ``author``, ``maintainer``, ``projects`` and ``references`` in the recipe should be known by ESMValTool. A list of ESMValTool author, maintainer, and projects can be found in the -``config-references.yml``. You could download this file: +[config-references.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml). ~~~bash wget https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml From be661e420d22ea22e4d8a63bc343e15e0ac5b3ed Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 7 Sep 2020 15:20:59 +0200 Subject: [PATCH 396/647] Update _episodes/04-recipe.md Co-authored-by: Stefan Verhoeven --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index e85b7034..4f618f1a 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -195,7 +195,7 @@ Please note the following sections: > [ESMValTool/esmvaltool](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml). > > ESMValTool references in `BibTeX` format can be found in -> [ESMValTool/esmvaltool/references](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references). +> [ESMValTool/esmvaltool/references](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) directory. {: .callout} - datasets: lines 22-23 From f45d5d20ad49525fac53dac4299d30defe677098 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Sep 2020 15:25:21 +0200 Subject: [PATCH 397/647] revise the text --- _episodes/04-recipe.md | 6 ++++-- _episodes/06-debugging.md | 13 +++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 4f618f1a..ed18a324 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -189,12 +189,14 @@ Please note the following sections: > ## config-references.yml and references > > The values for the keys ``author``, ``maintainer``, ``projects`` and -> ``references`` in the recipe should be known by ESMValTool. A list of ESMValTool +> ``references`` in the recipe should be known by ESMValTool: +> +> - A list of ESMValTool > author, maintainer, and projects are mentioned in the file ``config-references.yml`` > that can be found in > [ESMValTool/esmvaltool](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml). > -> ESMValTool references in `BibTeX` format can be found in +> - ESMValTool references in `BibTeX` format can be found in > [ESMValTool/esmvaltool/references](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) directory. {: .callout} diff --git a/_episodes/06-debugging.md b/_episodes/06-debugging.md index d70ee3cf..a15dbde6 100644 --- a/_episodes/06-debugging.md +++ b/_episodes/06-debugging.md @@ -214,15 +214,12 @@ attach the run/recipe_*.yml and run/main_log_debug.txt files from the output dir {: .error} The values for the keys ``author``, ``maintainer``, ``projects`` and -``references`` in the recipe should be known by ESMValTool. A list of ESMValTool -author, maintainer, and projects can be found in the -[config-references.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml). +``references`` in the recipe should be known by ESMValTool: -~~~bash - wget https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml -~~~ - -And ESMValTool references in `BibTeX` format can be found +- A list of ESMValTool +author, maintainer, and projects can be found in the +[config-references.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml). +- ESMValTool references in `BibTeX` format can be found in the [ESMValTool/esmvaltool/references](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) directory. > ## ESMValTool can’t locate the data From 2c64d51d9207f3f48029a64efce2eef2235b5e13 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Sep 2020 16:35:00 +0200 Subject: [PATCH 398/647] reduce data --- _episodes/04-recipe.md | 46 ++++--- _episodes/05-preprocessor.md | 120 ++++++++---------- data/dataset.urls | 15 +-- data/recipe_example.yml | 2 +- data/recipe_example_multi_preprocessors.yml | 11 +- ...ries_temperature_1859_2005_timeseries_.png | Bin 33451 -> 0 bytes ...ries_temperature_1900_2000_timeseries_.png | Bin 0 -> 38000 bytes ...ies_temperature_1859_2005_timeseries_0.png | Bin 32930 -> 0 bytes ...ies_temperature_1900_2000_timeseries_0.png | Bin 0 -> 37037 bytes 9 files changed, 86 insertions(+), 108 deletions(-) delete mode 100644 fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png create mode 100644 fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_.png delete mode 100644 fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png create mode 100644 fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_0.png diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index dd488b11..9f7193f8 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -133,7 +133,7 @@ wget https://raw.githubusercontent.com/ESMValGroup/ESMValTool_Tutorial/master/da > 20 - ukesm > 21 > 22 datasets: -> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} +> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} > 24 > 25 preprocessors: > 26 prep_timeseries: # For 0D fields @@ -200,7 +200,7 @@ Please note the following sections: - experiment (key: exp) - mip (for CMIP data, key: mip) - ensemble member (key: ensemble) - - time range (e.g. key-value-pair: start_year: 1970, end_year: 2000) + - time range (e.g. key-value-pair: start_year: 1900, end_year: 2000) - model grid (for CMIP6 data only, key: grid) - alias (key: alias; use the alias for e.g. a more human readable name for the dataset) @@ -258,7 +258,7 @@ Please note the following sections: {: .solution} > ## How many years of data are being analyzed? -> 1970 to 2000. +> 1900 to 2000. {: .solution} > ## What do you think running this recipe will produce? @@ -523,14 +523,14 @@ available) can be found below. Note that the timestamps differ. > This file is located at `./recipe_example_#_#/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml`. > > ```YAML -> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1970-2000.nc +> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1900-2000.nc > : alias: HadGEM2-ES > dataset: HadGEM2-ES > diagnostic: diag_timeseries_temperature > end_year: 2000 > ensemble: r1i1p1 > exp: historical -> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1970-2000.nc +> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1900-2000.nc > frequency: mon > institute: > - INPE @@ -557,14 +557,14 @@ available) can be found below. Note that the timestamps differ. > Starting diagnostic script timeseries_diag with configuration: > auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data > input_data: -> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1970-2000.nc +> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1900-2000.nc > : alias: HadGEM2-ES > dataset: HadGEM2-ES > diagnostic: diag_timeseries_temperature > end_year: 2005 > ensemble: r1i1p1 > exp: historical -> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1970-2000.nc +> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1900-2000.nc > frequency: mon > institute: > - INPE @@ -599,12 +599,12 @@ available) can be found below. Note that the timestamps differ. > Creating /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag > metadata filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml > No handles with labels found to put in legend. -> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1970-2000_timeseries_.png -> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1970-2000_timeseries_.png +> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900-2000_timeseries_.png +> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900-2000_timeseries_.png > ----------------- > model filenames: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc -> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1970-2000_timeseries_0.png -> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1970-2000_timeseries_0.png +> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1900-2000_timeseries_0.png +> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1900-2000_timeseries_0.png > Success > End of diagnostic script run. > ~~~ @@ -652,6 +652,11 @@ The snippets for the edits can be found below: > --- data/recipe_example.yml > +++ data/recipe_example_ts.yml > @@ -20,12 +20,14 @@ +> - ukesm +> +> datasets: +> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} +> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} > > preprocessors: > prep_timeseries: # For 0D fields @@ -683,7 +688,12 @@ The snippets for the edits can be found below: > ```diff > --- data/recipe_example.yml > +++ data/recipe_example_tas.yml -> @@ -20,12 +20,15 @@ +> @@ -20,12 +20,14 @@ +> - ukesm +> +> datasets: +> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} +> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} > > preprocessors: > prep_timeseries: # For 0D fields @@ -694,7 +704,7 @@ The snippets for the edits can be found below: > > diagnostics: > # -------------------------------------------------- -> @@ -35,7 +38,7 @@ +> @@ -35,7 +37,7 @@ > description: simple_time_series > variables: > timeseries_variable: @@ -704,7 +714,6 @@ The snippets for the edits can be found below: > scripts: > timeseries_diag: > ``` -> Note: There are now 3 plots in the work directory. One for each dataset and one for the multiple dataset overview. > > Complete recipe can be downloaded as [recipe_example_tas.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_tas.yml) {: .solution} @@ -714,12 +723,13 @@ The snippets for the edits can be found below: > ```diff > --- data/recipe_example.yml > +++ data/recipe_example_tos.yml -> @@ -20,12 +20,16 @@ +> @@ -20,12 +20,15 @@ > - ukesm > > datasets: -> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} -> + - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} +> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} +> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} +> + - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} > > preprocessors: > prep_timeseries: # For 0D fields @@ -730,7 +740,7 @@ The snippets for the edits can be found below: > > diagnostics: > # -------------------------------------------------- -> @@ -35,7 +39,7 @@ +> @@ -35,7 +38,7 @@ > description: simple_time_series > variables: > timeseries_variable: diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 07f181fa..4a67cebe 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -173,8 +173,7 @@ specific preprocessor which should be applied. >> ```yaml >> >> datasets: ->> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, ->> ensemble: r1i1p1f2} # single dataset as an example +>> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} >> >> preprocessors: >> prep_map: # preprocessor to just regrid data @@ -195,10 +194,6 @@ specific preprocessor which should be applied. >> # apply the first preprocessor i.e. name your preprocessor >> # edit the following 4 lines for mip, grid and time >> # based on your variable choice ->> mip: Amon ->> grid: gn # can change for variables from the same model ->> start_year: 1970 ->> end_year: 2000 >> scripts: null # no scripts called >> diag_land_only_plot: # second diagnostic >> description: # preprocess a variable for a 2D land only plot @@ -216,55 +211,64 @@ specific preprocessor which should be applied. >> Here is one solution to complete the challenge above using two different >> preprocessors: >> ->>```yaml ->> ->> datasets: ->> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, ->> ensemble: r1i1p1f2} # single dataset as an example +>>```diff +>> --- data/recipe_example.yml +>> +++ data/recipe_example_multi_preprocessors.yml +>> @@ -20,23 +20,37 @@ +>> - ukesm >> ->> preprocessors: ->> prep_map: ->> regrid: # apply the preprocessor to regrid ->> target_grid: 1x1 # target resolution ->> scheme: linear # how to interpolate for regridding +>> datasets: +>> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} +>> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} >> ->> prep_map_land: ->> custom_order: true # ensure that given order of preprocessing is followed ->> mask_landsea: # apply a mask ->> mask_out: sea # mask out sea grid cells ->> regrid: # now apply the preprocessor to regrid ->> target_grid: 1x1 # target resolution ->> scheme: linear # how to interpolate for regridding +>> preprocessors: +>> - prep_timeseries: # For 0D fields +>> - annual_statistics: +>> - operator: mean +>> + prep_map: +>> + regrid: #apply the preprocessor to regrid +>> + target_grid: 1x1 # target resolution +>> + scheme: linear #how to interpolate for regridding +>> + +>> + prep_map_land: +>> + custom_order: true #ensure that given order of preprocessing is followed +>> + mask_landsea: #apply a mask +>> + mask_out: sea #mask out sea grid cells +>> + regrid: # now apply the preprocessor to regrid +>> + target_grid: 1x1 # target resolution +>> + scheme: linear #how to interpolate for regridding >> ->> diagnostics: ->> # -------------------------------------------------- ->> # Two Simple diagnostics that illustrate the use of ->> # different preprocessors ->> # -------------------------------------------------- ->> diag_simple_plot: ->> description: # preprocess a variable for a simple 2D plot ->> variables: ->> tas: # surface temperature ->> preprocessor: prep_map ->> mip: Amon ->> grid: gn # can change for variables from the same model ->> start_year: 1970 ->> end_year: 2000 ->> scripts: null ->> ->> diag_land_only_plot: ->> description: # preprocess a variable for a 2D land only plot ->> variables: ->> tas: # surface temperature ->> preprocessor: prep_map_land ->> mip: Amon ->> grid: gn # can change for variables from the same model ->> start_year: 1970 ->> end_year: 2000 ->> scripts: null +>> diagnostics: +>> # -------------------------------------------------- +>> - # Time series diagnostics +>> + # Two Simple diagnostics that illustrate the use of +>> + # different preprocessors +>> # -------------------------------------------------- +>> - diag_timeseries_temperature: +>> - description: simple_time_series +>> + diag_simple_plot: +>> + description: # preprocess a variable for a simple 2D plot +>> + variables: +>> + tas: # surface temperature +>> + preprocessor: prep_map +>> + scripts: null +>> + +>> + diag_land_only_plot: +>> + description: #preprocess a variable for a 2D land only plot +>> variables: +>> - timeseries_variable: +>> - short_name: thetaoga +>> - preprocessor: prep_timeseries +>> - scripts: +>> - timeseries_diag: +>> - script: ocean/diagnostic_timeseries.py +>> + tas: # surface temperature +>> + preprocessor: prep_map_land +>> + scripts: null >> ``` >> ->> Complete recipe can be downloaded [here](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_multi_preprocessors.yml). +>> Complete recipe can be downloaded as +>> [recipe_example_multi_preprocessors.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_multi_preprocessors.yml). > {: .solution} {: .challenge} @@ -282,8 +286,7 @@ simple preprocessor and diagnostic setup for that: > ```yaml > > datasets: -> - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, -> ensemble: r1i1p1f2} # common to both variables discussed below +> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} > > preprocessors: > prep_regrid: # regrid to get all data to the same resolution @@ -301,24 +304,11 @@ simple preprocessor and diagnostic setup for that: > variables: > pr: # first variable is precipitation > preprocessor: prep_regrid -> mip: Amon -> grid: gn # can change for variables from the same model -> start_year: 1970 -> end_year: 2000 # start and end years for a 30 year period, -> # we assume this is common and exists for all -> # model and obs data > additional_datasets: > - {dataset: GPCP-SG, project: obs4mips, level: L3, > version: v2.2, tier: 1} # dataset specific to this variable > tas: # second variable is surface temperature > preprocessor: prep_regrid -> mip: Amon -> grid: gn # can change for variables from the same model -> start_year: 1970 # some 30 year period -> end_year: 2000 -> additional_datasets: -> - {dataset: HadCRUT4, project: OBS, type: ground, -> version: 1, tier: 2} # dataset specific to the temperature variable > scripts: null > ``` > diff --git a/data/dataset.urls b/data/dataset.urls index 7620e28e..6e54e184 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -14,11 +14,7 @@ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_195912-200512.nc # # For Working with preprocessors episode -# Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = thetao, pr and tas, 1970-2000 -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Omon/thetao/gn/v20190627/thetao_Omon_UKESM1-0-LL_historical_r1i1p1f2_gn_200001-201412.nc -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Omon/thetao/gn/v20190627/thetao_Omon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-199912.nc -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Amon/tas/gn/v20190406/tas_Amon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-201412.nc -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Amon/pr/gn/v20190406/pr_Amon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-201412.nc + # Model = CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5, variable = tas http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r1i1p1/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r2i1p1/tas_Amon_CanESM2_historical_r2i1p1_185001-200512.nc @@ -27,12 +23,3 @@ http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CC # Model = MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5, variable = tas http://esgf1.dkrz.de/thredds/fileServer/cmip5/cmip5/output1/MPI-M/MPI-ESM-LR/historical/mon/atmos/Amon/r1i1p1/v20120315/tas/tas_Amon_MPI-ESM-LR_historical_r1i1p1_185001-200512.nc http://esgf1.dkrz.de/thredds/fileServer/cmip5/cmip5/output1/MPI-M/MPI-ESM-LR/historical/mon/atmos/Amon/r2i1p1/v20120315/tas/tas_Amon_MPI-ESM-LR_historical_r2i1p1_185001-200512.nc -# Model = UKESM1-0-LL, ensemble: "r(1:4)i1p1f2", grid: gn, project: CMIP6, variable = tas -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r2i1p1f2/Amon/tas/gn/v20190502/tas_Amon_UKESM1-0-LL_historical_r2i1p1f2_gn_195001-201412.nc -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r3i1p1f2/Amon/tas/gn/v20190502/tas_Amon_UKESM1-0-LL_historical_r3i1p1f2_gn_195001-201412.nc -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r4i1p1f2/Amon/tas/gn/v20190502/tas_Amon_UKESM1-0-LL_historical_r4i1p1f2_gn_195001-201412.nc -# Model = CanESM5, ensemble: "r(1:4)i1p2f1", grid: gn, project: CMIP6, variable = tas -http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r1i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r1i1p2f1_gn_185001-201412.nc -http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r2i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r2i1p2f1_gn_185001-201412.nc -http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r3i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r3i1p2f1_gn_185001-201412.nc -http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esgC_dataroot/AR6/CMIP6/CMIP/CCCma/CanESM5/historical/r4i1p2f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r4i1p2f1_gn_185001-201412.nc diff --git a/data/recipe_example.yml b/data/recipe_example.yml index 21f3983c..9675a936 100644 --- a/data/recipe_example.yml +++ b/data/recipe_example.yml @@ -20,7 +20,7 @@ documentation: - ukesm datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} preprocessors: prep_timeseries: # For 0D fields diff --git a/data/recipe_example_multi_preprocessors.yml b/data/recipe_example_multi_preprocessors.yml index e65d6c16..1cdbf6eb 100644 --- a/data/recipe_example_multi_preprocessors.yml +++ b/data/recipe_example_multi_preprocessors.yml @@ -20,8 +20,7 @@ documentation: - ukesm datasets: - - {dataset: UKESM1-0-LL, project: CMIP6, exp: historical, - ensemble: r1i1p1f2} #single dataset as an example + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} preprocessors: prep_map: @@ -47,10 +46,6 @@ diagnostics: variables: tas: # surface temperature preprocessor: prep_map - mip: Amon - grid: gn #can change for variables from the same model - start_year: 1970 - end_year: 2000 scripts: null diag_land_only_plot: @@ -58,8 +53,4 @@ diagnostics: variables: tas: # surface temperature preprocessor: prep_map_land - mip: Amon - grid: gn #can change for variables from the same model - start_year: 1970 - end_year: 2000 scripts: null diff --git a/fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png b/fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png deleted file mode 100644 index 29c8ba476b7bb07bd13ea7901a7d76d8e870e3de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33451 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 diff --git a/fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_.png b/fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_.png new file mode 100644 index 0000000000000000000000000000000000000000..0554abf0fa2cda6e976acd0fe4a952ff500df5dc GIT binary patch literal 38000 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

Y`W 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 literal 0 HcmV?d00001 diff --git a/fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png b/fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png deleted file mode 100644 index 14c3bf0b22ed0b0b7e05ed7b3593db986955328b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32930 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 nG;sX?gUkOfHNZaZ4Kd diff --git a/fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_0.png b/fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_0.png new file mode 100644 index 0000000000000000000000000000000000000000..3ad21872e122bf78ade53bae037afd4117fdd8da GIT binary patch literal 37037 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 literal 0 HcmV?d00001 From 00d6c6b5ae5ba39b6aaee698bcb577c1e2623f01 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Sep 2020 16:51:07 +0200 Subject: [PATCH 399/647] add explanantion about drs --- setup.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/setup.md b/setup.md index 34e35b5e..3cdbd7cb 100644 --- a/setup.md +++ b/setup.md @@ -257,11 +257,20 @@ To download the data, run the following command using [wget](https://en.wikipedi wget --no-clobber --input-file \ https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls \ --directory-prefix $HOME/esmvaltool_tutorial/data/ +~~~ + +The `dataset.urls` contains the dataset `GPCP-SG` that is a part of +[obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/) project. +To set the correct directory structure for this project, run the following command: + +~~~shell cd $HOME/esmvaltool_tutorial/data/ mkdir -p Tier1/GPCP-SG mv pr_GPCP-SG_*.nc Tier1/GPCP-SG/ ~~~ +We will learn more about this in the lesson **Configuration** in this tutorial. + ## GitHub account (Advanced) You don’t need a github account to participate in the tutorial. However, if you From 6ffdfa25360f9fb800492c970fec2448c4776e09 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Sep 2020 17:25:17 +0200 Subject: [PATCH 400/647] reduce data --- _episodes/05-preprocessor.md | 8 +++++++- data/dataset.urls | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 4a67cebe..79cbed80 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -286,7 +286,7 @@ simple preprocessor and diagnostic setup for that: > ```yaml > > datasets: -> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} +> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, ensemble: r1i1p1} > > preprocessors: > prep_regrid: # regrid to get all data to the same resolution @@ -303,11 +303,17 @@ simple preprocessor and diagnostic setup for that: > description: diff_datasets_for_vars > variables: > pr: # first variable is precipitation +> mip: Amon +> start_year: 2000 +> end_year: 2004 > preprocessor: prep_regrid > additional_datasets: > - {dataset: GPCP-SG, project: obs4mips, level: L3, > version: v2.2, tier: 1} # dataset specific to this variable > tas: # second variable is surface temperature +> mip: Amon +> start_year: 2000 +> end_year: 2004 > preprocessor: prep_regrid > scripts: null > ``` diff --git a/data/dataset.urls b/data/dataset.urls index 6e54e184..44d8db15 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -13,6 +13,7 @@ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/ # Variable = tos, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_195912-200512.nc # +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/pr/pr_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc # For Working with preprocessors episode # Model = CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5, variable = tas From aa376647c53c30888d9fa2408fd54f94bc5ca95a Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Sep 2020 17:54:38 +0200 Subject: [PATCH 401/647] reduce dataset --- _episodes/05-preprocessor.md | 26 +++++++++++++------------- data/dataset.urls | 16 ++++++---------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 01efcc2e..61a3cb2e 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -376,32 +376,31 @@ separate multimodel means for CMIP5 and CMIP6 data given the same variable. > ># note that there is no field called datasets anymore ># note how multiple ensembles are added by using (1:4) ->cmip5_datasets: &cmip5_datasets -> - {dataset: CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5} -> - {dataset: MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5} +>cmip5_control: &cmip5_control +> - {dataset: HadGEM2-ES, ensemble: r1i1p1, project: CMIP5} +> - {dataset: MPI-ESM-LR, ensemble: r1i1p1, project: CMIP5} > ->cmip6_datasets: &cmip6_datasets -> - {dataset: UKESM1-0-LL, ensemble: "r(1:4)i1p1f2", grid: gn, project: CMIP6} -> - {dataset: CanESM5, ensemble: "r(1:4)i1p2f1", grid: gn, project: CMIP6} +>cmip5_target: &cmip5_target +> - {dataset: CanESM2, ensemble: "r(1:2)i1p1", project: CMIP5} > >diagnostics: > > diag_variable_groups: > description: Demonstrate the use of variable groups. > variables: -> tas_cmip5: &variable_settings # need a key name for the grouping +> tas_contorl: &variable_settings # need a key name for the grouping > short_name: tas # specify variable to look for > preprocessor: prep_mmm > mip: Amon > exp: historical > start_year: 2000 > end_year: 2005 -> tag: TAS_CMIP5 # tag is optional if you are using these settings just once -> additional_datasets: *cmip5_datasets -> tas_cmip6: +> tag: TAS_CONTROL # tag is optional if you are using these settings just once +> additional_datasets: *cmip5_control +> tas_target: > <<: *variable_settings -> tag: TAS_CMIP6 -> additional_datasets: *cmip6_datasets # nothing changes from cmip5 except the data set +> tag: TAS_TARGET +> additional_datasets: *cmip5_target # nothing changes from cmip5 except the data set > scripts: null >``` > @@ -409,7 +408,8 @@ separate multimodel means for CMIP5 and CMIP6 data given the same variable. You should be able to see the variables grouped under different subdirectories under your output preproc directory. The different groupings can be accessed in -your diagnostic by selecting the key name of the field `variable_group` such as `tas_cmip5`, or `tas_cmip6`. +your diagnostic by selecting the key name of the field +`variable_group` such as `TAS_CONTROL`, or `TAS_TARGET`. > ## How to find what CMIP data is available? > diff --git a/data/dataset.urls b/data/dataset.urls index 896b0f5d..9c57539d 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -17,16 +17,12 @@ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/ # For Working with preprocessors episode # Variable = thetao, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetao/thetao_Omon_HadGEM2-ES_historical_r1i1p1_199912-200512.nc -# Model = UKESM1-0-LL, project = CMIP6, Experiment = historical, ensemble= r1i1p1f2, variable = thetao, pr and tas, 1970-2000 -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Omon/thetao/gn/v20190627/thetao_Omon_UKESM1-0-LL_historical_r1i1p1f2_gn_200001-201412.nc -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Omon/thetao/gn/v20190627/thetao_Omon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-199912.nc -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Amon/tas/gn/v20190406/tas_Amon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-201412.nc -http://esgf-data3.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/CMIP/MOHC/UKESM1-0-LL/historical/r1i1p1f2/Amon/pr/gn/v20190406/pr_Amon_UKESM1-0-LL_historical_r1i1p1f2_gn_195001-201412.nc -# Model = CanESM2, ensemble: "r(1:4)i1p1", project: CMIP5, variable = tas +# Model = CanESM2, ensemble: "r(1:2)i1p1", project: CMIP5, variable = tas http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r1i1p1/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r2i1p1/tas_Amon_CanESM2_historical_r2i1p1_185001-200512.nc -http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r3i1p1/tas_Amon_CanESM2_historical_r3i1p1_185001-200512.nc -http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r4i1p1/tas_Amon_CanESM2_historical_r4i1p1_185001-200512.nc -# Model = MPI-ESM-LR, ensemble: "r(1:2)i1p1", project: CMIP5, variable = tas +# Model = MPI-ESM-LR, ensemble: r1i1p1", project: CMIP5, variable = tas http://esgf1.dkrz.de/thredds/fileServer/cmip5/cmip5/output1/MPI-M/MPI-ESM-LR/historical/mon/atmos/Amon/r1i1p1/v20120315/tas/tas_Amon_MPI-ESM-LR_historical_r1i1p1_185001-200512.nc -http://esgf1.dkrz.de/thredds/fileServer/cmip5/cmip5/output1/MPI-M/MPI-ESM-LR/historical/mon/atmos/Amon/r2i1p1/v20120315/tas/tas_Amon_MPI-ESM-LR_historical_r2i1p1_185001-200512.nc +# Variable = pr, model = GPCP-SG, project= obs4mips +https://dpesgf03.nccs.nasa.gov/thredds/fileServer/obs4MIPs/observations/NASA-GSFC/Obs-GPCP/GPCP/V2.2/atmos/pr/pr_GPCP-SG_L3_v2.2_197901-201312.nc +# Variable = pr, model = HadGEM2-ES, project= CMIP5 +http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/pr/pr_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc From 1c86833e7f5336f6e36a8efc02f29770bf6689d6 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 8 Sep 2020 10:09:40 +0200 Subject: [PATCH 402/647] fix minor thing --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 2e039b62..919a5039 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -554,7 +554,7 @@ available) can be found below. Note that the timestamps differ. > recipe_dataset_index: 0 > short_name: thetaoga > standard_name: sea_water_potential_temperature -> start_year: 1970 +> start_year: 1900 > units: K > variable_group: timeseries_variable > ``` From e1f54f4d9773353b57875d3cd9c68a7e7c20d01f Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 8 Sep 2020 10:25:34 +0200 Subject: [PATCH 403/647] add two more recipes, and fix some minor things --- _episodes/05-preprocessor.md | 9 ++- data/recipe_example_multi_preprocessors.yml | 2 +- data/recipe_example_pr_tas.yml | 52 +++++++++++++++++ data/recipe_example_tas_control_target.yml | 64 +++++++++++++++++++++ 4 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 data/recipe_example_pr_tas.yml create mode 100644 data/recipe_example_tas_control_target.yml diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 61a3cb2e..f2be2f95 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -247,7 +247,7 @@ specific preprocessor which should be applied. >> >> datasets: >> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} ->> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} +>> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} >> >> preprocessors: >> - prep_timeseries: # For 0D fields @@ -345,6 +345,7 @@ simple preprocessor and diagnostic setup for that: > preprocessor: prep_regrid > scripts: null > ``` +> Complete recipe can be downloaded as [recipe_example_pr_tas.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_pr_tas.yml). > {: .solution} @@ -352,7 +353,7 @@ simple preprocessor and diagnostic setup for that: Variable grouping can be used to preprocess different clusters of data for the same variable. For instance, the example below illustrates how we can compute -separate multimodel means for CMIP5 and CMIP6 data given the same variable. +separate multimodel means for different CMIP5 datasets given the same variable. > ## Example >```yaml @@ -403,6 +404,10 @@ separate multimodel means for CMIP5 and CMIP6 data given the same variable. > additional_datasets: *cmip5_target # nothing changes from cmip5 except the data set > scripts: null >``` +> There is no field called datasets anymore. +> Also, note how multiple ensembles are added by using (1:2). +> Complete recipe can be downloaded as +> [recipe_example_tas_control_target.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_tas_control_target.yml). > {: .solution} diff --git a/data/recipe_example_multi_preprocessors.yml b/data/recipe_example_multi_preprocessors.yml index 1cdbf6eb..8a512910 100644 --- a/data/recipe_example_multi_preprocessors.yml +++ b/data/recipe_example_multi_preprocessors.yml @@ -20,7 +20,7 @@ documentation: - ukesm datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} preprocessors: prep_map: diff --git a/data/recipe_example_pr_tas.yml b/data/recipe_example_pr_tas.yml new file mode 100644 index 00000000..3948b751 --- /dev/null +++ b/data/recipe_example_pr_tas.yml @@ -0,0 +1,52 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +datasets: + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, ensemble: r1i1p1} + +preprocessors: + prep_regrid: # regrid to get all data to the same resolution + regrid: # apply the preprocessor to regrid + target_grid: 2.5x2.5 # target resolution + scheme: linear # how to interpolate for regridding + +diagnostics: + # -------------------------------------------------- + # Simple diagnostic to illustrate use of different + # datasets for different variables + # -------------------------------------------------- + diag_diff_datasets: + description: diff_datasets_for_vars + variables: + pr: # first variable is precipitation + mip: Amon + start_year: 2000 + end_year: 2005 + preprocessor: prep_regrid + additional_datasets: + - {dataset: GPCP-SG, project: obs4mips, level: L3, + version: v2.2, tier: 1} # dataset specific to this variable + tas: # second variable is surface temperature + mip: Amon + start_year: 2000 + end_year: 2005 + preprocessor: prep_regrid + scripts: null diff --git a/data/recipe_example_tas_control_target.yml b/data/recipe_example_tas_control_target.yml new file mode 100644 index 00000000..57a837ef --- /dev/null +++ b/data/recipe_example_tas_control_target.yml @@ -0,0 +1,64 @@ +# ESMValTool +# recipe_example.yml +--- +documentation: + description: Demonstrate basic ESMValTool example + + authors: + - demora_lee + - mueller_benjamin + - swaminathan_ranjini + + maintainer: + - demora_lee + + references: + - demora2018gmd + # Some plots also appear in ESMValTool paper 2. + + projects: + - ukesm + +preprocessors: + prep_mmm: + custom_order: true + regrid: + target_grid: 2.5 x 2.5 + scheme: linear + multi_model_statistics: + span: full + statistics: [mean, median] + + prep_obs: + mask_landsea: + mask_out: sea + regrid: + target_grid: 2.5 x 2.5 + scheme: linear + +cmip5_control: &cmip5_control + - {dataset: HadGEM2-ES, ensemble: r1i1p1, project: CMIP5} + - {dataset: MPI-ESM-LR, ensemble: r1i1p1, project: CMIP5} + +cmip5_target: &cmip5_target + - {dataset: CanESM2, ensemble: "r(1:2)i1p1", project: CMIP5} + +diagnostics: + + diag_variable_groups: + description: Demonstrate the use of variable groups. + variables: + tas_contorl: &variable_settings # need a key name for the grouping + short_name: tas # specify variable to look for + preprocessor: prep_mmm + mip: Amon + exp: historical + start_year: 2000 + end_year: 2005 + tag: TAS_CONTROL # tag is optional if you are using these settings just once + additional_datasets: *cmip5_control + tas_target: + <<: *variable_settings + tag: TAS_TARGET + additional_datasets: *cmip5_target # nothing changes from cmip5 except the data set + scripts: null From a83d72384b2269c9470afd43f9318b25b25ecf50 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 8 Sep 2020 10:30:04 +0200 Subject: [PATCH 404/647] fix time --- _episodes/05-preprocessor.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index f2be2f95..93b31090 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -333,7 +333,7 @@ simple preprocessor and diagnostic setup for that: > pr: # first variable is precipitation > mip: Amon > start_year: 2000 -> end_year: 2004 +> end_year: 2005 > preprocessor: prep_regrid > additional_datasets: > - {dataset: GPCP-SG, project: obs4mips, level: L3, @@ -341,7 +341,7 @@ simple preprocessor and diagnostic setup for that: > tas: # second variable is surface temperature > mip: Amon > start_year: 2000 -> end_year: 2004 +> end_year: 2005 > preprocessor: prep_regrid > scripts: null > ``` From 9e354621760e12571e0384dc186c5837d861575e Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 8 Sep 2020 10:41:48 +0200 Subject: [PATCH 405/647] change data size --- setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.md b/setup.md index 3cdbd7cb..183ca1d5 100644 --- a/setup.md +++ b/setup.md @@ -226,8 +226,8 @@ local machine and go [here](#gitHub-account-(advanced)). If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space -available to install conda & ESMValTool, but also enough to make a copy of some -data (13Gb). +available to install conda and ESMValTool, but also enough to make a copy of some +data (~2Gb). We can download a single data file following the instructions as described below: From 9565d3f4ba31e38855ff179e62dcf9e0b5d6824f Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 9 Sep 2020 09:01:35 +0200 Subject: [PATCH 406/647] remove duplicate link of pr --- data/dataset.urls | 2 -- 1 file changed, 2 deletions(-) diff --git a/data/dataset.urls b/data/dataset.urls index 9c57539d..945063dd 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -12,8 +12,6 @@ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/ http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-CC/historical/mon/ocean/Omon/r1i1p1/v20110930/tos/tos_Omon_HadGEM2-CC_historical_r1i1p1_195912-200511.nc # Variable = tos, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_195912-200512.nc -# -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/pr/pr_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc # For Working with preprocessors episode # Variable = thetao, model = HadGEM2-ES http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetao/thetao_Omon_HadGEM2-ES_historical_r1i1p1_199912-200512.nc From a99e3b5864e1e8f00750f0807bffdfda0286d8d9 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 9 Sep 2020 09:04:53 +0200 Subject: [PATCH 407/647] fix version --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 919a5039..378acf8d 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -521,7 +521,7 @@ available) can be found below. Note that the timestamps differ. > recipe: recipe_example.yml > run_dir: /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag > script: timeseries_diag -> version: 2.0.0 +> version: 2.0.0b9 > work_dir: /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag > write_netcdf: true > write_plots: true From 0abf318c8f695a3d96b2af25a5aba0d65a722091 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 9 Sep 2020 09:19:14 +0200 Subject: [PATCH 408/647] fix the year --- _episodes/04-recipe.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 378acf8d..54e27a95 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -412,11 +412,11 @@ available) can be found below. Note that the timestamps differ. > > For a single dataset: > -> ![single dataset](../fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png "single dataset") +> ![single dataset](../fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_0.png "single dataset") > > Or an overlay plot, if multiple datasets are defined: > -> ![multiple datasets](../fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png "multiple datasets") +> ![multiple datasets](../fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_.png "multiple datasets") {: .solution} > ## Your main output log file. @@ -571,7 +571,7 @@ available) can be found below. Note that the timestamps differ. > : alias: HadGEM2-ES > dataset: HadGEM2-ES > diagnostic: diag_timeseries_temperature -> end_year: 2005 +> end_year: 2000 > ensemble: r1i1p1 > exp: historical > filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1900-2000.nc @@ -588,7 +588,7 @@ available) can be found below. Note that the timestamps differ. > recipe_dataset_index: 0 > short_name: thetaoga > standard_name: sea_water_potential_temperature -> start_year: 1859 +> start_year: 2000 > units: K > variable_group: timeseries_variable > input_files: From 2b74fa0d8687379375c1b66dd5b05ebe0c037545 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 9 Sep 2020 09:20:56 +0200 Subject: [PATCH 409/647] add dataset for tos --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 54e27a95..10da50b2 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -628,7 +628,7 @@ available) can be found below. Note that the timestamps differ. > > - Land surface temperature (ts) for dataset HadGEM2-ES for 1970-2000 > - Atmospheric surface average temperature (tas) for dataset HadGEM2-ES for 1970-2000 -> - Ocean surface average temperature (tos) for dataset HadGEM2-ES for 1970-2000 +> - Ocean surface average temperature (tos) for datasets HadGEM2-ES and HadGEM2-CC for 1970-2000 > > You will need to edit: > From f684a80c25fd3121d34dcd7ec2af99b310e47bbb Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 9 Sep 2020 09:27:44 +0200 Subject: [PATCH 410/647] fix year, and a typo --- _episodes/05-preprocessor.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 93b31090..84030a8d 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -201,7 +201,7 @@ specific preprocessor which should be applied. >> ```yaml >> >> datasets: ->> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} +>> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} >> >> preprocessors: >> prep_map: # preprocessor to just regrid data @@ -389,7 +389,7 @@ separate multimodel means for different CMIP5 datasets given the same variable. > diag_variable_groups: > description: Demonstrate the use of variable groups. > variables: -> tas_contorl: &variable_settings # need a key name for the grouping +> tas_control: &variable_settings # need a key name for the grouping > short_name: tas # specify variable to look for > preprocessor: prep_mmm > mip: Amon From 7a583b5ef0c71a7110cd1db684252d72947caa94 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 9 Sep 2020 17:21:32 +0200 Subject: [PATCH 411/647] replace the recipe code-snippet with text --- _episodes/05-preprocessor.md | 66 ++++++++++++++---------------------- 1 file changed, 26 insertions(+), 40 deletions(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 84030a8d..ac097e81 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -193,48 +193,34 @@ specific preprocessor which should be applied. >you perform the masking first before regridding (hint: custom order your >operations). Now, use the two preprocessors in different diagnostics within the >same recipe. You may use any variable(s) of your choice. Once you succeed, try ->to add new datasets to the same recipe. Placeholders for the different ->components are provided below: +>to add new datasets to the same recipe. > ->> ## Recipe ->> ->> ```yaml ->> ->> datasets: ->> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} ->> ->> preprocessors: ->> prep_map: # preprocessor to just regrid data ->> # fill preprocessor details here ->> ->> prep_map_land: # preprocessor to mask grid cells and then regrid ->> # fill preprocessor details here including ordering ->> ->> diagnostics: ->> # -------------------------------------------------- ->> # Two Simple diagnostics that illustrate the use of ->> # different preprocessors ->> # -------------------------------------------------- ->> diag_simple_plot: ->> description: # preprocess a variable for a simple 2D plot ->> variables: ->> # put your variable of choice here ->> # apply the first preprocessor i.e. name your preprocessor ->> # edit the following 4 lines for mip, grid and time ->> # based on your variable choice ->> scripts: null # no scripts called ->> diag_land_only_plot: # second diagnostic ->> description: # preprocess a variable for a 2D land only plot ->> variables: ->> # include a variable and information ->> # as in the previous diagnostic and ->> # include your second preprocessor (masking and regridding) ->> scripts: null # no scripts ->> ``` ->> ->{: .solution} +> To complete this exercise, we need to change the following sections in the recipe: +> +> - `preprocessors`: +> - `prep_map`: add a preprocessor to regrid data +> - fill preprocessor details here +> +> - `prep_map_land`: add a preprocessor to mask grid cells and then regrid +> - fill preprocessor details here including ordering +> +> - `diag_simple_plot`: +> - `description`: preprocess a variable for a simple 2D plot +> - `variables`: +> - put your variable of choice here +> - edit mip, and time based on your variable choice +> - apply the first preprocessor i.e. name your preprocessor > ->> ## Solution: +> - `scripts`: `null` it means that no scripts called. +> +> - `diag_land_only_plot`: second diagnostic +> - `description`: preprocess a variable for a 2D land only plot +> - ``variables``: +> - include a variable and information as in the previous diagnostic +> - include your second preprocessor (masking and regridding) +> - `scripts`: `null` it means that no scripts called. +> +>> ## Solution >> >> Here is one solution to complete the challenge above using two different >> preprocessors: From 2ec2dca4cde2dcb1972b7c6982d1d9d0ba0a123b Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Wed, 16 Sep 2020 17:50:16 +0200 Subject: [PATCH 412/647] Fix broken link --- _episodes/05-preprocessor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index ac097e81..1b40d3fd 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -65,7 +65,7 @@ operations can be performed using ESMValTool preprocessors. >``` > > The default preprocessor order is listed in the [ESMValCore preprocessor API -> page](>https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html). +> page](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html). > > Also note that preprocessor operations aren't always commutative - meaning > that the order of operations matters. For instance, when you run the two From bc17e722cc46aa1059e99ab1d602e81be938bc38 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 17 Sep 2020 13:58:22 +0200 Subject: [PATCH 413/647] Update time span in exercise --- _episodes/05-preprocessor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 1b40d3fd..f82472ef 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -89,7 +89,7 @@ file afterwards. These do not need to be explicitly included in recipes. > ## Exercise: Adding more preprocessor steps > > Edit the [example recipe](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) to first change the variable to -> `thetao`, then add preprocessors to average over the latitude and longitude +> `thetao`, using only the years 2000-2005. Then add preprocessors to average over the latitude and longitude > dimensions and finally average over the depth. Now run the recipe. > >> ## Solution From 6ca4020c2b1802ea2158231efc569d9613299155 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 17 Sep 2020 15:57:09 +0200 Subject: [PATCH 414/647] Hide julia instructions --- _episodes/02-installation.md | 136 +++++++++++++++++------------------ 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 1cefe292..9ba20e9d 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -124,78 +124,78 @@ instructions. ## Install Julia +Some ESMValTool diagnostics are written in the Julia programming language. +If you want a full installation of ESMValTool including Julia diagnostics, you need +to make sure Julia is installed before installing ESMValTool. + +In this tutorial, we will not use Julia, but for reference, we have listed the steps +to install Julia below. Complete instructions for installing Julia can be found on the [Julia installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). -In this tutorial, we will use the following steps. First, open a bash terminal -and create a directory to install Julia in and cd into it - -```bash -mkdir ~/julia -cd ~/julia -``` - -Next, to download and extract the file `julia-1.0.5-linux-x86_64.tar.gz`, you can use the following commands:: - -```bash -wget https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz -tar -xvzf julia-1.0.5-linux-x86\_64.tar.gz -``` - -This will extract the files to a directory named `~/julia/julia-1.0.5`. To run -Julia, you need to add the full path of Julia's `bin` folder to PATH environment -variable. To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. -Open the file in a text editor called ``nano``: - -```bash -nano ~/.bashrc -``` - -and add a new line as follows at the -bottom of the file: - -```bash -export PATH="$PATH:$HOME/julia/julia-1.0.5/bin" -``` - -Finally, for the settings to take effect, either reload your bash profile - -```bash -source ~/.bashrc -``` - -(or `source ~/.bash_profile`), or close the bash terminal window and open a new -one. - -To check that the Julia executable can be found, run - -```bash -which julia -``` - -to display the path to the Julia executable, it should be -``` -~/julia/julia-1.0.5/bin/julia -``` -{: .output} - -To test that Julia is installed correctly, run - -```bash -julia -``` - -to start the interactive Julia interpreter. Press `Ctrl+D` to exit. - -> ## Text editor side note +> ## Julia installation instructions > -> No matter what editor you use, you will need to know where it searches -> for and saves files. If you start it from the shell, it will (probably) -> use your current working directory as its default location. We use ``nano`` -> in examples here because it is one of the least complex text editors. -> Press ctrl + O to save the file, -> and then ctrl + X to exit ``nano``. -{: .callout} +> First, open a bash terminal and create a directory to install Julia in and cd +> into it +> +> ```bash +> mkdir ~/julia +> cd ~/julia +> ``` +> +> Next, to download and extract the file `julia-1.0.5-linux-x86_64.tar.gz`, you can use the following commands:: +> +> ```bash +> wget https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz +> tar -xvzf julia-1.0.5-linux-x86\_64.tar.gz +> ``` +> +> This will extract the files to a directory named `~/julia/julia-1.0.5`. To run +> Julia, you need to add the full path of Julia's `bin` folder to PATH environment +> variable. To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. +> Open the file in a text editor called ``nano``: +> +> ```bash +> nano ~/.bashrc +> ``` +> +> and add a new line as follows at the +> bottom of the file: +> +> ```bash +> export PATH="$PATH:$HOME/julia/julia-1.0.5/bin" +> ``` +> +> Finally, for the settings to take effect, either reload your bash profile +> +> ```bash +> source ~/.bashrc +> ``` +> +> (or `source ~/.bash_profile`), or close the bash terminal window and open a new +> one. +> +> To check that the Julia executable can be found, run +> +> ```bash +> which julia +> ``` +> +> to display the path to the Julia executable, it should be +> +> ``` +> ~/julia/julia-1.0.5/bin/julia +> ``` +> {: .output} +> +> To test that Julia is installed correctly, run +> +> ```bash +> julia +> ``` +> +> to start the interactive Julia interpreter. Press `Ctrl+D` to exit. +{: .solution} ## Install the ESMValTool package From a48d15afb1a287f4a357e2286e0ae4a1cd07950a Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 17 Sep 2020 15:57:39 +0200 Subject: [PATCH 415/647] Explain subpackages; use esmvaltool-python only --- _episodes/02-installation.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 9ba20e9d..00cf4660 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -199,15 +199,28 @@ installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). ## Install the ESMValTool package -To install the ESMValTool package, run +The ESMValTool package contains diagnostics scripts in four languages: R, +Python, Julia and NCL. This introduces a lot of dependencies, and therefore the +installation can take quite long. It is, however, possible to install +'subpackages' for each of the languages. The following (sub)packages are +available: + +- `esmvaltool-python` +- `esmvaltool-ncl` +- `esmvaltool-r` +- `esmvaltool-julia` +- `esmvaltool` --> the complete package, i.e. the combination of the above. + +For the tutorial, we will use only Python diagnostics. Thus, to install the +ESMValTool-python package, run ```bash -conda create -n esmvaltool -c conda-forge -c esmvalgroup esmvaltool +conda create -n esmvaltool -c conda-forge -c esmvalgroup esmvaltool-python ``` This will create a new [Conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) -called `esmvaltool`, with the ESMValTool package and all of its dependencies +called `esmvaltool`, with the ESMValTool-Python package and all of its dependencies installed in it. > ## Conda common problems From 4ca2835385a4e909ca82a68dec57d1c080cb03c0 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 18 Sep 2020 08:46:01 +0200 Subject: [PATCH 416/647] Also remove julia from intro --- _episodes/02-installation.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 00cf4660..a8996798 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -19,10 +19,8 @@ In this tutorial we will be using the install the ESMValTool. Other installation methods are also available, they can be found in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). -ESMValTool also contains diagnostics written in [Julia](https://julialang.org/). -Because Julia cannot be installed by Conda, we will install Julia separately. We -will first learn how to install Conda, Julia, and finally the ESMValTool. We end -this chapter by testing that the installation was successful. +We will first install Conda, and then ESMValTool. We end this chapter by testing +that the installation was successful. ## Install Conda From 89e19a095978fe4aa2314f9c81a40b300783bc3b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 18 Sep 2020 14:35:08 +0200 Subject: [PATCH 417/647] revise text, fix links --- setup.md | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/setup.md b/setup.md index 183ca1d5..18aa43df 100644 --- a/setup.md +++ b/setup.md @@ -69,10 +69,13 @@ and the [CMIP6 Data Request](http://clipc-services.ceda.ac.uk/dreq/index.html). - A full list of [all ESGF nodes](https://esgf.llnl.gov/nodes.html). +- A good [tutorial](https://esgf.github.io/esgf-user-support/user_guide.html#data-search-and-download) +on how to search and download CMIP data from ESGF nodes. + ### CEDA-Jasmin Please skip this section if you are not going to use JASMIN -and go [here](#Github-account-(Advanced)). +and go [here](#github-account-advanced). If you do not already have an account on JASMIN, then request an account as soon as possible. Please follow [these instructions on how to create a Jasmin @@ -156,12 +159,12 @@ access the BADC archives via JASMIN. Some CMIP5 data sets such as MIROC are not accessible by default and special permission has to be requested to access them via [the CEDA catalogue page](https://catalogue.ceda.ac.uk/). -Congratulations! Please go here [here](#gitHub-account-(advanced)) next. +Congratulations! Please go here [here](#gitHub-account-advanced) next. ### DKRZ -Please skip this section if you are not going to use DKRZ and go [here](#github-account-(advanced)). +Please skip this section if you are not going to use DKRZ and go [here](#github-account-advanced). If you do not already have an account at the DKRZ, then [register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could @@ -217,41 +220,20 @@ Data storage: Running batch jobs: Info and examples on SLURM job scheduling system at DKRZ can be found [here](https://www.dkrz.de/up/systems/mistral/running-job). -Congratulations! Please go here [here](#GitHub-account-(Advanced)) next. +Congratulations! Please go here [here](#github-account-advanced) next. ### Using your own machine Please skip this section if you are not going to use ESMValTool on your -local machine and go [here](#gitHub-account-(advanced)). +local machine and go [here](#github-account-advanced). If you are planning on running ESMValTool on your own machine, please make sure that you are able to download CMIP data and that you have several GB of space available to install conda and ESMValTool, but also enough to make a copy of some data (~2Gb). -We can download a single data file following the instructions as described below: - -1. Go to the [CMIP5 search page on the DKRZ ESGF node][cmip5-search] -2. Perform the following search constraints - - - Model = HadGEM2-ES - - Experiment = historical - - Time frequency = mon - - Ensemble = r1i1p1 - - Variable = thetaoga - -3. Press search button -4. On single search result press `List files` -5. At bottom of page click on `Show All Files` -6. Find the file which starts with `thetaoga` in the list -7. Use `HTTP Download` link to download - the [thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc][theatoga.nc] file - to `~/default_inputpath/` directory. - -However, the tutorial needs more data files. The [dataset.urls][ds] file contains all data set URLs and in comments the used search constraints. All of the data files should be downloaded -to `~/default_inputpath/` directory. - -To download the data, run the following command using [wget](https://en.wikipedia.org/wiki/Wget): +To download the data required by this tutorial, run the following command using +[wget](https://en.wikipedia.org/wiki/Wget): ~~~shell wget --no-clobber --input-file \ From fca87d641fe5171d4454c140979d9ea6b50d9264 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 18 Sep 2020 15:29:40 +0200 Subject: [PATCH 418/647] polish the episode --- _episodes/02-installation.md | 87 +++++++++++++----------------------- 1 file changed, 32 insertions(+), 55 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index a8996798..6c5eda11 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -22,64 +22,54 @@ be found in the We will first install Conda, and then ESMValTool. We end this chapter by testing that the installation was successful. -## Install Conda +## Install ESMValTool on Windows -ESMValTool is distributed using [Conda](https://conda.io/). We will be using the -Miniconda minimal installer for conda. We suggest a Python 3 based installer, -though if you happen to already have Conda installed it should also work with -Python 2. For more information about installing conda, see [the conda -installation -documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). +ESMValTool does not directly support Windows, but succesful usage has been +reported through the [Windows Subsystem for +Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows +10. -### Linux +To install the WSL please follow the instructions [on the Windows Documentation +page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). -1. Please download Miniconda3 by running: +After installing the WSL, installation can be done using the same instructions for Linux/MacOSX. - ```bash - wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh - ``` +## Install ESMValTool on Linux/MacOSX -It is also possible to download Miniconda3 for Linux on the [miniconda page](https://docs.conda.io/en/latest/miniconda.html). If you have problems with the 64 bit version in the next step(s) you can alternatively try a 32 bit version. +### Install Conda -2. Next, run the installer from the place where you downloaded it +ESMValTool is distributed using [Conda](https://conda.io/). +Let's check if we already have Conda installed by running: - ```bash - bash Miniconda3-latest-Linux-x86_64.sh - ``` +```bash +conda list +``` -3. Follow the instructions in the installer. The defaults should normally - suffice. +If conda is installed, we will see a list of packages. +We recommend updating conda before esmvaltool installation. To do so, run: -4. You will need to restart your terminal for the changes to have effect. +```bash +conda update +``` -5. Verify you have a working conda installation by listing all installed - packages +If conda is **not** installed, We can use Miniconda minimal installer for conda. +We recommend a Python 3 based installer. For more information about installing conda, +see [the conda installation documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). - ```bash - conda list - ``` +To install conda on ``Linux`` or ``MacOSX``, follow the instructions below: - Should output something like +1. Please download Miniconda3 by running: + ```bash + wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh ``` - # packages in environment at ~/miniconda3: - # - # Name Version Build Channel - ... - conda 4.8.3 py37_0 - ... - ``` - {: .output} -### MacOSX - -1. Please download Miniconda3 for MacOSX at [the miniconda - page](https://docs.conda.io/en/latest/miniconda.html). + If you have problems with the 64 bit version in the next step(s) you can alternatively try a 32 bit version. 2. Next, run the installer from the place where you downloaded it ```bash - bash Miniconda3-latest-MacOSX-x86_64.sh + bash Miniconda3-latest-Linux-x86_64.sh ``` 3. Follow the instructions in the installer. The defaults should normally @@ -107,20 +97,7 @@ It is also possible to download Miniconda3 for Linux on the [miniconda page](htt {: .output} -### Windows - -ESMValTool does not directly support Windows, but succesful usage has been -reported through the [Windows Subsystem for -Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows -10. - -To install the WSL please follow the instructions [on the Windows Documentation -page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). - -After installing the WSL, installation can be done using the Linux installation -instructions. - -## Install Julia +### Install Julia Some ESMValTool diagnostics are written in the Julia programming language. If you want a full installation of ESMValTool including Julia diagnostics, you need @@ -195,7 +172,7 @@ installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). > to start the interactive Julia interpreter. Press `Ctrl+D` to exit. {: .solution} -## Install the ESMValTool package +### Install the ESMValTool package The ESMValTool package contains diagnostics scripts in four languages: R, Python, Julia and NCL. This introduces a lot of dependencies, and therefore the @@ -239,7 +216,7 @@ installed in it. > {: .callout} -## Test that the installation was successful +### Test that the installation was successful To test that the installation was successful, run From bc972da31e240e7fe9121ab2692804f083d105a1 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 18 Sep 2020 16:41:04 +0200 Subject: [PATCH 419/647] polish text --- _episodes/02-installation.md | 42 ++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 6c5eda11..a7d3144c 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -32,7 +32,8 @@ Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows To install the WSL please follow the instructions [on the Windows Documentation page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). -After installing the WSL, installation can be done using the same instructions for Linux/MacOSX. +After installing the WSL, installation can be done using the same instructions for ``Linux``. + ## Install ESMValTool on Linux/MacOSX @@ -52,24 +53,29 @@ We recommend updating conda before esmvaltool installation. To do so, run: conda update ``` -If conda is **not** installed, We can use Miniconda minimal installer for conda. +If conda is **not** installed, we can use Miniconda minimal installer for conda. We recommend a Python 3 based installer. For more information about installing conda, see [the conda installation documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). To install conda on ``Linux`` or ``MacOSX``, follow the instructions below: -1. Please download Miniconda3 by running: +1. Please download Miniconda3 at [the miniconda + page](https://docs.conda.io/en/latest/miniconda.html). + If you have problems with the 64 bit version in the next step(s) + you can alternatively try a 32 bit version. + +2. Next, run the installer from the place where you downloaded it: + + On ``Linux``: ```bash - wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh + bash Miniconda3-latest-Linux-x86_64.sh ``` - If you have problems with the 64 bit version in the next step(s) you can alternatively try a 32 bit version. - -2. Next, run the installer from the place where you downloaded it + On ``MacOSX``: ```bash - bash Miniconda3-latest-Linux-x86_64.sh + bash Miniconda3-latest-MacOSX-x86_64.sh ``` 3. Follow the instructions in the installer. The defaults should normally @@ -84,19 +90,6 @@ To install conda on ``Linux`` or ``MacOSX``, follow the instructions below: conda list ``` - Should output something like - - ``` - # packages in environment at ~/miniconda3: - # - # Name Version Build Channel - ... - conda 4.8.3 py37_0 - ... - ``` - {: .output} - - ### Install Julia Some ESMValTool diagnostics are written in the Julia programming language. @@ -198,9 +191,8 @@ environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/man called `esmvaltool`, with the ESMValTool-Python package and all of its dependencies installed in it. -> ## Conda common problems -> -> Below are some common problems that could happen while installing. + +> ## Common issues > > - Installation takes long time > - Downloads and compilations can take several minutes to complete, @@ -213,6 +205,8 @@ installed in it. > - Downloads fail due to company proxy, see [conda > docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to > resolve +> - On ``MacOSX``, installation only works fine for ``esmvaltool-python`` and +> ``esmvaltool-ncl`` with Python 3.7. > {: .callout} From db873ea905dd6bbb06be18377f41bec6ceb357e1 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 18 Sep 2020 17:34:20 +0200 Subject: [PATCH 420/647] Rewrite entire episode --- _episodes/01-introduction.md | 202 ++++++++++++++--------------------- 1 file changed, 83 insertions(+), 119 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 22d480ea..146159b7 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -1,155 +1,127 @@ --- title: "Introduction" -teaching: 20 +teaching: 5 exercises: 10 questions: -- What is ESMValTool and when is it useful? -- What are the main components of ESMValTool? -- How does ESMValTool contribute to FAIR climate research? -- What is the role of the ESMValTool community? +- What is ESMValTool? +- Who are the people behind ESMValTool? objectives: -- Describe key strengths and weaknesses of ESMValTool -- Know the different components of ESMValTool -- Understand the concept of a community-driven software project +- Familiarize with ESMValTool +- Synchronize expectations keypoints: - ESMValTool provides a reliable interface to analyse and evaluate climate data -- Using ESMValTool promotes standardization, collaboration, and reuse +- A large collection of recipes and diagnostic scripts is already available - ESMValTool is built and maintained by an active community of scientists and developers -- ESMValTool is written in Python, but supports diagnostic scripts in multiple - languages - --- ## What is ESMValTool? -ESMValTool is first and foremost a tool to analyse climate data. But you -probably already knew that and we like to think there's more to it than that. So -let's start with a quick check to synchronize our expectations. +This tutorial is a first introduction to ESMValTool. Before diving into the +technical steps, let's talk about what ESMValTool is all about. -> ## Question: what is ESMValTool -> -> Which of the following items would you say apply to ESMValTool? +> ## What is ESMValTool? > -> - A tool to analyse climate data -> - The easy way out -> - A community effort -> - Free -> - A command line tool -> - A way to make climate science more [FAIR](https://fair-software.eu/about) -> - Perfect -> - Suitable for (Jupyter) notebooks +> What do you already know about, or expect from ESMValTool? > -> Check our answers by unfolding the box below. -> -> > ## ESMValTool is -> > -> > ✓ **A tool to analyse climate data.** It takes care of finding, -> > opening, checking, fixing, concatenating, and preprocessing CMIP data and -> > several other supported datasets. +> > ## ESMValTool is... > > -> > ✕ **The easy way out.** If you just want to do an exploratory -> > analysis or quickly hack something together, ESMValTool is probably not the -> > way to go. The tool is intended for robust, repeatable and shareable climate -> > analysis. That *does* require a bit more effort. +> > EMSValTool is many things, but in this tutorial we will focus on the +> > following traits: > > -> > ✓ **A community effort.** ESMValTool is developed and maintained by a -> > large team of climate scientists and software engineers. It is an open -> > source project to which anyone can contribute. Its longevity depends on -> > these contributions. +> > ✓ **A tool to analyse climate data** > > -> > ✓ **Free.** ESMValTool is licenced under Apache 2.0, which means -> > everyone can use, modify, or share it free of charge. However, we *do* -> > encourage all users to contribute to the community once they get more -> > comfortable with the tool. +> > ✓ **A library for reproducible climate science** > > -> > ✓ **A command line tool.** ESMValTool was originally designed for the -> > command line. But, we are working on a user-friendly python interface as -> > well. +> > ✓ **A community effort** > > -> > ✓ **A way to make climate science more -> > [FAIR](https://fair-software.eu/about).** ESMValTool collects provenance -> > information about the data and code that are used to obtain a result. It -> > comes with a readable recipe format that makes climate analysis consistent, -> > reproducible, and easy to share. -> > -> > ✕ **Perfect.** Although we are continuously working to improve the -> > tool, you may encounter some bugs or missing features. In the following -> > episodes, you will learn how to troubleshoot, find help, and maybe even -> > contribute to the solution yourself. -> > -> > ✕ **Suitable for (Jupyter) notebooks.** ESMValTool was designed as a -> > command line tool. But, we are working on a user-friendly Python interface -> > as well. > {: .solution} {: .challenge} -To learn more about ESMValTool, you can look at the section -``Where can I get more information on ESMValTool?`` in the lesson -[Conclusion of the basic tutorial]({{ page.root }}{% link _episodes/07-conclusions.md %}). +## A tool to analyse climate data -## How does ESMValTool work +ESMValTool takes care of finding, opening, checking, fixing, concatenating, and +preprocessing CMIP data and several other supported datasets. -The figure below shows the different components of ESMValTool. Some of the most -important work is done in the 'core', which performs a number of preprocessor -steps. Outside of the core we have some configuration files that specify things -like *where to find the CMIP data*. The most important file however, is the -*recipe* that specifies which preprocessor functions need to be applied to what -data. The recipe also points to a diagnostic script that is executed after the -preprocessor and performs a more specific analysis on the preprocessed data. +The central componnent of ESMValTool that we will see in this tutorial is the +**recipe**. Any ESMValTool recipe is basically a set of instructions to reproduce +a certain result. The basic structure of a recipe is as follows: -![figure showing ESMValTool architecture]({{ page.root -}}/fig/esmvaltool_architecture.png) +- **Description** with relevant (citation) information +- **Datasets** that should be analysed +- **Preprocessor** steps that must be applied +- **Diagnostic** scripts performing more specific evaluation steps -> ## Discussion: (dis)advantages of this approach -> -> Discuss or think about the pros and cons of this architecture for a moment. -> Then unfold the box below to see our answers. +An example recipe could look like this: + +```yaml +documentation: + description: Example recipe + authors: + - lastname_firstname + +datasets: + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1960, end_year: 2099} + +preprocessors: + global_mean: + area_statistics: + operator: mean + +diagnostics: + hockeystick_plot: + description: plot of global mean temperature change + variables: + temperature: + short_name: tas + preprocessor: global_mean + scripts: hockeystick.py +``` + +> ## Understanding the different section of the recipe > +> Try to figure out the meaning of the different dataset keys. Hint: they can +> be found in the documentation of ESMValTool. > -> > ## See our thoughts -> > -> > - Streamlining common preprocessing steps ensures consistency in the -> > algorithms being used and the way they are executed. This facilitates -> > comparison and reproducibility. -> > - Provenance and citation information can be tracked through the entire -> > workflow. -> > - The core builds upon the [iris](https://scitools.org.uk/iris/docs/latest/) -> > package, which is quite strict in order to comply with CF conventions and -> > minimize unexpected results. -> > - Recipes are easy to read and share. -> > - A collection of recipes and diagnostic scripts is shipped with ESMValTool, -> > ready for re-use. Everyone can add to this collection. -> > - The recipe format takes some getting used to and may be a bit less -> > flexible then working on the datasets directly. -> > - Features or dataset support that are missing from ESMValCore can be a -> > limiting factor. +> > ## Solution +> > The keys are explained in the ESMValTool documentation, in the section `The +> recipe format`, under +> [datasets](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-datasets) > {: .solution} -{: .discussion} +{: .challenge} + +## A library for reproducible climate science -## Community +More than a tool, ESMValTool is a library of publicly available recipes and +diagnostic scripts. It comes with a large collection of recipes and diagnostic +scripts to reproduce important results. + +> ## Explore the available recipes +> +> Go to the [documentation of esmvaltool](https://docs.esmvaltool.org/) and +> explore the `available recipes` section. Which recipe(s) would you like to +> try? +{: .challenge} + +## A community effort ESMValTool is built and maintained by an active community of scientists and -software engineers. Many of the interactions take place on GitHub. Here, we -briefly introduce you to some of the most important pages. +software engineers. It is an open source project to which anyone can contribute. +Many of the interactions take place on GitHub. Here, we briefly introduce you to +some of the most important pages. > ## Meet ESMValGroup > > Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is > our 'organization' GitHub page. Have a look around. How many collaborators are -> there? Do you know any of them? Near the top of the page there are 2 pinned -> repositories: ESMValTool and ESMValCore. Visit each of the repositories. How -> many people have contributed to each of them? Can you also find out how many -> people have contributed to this tutorial? +> there? Do you know any of them? > -> > ## Solution -> > -> > At the time of making this lesson, there were 138 members of ESMValGroup. 55 -> > of them contributed to ESMValTool, 48 to ESMValCore. 52 (!) people -> > contributed to this tutorial. -> {: .solution} +> Near the top of the page there are 2 pinned repositories: ESMValTool and +> ESMValCore. Visit each of the repositories. How many people have contributed +> to each of them? Can you also find out how many people have contributed to +> this tutorial? {: .challenge} > ## Issues and pull requests @@ -162,20 +134,12 @@ briefly introduce you to some of the most important pages. > bugs have been fixed in ESMValCore? There is also an 'insights' tab, where you > can see a summary of recent activity. How many issues have been opened and > closed in the past month? -> -> > ## Solution -> > -> > At the time of making this lesson, there were 50 ESMValTool issues (the -> > majority) about enhancement and 31 bugs had been fixed in the Core. 13 -> > ESMValTool issues had been closed in the past month, versus 8 opened: -> > overall good progress. -> {: .solution} {: .challenge} ## Conclusion This concludes the introduction of the tutorial. You now have a basic knowledge -of ESMValTool and our community. The following episodes will walk you through +of ESMValTool and its community. The following episodes will walk you through the installation, configuration and running your first recipes. {% include links.md %} From d685d169f58da7cbf276c50f2abb3463640a97a5 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 1 Oct 2020 10:44:26 +0200 Subject: [PATCH 421/647] add another link for searching data, revise text --- setup.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/setup.md b/setup.md index 18aa43df..5913a5fd 100644 --- a/setup.md +++ b/setup.md @@ -64,14 +64,17 @@ For more information see: under the [CMIP5 data request](https://pcmdi.llnl.gov/mips/cmip5/docs/standard_output.pdf?id=28) and the [CMIP6 Data Request](http://clipc-services.ceda.ac.uk/dreq/index.html). -- A full list of all +- List of all [CMIP named variables](http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html). -- A full list of [all ESGF nodes](https://esgf.llnl.gov/nodes.html). +- List of all [ESGF nodes](https://esgf.llnl.gov/nodes.html). - A good [tutorial](https://esgf.github.io/esgf-user-support/user_guide.html#data-search-and-download) on how to search and download CMIP data from ESGF nodes. +- [Exploring climate model data](https://climate4impact.eu/impactportal/data/esgfsearch.jsp) +on infrastructure for the European network for Earth system modelling. + ### CEDA-Jasmin Please skip this section if you are not going to use JASMIN From 5293dda991547b5031a6585562a2a21c48bd18dd Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 1 Oct 2020 11:19:14 +0200 Subject: [PATCH 422/647] revise text, fix conda command --- _episodes/02-installation.md | 38 ++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index a7d3144c..7644fdb6 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -9,31 +9,35 @@ objectives: - "Install ESMValTool" - "Demonstrate that the installation was successful" keypoints: -- "All the required packages can be installed using conda" -- "You can find more information about installation in the documentation" +- "All the required packages can be installed using conda." +- "You can find more information about installation in the +[documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html)." --- ## Overview -In this tutorial we will be using the -[Conda](https://conda.io/projects/conda/en/latest/index.html) package manager to +The instructions help with the installation of ESMValTool on operating systems +like Linux/MacOSX/Windows. +We use the [Conda](https://conda.io/projects/conda/en/latest/index.html) +package manager to install the ESMValTool. Other installation methods are also available, they can be found in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). We will first install Conda, and then ESMValTool. We end this chapter by testing that the installation was successful. -## Install ESMValTool on Windows - -ESMValTool does not directly support Windows, but succesful usage has been -reported through the [Windows Subsystem for -Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), available in Windows -10. - -To install the WSL please follow the instructions [on the Windows Documentation -page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). - -After installing the WSL, installation can be done using the same instructions for ``Linux``. - +> ## Install ESMValTool on Windows +> +> ESMValTool does not directly support Windows, but successful usage has been +> reported through the [Windows Subsystem for +> Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), +> available in Windows 10. +> +> To install the WSL please follow the instructions [on the Windows Documentation +> page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). +> +> After installing the WSL, installation can be done using the same instructions for +> [Linux/MacOSX](#install-esmvaltool-on-linuxmacosx). +{: .callout} ## Install ESMValTool on Linux/MacOSX @@ -50,7 +54,7 @@ If conda is installed, we will see a list of packages. We recommend updating conda before esmvaltool installation. To do so, run: ```bash -conda update +conda update -n base conda ``` If conda is **not** installed, we can use Miniconda minimal installer for conda. From d015508d9185ee5db800017ba2384c1b345a9ed2 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 1 Oct 2020 12:13:22 +0200 Subject: [PATCH 423/647] Update _episodes/02-installation.md Co-authored-by: Peter Kalverla --- _episodes/02-installation.md | 1 - 1 file changed, 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 7644fdb6..2dbaf2e3 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -31,7 +31,6 @@ that the installation was successful. > reported through the [Windows Subsystem for > Linux(WSL)](https://docs.microsoft.com/en-us/windows/wsl/), > available in Windows 10. -> > To install the WSL please follow the instructions [on the Windows Documentation > page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). > From 4716e89ca9e415731f7019537b4bdd0ccabf44f1 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 1 Oct 2020 12:13:28 +0200 Subject: [PATCH 424/647] Update _episodes/02-installation.md Co-authored-by: Peter Kalverla --- _episodes/02-installation.md | 1 - 1 file changed, 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 2dbaf2e3..3f53b484 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -33,7 +33,6 @@ that the installation was successful. > available in Windows 10. > To install the WSL please follow the instructions [on the Windows Documentation > page](https://docs.microsoft.com/en-us/windows/wsl/install-win10). -> > After installing the WSL, installation can be done using the same instructions for > [Linux/MacOSX](#install-esmvaltool-on-linuxmacosx). {: .callout} From 867fd6180345844c39a56d088b7f17bb00fa8654 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 1 Oct 2020 12:20:42 +0200 Subject: [PATCH 425/647] Address Niels' comments --- _episodes/01-introduction.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 146159b7..a21c1c98 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -33,7 +33,7 @@ technical steps, let's talk about what ESMValTool is all about. > > > > ✓ **A tool to analyse climate data** > > -> > ✓ **A library for reproducible climate science** +> > ✓ **A collection of diagnostics for reproducible climate science** > > > > ✓ **A community effort** > > @@ -49,7 +49,7 @@ The central componnent of ESMValTool that we will see in this tutorial is the **recipe**. Any ESMValTool recipe is basically a set of instructions to reproduce a certain result. The basic structure of a recipe is as follows: -- **Description** with relevant (citation) information +- **Documentation** with relevant (citation) information - **Datasets** that should be analysed - **Preprocessor** steps that must be applied - **Diagnostic** scripts performing more specific evaluation steps @@ -63,7 +63,7 @@ documentation: - lastname_firstname datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1960, end_year: 2099} + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1960, end_year: 2005} preprocessors: global_mean: @@ -92,11 +92,11 @@ diagnostics: > {: .solution} {: .challenge} -## A library for reproducible climate science +## A collection of diagnostics for reproducible climate science -More than a tool, ESMValTool is a library of publicly available recipes and -diagnostic scripts. It comes with a large collection of recipes and diagnostic -scripts to reproduce important results. +More than a tool, ESMValTool is a collection of publicly available recipes and +diagnostic scripts. This makes it possible to easily reproduce important +results. > ## Explore the available recipes > From 5c7f1ea6212d0409b4a60dbe25a1490257c0bdfb Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 1 Oct 2020 15:14:30 +0200 Subject: [PATCH 426/647] add more challenges, revise the text --- _episodes/03-configuration.md | 199 ++++++++++++++++++++++++---------- 1 file changed, 142 insertions(+), 57 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 84f3973e..76b6490a 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -12,8 +12,9 @@ objectives: keypoints: - The ``config-user.yml`` tells ESMValTool where to find input data. -- "``rootpath`` defines the root directory for the input data." - "``output_dir`` defines the destination directory." +- "``rootpath`` defines the root path of the data." +- "``drs`` defines the directory structure of the data." --- @@ -98,7 +99,22 @@ config_developer_file: null profile_diagnostic: false ``` -In general there is no need to change the settings listed above. +> ## Saving preprocessed data +> +> In the configuration file, which settings are useful to make sure preprocessed +> data is stored when ESMValTool is run? +> +>> ## Solution +>> +>> If the option ``remove_preproc_dir`` is set to ``false``, then the +>> ``preproc/`` directory contains all the pre-processed data and the +>> metadata interface files. +>> If the option ``save_intermediary_cubes`` is set to ``true`` +>> then data will also be saved after each preprocessor step in the folder +>> ``preproc``. Note that saving all intermediate results to file will result +>> in a considerable slowdown. +> {: .solution} +{: .challenge} ## Destination directory @@ -108,12 +124,6 @@ a new output folder determined by recipe name, and date and time using the format: YYYYMMDD_HHMMSS. This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. -Let's name our destination directory ``esmvaltool_output`` in the working directory: - -```yaml -output_dir: ./esmvaltool_output -``` - > ## Content of subfolders > > - ``plots``: the location for all plots, split by individual diagnostics and fields. @@ -130,6 +140,22 @@ are not plots, e.g. files in NetCDF format (depends on the diagnostic script). [lesson]({{ page.root }}{% link _episodes/04-recipe.md %}) {: .callout} +> ## Set the destination directory +> +> Let's name our destination directory ``esmvaltool_output`` in the working directory. +> How to tell ESMValTool about our destination directory? +> +>> ## Solution +>> +>> We use `output_dir` entry in the `config-user.yml` file as: +>>```yaml +>> output_dir: ./esmvaltool_output +>>``` +>> +>> If the `esmvaltool_output` does not exist, ESMValTool will generate it for you. +> {: .solution} +{: .challenge} + ## Auxiliary data directory The ``auxiliary_data_dir`` setting is the path where any required additional @@ -151,7 +177,6 @@ You can choose the number of tasks in parallel as ESMValTool to use the maximum number of available CPUs: ```yaml - max_parallel_tasks: null ``` @@ -164,7 +189,6 @@ Using the number there you can increase the number of parallel tasks again to a reasonable number for the amount of memory available in your system. {: .callout} - ## Rootpath to input data ESMValTool uses several categories (in ESMValTool, this is referred to as projects) @@ -175,6 +199,7 @@ We can find more information about the projects in the ESMValTool [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html). The ``rootpath`` specifies the directories where ESMValTool will look for input data. For each category, you can define either one path or several paths as a list. +For example: ```yaml rootpath: @@ -184,71 +209,131 @@ rootpath: default: ~/default_inputpath CORDEX: ~/default_inputpath ``` -Site-specific entries for Jasmin, DKRZ and ETHZ are listed at the end of the -example configuration file. -In this lesson, we will work with data from -[CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) -and [obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/). -We add the root path of the folder where our/your data is available. - -```yaml - rootpath: - ... - CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2, ~/esmvaltool_tutorial/data] - obs4mips: ~/esmvaltool_tutorial/data -``` +Site-specific entries for Jasmin and DKRZ are listed at the end of the +example configuration file. -> ## Setting the correct rootpath +> ## Set the correct rootpath > -> - To get the data (or its correct rootpath), check instruction in -> [Setup]({{ page.root }}{% link setup.md %}). -> - For more information about setting the rootpath, see also the ESMValTool -> [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/esmvalcore/datafinder.html). -{: .callout} +> In this tutorial, we will work with data from +> [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) +> and [obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/). +> How does ESMValTool find the data? +> +> Hint: +> to get the data (or its correct rootpath), check instruction in +> [Setup]({{ page.root }}{% link setup.md %}). +> +>> ## Solution +>> +>> - Are you working on your own local machine? +>> You need to add the root path of the folder where the data is available +>> to the `config-user.yml` file as: +>>```yaml +>> rootpath: +>> ... +>> CMIP5: ~/esmvaltool_tutorial/data +>> obs4mips: ~/esmvaltool_tutorial/data +>>``` +>> +>> - Are you working with on a computer cluster like Jasmin or DKRZ? +>> Site-specific path to the data are already listed at the end of the +>> `config-user.yml` file. You need to uncomment the related lines. +>> For example, on Jasmin: +>>```yaml +>> # Site-specific entries: Jasmin +>> # Uncomment the lines below to locate data on JASMIN +>> rootpath: +>> # CMIP6: /badc/cmip6/data/CMIP6 +>> CMIP5: /badc/cmip5/data/cmip5/output1 +>> # CMIP3: /badc/cmip3_drs/data/cmip3/output +>> # OBS: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> # OBS6: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> obs4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> # ana4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> # CORDEX: /badc/cordex/data/CORDEX/output +>>``` +>> +>> - For more information about setting the rootpath, see also the ESMValTool +>> [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html). +> {: .solution} +{: .challenge} ## Directory structure for the data from different projects Input data can be from various models, observations and reanalysis data that adhere to the [CF/CMOR standard](https://cmor.llnl.gov/). The ``drs`` setting -describes the file structure. Let's use ``default`` for ``CMIP5`` in our example -here: +describes the file structure. -```yaml -drs: - CMIP5: default -``` +The ``drs`` setting describes the file structure for several projects (e.g. +CMIP6, CMIP5, obs4mips, OBS6, OBS) on several key machines +(e.g. BADC, CP4CDS, DKRZ, ETHZ, SMHI, BSC). For more +information about ``drs``, you can visit the ESMValTool documentation on +[Data Reference Syntax (DRS)](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html#cmor-drs). -> ## Available drs +> ## Set the correct drs > -> The ``drs`` setting describes the file structure for several projects (e.g. -> ``CMIP6``, ``CMIP5``, ``obs4mips``, ``OBS6``, ``OBS``) on several key machines -> (e.g. ``BADC``, ``CP4CDS``, ``DKRZ``, ``ETHZ``, ``SMHI``, ``BSC``). For more -> information about ``drs``, you can visit the ESMValTool -> [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html#cmor-drs). -{: .callout} - -> ## Make your own configuration file +> In this lesson, we will work with data from +> [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) +> and [obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/). +> How does ESMValTool know the data structure? > -> It is possible to have several configuration files with different purposes, -> for example: config-user_formalised_runs.yml, config-user_debugging.yml -{: .callout} +>> ## Solution +>> +>> - Are you working on your own local machine? +>> You need to set the `drs` of the data +>> in the `config-user.yml` file as: +>>```yaml +>> drs: +>> CMIP5: default +>> obs4mips: default +>>``` +>> +>> - Are you working with on a computer cluster like Jasmin or DKRZ? +>> Site-specific `drs` of the data are already listed at the end of the +>> `config-user.yml` file. You need to uncomment the related lines. +>> For example, on Jasmin: +>>```yaml +>> # Site-specific entries: Jasmin +>> # Uncomment the lines below to locate data on JASMIN +>> drs: +>> # CMIP6: BADC +>> CMIP5: BADC +>> # CMIP3: BADC +>> # CORDEX: BADC +>> # OBS: BADC +>> # OBS6: BADC +>> obs4mips: BADC +>> # ana4mips: BADC +>>``` +>> +> {: .solution} +{: .challenge} -> ## Saving preprocessed data +> ## Explain the default drs (if working on local machine) > -> In the configuration file, which settings are useful to make sure preprocessed -> data is stored when ESMValTool is run? +> 1. In the previous exercise, we set the `drs` of CMIP5 data to `default`. +> Can you explain why? +> +> 2. Have a look at the directory structure of the data. +> There is the folder `Tier1`. What does it mean? > >> ## Solution >> -> > If the option ``remove_preproc_dir`` is set to ``false``, then the -> > ``preproc/`` directory contains all the pre-processed data and the -> > metadata interface files. -> > If the option ``save_intermediary_cubes`` is set to ``true`` -> > then data will also be saved after each preprocessor step in the folder -> > ``preproc``. Note that saving all intermediate results to file will result -> > in a considerable slowdown. +>> 1. `drs: default` is one way to retrieve data from a ROOT directory that has no DRS-like structure. +>> ``default`` indicates that all the files are in a folder without any structure. +>> +>> 2. Observational data are organized in Tiers depending on their level of public availability. +>> Therefore the default directory must be structured accordingly with sub-directories +>> `TierX` e.g. Tier1, Tier2 or Tier3, even when `drs: default`. +>> > {: .solution} {: .challenge} +> ## Make your own configuration file +> +> It is possible to have several configuration files with different purposes, +> for example: config-user_formalised_runs.yml, config-user_debugging.yml +{: .callout} + {% include links.md %} From f07aa71c33fe08a7a7f76c6ec9aea63f605efae9 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 1 Oct 2020 15:26:38 +0200 Subject: [PATCH 427/647] minor edit --- _episodes/03-configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 76b6490a..cddbc7a3 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -220,8 +220,8 @@ example configuration file. > and [obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/). > How does ESMValTool find the data? > -> Hint: -> to get the data (or its correct rootpath), check instruction in +> Note: +> to get the data, check instruction in > [Setup]({{ page.root }}{% link setup.md %}). > >> ## Solution From 1eb82c1dd779fbe2ebe529c8e541756d5fe908a8 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 1 Oct 2020 17:39:43 +0200 Subject: [PATCH 428/647] move recipes from data to files folder --- _episodes/04-recipe.md | 10 +++++----- _episodes/05-preprocessor.md | 12 ++++++------ {data => files}/recipe_example.yml | 0 .../recipe_example_multi_preprocessors.yml | 0 {data => files}/recipe_example_pr_tas.yml | 0 {data => files}/recipe_example_tas.yml | 0 .../recipe_example_tas_control_target.yml | 0 {data => files}/recipe_example_thetao.yml | 0 {data => files}/recipe_example_thetao_thetaoga.yml | 0 {data => files}/recipe_example_tos.yml | 0 {data => files}/recipe_example_ts.yml | 0 11 files changed, 11 insertions(+), 11 deletions(-) rename {data => files}/recipe_example.yml (100%) rename {data => files}/recipe_example_multi_preprocessors.yml (100%) rename {data => files}/recipe_example_pr_tas.yml (100%) rename {data => files}/recipe_example_tas.yml (100%) rename {data => files}/recipe_example_tas_control_target.yml (100%) rename {data => files}/recipe_example_thetao.yml (100%) rename {data => files}/recipe_example_thetao_thetaoga.yml (100%) rename {data => files}/recipe_example_tos.yml (100%) rename {data => files}/recipe_example_ts.yml (100%) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 10da50b2..e8ff070a 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -102,11 +102,11 @@ The recipe presented here is a simple, basic recipe that takes a single dataset and produces a time series plot. Please download -[recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) +[recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example.yml) into your ESMValTool working directory: ~~~bash -wget https://raw.githubusercontent.com/ESMValGroup/ESMValTool_Tutorial/master/data/recipe_example.yml +wget https://raw.githubusercontent.com/ESMValGroup/ESMValTool_Tutorial/master/files/recipe_example.yml ~~~ > ## recipe_example.yml @@ -690,7 +690,7 @@ The snippets for the edits can be found below: > > Note: The x-axis in the plot now shows the years 1970 - 2000. > -> Complete recipe can be downloaded as [recipe_example_ts.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_ts.yml) +> Complete recipe can be downloaded as [recipe_example_ts.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_ts.yml) {: .solution} > ## Atmospheric surface average temperature @@ -725,7 +725,7 @@ The snippets for the edits can be found below: > timeseries_diag: > ``` > -> Complete recipe can be downloaded as [recipe_example_tas.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_tas.yml) +> Complete recipe can be downloaded as [recipe_example_tas.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_tas.yml) {: .solution} > ## Ocean surface average temperature @@ -762,7 +762,7 @@ The snippets for the edits can be found below: > ``` > Note: The unit in the plots is now degrees celsius! There are now 3 plots in the work directory. One for each dataset and one for the multiple dataset overview. > -> Complete recipe can be downloaded as [recipe_example_tos.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_tos.yml) +> Complete recipe can be downloaded as [recipe_example_tos.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_tos.yml) {: .solution} > ## Advanced: diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index f82472ef..164cfb87 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -88,7 +88,7 @@ file afterwards. These do not need to be explicitly included in recipes. > ## Exercise: Adding more preprocessor steps > -> Edit the [example recipe](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example.yml) to first change the variable to +> Edit the [example recipe](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example.yml) to first change the variable to > `thetao`, using only the years 2000-2005. Then add preprocessors to average over the latitude and longitude > dimensions and finally average over the depth. Now run the recipe. > @@ -127,7 +127,7 @@ file afterwards. These do not need to be explicitly included in recipes. >> timeseries_diag: >> ``` >> ->> Complete recipe can be downloaded as [recipe_example_thetao.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_thetao.yml) +>> Complete recipe can be downloaded as [recipe_example_thetao.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_thetao.yml) >{: .solution} {: .challenge} @@ -179,7 +179,7 @@ specific preprocessor which should be applied. > script: ocean/diagnostic_timeseries.py > ``` > -> Complete recipe can be downloaded as [recipe_example_thetao_thetaoga.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_thetao_thetaoga.yml) +> Complete recipe can be downloaded as [recipe_example_thetao_thetaoga.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_thetao_thetaoga.yml) {: .solution} >## Challenge : How to write a recipe with multiple preprocessors @@ -282,7 +282,7 @@ specific preprocessor which should be applied. >> ``` >> >> Complete recipe can be downloaded as ->> [recipe_example_multi_preprocessors.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_multi_preprocessors.yml). +>> [recipe_example_multi_preprocessors.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_multi_preprocessors.yml). > {: .solution} {: .challenge} @@ -331,7 +331,7 @@ simple preprocessor and diagnostic setup for that: > preprocessor: prep_regrid > scripts: null > ``` -> Complete recipe can be downloaded as [recipe_example_pr_tas.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_pr_tas.yml). +> Complete recipe can be downloaded as [recipe_example_pr_tas.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_pr_tas.yml). > {: .solution} @@ -393,7 +393,7 @@ separate multimodel means for different CMIP5 datasets given the same variable. > There is no field called datasets anymore. > Also, note how multiple ensembles are added by using (1:2). > Complete recipe can be downloaded as -> [recipe_example_tas_control_target.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/data/recipe_example_tas_control_target.yml). +> [recipe_example_tas_control_target.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_tas_control_target.yml). > {: .solution} diff --git a/data/recipe_example.yml b/files/recipe_example.yml similarity index 100% rename from data/recipe_example.yml rename to files/recipe_example.yml diff --git a/data/recipe_example_multi_preprocessors.yml b/files/recipe_example_multi_preprocessors.yml similarity index 100% rename from data/recipe_example_multi_preprocessors.yml rename to files/recipe_example_multi_preprocessors.yml diff --git a/data/recipe_example_pr_tas.yml b/files/recipe_example_pr_tas.yml similarity index 100% rename from data/recipe_example_pr_tas.yml rename to files/recipe_example_pr_tas.yml diff --git a/data/recipe_example_tas.yml b/files/recipe_example_tas.yml similarity index 100% rename from data/recipe_example_tas.yml rename to files/recipe_example_tas.yml diff --git a/data/recipe_example_tas_control_target.yml b/files/recipe_example_tas_control_target.yml similarity index 100% rename from data/recipe_example_tas_control_target.yml rename to files/recipe_example_tas_control_target.yml diff --git a/data/recipe_example_thetao.yml b/files/recipe_example_thetao.yml similarity index 100% rename from data/recipe_example_thetao.yml rename to files/recipe_example_thetao.yml diff --git a/data/recipe_example_thetao_thetaoga.yml b/files/recipe_example_thetao_thetaoga.yml similarity index 100% rename from data/recipe_example_thetao_thetaoga.yml rename to files/recipe_example_thetao_thetaoga.yml diff --git a/data/recipe_example_tos.yml b/files/recipe_example_tos.yml similarity index 100% rename from data/recipe_example_tos.yml rename to files/recipe_example_tos.yml diff --git a/data/recipe_example_ts.yml b/files/recipe_example_ts.yml similarity index 100% rename from data/recipe_example_ts.yml rename to files/recipe_example_ts.yml From f710f80da3b47b5020ae413148ec7a2db3783876 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 1 Oct 2020 18:07:03 +0200 Subject: [PATCH 429/647] remove example outputs --- _episodes/04-recipe.md | 216 +++++++---------------------------------- 1 file changed, 37 insertions(+), 179 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index e8ff070a..2f363f96 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -294,6 +294,12 @@ Please note the following sections: {: .challenge} > ## Exemplary output +> +> After running the `recipe_example.yml`, you will see some log information in the terminal. +> The information is based on the settings in both `recipe_example.yml` and +> the `config-user.yml` files. +> As an example, the log information is: +> > ~~~bash > 2020-07-01 08:22:58,571 UTC [33433] INFO > ______________________________________________________________________ @@ -381,12 +387,14 @@ Please note the following sections: Each time you run the ESMValTool, it will produce a new output directory within your specified work directory with the name of the recipe and the tagged runtime. This folder should contain four folders: + - run - work - preproc - plots -> ## Inspect the output: +> ## Inspect the output +> > Now that you have run the esmvaltool command for the first time, please locate > your output directory. If you’re missing the preproc directory, then your > `config-user.yml` file has the value remove_preproc_dir set to true (this is @@ -395,8 +403,10 @@ runtime. This folder should contain four folders: > {: .challenge} -> ## Inspect specific files: +> ## Inspect specific files +> > Please locate and inspect the following files: +> > - Your output plot(s). > - Your main output log file. > - Your settings.yml file. @@ -407,7 +417,8 @@ runtime. This folder should contain four folders: Exemplary output (depending on the directory paths and package versions that are available) can be found below. Note that the timestamps differ. -> ## Your output plot(s). +> ## Your output plot(s) +> > Plots for the dataset(s) are located in `./recipe_example_#_#/plots/timeseries_diag/` > > For a single dataset: @@ -419,210 +430,57 @@ available) can be found below. Note that the timestamps differ. > ![multiple datasets](../fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_.png "multiple datasets") {: .solution} -> ## Your main output log file. +> ## Your main output log file +> > The main output file is located at `./recipe_example_#_#/run/main_log.txt/` +> Let's have look at the file: > > ~~~bash -> INFO [33433] -> ______________________________________________________________________ -> _____ ____ __ ____ __ _ _____ _ -> | ____/ ___|| \/ \ \ / /_ _| |_ _|__ ___ | | -> | _| \___ \| |\/| |\ \ / / _` | | | |/ _ \ / _ \| | -> | |___ ___) | | | | \ V / (_| | | | | (_) | (_) | | -> |_____|____/|_| |_| \_/ \__,_|_| |_|\___/ \___/|_| -> ______________________________________________________________________ -> -> ESMValTool - Earth System Model Evaluation Tool. -> -> http://www.esmvaltool.org -> -> CORE DEVELOPMENT TEAM AND CONTACTS: -> Veronika Eyring (PI; DLR, Germany - veronika.eyring@dlr.de) -> Bouwe Andela (NLESC, Netherlands - b.andela@esciencecenter.nl) -> Bjoern Broetz (DLR, Germany - bjoern.broetz@dlr.de) -> Lee de Mora (PML, UK - ledm@pml.ac.uk) -> Niels Drost (NLESC, Netherlands - n.drost@esciencecenter.nl) -> Nikolay Koldunov (AWI, Germany - nikolay.koldunov@awi.de) -> Axel Lauer (DLR, Germany - axel.lauer@dlr.de) -> Benjamin Mueller (LMU, Germany - b.mueller@iggf.geo.uni-muenchen.de) -> Valeriu Predoi (URead, UK - valeriu.predoi@ncas.ac.uk) -> Mattia Righi (DLR, Germany - mattia.righi@dlr.de) -> Manuel Schlund (DLR, Germany - manuel.schlund@dlr.de) -> Javier Vegas-Regidor (BSC, Spain - javier.vegas@bsc.es) -> Klaus Zimmermann (SMHI, Sweden - klaus.zimmermann@smhi.se) -> -> For further help, please read the documentation at -> http://esmvaltool.readthedocs.io. Have fun! -> -> INFO [33433] Using config file /pf/b/b380506/work/config-DKRZ.yml -> INFO [33433] Writing program log files to: -> /scratch/b/b380506/recipe_example_20200701_082257/run/main_log.txt -> /scratch/b/b380506/recipe_example_20200701_082257/run/main_log_debug.txt -> INFO [33433] Starting the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:22:58 UTC -> INFO [33433] ---------------------------------------------------------------------- -> INFO [33433] RECIPE = /pf/b/b380506/work/recipes/recipe_example.yml -> INFO [33433] RUNDIR = /scratch/b/b380506/recipe_example_20200701_082257/run -> INFO [33433] WORKDIR = /scratch/b/b380506/recipe_example_20200701_082257/work -> INFO [33433] PREPROCDIR = /scratch/b/b380506/recipe_example_20200701_082257/preproc -> INFO [33433] PLOTDIR = /scratch/b/b380506/recipe_example_20200701_082257/plots -> INFO [33433] ---------------------------------------------------------------------- -> INFO [33433] Running tasks using at most 8 processes -> INFO [33433] If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. -> INFO [33433] If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. -> INFO [33433] Creating tasks from recipe -> INFO [33433] Creating tasks for diagnostic diag_timeseries_temperature -> INFO [33433] Creating preprocessor task diag_timeseries_temperature/timeseries_variable -> INFO [33433] Creating preprocessor 'prep_timeseries' task for variable 'thetaoga' -> INFO [33433] Using input files for variable thetaoga of dataset HadGEM2-ES: -> /mnt/lustre01/work/kd0956/CMIP5/data/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc -> INFO [33433] PreprocessingTask diag_timeseries_temperature/timeseries_variable created. It will create the files: -> /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc -> INFO [33433] Creating diagnostic task diag_timeseries_temperature/timeseries_diag -> INFO [33433] These tasks will be executed: diag_timeseries_temperature/timeseries_variable, diag_timeseries_temperature/timeseries_diag -> INFO [39196] Starting task diag_timeseries_temperature/timeseries_variable in process [39196] -> INFO [33433] Progress: 1 tasks running, 1 tasks waiting for ancestors, 0/2 done -> INFO [39196] Successfully completed task diag_timeseries_temperature/timeseries_variable (priority 0) in 0:00:07.241490 -> INFO [33433] Progress: 0 tasks running, 1 tasks waiting for ancestors, 1/2 done -> INFO [39197] Starting task diag_timeseries_temperature/timeseries_diag in process [39197] -> INFO [39197] Running command ['/pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python', '/mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py', '/scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml'] -> INFO [39197] Writing output to /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag -> INFO [39197] Writing plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag -> INFO [39197] Writing log to /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/log.txt -> INFO [39197] To re-run this diagnostic script, run: -> cd /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag; MPLBACKEND="Agg" /pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python /mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml -> INFO [33433] Progress: 1 tasks running, 0 tasks waiting for ancestors, 1/2 done -> INFO [39197] Maximum memory used (estimate): 0.2 GB -> INFO [39197] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. -> WARNING [39197] No provenance information was written to /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/diagnostic_provenance.yml -> INFO [39197] Successfully completed task diag_timeseries_temperature/timeseries_diag (priority 1) in 0:00:07.347165 -> INFO [33433] Progress: 0 tasks running, 0 tasks waiting for ancestors, 2/2 done -> INFO [33433] Successfully completed all tasks. -> INFO [33433] Ending the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:23:13 UTC -> INFO [33433] Time for running the recipe was: 0:00:14.820802 -> INFO [33433] Maximum memory used (estimate): 0.7 GB -> INFO [33433] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. -> INFO [33433] Run was successful +> nano ./recipe_example_#_#/run/main_log.txt > ~~~ > > Note: This is the same information as the terminal output, above, but without the time stamps. {: .solution} -> ## Your settings.yml file. +> ## Your settings.yml file +> > This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/settings.yaml`. +> Let's have look at the file: +> +> ~~~bash +> nano ./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/settings.yaml +> ~~~ > -> ```YAML -> auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data -> input_files: -> - /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml -> log_level: info -> output_file_type: png -> plot_dir: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag -> profile_diagnostic: false -> recipe: recipe_example.yml -> run_dir: /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag -> script: timeseries_diag -> version: 2.0.0b9 -> work_dir: /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag -> write_netcdf: true -> write_plots: true -> ``` {: .solution} > ## A metadata.yml file. > > This file is located at `./recipe_example_#_#/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml`. +> Please note that `preproc` diretctory exist if only `remove_preproc_dir: false` +> in ``config-user.yml`` file. +> Let's have look at the file: +> +> ~~~bash +> nano ./recipe_example_#_#/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml +> ~~~ > -> ```YAML -> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1900-2000.nc -> : alias: HadGEM2-ES -> dataset: HadGEM2-ES -> diagnostic: diag_timeseries_temperature -> end_year: 2000 -> ensemble: r1i1p1 -> exp: historical -> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1900-2000.nc -> frequency: mon -> institute: -> - INPE -> - MOHC -> long_name: Global Average Sea Water Potential Temperature -> mip: Omon -> modeling_realm: -> - ocean -> preprocessor: prep_timeseries -> project: CMIP5 -> recipe_dataset_index: 0 -> short_name: thetaoga -> standard_name: sea_water_potential_temperature -> start_year: 1900 -> units: K -> variable_group: timeseries_variable -> ``` {: .solution} > ## The diagnostic log file. +> > This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/log.txt` +> Let's have look at the file: > > ~~~bash -> Starting diagnostic script timeseries_diag with configuration: -> auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data -> input_data: -> ? /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1900-2000.nc -> : alias: HadGEM2-ES -> dataset: HadGEM2-ES -> diagnostic: diag_timeseries_temperature -> end_year: 2000 -> ensemble: r1i1p1 -> exp: historical -> filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1900-2000.nc -> frequency: mon -> institute: -> - INPE -> - MOHC -> long_name: Global Average Sea Water Potential Temperature -> mip: Omon -> modeling_realm: -> - ocean -> preprocessor: prep_timeseries -> project: CMIP5 -> recipe_dataset_index: 0 -> short_name: thetaoga -> standard_name: sea_water_potential_temperature -> start_year: 2000 -> units: K -> variable_group: timeseries_variable -> input_files: -> - /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml -> log_level: info -> output_file_type: png -> plot_dir: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag -> profile_diagnostic: false -> recipe: recipe_example.yml -> run_dir: /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag -> script: timeseries_diag -> version: 2.0.0b9 -> work_dir: /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag -> write_netcdf: true -> write_plots: true -> -> Creating /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag -> Creating /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag -> metadata filename: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml -> No handles with labels found to put in legend. -> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900-2000_timeseries_.png -> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900-2000_timeseries_.png -> ----------------- -> model filenames: /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc -> Image path will be: /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1900-2000_timeseries_0.png -> Saving plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1900-2000_timeseries_0.png -> Success -> End of diagnostic script run. +> nano ./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/log.txt > ~~~ +> {: .solution} ## Do your first edits > ## Edit the recipe and run again +> > So far, the example recipe has used global volume-weighted ocean temperature. > Please edit this recipe to investigate one of the following fields: > From 820cedabed3be73c2bf21b229e78db6187152f12 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 2 Oct 2020 10:25:42 +0200 Subject: [PATCH 430/647] minor revision in text --- _episodes/04-recipe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 2f363f96..c4b20148 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -295,8 +295,8 @@ Please note the following sections: > ## Exemplary output > -> After running the `recipe_example.yml`, you will see some log information in the terminal. -> The information is based on the settings in both `recipe_example.yml` and +> After running the `recipe_example.yml`, some information (log messages) will be printed in the terminal. +> The log messages depends on the settings in both `recipe_example.yml` and > the `config-user.yml` files. > As an example, the log information is: > From 4901157c7108b679228297a23f40d3a3320eaf1c Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Fri, 2 Oct 2020 10:29:33 +0200 Subject: [PATCH 431/647] Update _episodes/03-configuration.md Co-authored-by: Peter Kalverla --- _episodes/03-configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index cddbc7a3..0550a7b2 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -112,7 +112,7 @@ profile_diagnostic: false >> If the option ``save_intermediary_cubes`` is set to ``true`` >> then data will also be saved after each preprocessor step in the folder >> ``preproc``. Note that saving all intermediate results to file will result ->> in a considerable slowdown. +>> in a considerable slowdown, and can quickly fill your disk. > {: .solution} {: .challenge} From c556592a4cf1fb699cfbe58f3c47f64c0b21e635 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Fri, 2 Oct 2020 10:52:29 +0200 Subject: [PATCH 432/647] Update _episodes/03-configuration.md Co-authored-by: Peter Kalverla --- _episodes/03-configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 0550a7b2..8a7dd532 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -333,7 +333,7 @@ information about ``drs``, you can visit the ESMValTool documentation on > ## Make your own configuration file > > It is possible to have several configuration files with different purposes, -> for example: config-user_formalised_runs.yml, config-user_debugging.yml +> for example: config-user_formalised_runs.yml, config-user_debugging.yml. In this case, you have to pass the path to the config file you want to use as a command line option when running the ESMValTool. {: .callout} {% include links.md %} From 48febe6eb4a9410af6437e769be7f8d77be16942 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 2 Oct 2020 12:09:02 +0200 Subject: [PATCH 433/647] revise the text --- _episodes/03-configuration.md | 123 ++++++++++++++-------------------- 1 file changed, 49 insertions(+), 74 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 8a7dd532..510daa14 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -23,10 +23,8 @@ keypoints: The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. This is a [YAML file](https://yaml.org/spec/1.2/spec.html). -An example configuration file can be found in the ESMValCore repository: -[config-user-example.yml](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-user.yml). -You can generate the default configuration file by running: +You can get the default configuration file by running: ~~~bash esmvaltool config get_config_user @@ -37,7 +35,8 @@ path to your home directory. Note that files and directories starting with a period are "hidden", to see the `.esmvaltool` directory in the terminal use `ls -la ~`. -We run a text editor called ``nano`` to have a look inside the configuration file: +We run a text editor called ``nano`` to have a look inside the configuration file +and then modify it if needed: ~~~bash nano ~/.esmvaltool/config-user.yml @@ -66,43 +65,14 @@ This file contains the information for: These settings are used to inform ESMValTool about your preference about specific actions. You can turn on or off the setting by ``true`` or ``false`` -values. Most of these settings are fairly self-explanatory, ie: - -```yaml -# Diagnostics create plots? [true]/false -write_plots: true -# Diagnositcs write NetCDF files? [true]/false -write_netcdf: true -# Set the console log level debug, [info], warning, error -log_level: info -# Exit on warning (only for NCL diagnostic scripts)? true/[false] -exit_on_warning: false -# Plot file format? [png]/pdf/ps/eps/epsi -output_file_type: png - -... - -# Use netCDF compression true/[false] -compress_netcdf: false -# Save intermediary cubes in the preprocessor true/[false] -save_intermediary_cubes: false -# Remove the preproc dir if all fine -remove_preproc_dir: true - -... - -# Path to custom config-developer file, to customise project configurations. -# See config-developer.yml for an example. Set to [null] to use the default -config_developer_file: null -# Get profiling information for diagnostics -# Only available for Python diagnostics -profile_diagnostic: false -``` +values. Most of these settings are fairly self-explanatory. +For example, `write_plots: true` means that diagnostics create plots. > ## Saving preprocessed data > -> In the configuration file, which settings are useful to make sure preprocessed -> data is stored when ESMValTool is run? +> Later in this tutorial, we will want to look at the contents of the `preproc` folder. +> This folder contains preprocessed data and is removed by default when ESMValTool is run. +> In the configuration file, which settings can be modified to prevent this from happening? > >> ## Solution >> @@ -143,7 +113,8 @@ are not plots, e.g. files in NetCDF format (depends on the diagnostic script). > ## Set the destination directory > > Let's name our destination directory ``esmvaltool_output`` in the working directory. -> How to tell ESMValTool about our destination directory? +> ESMValTool should write the output to this path. +> How to modify the `config-user.yml`? > >> ## Solution >> @@ -156,39 +127,6 @@ are not plots, e.g. files in NetCDF format (depends on the diagnostic script). > {: .solution} {: .challenge} -## Auxiliary data directory - -The ``auxiliary_data_dir`` setting is the path where any required additional -auxiliary data files are stored. This location allows us to tell the diagnostic -script where to find the files if they can not be downloaded at runtime. This -option should not be used for model or observational datasets, but for data -files (e.g. shape files) used in plotting such as coastline descriptions and so -on. - -```yaml -auxiliary_data_dir: ~/auxiliary_data -``` - -## Number of parallel tasks - -This option enables you to perform parallel processing. -You can choose the number of tasks in parallel as -1/2/3/4/... or you can set it to ``null``. That tells -ESMValTool to use the maximum number of available CPUs: - -```yaml -max_parallel_tasks: null -``` - -> ## Set the number of tasks -> -> If you run out of memory, try setting ``max_parallel_tasks`` to 1. -Then, check the amount of memory you need for that by inspecting -the file ``run/resource_usage.txt`` in the output directory. -Using the number there you can increase the number of parallel tasks -again to a reasonable number for the amount of memory available in your system. -{: .callout} - ## Rootpath to input data ESMValTool uses several categories (in ESMValTool, this is referred to as projects) @@ -218,7 +156,8 @@ example configuration file. > In this tutorial, we will work with data from > [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) > and [obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/). -> How does ESMValTool find the data? +> How can we moodify the `rootpath` to make sure the data path is set correctly +> for both CMIP5 and obs4mips. > > Note: > to get the data, check instruction in @@ -276,7 +215,7 @@ information about ``drs``, you can visit the ESMValTool documentation on > In this lesson, we will work with data from > [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) > and [obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/). -> How does ESMValTool know the data structure? +> How can we set the correct `drs`? > >> ## Solution >> @@ -330,6 +269,42 @@ information about ``drs``, you can visit the ESMValTool documentation on > {: .solution} {: .challenge} +## Other settings + +> ## Auxiliary data directory +> +> The ``auxiliary_data_dir`` setting is the path where any required additional +auxiliary data files are stored. This location allows us to tell the diagnostic +script where to find the files if they can not be downloaded at runtime. This +option should not be used for model or observational datasets, but for data +files (e.g. shape files) used in plotting such as coastline descriptions and +if you want to feed some additional data (e.g. shape files) to your recipe. +> +>```yaml +> auxiliary_data_dir: ~/auxiliary_data +> ``` +> See more information in ESMValTool +[document](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/quickstart/configure.html?highlight=auxiliary_data#user-configuration-file). +{: .callout} + +> ## Number of parallel tasks +> +> This option enables you to perform parallel processing. +You can choose the number of tasks in parallel as +1/2/3/4/... or you can set it to ``null``. That tells +ESMValTool to use the maximum number of available CPUs: +> +>```yaml +> max_parallel_tasks: null +> ``` +> +> If you run out of memory, try setting ``max_parallel_tasks`` to 1. +Then, check the amount of memory you need for that by inspecting +the file ``run/resource_usage.txt`` in the output directory. +Using the number there you can increase the number of parallel tasks +again to a reasonable number for the amount of memory available in your system. +{: .callout} + > ## Make your own configuration file > > It is possible to have several configuration files with different purposes, From 0a7f621c1b596c6f26fbea2afaa920b895e4bda4 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 2 Oct 2020 12:19:09 +0200 Subject: [PATCH 434/647] add a link, reise the text --- _episodes/03-configuration.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 510daa14..d7925df9 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -308,7 +308,11 @@ again to a reasonable number for the amount of memory available in your system. > ## Make your own configuration file > > It is possible to have several configuration files with different purposes, -> for example: config-user_formalised_runs.yml, config-user_debugging.yml. In this case, you have to pass the path to the config file you want to use as a command line option when running the ESMValTool. +> for example: config-user_formalised_runs.yml, config-user_debugging.yml. +> In this case, you have to pass the path of your own configuration file +> as a command-line option when running the ESMValTool. +> We will learn how to do this in the +> [next lesson]({{ page.root }}{% link _episodes/04-recipe.md %}). {: .callout} {% include links.md %} From cc6cb75427093f7b4ddfb31a4ef612bb30b645e8 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 2 Oct 2020 13:48:14 +0200 Subject: [PATCH 435/647] fix path to recipe --- .github/workflows/recipes.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 2e54e637..a32d491c 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -12,11 +12,11 @@ jobs: - name: Cache conda uses: actions/cache@v1 env: - # Increase this value to reset cache if data/recipe_example.yml has not changed + # Increase this value to reset cache if files/recipe_example.yml has not changed CACHE_NUMBER: 1 with: path: ~/conda_pkgs_dir - key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/recipe_example.yml') }} + key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('files/recipe_example.yml') }} - uses: goanpeca/setup-miniconda@v1 - name: Install esmvaltool run: conda install -n test -y -c esmvalgroup -c conda-forge esmvaltool-python @@ -41,8 +41,8 @@ jobs: with: path: ~/default_inputpath key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} - - name: Download dataset files for data/recipe_example.yml + - name: Download dataset files for files/recipe_example.yml run: | head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --directory-prefix $HOME/default_inputpath/ - - name: Run data/recipe_example.yml - run: $CONDA/envs/test/bin/esmvaltool run $PWD/data/recipe_example.yml + - name: Run files/recipe_example.yml + run: $CONDA/envs/test/bin/esmvaltool run $PWD/files/recipe_example.yml From e645581f15007708f77bacee8ff79009d8656022 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 2 Oct 2020 14:02:50 +0200 Subject: [PATCH 436/647] revise the text --- _episodes/03-configuration.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index d7925df9..7a2d5de4 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -63,8 +63,9 @@ This file contains the information for: ## Output settings -These settings are used to inform ESMValTool about your preference about -specific actions. You can turn on or off the setting by ``true`` or ``false`` +The configuration file starts with output settings that +inform ESMValTool about your preference for output. +You can turn on or off the setting by ``true`` or ``false`` values. Most of these settings are fairly self-explanatory. For example, `write_plots: true` means that diagnostics create plots. From c7401f2d7d7c0c3f87e562a9ea601f0ddf582c0d Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Thu, 8 Oct 2020 13:46:21 +0200 Subject: [PATCH 437/647] Update glossary --- _extras/glossary.md | 48 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index 00d8b704..abcb8dbe 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -1,18 +1,58 @@ --- -title: Glossary +title: Glossary --- ## ESMValTool Glossary Here, there are some definitions used throughout this tutorial: -- **Diagnostics**: A diagnostic script is the last step in a recipe to convert the pre-processed input data to the desired output like plots or NetCDF files. +- **-ga**: Suffix indicating a variable is a global average + +- **Amon**: Monthly mean atmopsheric fields - **CMIP**: The Coupled Model Intercomparison Project (CMIP) aims at better understanding past, present and future climate changes arising from natural, unforced variability or in response to changes in radiative forcing in a multi-model context. For more information, check the [WCR-Climate webpage](https://www.wcrp-climate.org/). -- **CMOR**: CMOR stands for [“Climate Model Output Rewriter” library](https://pcmdi.github.io/cmor-site/index.html). It comprises a set of C-based functions, with bindings to both Python and FORTRAN 90, that can be used to produce CF-compliant netCDF files that fulfill the requirements of many of the climate community's standard model experiments. +- **CMOR**: CMOR stands for [*Climate Model Output Rewriter* library](https://pcmdi.github.io/cmor-site/index.html). It comprises a set of C-based functions, with bindings to both Python and FORTRAN 90, that can be used to produce CF-compliant netCDF files that fulfill the requirements of many of the climate community's standard model experiments. + +- **dataset**: Refers to the model that was used to simulate the data, e.g. HadGEM2-ES) + +- **diagnostic**: A diagnostic script is the last step in a recipe to convert the pre-processed input data to the desired output like plots or NetCDF files. + +- **ensemble**: An ensemble is a collection of experiments based on standardised inputs. This ensures that ensemble calculations use the same initial states, initialisation methods, and physics details. Ensemble members are named in the rip-nomenclature, *r* for realization, *i* for initialisation and *p* for physics, followed by an integer, e.g. r1i1p1. + +- **experiment**: An experiment is defined as an activity aimed at addressing a specific scientific problem. In CMIP, experiments are numerical experiments with climate models + +- **grid**: A grid is the array of coordinates on which a variable has been sampled. + +- **mask**: Masks are used to isolate regions. For example, if you apply an ocean mask, then coordinates in the ocean will not be taken into account for the preprocessors/diagnostics. Masks can also be used to work with regions that have have missing or invalid entries. + +- **mip**: Typically used to refer to a table of variables in ESMValTool. These are standardized per project, e.g. the [MIP tables for CMIP6](http://clipc-services.ceda.ac.uk/dreq/index/miptable.html). + +- **Omon**: Monthly mean ocean fields + +- **pr**: CMIP short-hand for 'precipitation' + +- **preprocessor**: A preprocessor is a function that is applied to a dataset + +- **project**: Typically refers to a standard experimental protocol for global models, e.g. CMIP. + +- **RCP**: *Representative Concentration Pathways* are scenarios that represent the full bandwidth of possible future emission trajectories. Depending on population growth and the development of energy production, food production and land use, various emission trajectories are possible. + +- **recipe**: A recipe contains the instructions to be carried out by the ESMValTool. This includes four main sections: datasets, preprocessors, diagnostics and description. + +- **ta**: CMIP short-hand for 'air temperature' + +- **tas**: CMIP short-hand for 'near-surface air temperature' + +- **thetao**: Sea water potential temperature variable (assume reference height is sea level) + +- **thetaoga**: Global average sea water potential temperature + +- **tos**: CMIP short-hand for 'sea surface temperature' + +- **ts**: CMIP short-hand for 'surface temperature' -- **Recipe**: A recipe contains the instructions to be carried out by the ESMValTool. This includes four main sections: datasets, preprocessors, diagnostics and description. +- **yaml**: YAML is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or exchanged. For more details on ESMValTool, please go to: Additional info can be found in [ESMValTool home page](https://esmvaltool.org) From a4c2b86070dd626dd02e1c087f1bcd6fe1a677f4 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 12 Oct 2020 11:13:09 +0200 Subject: [PATCH 438/647] Apply suggestions from code review Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _extras/glossary.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index abcb8dbe..c141fba7 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -6,13 +6,11 @@ title: Glossary Here, there are some definitions used throughout this tutorial: -- **-ga**: Suffix indicating a variable is a global average - -- **Amon**: Monthly mean atmopsheric fields +- **Amon**: Monthly atmospheric data - **CMIP**: The Coupled Model Intercomparison Project (CMIP) aims at better understanding past, present and future climate changes arising from natural, unforced variability or in response to changes in radiative forcing in a multi-model context. For more information, check the [WCR-Climate webpage](https://www.wcrp-climate.org/). -- **CMOR**: CMOR stands for [*Climate Model Output Rewriter* library](https://pcmdi.github.io/cmor-site/index.html). It comprises a set of C-based functions, with bindings to both Python and FORTRAN 90, that can be used to produce CF-compliant netCDF files that fulfill the requirements of many of the climate community's standard model experiments. +- **CMOR**: CMOR stands for [*Climate Model Output Rewriter* library](https://pcmdi.github.io/cmor-site/index.html). It comprises a set of C-based functions, with bindings to both Python and FORTRAN 90, that can be used to produce CF-compliant NetCDF files that fulfill the requirements of many of the climate community's standard model experiments. - **dataset**: Refers to the model that was used to simulate the data, e.g. HadGEM2-ES) From 314f5f503182b12f9c3dbaea212b1902fa51f8d5 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 12 Oct 2020 09:14:10 +0000 Subject: [PATCH 439/647] Update glossary.md --- _extras/glossary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index c141fba7..e1cbfc20 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -12,7 +12,7 @@ Here, there are some definitions used throughout this tutorial: - **CMOR**: CMOR stands for [*Climate Model Output Rewriter* library](https://pcmdi.github.io/cmor-site/index.html). It comprises a set of C-based functions, with bindings to both Python and FORTRAN 90, that can be used to produce CF-compliant NetCDF files that fulfill the requirements of many of the climate community's standard model experiments. -- **dataset**: Refers to the model that was used to simulate the data, e.g. HadGEM2-ES) +- **dataset**: In a recipe, dataset refers to the name of the model or observation data, e.g. HadGEM2-ES - **diagnostic**: A diagnostic script is the last step in a recipe to convert the pre-processed input data to the desired output like plots or NetCDF files. From 2390a9f63c96463234f12f86906139887738a783 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 12 Oct 2020 13:18:47 +0200 Subject: [PATCH 440/647] Apply suggestions from code review Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _extras/glossary.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index e1cbfc20..2164e9be 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -12,25 +12,25 @@ Here, there are some definitions used throughout this tutorial: - **CMOR**: CMOR stands for [*Climate Model Output Rewriter* library](https://pcmdi.github.io/cmor-site/index.html). It comprises a set of C-based functions, with bindings to both Python and FORTRAN 90, that can be used to produce CF-compliant NetCDF files that fulfill the requirements of many of the climate community's standard model experiments. -- **dataset**: In a recipe, dataset refers to the name of the model or observation data, e.g. HadGEM2-ES +- **dataset**: In a recipe, dataset refers to the name of the model or observation data, e.g. HadGEM2-ES. -- **diagnostic**: A diagnostic script is the last step in a recipe to convert the pre-processed input data to the desired output like plots or NetCDF files. +- **diagnostic**: In a recipe, the diagnostic section(s) define the tasks that will be executed when running the recipe. It can also include a diagnostic script that converts the preprocessed input data to the desired output like plots or NetCDF files. - **ensemble**: An ensemble is a collection of experiments based on standardised inputs. This ensures that ensemble calculations use the same initial states, initialisation methods, and physics details. Ensemble members are named in the rip-nomenclature, *r* for realization, *i* for initialisation and *p* for physics, followed by an integer, e.g. r1i1p1. - **experiment**: An experiment is defined as an activity aimed at addressing a specific scientific problem. In CMIP, experiments are numerical experiments with climate models -- **grid**: A grid is the array of coordinates on which a variable has been sampled. +- **grid**: In the dataset section of a recipe, a grid is the array of coordinates on which a variable has been sampled. -- **mask**: Masks are used to isolate regions. For example, if you apply an ocean mask, then coordinates in the ocean will not be taken into account for the preprocessors/diagnostics. Masks can also be used to work with regions that have have missing or invalid entries. +- **mask**: Masks are used to isolate regions. For example, if you apply an ocean mask, then coordinates in the ocean will not be taken into account for the preprocessors/diagnostics. Masks can also be used to work with regions that have missing or invalid entries. - **mip**: Typically used to refer to a table of variables in ESMValTool. These are standardized per project, e.g. the [MIP tables for CMIP6](http://clipc-services.ceda.ac.uk/dreq/index/miptable.html). -- **Omon**: Monthly mean ocean fields +- **Omon**: Monthly ocean data - **pr**: CMIP short-hand for 'precipitation' -- **preprocessor**: A preprocessor is a function that is applied to a dataset +- **preprocessor**: A preprocessor is an operation that is applied to a dataset. - **project**: Typically refers to a standard experimental protocol for global models, e.g. CMIP. From 8ea7561fc097369f4f179961b8c22cbf02f7548d Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 12 Oct 2020 11:22:06 +0000 Subject: [PATCH 441/647] Update glossary.md --- _extras/glossary.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index 2164e9be..31de648c 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -28,27 +28,27 @@ Here, there are some definitions used throughout this tutorial: - **Omon**: Monthly ocean data -- **pr**: CMIP short-hand for 'precipitation' +- **pr**: CMIP short-hand for 'precipitation'. - **preprocessor**: A preprocessor is an operation that is applied to a dataset. -- **project**: Typically refers to a standard experimental protocol for global models, e.g. CMIP. +- **project**: In the dataset section of a recipe, "project" Typically refers to a standard experimental protocol for global models, e.g. CMIP. - **RCP**: *Representative Concentration Pathways* are scenarios that represent the full bandwidth of possible future emission trajectories. Depending on population growth and the development of energy production, food production and land use, various emission trajectories are possible. - **recipe**: A recipe contains the instructions to be carried out by the ESMValTool. This includes four main sections: datasets, preprocessors, diagnostics and description. -- **ta**: CMIP short-hand for 'air temperature' +- **ta**: CMIP short-hand for 'air temperature'. -- **tas**: CMIP short-hand for 'near-surface air temperature' +- **tas**: CMIP short-hand for 'near-surface air temperature'. - **thetao**: Sea water potential temperature variable (assume reference height is sea level) - **thetaoga**: Global average sea water potential temperature -- **tos**: CMIP short-hand for 'sea surface temperature' +- **tos**: CMIP short-hand for 'sea surface temperature'. -- **ts**: CMIP short-hand for 'surface temperature' +- **ts**: CMIP short-hand for 'surface temperature'. - **yaml**: YAML is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or exchanged. From a5b0b25ef7f50b6586e5fa988cf5d910d9896258 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 12 Oct 2020 13:58:05 +0200 Subject: [PATCH 442/647] Update glossary --- _extras/glossary.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index 31de648c..ab125e04 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -4,9 +4,7 @@ title: Glossary ## ESMValTool Glossary -Here, there are some definitions used throughout this tutorial: - -- **Amon**: Monthly atmospheric data +- **Amon**: Monthly atmospheric data. - **CMIP**: The Coupled Model Intercomparison Project (CMIP) aims at better understanding past, present and future climate changes arising from natural, unforced variability or in response to changes in radiative forcing in a multi-model context. For more information, check the [WCR-Climate webpage](https://www.wcrp-climate.org/). @@ -18,7 +16,7 @@ Here, there are some definitions used throughout this tutorial: - **ensemble**: An ensemble is a collection of experiments based on standardised inputs. This ensures that ensemble calculations use the same initial states, initialisation methods, and physics details. Ensemble members are named in the rip-nomenclature, *r* for realization, *i* for initialisation and *p* for physics, followed by an integer, e.g. r1i1p1. -- **experiment**: An experiment is defined as an activity aimed at addressing a specific scientific problem. In CMIP, experiments are numerical experiments with climate models +- **experiment**: An experiment is defined as an activity aimed at addressing a specific scientific problem. In CMIP, experiments are numerical experiments with climate models. - **grid**: In the dataset section of a recipe, a grid is the array of coordinates on which a variable has been sampled. @@ -26,7 +24,7 @@ Here, there are some definitions used throughout this tutorial: - **mip**: Typically used to refer to a table of variables in ESMValTool. These are standardized per project, e.g. the [MIP tables for CMIP6](http://clipc-services.ceda.ac.uk/dreq/index/miptable.html). -- **Omon**: Monthly ocean data +- **Omon**: Monthly ocean data. - **pr**: CMIP short-hand for 'precipitation'. @@ -42,7 +40,7 @@ Here, there are some definitions used throughout this tutorial: - **tas**: CMIP short-hand for 'near-surface air temperature'. -- **thetao**: Sea water potential temperature variable (assume reference height is sea level) +- **thetao**: Sea water potential temperature variable (assume reference height is sea level). - **thetaoga**: Global average sea water potential temperature @@ -52,6 +50,12 @@ Here, there are some definitions used throughout this tutorial: - **yaml**: YAML is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or exchanged. -For more details on ESMValTool, please go to: -Additional info can be found in [ESMValTool home page](https://esmvaltool.org) -and [https://esmvaltool.readthedocs.io/](ESMValTool Read The Docs page). + +> ## Additional info +> +> Additional info can be found at the [ESMValTool homepage](https://esmvaltool.org) +> and in the [ESMValTool documentation](https://esmvaltool.readthedocs.io/). +{: .callout} + + +{% include links.md %} From 8ead65b343c3a7679e0de355810a0e67d5e885ab Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 12 Oct 2020 12:43:01 +0000 Subject: [PATCH 443/647] short-hand -> short-name --- _extras/glossary.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index ab125e04..d096e425 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -26,7 +26,7 @@ title: Glossary - **Omon**: Monthly ocean data. -- **pr**: CMIP short-hand for 'precipitation'. +- **pr**: CMIP shortname for 'precipitation'. - **preprocessor**: A preprocessor is an operation that is applied to a dataset. @@ -36,17 +36,17 @@ title: Glossary - **recipe**: A recipe contains the instructions to be carried out by the ESMValTool. This includes four main sections: datasets, preprocessors, diagnostics and description. -- **ta**: CMIP short-hand for 'air temperature'. +- **ta**: CMIP shortname for 'air temperature'. -- **tas**: CMIP short-hand for 'near-surface air temperature'. +- **tas**: CMIP shortname for 'near-surface air temperature'. - **thetao**: Sea water potential temperature variable (assume reference height is sea level). - **thetaoga**: Global average sea water potential temperature -- **tos**: CMIP short-hand for 'sea surface temperature'. +- **tos**: CMIP shortname for 'sea surface temperature'. -- **ts**: CMIP short-hand for 'surface temperature'. +- **ts**: CMIP shortname for 'surface temperature'. - **yaml**: YAML is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or exchanged. From 383e9eb49ef85a8018c5c2f2d62d498c312e6c47 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 12 Oct 2020 12:44:02 +0000 Subject: [PATCH 444/647] Add dash --- _extras/glossary.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_extras/glossary.md b/_extras/glossary.md index d096e425..3ef37da0 100644 --- a/_extras/glossary.md +++ b/_extras/glossary.md @@ -26,7 +26,7 @@ title: Glossary - **Omon**: Monthly ocean data. -- **pr**: CMIP shortname for 'precipitation'. +- **pr**: CMIP short-name for 'precipitation'. - **preprocessor**: A preprocessor is an operation that is applied to a dataset. @@ -36,17 +36,17 @@ title: Glossary - **recipe**: A recipe contains the instructions to be carried out by the ESMValTool. This includes four main sections: datasets, preprocessors, diagnostics and description. -- **ta**: CMIP shortname for 'air temperature'. +- **ta**: CMIP short-name for 'air temperature'. -- **tas**: CMIP shortname for 'near-surface air temperature'. +- **tas**: CMIP short-name for 'near-surface air temperature'. - **thetao**: Sea water potential temperature variable (assume reference height is sea level). - **thetaoga**: Global average sea water potential temperature -- **tos**: CMIP shortname for 'sea surface temperature'. +- **tos**: CMIP short-name for 'sea surface temperature'. -- **ts**: CMIP shortname for 'surface temperature'. +- **ts**: CMIP short-name for 'surface temperature'. - **yaml**: YAML is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or exchanged. From 6fb4f99d290d8a0d955f74ad650afc21f8ecdbb2 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Mon, 19 Oct 2020 10:43:28 +0200 Subject: [PATCH 445/647] Refactor episode 4 and 5 (#154) * Start refactoring episode 4 * Complete rewrite of episode 4; move explanation of output folders from episode 3 to 4 * Add new content to episode 5 * Add python diagnostic for episode 5 * Remove old stuff * Add (modified) recipe files; remove old ones * Apply suggestions from code review Co-authored-by: Stef Smeets * Finish rewrite of episode 5 * resolve merge conflict * Finetune episode 4 * Update config episode to set different roothpaths and max_parallel_tasks * Fix solution boxes in episode 5 * update setup instructions and dataset urls * update link to example recipe documentation * Apply suggestions from code review Co-authored-by: Stef Smeets * Fix issues with modified recipes * Trying to update gh workflow to run all recipes * Revert "Trying to update gh workflow to run all recipes" This reverts commit ea6ab3c6188ffa248c1726a7f24597e03cd876a2. * Second attempt on gh workflow to run all recipes * Add indentation * Make sure gh action finds diagnostic script Co-authored-by: Stef Smeets --- .github/workflows/recipes.yml | 9 +- _episodes/03-configuration.md | 58 +- _episodes/04-recipe.md | 1082 ++++++++--------- _episodes/05-preprocessor.md | 822 +++++++------ data/dataset.urls | 28 +- fig/warming_stripes.png | Bin 0 -> 25980 bytes files/recipe_example.yml | 42 - files/recipe_example_multi_preprocessors.yml | 56 - files/recipe_example_output/log.txt | 53 - files/recipe_example_output/main_log.txt | 80 -- files/recipe_example_output/metadata.yml | 24 - files/recipe_example_output/settings.yml | 14 - files/recipe_example_pr_tas.yml | 52 - files/recipe_example_tas.yml | 44 - files/recipe_example_tas_control_target.yml | 64 - files/recipe_example_thetao.yml | 45 - files/recipe_example_thetao_thetaoga.yml | 57 - files/recipe_example_tos.yml | 45 - files/recipe_example_ts.yml | 44 - files/recipe_warming_stripes.yml | 36 + ...pe_warming_stripes_additional_datasets.yml | 53 + files/recipe_warming_stripes_local.yml | 38 + ...ipe_warming_stripes_multiple_locations.yml | 51 + files/recipe_warming_stripes_periods.yml | 45 + files/warming_stripes.py | 58 + setup.md | 11 - 26 files changed, 1256 insertions(+), 1655 deletions(-) create mode 100644 fig/warming_stripes.png delete mode 100644 files/recipe_example.yml delete mode 100644 files/recipe_example_multi_preprocessors.yml delete mode 100644 files/recipe_example_output/log.txt delete mode 100644 files/recipe_example_output/main_log.txt delete mode 100644 files/recipe_example_output/metadata.yml delete mode 100644 files/recipe_example_output/settings.yml delete mode 100644 files/recipe_example_pr_tas.yml delete mode 100644 files/recipe_example_tas.yml delete mode 100644 files/recipe_example_tas_control_target.yml delete mode 100644 files/recipe_example_thetao.yml delete mode 100644 files/recipe_example_thetao_thetaoga.yml delete mode 100644 files/recipe_example_tos.yml delete mode 100644 files/recipe_example_ts.yml create mode 100644 files/recipe_warming_stripes.yml create mode 100644 files/recipe_warming_stripes_additional_datasets.yml create mode 100644 files/recipe_warming_stripes_local.yml create mode 100644 files/recipe_warming_stripes_multiple_locations.yml create mode 100644 files/recipe_warming_stripes_periods.yml create mode 100644 files/warming_stripes.py diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index a32d491c..92c2c6d4 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -41,8 +41,11 @@ jobs: with: path: ~/default_inputpath key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} - - name: Download dataset files for files/recipe_example.yml + - name: Download dataset files for episodes 4 and 5 run: | head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --directory-prefix $HOME/default_inputpath/ - - name: Run files/recipe_example.yml - run: $CONDA/envs/test/bin/esmvaltool run $PWD/files/recipe_example.yml + - name: Run all recipes in files/ + run: | + mkdir ~/esmvaltool_tutorial + cp files/warming_stripes.py ~/esmvaltool_tutorial/ + for file in files/recipe*.yml; do $CONDA/envs/test/bin/esmvaltool run $PWD/$file; done diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 7a2d5de4..9b12739e 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -93,23 +93,6 @@ The destination directory is the rootpath where ESMValTool will store its output e.g. figures, data, logs, etc. With every run, ESMValTool automatically generates a new output folder determined by recipe name, and date and time using the format: YYYYMMDD_HHMMSS. -This folder contains four further subfolders: ``plots``, ``preproc``, ``run``, ``work``. - -> ## Content of subfolders -> -> - ``plots``: the location for all plots, split by individual diagnostics and fields. -> - ``preproc``: this folder contains all the preprocessed data and metadata.yml -interface files. Note that by default this directory will be deleted after -each run because most users will only need the results from the diagnostic scripts. -> - ``run``: this folder includes all log files, a copy of the recipe, -a summary of the resource usage, and the settings.yml interface files, -resource_usage.txt and temporary files created by the diagnostic scripts. -> - ``work``: this folder is a place for any diagnostic script results that -are not plots, e.g. files in NetCDF format (depends on the diagnostic script). -> -> We explain more about output in the next -[lesson]({{ page.root }}{% link _episodes/04-recipe.md %}) -{: .callout} > ## Set the destination directory > @@ -156,7 +139,7 @@ example configuration file. > > In this tutorial, we will work with data from > [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) -> and [obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/). +> and [CMIP6](https://esgf-node.llnl.gov/projects/cmip6). > How can we moodify the `rootpath` to make sure the data path is set correctly > for both CMIP5 and obs4mips. > @@ -173,7 +156,7 @@ example configuration file. >> rootpath: >> ... >> CMIP5: ~/esmvaltool_tutorial/data ->> obs4mips: ~/esmvaltool_tutorial/data +>> CMIP6: ~/esmvaltool_tutorial/data >>``` >> >> - Are you working with on a computer cluster like Jasmin or DKRZ? @@ -184,12 +167,12 @@ example configuration file. >> # Site-specific entries: Jasmin >> # Uncomment the lines below to locate data on JASMIN >> rootpath: ->> # CMIP6: /badc/cmip6/data/CMIP6 +>> CMIP6: /badc/cmip6/data/CMIP6 >> CMIP5: /badc/cmip5/data/cmip5/output1 >> # CMIP3: /badc/cmip3_drs/data/cmip3/output >> # OBS: /group_workspaces/jasmin4/esmeval/obsdata-v2 >> # OBS6: /group_workspaces/jasmin4/esmeval/obsdata-v2 ->> obs4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> # obs4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 >> # ana4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 >> # CORDEX: /badc/cordex/data/CORDEX/output >>``` @@ -260,12 +243,14 @@ information about ``drs``, you can visit the ESMValTool documentation on > >> ## Solution >> ->> 1. `drs: default` is one way to retrieve data from a ROOT directory that has no DRS-like structure. ->> ``default`` indicates that all the files are in a folder without any structure. +>> 1. `drs: default` is one way to retrieve data from a ROOT directory that has +>> no DRS-like structure. ``default`` indicates that all the files are in a +>> folder without any structure. >> ->> 2. Observational data are organized in Tiers depending on their level of public availability. ->> Therefore the default directory must be structured accordingly with sub-directories ->> `TierX` e.g. Tier1, Tier2 or Tier3, even when `drs: default`. +>> 2. Observational data are organized in Tiers depending on their level of +>> public availability. Therefore the default directory must be structured +>> accordingly with sub-directories `TierX` e.g. Tier1, Tier2 or Tier3, even +>> when `drs: default`. >> > {: .solution} {: .challenge} @@ -290,21 +275,20 @@ if you want to feed some additional data (e.g. shape files) to your recipe. > ## Number of parallel tasks > -> This option enables you to perform parallel processing. -You can choose the number of tasks in parallel as -1/2/3/4/... or you can set it to ``null``. That tells -ESMValTool to use the maximum number of available CPUs: +> This option enables you to perform parallel processing. You can choose the +number of tasks in parallel as 1/2/3/4/... or you can set it to ``null``. That +tells ESMValTool to use the maximum number of available CPUs. For the purpose of +the tutorial, please set ESMValTool use only 1 cpu: > >```yaml -> max_parallel_tasks: null +> max_parallel_tasks: 1 > ``` > -> If you run out of memory, try setting ``max_parallel_tasks`` to 1. -Then, check the amount of memory you need for that by inspecting -the file ``run/resource_usage.txt`` in the output directory. -Using the number there you can increase the number of parallel tasks -again to a reasonable number for the amount of memory available in your system. -{: .callout} +> In general, if you run out of memory, try setting ``max_parallel_tasks`` to 1. +Then, check the amount of memory you need for that by inspecting the file +``run/resource_usage.txt`` in the output directory. Using the number there you +can increase the number of parallel tasks again to a reasonable number for the +amount of memory available in your system. {: .callout} > ## Make your own configuration file > diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index c4b20148..bb898037 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -1,307 +1,49 @@ --- -title: "Running a recipe (First example)" -teaching: 25 -exercises: 30 +title: "Running your first recipe" +teaching: 15 +exercises: 15 questions: -- "What is a recipe?" -- "How can I do the same preprocessing on many different datasets?" +- "How to run a recipe?" - "What happens when I run a recipe?" -- "What are the files and directories that are created after running a recipe?" objectives: -- "Run an ESMValTool recipe" -- "Understand the purpose of different settings in the recipe" -- "Inspect the output directories" +- "Run an existing ESMValTool recipe" - "Examine the log information" +- "Navigate the output created by ESMValTool" +- "Make small adjustments to an existing recipe" keypoints: -- "A recipe does not break by fiddling with it" -- "Log information is useful when interpreting the first warnings/errors" -- "The dataset section resembles the filename or directory structure (e.g. CMIP subdirectories)" +- "ESMValTool recipes work 'out of the box' (if input data is available)" +- "There are strong links between the recipe, log file, and output folders" +- "Recipes can easily be modified to re-use existing code for your own use case" --- This episode describes how ESMValTool recipes work, how to run a recipe and how to explore the recipe output. By the end of this episode, you should be able to -run your first recipe, look at the recipe output, modify a recipe, explore and -run some basic recipe debugging. - -## Introduction to Recipes - -Recipes are the instructions that you give to ESMValTool that tell it what you -want to do. This includes four main sections: datasets, preprocessors, -diagnostics and description. - - - datasets: what datasets you want to use, including - - the time period and temporal resolution, - - the MIP (Model Intercomparison Project, like atmospheric realm of MIP - monthly data: Amon), - - ensemble member, - - the experiment (e.g. historical, ssp125), - - and the grid type (necessary for CMIP6 only). - - - preprocessors: general operations applied to a dataset before handling it in - a diagnostic, defining - - which preprocessor modules to apply, - - the order in which they are applied, - - and the preprocessor arguments. - - This section can also be optional, if no preprocessing is needed. - - - diagnostics: all the information about the diagnostic, including - - list of variables to evaluate (with their respective configurations), - - the desired diagnostic script to use, - - and additional diagnostic script options or arguments, if needed. - - It is possible to also include additional datasets beyond those included in - the datasets section mentioned above, for instance variable specific - observational data. - - - description: a brief description of the recipe, including - - who wrote the recipe and who maintains it, - - which project the recipe was written for, - - and which publications and references are linked with the recipe. - - Note that the authors, publications and references need to be included in - the `config-references.yml` for the recipe to run successfully. - -The information you provide in the recipe is not only affecting the processes -you are starting, but also the directory names your output will be structured -in. -For additional reads, please have a look at the recipe format description in the -[ESMValTool manual](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics). - -## How to run ESMValTool - -Once you’ve set up your conda environment and installed ESMValTool (see -[episode #2]({{ page.root}}{% link _episodes/02-installation.md %}) -) and set up your `config-user.yml` file to correctly match your local -environment, (see -[episode #3]({{ page.root}}{% link _episodes/03-configuration.md %}) -), ESMValTool is invoked using the command: - -~~~bash -esmvaltool run /path/to/recipe_example.yml -~~~ - -If the configuration file is not in the default location -`~/.esmvaltool/config-user.yml`, you can pass its path explicitly: - -~~~bash -esmvaltool run --config_file /path/to/config-user.yml /path/to/recipe_example.yml -~~~ - -Note that the path to the recipe can be either a path to a recipe file or it can -be the name of an installed recipe. -To view the list of installed recipes, run -~~~bash -esmvaltool recipes list -~~~ - -To try your hand with a basic recipe, please work through this episode. - -## Introduction to the example recipe -The recipe presented here is a simple, basic recipe that takes a single dataset -and produces a time series plot. - -Please download -[recipe_example.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example.yml) -into your ESMValTool working directory: - -~~~bash -wget https://raw.githubusercontent.com/ESMValGroup/ESMValTool_Tutorial/master/files/recipe_example.yml -~~~ - -> ## recipe_example.yml -> ```YAML -> 1 # ESMValTool -> 2 # recipe_example.yml -> 3 --- -> 4 documentation: -> 5 description: Demonstrate basic ESMValTool example -> 6 -> 7 authors: -> 8 - demora_lee -> 9 - mueller_benjamin -> 10 - swaminathan_ranjini -> 11 -> 12 maintainer: -> 13 - demora_lee -> 14 -> 15 references: -> 16 - demora2018gmd -> 17 # Some plots also appear in ESMValTool paper 2. -> 18 -> 19 projects: -> 20 - ukesm -> 21 -> 22 datasets: -> 23 - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} -> 24 -> 25 preprocessors: -> 26 prep_timeseries: # For 0D fields -> 27 annual_statistics: -> 28 operator: mean -> 29 -> 30 diagnostics: -> 31 # -------------------------------------------------- -> 32 # Time series diagnostics -> 33 # -------------------------------------------------- -> 34 diag_timeseries_temperature: -> 35 description: simple_time_series -> 36 variables: -> 37 timeseries_variable: -> 38 short_name: thetaoga -> 39 preprocessor: prep_timeseries -> 40 scripts: -> 41 timeseries_diag: -> 42 script: ocean/diagnostic_timeseries.py -> ``` -{: .solution} +run your first recipe, look at the recipe output, and make small modifications. -> ## Explore the recipe -> We use the text editor ``nano`` to investigate the sample recipe. -> ~~~bash -> nano recipe_example.yml -> ~~~ -{: .challenge} - -> ## Text editor side note -> -> No matter what editor you use, you will need to know where it searches -> for and saves files. If you start it from the shell, it will (probably) -> use your current working directory as its default location. We use ``nano`` -> in examples here because it is one of the least complex text editors. -> Press ctrl + O to save the file, -> and then ctrl + X to exit ``nano``. -> The line numbers can be shown by pressing alt + shift + 3. -{: .callout} +## Running an existing recipe -Please note the following sections: +The recipe format has briefly been introduced in episode 1. To see all the +recipes that are shipped with ESMValTool, type - - documentation: lines 4-20 - - The documentation consists of the following information: - - - description: a short description of the recipe - - authors: a list of authors - - maintainer: a list of maintainers - - references: a list of references - - projects: a list of projects - -> ## config-references.yml and references -> -> The values for the keys ``author``, ``maintainer``, ``projects`` and -> ``references`` in the recipe should be known by ESMValTool: -> -> - A list of ESMValTool -> author, maintainer, and projects are mentioned in the file ``config-references.yml`` -> that can be found in -> [ESMValTool/esmvaltool](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/config-references.yml). -> -> - ESMValTool references in `BibTeX` format can be found in -> [ESMValTool/esmvaltool/references](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) directory. -{: .callout} - - - datasets: lines 22-23 - - The dataset definition consists of a list of python dictionaries with the - information on the datasets. - - - dataset name (key: dataset) - - project (key: project) - - experiment (key: exp) - - mip (for CMIP data, key: mip) - - ensemble member (key: ensemble) - - time range (e.g. key-value-pair: start_year: 1900, end_year: 2000) - - model grid (for CMIP6 data only, key: grid) - - alias (key: alias; use the alias for e.g. a more human readable name for - the dataset) - - - preprocessors: lines 25-28 - - The definition for different preprocessors or preprocessor combinations. - If no preprocessing is needed, the preprocessor can be set to an empty - map (`{}`). Here, we produce annual means. The preprocessor is called - with its name (here: prep_timeseries), later in the diagnostic (line 39). - (See [episode #5]({{ page.root}}{% link _episodes/05-preprocessor.md %}) - for more details.) - - - diagnostic section: lines 30-42 - - The information of which diagnostic script to run with which variables. The - diagnostics section has some indents that are free to be called. - - - the first indent (here: diag_timeseries_temperature) is the diagnostic’s - name (a string without whitespace), used for setting up the respective - directories - - description: a short description of the diagnostic - - variables: a definition of all variables that are used in this diagnostic - - the next indent (here: timeseries_variable) is the variables’ names (a - string without whitespace) for the diagnostic to use - - short_name: the variable name as listed in the dataset - - preprocessor: the preprocessor(s) applied to the variable before running - the diagnostic - - scripts: a definition of all scripts that are used in this diagnostic - - the next indent (here: timeseries_diag) is the scripts’ names (a string - without whitespace) for the script to use - - script: a script that will produce the plots. The path can be either - relative the ESMValTool installation with subdirectory - [`esmvaltool/diag_scripts/`](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/diag_scripts) - or an absolute path. In this case, it is a diagnostic script that is - installed with ESMValTool. - -> ## Please answer the following questions: -> What is the short_name of the variable being analyzed? -> -> What is the diagnostic script being used? -> -> How many years of data are being analyzed? -> -> What do you think running this recipe will produce? -{: .challenge} - -> ## What is the short_name of the variable being analyzed? -> thetaoga - Global Average Sea Water Potential Temperature -{: .solution} - -> ## What is the diagnostic script being used? -> The installed copy of -> [`ocean/diagnostic_timeseries.py`](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py) -{: .solution} - -> ## How many years of data are being analyzed? -> 1900 to 2000. -{: .solution} +```bash +esmvaltool recipes list +``` -> ## What do you think running this recipe will produce? -> A time series plot of thetaoga with increments of 1 year. -{: .solution} +We will start by running [examples/recipe_python.yml](https://docs.esmvaltool.org/en/latest/recipes/recipe_python.html) -> ## Not all parts of the recipe are mandatory -> Some functionalities of the example recipe are mandatory, while others are -> not. E.g., if you miss any of the documentation information, the call will -> break. -{: .callout} +``` +esmvaltool run examples/recipe_python.yml +``` -> ## Running ESMValTool -> -> Use the command: -> ~~~bash -> esmvaltool run ./path_to_file/recipe_example.yml -> ~~~ -> -> Follow the terminal guiding you through the subprocesses that are running. Can -> you find where the preprocessor and the diagnostic are starting? Which one -> took longer to process? -{: .challenge} +If everything is okay, you should see that ESMValTool is printing a lot of +output to the command line. The final message should be "Run was successful". +The exact output varies depending on your machine, but it should look something +like the example output below. -> ## Exemplary output -> -> After running the `recipe_example.yml`, some information (log messages) will be printed in the terminal. -> The log messages depends on the settings in both `recipe_example.yml` and -> the `config-user.yml` files. -> As an example, the log information is: +> ## Example output > -> ~~~bash -> 2020-07-01 08:22:58,571 UTC [33433] INFO +> ``` +> INFO [29586] > ______________________________________________________________________ > _____ ____ __ ____ __ _ _____ _ > | ____/ ___|| \/ \ \ / /_ _| |_ _|__ ___ | | @@ -330,344 +72,474 @@ Please note the following sections: > Klaus Zimmermann (SMHI, Sweden - klaus.zimmermann@smhi.se) > > For further help, please read the documentation at -> http://esmvaltool.readthedocs.io. Have fun! -> -> 2020-07-01 08:22:58,573 UTC [33433] INFO Using config file /pf/b/b380506/work/config-DKRZ.yml -> 2020-07-01 08:22:58,573 UTC [33433] INFO Writing program log files to: -> /scratch/b/b380506/recipe_example_20200701_082257/run/main_log.txt -> /scratch/b/b380506/recipe_example_20200701_082257/run/main_log_debug.txt -> 2020-07-01 08:22:58,574 UTC [33433] INFO Starting the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:22:58 UTC -> 2020-07-01 08:22:58,574 UTC [33433] INFO ---------------------------------------------------------------------- -> 2020-07-01 08:22:58,574 UTC [33433] INFO RECIPE = /pf/b/b380506/work/recipes/recipe_example.yml -> 2020-07-01 08:22:58,575 UTC [33433] INFO RUNDIR = /scratch/b/b380506/recipe_example_20200701_082257/run -> 2020-07-01 08:22:58,575 UTC [33433] INFO WORKDIR = /scratch/b/b380506/recipe_example_20200701_082257/work -> 2020-07-01 08:22:58,575 UTC [33433] INFO PREPROCDIR = /scratch/b/b380506/recipe_example_20200701_082257/preproc -> 2020-07-01 08:22:58,575 UTC [33433] INFO PLOTDIR = /scratch/b/b380506/recipe_example_20200701_082257/plots -> 2020-07-01 08:22:58,575 UTC [33433] INFO ---------------------------------------------------------------------- -> 2020-07-01 08:22:58,575 UTC [33433] INFO Running tasks using at most 8 processes -> 2020-07-01 08:22:58,575 UTC [33433] INFO If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. -> 2020-07-01 08:22:58,575 UTC [33433] INFO If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. -> 2020-07-01 08:22:58,607 UTC [33433] INFO Creating tasks from recipe -> 2020-07-01 08:22:58,607 UTC [33433] INFO Creating tasks for diagnostic diag_timeseries_temperature -> 2020-07-01 08:22:58,607 UTC [33433] INFO Creating preprocessor task diag_timeseries_temperature/timeseries_variable -> 2020-07-01 08:22:58,608 UTC [33433] INFO Creating preprocessor 'prep_timeseries' task for variable 'thetaoga' -> 2020-07-01 08:22:58,610 UTC [33433] INFO Using input files for variable thetaoga of dataset HadGEM2-ES: -> /mnt/lustre01/work/kd0956/CMIP5/data/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc -> 2020-07-01 08:22:58,617 UTC [33433] INFO PreprocessingTask diag_timeseries_temperature/timeseries_variable created. It will create the files: -> /scratch/b/b380506/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc -> 2020-07-01 08:22:58,617 UTC [33433] INFO Creating diagnostic task diag_timeseries_temperature/timeseries_diag -> 2020-07-01 08:22:58,618 UTC [33433] INFO These tasks will be executed: diag_timeseries_temperature/timeseries_variable, diag_timeseries_temperature/timeseries_diag -> 2020-07-01 08:22:58,621 UTC [33433] INFO Running 2 tasks using 2 processes -> 2020-07-01 08:22:58,641 UTC [39196] INFO Starting task diag_timeseries_temperature/timeseries_variable in process [39196] -> 2020-07-01 08:22:58,735 UTC [33433] INFO Progress: 1 tasks running, 1 tasks waiting for ancestors, 0/2 done -> 2020-07-01 08:23:05,884 UTC [39196] INFO Successfully completed task diag_timeseries_temperature/timeseries_variable (priority 0) in 0:00:07.241490 -> 2020-07-01 08:23:05,963 UTC [33433] INFO Progress: 0 tasks running, 1 tasks waiting for ancestors, 1/2 done -> 2020-07-01 08:23:05,969 UTC [39197] INFO Starting task diag_timeseries_temperature/timeseries_diag in process [39197] -> 2020-07-01 08:23:05,975 UTC [39197] INFO Running command ['/pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python', '/mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py', '/scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml'] -> 2020-07-01 08:23:05,976 UTC [39197] INFO Writing output to /scratch/b/b380506/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag -> 2020-07-01 08:23:05,976 UTC [39197] INFO Writing plots to /scratch/b/b380506/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag -> 2020-07-01 08:23:05,976 UTC [39197] INFO Writing log to /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/log.txt -> 2020-07-01 08:23:05,977 UTC [39197] INFO To re-run this diagnostic script, run: -> cd /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag; MPLBACKEND="Agg" /pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python /mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml -> 2020-07-01 08:23:06,064 UTC [33433] INFO Progress: 1 tasks running, 0 tasks waiting for ancestors, 1/2 done -> 2020-07-01 08:23:13,312 UTC [39197] INFO Maximum memory used (estimate): 0.2 GB -> 2020-07-01 08:23:13,313 UTC [39197] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. -> 2020-07-01 08:23:13,316 UTC [39197] WARNING No provenance information was written to /scratch/b/b380506/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/diagnostic_provenance.yml -> 2020-07-01 08:23:13,316 UTC [39197] INFO Successfully completed task diag_timeseries_temperature/timeseries_diag (priority 1) in 0:00:07.347165 -> 2020-07-01 08:23:13,380 UTC [33433] INFO Progress: 0 tasks running, 0 tasks waiting for ancestors, 2/2 done -> 2020-07-01 08:23:13,380 UTC [33433] INFO Successfully completed all tasks. -> 2020-07-01 08:23:13,395 UTC [33433] INFO Ending the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:23:13 UTC -> 2020-07-01 08:23:13,395 UTC [33433] INFO Time for running the recipe was: 0:00:14.820802 -> 2020-07-01 08:23:14,283 UTC [33433] INFO Maximum memory used (estimate): 0.7 GB -> 2020-07-01 08:23:14,284 UTC [33433] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. -> 2020-07-01 08:23:14,286 UTC [33433] INFO Run was successful -> ~~~ -{: .solution} - -Each time you run the ESMValTool, it will produce a new output directory within -your specified work directory with the name of the recipe and the tagged -runtime. This folder should contain four folders: - - - run - - work - - preproc - - plots - -> ## Inspect the output -> -> Now that you have run the esmvaltool command for the first time, please locate -> your output directory. If you’re missing the preproc directory, then your -> `config-user.yml` file has the value remove_preproc_dir set to true (this is -> used to save disk space). Please set this value to false and run the recipe -> again. -> -{: .challenge} - -> ## Inspect specific files -> -> Please locate and inspect the following files: -> -> - Your output plot(s). -> - Your main output log file. -> - Your settings.yml file. -> - A metadata.yml file. -> - The diagnostic log file. -{: .checklist} - -Exemplary output (depending on the directory paths and package versions that are -available) can be found below. Note that the timestamps differ. - -> ## Your output plot(s) -> -> Plots for the dataset(s) are located in `./recipe_example_#_#/plots/timeseries_diag/` -> -> For a single dataset: -> -> ![single dataset](../fig/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_0.png "single dataset") -> -> Or an overlay plot, if multiple datasets are defined: -> -> ![multiple datasets](../fig/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1900_2000_timeseries_.png "multiple datasets") -{: .solution} - -> ## Your main output log file -> -> The main output file is located at `./recipe_example_#_#/run/main_log.txt/` -> Let's have look at the file: -> -> ~~~bash -> nano ./recipe_example_#_#/run/main_log.txt -> ~~~ +> http://docs.esmvaltool.org. Have fun! +> +> INFO [29586] Using config file esmvaltool_config.yml +> INFO [29586] Writing program log files to: +> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/main_log.txt +> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/main_log_debug.txt +> INFO [29586] Starting the Earth System Model Evaluation Tool v2.0.0 at time: 2020-10-07 14:17:34 UTC +> INFO [29586] ---------------------------------------------------------------------- +> INFO [29586] RECIPE = /home/user/gh/esmvalgroup/ESMValTool/esmvaltool/recipes/examples/recipe_python.yml +> INFO [29586] RUNDIR = /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run +> INFO [29586] WORKDIR = /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/work +> INFO [29586] PREPROCDIR = /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc +> INFO [29586] PLOTDIR = /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/plots +> INFO [29586] ---------------------------------------------------------------------- +> INFO [29586] Running tasks using at most 1 processes +> INFO [29586] If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. +> INFO [29586] If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. +> INFO [29586] Creating tasks from recipe +> INFO [29586] Creating tasks for diagnostic map +> INFO [29586] Creating preprocessor task map/tas +> INFO [29586] Creating preprocessor 'select_january' task for variable 'tas' +> INFO [29586] Using input files for variable tas of dataset BCC-ESM1: +> /home/user/esmvaltool_tutorial/data/cmip6/tas_Amon_BCC-ESM1_historical_r1i1p1f1_gn_185001-201412.nc +> INFO [29586] Using input files for variable tas of dataset CanESM2: +> /home/user/esmvaltool_tutorial/data/cmip5/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc +> INFO [29586] PreprocessingTask map/tas created. It will create the files: +> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/map/tas/CMIP5_CanESM2_Amon_historical_r1i1p1_tas_2000-2000.nc +> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/map/tas/CMIP6_BCC-ESM1_Amon_historical_r1i1p1f1_tas_2000-2000.nc +> INFO [29586] Creating diagnostic task map/script1 +> INFO [29586] Creating tasks for diagnostic timeseries +> INFO [29586] Creating preprocessor task timeseries/tas_amsterdam +> INFO [29586] Creating preprocessor 'annual_mean_amsterdam' task for variable 'tas' +> INFO [29586] Using input files for variable tas of dataset BCC-ESM1: +> /home/user/esmvaltool_tutorial/data/cmip6/tas_Amon_BCC-ESM1_historical_r1i1p1f1_gn_185001-201412.nc +> INFO [29586] Using input files for variable tas of dataset CanESM2: +> /home/user/esmvaltool_tutorial/data/cmip5/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc +> INFO [29586] PreprocessingTask timeseries/tas_amsterdam created. It will create the files: +> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_amsterdam/CMIP5_CanESM2_Amon_historical_r1i1p1_tas_1850-2000.> nc +> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_amsterdam/> CMIP6_BCC-ESM1_Amon_historical_r1i1p1f1_tas_1850-2000.nc +> INFO [29586] Creating preprocessor task timeseries/tas_global +> INFO [29586] Creating preprocessor 'annual_mean_global' task for variable 'tas' +> INFO [29586] Using input files for variable tas of dataset BCC-ESM1: +> /home/user/esmvaltool_tutorial/data/cmip6/tas_Amon_BCC-ESM1_historical_r1i1p1f1_gn_185001-201412.nc +> INFO [29586] Using input files for variable tas of dataset CanESM2: +> /home/user/esmvaltool_tutorial/data/cmip5/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc +> INFO [29586] PreprocessingTask timeseries/tas_global created. It will create the files: +> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_global/CMIP6_BCC-ESM1_Amon_historical_r1i1p1f1_tas_1850-2000.> nc +> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_global/CMIP5_CanESM2_Amon_historical_r1i1p1_tas_1850-2000.nc +> INFO [29586] Creating diagnostic task timeseries/script1 +> INFO [29586] These tasks will be executed: timeseries/tas_global, timeseries/tas_amsterdam, map/tas, map/script1, timeseries/script1 +> INFO [29586] Running 5 tasks sequentially +> INFO [29586] Starting task map/tas in process [29586] +> INFO [29586] Successfully completed task map/tas (priority 0) in 0:00:04.291697 +> INFO [29586] Starting task map/script1 in process [29586] +> INFO [29586] Running command ['/home/user/miniconda3/envs/esmvaltool_tutorial/bin/python3.8', '/home/user/gh/esmvalgroup/ESMValTool/esmvaltool/diag_scripts/> examples/diagnostic.py', '/home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/map/script1/settings.yml'] +> INFO [29586] Writing output to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/work/map/script1 +> INFO [29586] Writing plots to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/plots/map/script1 +> INFO [29586] Writing log to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/map/script1/log.txt +> INFO [29586] To re-run this diagnostic script, run: +> cd /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/map/script1; MPLBACKEND="Agg" /home/user/miniconda3/envs/esmvaltool_tutorial/bin/> python3.8 /home/user/gh/esmvalgroup/ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py /home/user/esmvaltool_tutorial/output/> recipe_python_20201007_141734/run/map/script1/settings.yml +> INFO [29586] Maximum memory used (estimate): 0.3 GB +> INFO [29586] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +> INFO [29586] Successfully completed task map/script1 (priority 1) in 0:00:03.574651 +> INFO [29586] Starting task timeseries/tas_amsterdam in process [29586] +> INFO [29586] Generated PreprocessorFile: /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_amsterdam/> MultiModelMean_Amon_tas_1850-2000.nc +> INFO [29586] Successfully completed task timeseries/tas_amsterdam (priority 2) in 0:00:09.730443 +> INFO [29586] Starting task timeseries/tas_global in process [29586] +> WARNING [29586] /home/user/miniconda3/envs/esmvaltool_tutorial/lib/python3.8/site-packages/iris/analysis/cartography.py:394: UserWarning: Using > DEFAULT_SPHERICAL_EARTH_RADIUS. +> warnings.warn("Using DEFAULT_SPHERICAL_EARTH_RADIUS.") +> +> INFO [29586] Calculated grid area shape: (1812, 64, 128) +> WARNING [29586] /home/user/miniconda3/envs/esmvaltool_tutorial/lib/python3.8/site-packages/iris/analysis/cartography.py:394: UserWarning: Using > DEFAULT_SPHERICAL_EARTH_RADIUS. +> warnings.warn("Using DEFAULT_SPHERICAL_EARTH_RADIUS.") +> +> INFO [29586] Calculated grid area shape: (1812, 64, 128) +> INFO [29586] Successfully completed task timeseries/tas_global (priority 3) in 0:00:06.073527 +> INFO [29586] Starting task timeseries/script1 in process [29586] +> INFO [29586] Running command ['/home/user/miniconda3/envs/esmvaltool_tutorial/bin/python3.8', '/home/user/gh/esmvalgroup/ESMValTool/esmvaltool/diag_scripts/> examples/diagnostic.py', '/home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/timeseries/script1/settings.yml'] +> INFO [29586] Writing output to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/work/timeseries/script1 +> INFO [29586] Writing plots to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/plots/timeseries/script1 +> INFO [29586] Writing log to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/timeseries/script1/log.txt +> INFO [29586] To re-run this diagnostic script, run: +> cd /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/timeseries/script1; MPLBACKEND="Agg" /home/user/miniconda3/envs/esmvaltool_tutorial/> bin/python3.8 /home/user/gh/esmvalgroup/ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py /home/user/esmvaltool_tutorial/output/> recipe_python_20201007_141734/run/timeseries/script1/settings.yml +> INFO [29586] Maximum memory used (estimate): 0.3 GB +> INFO [29586] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +> INFO [29586] Successfully completed task timeseries/script1 (priority 4) in 0:00:03.712112 +> INFO [29586] Ending the Earth System Model Evaluation Tool v2.0.0 at time: 2020-10-07 14:18:02 UTC +> INFO [29586] Time for running the recipe was: 0:00:27.483308 +> INFO [29586] Maximum memory used (estimate): 0.7 GB +> INFO [29586] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +> INFO [29586] Run was successful +> ``` > -> Note: This is the same information as the terminal output, above, but without the time stamps. {: .solution} -> ## Your settings.yml file -> -> This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/settings.yaml`. -> Let's have look at the file: -> -> ~~~bash -> nano ./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/settings.yaml -> ~~~ +> ## Pro tip: ESMValTool search paths > -{: .solution} +> You might wonder how ESMValTool was able find the recipe file, even though +> it's not in your working directory. All the recipe paths printed from +> `esmvaltool recipes list` are relative to ESMValTool's installation location. +> This is where ESMValTool will look if it cannot find the file by following the +> path from your working directory. +{: .callout} -> ## A metadata.yml file. -> -> This file is located at `./recipe_example_#_#/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml`. -> Please note that `preproc` diretctory exist if only `remove_preproc_dir: false` -> in ``config-user.yml`` file. -> Let's have look at the file: -> -> ~~~bash -> nano ./recipe_example_#_#/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml -> ~~~ -> -{: .solution} +## Investigating the log messages + +Let's dissect what's happening here. + + +> ## Output files and directories +> +> After the banner and general information, the output starts with some important locations. +> +> 1. Did ESMValTool use the right config file? +> 1. What is the path to the example recipe? +> 1. What is the main output folder generated by ESMValTool? +> 1. Can you guess what the different output directories are for? +> 1. ESMValTool creates two log files. What is the difference? +> +> > ## Answers +> > +> > 1. The config file should be the one we edited in the previous episode, +> > something like `/home//.esmvaltool/config-user.yml`. +> > 1. ESMValTool found the recipe in its installation directory, something like +> > `/home/user/miniconda3/envs/esmvaltool_tutorial/bin/esmvaltool/recipes/examples/`. +> > 1. ESMValTool creates a time-stamped output directory for every run. In this +> > case, it should be something like `recipe_python_YYYYMMDD_HHMMSS`. This +> > folder is made inside the output directory specified in the previous +> > episode: `~/home//esmvaltool_tutorial/output`. +> > 1. There should be four output folders: +> > - `plots/`: this is where output figures are stored. +> > - `preproc/`: this is where pre-processed data are stored. +> > - `run/`: this is where esmvaltool stores general information about the +> > run, such as log messages and a copy of the recipe file. +> > - `work/`: this is where output files (not figures) are stored. +> > 1. The log files are: +> > - `main_log.txt` is a copy of the command-line output +> > - `main_log_debug.txt` contains more detailed information that may be +> > useful for debugging. +> > +> {: .solution} +{: .challenge} -> ## The diagnostic log file. -> -> This file is located at `./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/log.txt` -> Let's have look at the file: +> ## Debugging: No 'preproc' directory? > -> ~~~bash -> nano ./recipe_example_#_#/run/diag_timeseries_temperature/timeseries_diag/log.txt -> ~~~ +> If you’re missing the preproc directory, then your `config-user.yml` file has +> the value `remove_preproc_dir` set to `true` (this is used to save disk space). +> Please set this value to `false` and run the recipe again. > -{: .solution} - -## Do your first edits +{: .callout} -> ## Edit the recipe and run again -> -> So far, the example recipe has used global volume-weighted ocean temperature. -> Please edit this recipe to investigate one of the following fields: -> -> - Land surface temperature (ts) for dataset HadGEM2-ES for 1970-2000 -> - Atmospheric surface average temperature (tas) for dataset HadGEM2-ES for 1970-2000 -> - Ocean surface average temperature (tos) for datasets HadGEM2-ES and HadGEM2-CC for 1970-2000 -> -> You will need to edit: -> -> - the dataset: -> -> - `mip`, `start_year`, `end_year` -> -> - the preprocessor: -> -> - These fields are all 2D fields, but thetaoga was a 0D field. This means -> that we need to take the average over the latitude and longitude -> dimensions. To do this, add the area_statistics to the preprocessor. -> -> - the diagnostic: -> -> - change the short_name value (thetaoga) for another: -> -> - Land surface average temperature (ts) -> - Atmospheric surface average temperature (tas) -> - Ocean surface average temperature (tos) -> +After the output locations, there are two main sections that can be +distinguished in the log messages: + +- Creating tasks +- Executing tasks + +> ## Analyse the tasks +> +> List all the tasks that ESMValTool is executing for this recipe. Can you guess +> what this recipe does? +> +> > ## Answer +> > +> > Just after 'creating tasks' and before 'executing tasks', we find the +> > following line in the output: +> > +> > ```sh +> > INFO [29586] These tasks will be executed: timeseries/tas_global, timeseries/tas_amsterdam, map/tas, map/script1, timeseries/script1 +> > ``` +> > +> > So there are three tasks related to timeseries: global temperature, +> > Amsterdam temperature, and a script (*tas*: near-surface air temperature). And +> > then there are two tasks related to a map: something with temperature, and +> > again a script. +> {: .solution} {: .challenge} -The snippets for the edits can be found below: - -> ## Land surface average temperature -> -> In the `diff` file below you will see the changes we have made to the file. The top 2 lines are the filenames and the lines like @@ -20,12 +20,14 @@ indicate the line numbers in the original and modified file, respectively. For more info on this format, see [here](https://en.wikipedia.org/wiki/Diff#Unified_format). -> -> ```diff -> --- data/recipe_example.yml -> +++ data/recipe_example_ts.yml -> @@ -20,12 +20,14 @@ -> - ukesm -> -> datasets: -> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} -> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} -> -> preprocessors: -> prep_timeseries: # For 0D fields -> annual_statistics: -> operator: mean -> + area_statistics: -> + operator: mean -> -> diagnostics: -> # -------------------------------------------------- -> @@ -35,7 +37,7 @@ -> description: simple_time_series -> variables: -> timeseries_variable: -> - short_name: thetaoga -> + short_name: ts -> preprocessor: prep_timeseries -> scripts: -> timeseries_diag: +## Examining the recipe file + +To get more insight into what is happening, we will have a look at the recipe +file itself. Use the following command to copy the recipe to your working +directory + +```bash +esmvaltool recipes get examples/recipe_python.yml +``` + +Now you should see the recipe file in your working directory (type `ls` to +verify). Use the `nano` editor to open this file: + +```bash +nano recipe_python.yml +``` + +For reference, you can also view the recipe by unfolding the box below. + +> ## recipe_python.yml +> +> ```yaml +> # ESMValTool +> # recipe_python.yml +> --- +> documentation: +> description: | +> Example recipe that plots a map and timeseries of temperature. +> +> authors: +> - andela_bouwe +> - righi_mattia +> +> maintainer: +> - schlund_manuel +> +> references: +> - acknow_project +> +> projects: +> - esmval +> - c3s-magic +> +> datasets: +> - {dataset: BCC-ESM1, project: CMIP6, exp: historical, ensemble: r1i1p1f1, grid: gn} +> - {dataset: CanESM2, project: CMIP5, exp: historical, ensemble: r1i1p1} +> +> preprocessors: +> +> select_january: +> extract_month: +> month: 1 +> +> annual_mean_amsterdam: +> extract_point: +> latitude: 52.379189 +> longitude: 4.899431 +> scheme: linear +> annual_statistics: +> operator: mean +> multi_model_statistics: +> statistics: +> - mean +> span: overlap +> +> annual_mean_global: +> area_statistics: +> operator: mean +> annual_statistics: +> operator: mean +> +> diagnostics: +> +> map: +> description: Global map of temperature in January 2000. +> themes: +> - phys +> realms: +> - atmos +> variables: +> tas: +> mip: Amon +> preprocessor: select_january +> start_year: 2000 +> end_year: 2000 +> scripts: +> script1: +> script: examples/diagnostic.py +> write_netcdf: true +> output_file_type: pdf +> quickplot: +> plot_type: pcolormesh +> cmap: Reds +> +> timeseries: +> description: Annual mean temperature in Amsterdam and global mean since 1850. +> themes: +> - phys +> realms: +> - atmos +> variables: +> tas_amsterdam: +> short_name: tas +> mip: Amon +> preprocessor: annual_mean_amsterdam +> start_year: 1850 +> end_year: 2000 +> tas_global: +> short_name: tas +> mip: Amon +> preprocessor: annual_mean_global +> start_year: 1850 +> end_year: 2000 +> scripts: +> script1: +> script: examples/diagnostic.py +> quickplot: +> plot_type: plot > ``` > -> Note: The x-axis in the plot now shows the years 1970 - 2000. -> -> Complete recipe can be downloaded as [recipe_example_ts.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_ts.yml) {: .solution} -> ## Atmospheric surface average temperature -> -> ```diff -> --- data/recipe_example.yml -> +++ data/recipe_example_tas.yml -> @@ -20,12 +20,14 @@ -> - ukesm -> -> datasets: -> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} -> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} -> -> preprocessors: -> prep_timeseries: # For 0D fields -> annual_statistics: -> operator: mean -> + area_statistics: -> + operator: mean -> -> diagnostics: -> # -------------------------------------------------- -> @@ -35,7 +37,7 @@ -> description: simple_time_series -> variables: -> timeseries_variable: -> - short_name: thetaoga -> + short_name: tas -> preprocessor: prep_timeseries -> scripts: -> timeseries_diag: -> ``` -> -> Complete recipe can be downloaded as [recipe_example_tas.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_tas.yml) -{: .solution} +Do you recognize the basic recipe structure that was introduced in episode 1? + +- **Documentation** with relevant (citation) information +- **Datasets** that should be analysed +- **Preprocessors** groups of common preprocessing steps +- **Diagnostics** scripts performing more specific evaluation steps + +> ## Analyse the recipe +> +> Try to answer the following questions: +> +> 1. Who wrote this recipe? +> 1. Who should be approached if there is a problem with this recipe? +> 1. How many datasets are analyzed? +> 1. What does the preprocessor called `annual_mean_global` do? +> 1. Which script is applied for the diagnostic called `map`? +> 1. Can you link specific lines in the recipe to the tasks that we saw before? +> +> > ## Answers +> > +> > 1. The example recipe is written by Bouwe Andela and Mattia Righi. +> > 1. Manual Schlund is listed as the maintainer of this recipe. +> > 1. Two datasets are analysed: +> > - CMIP6 data from the model BCC-ESM1 +> > - CMIP5 data from the model CANESM2 +> > 1. The preprocessor `annual_mean_global` computes an area mean as well as +> > annual means +> > 1. The diagnostic called `map` executes a script referred to as `script1`. +> > This is a python script named `examples/diagnostic.py` +> > 1. There are two diagnostics: `map` and `timeseries`. Under the diagnostic +> > `map` we find two tasks: +> > - a preprocessor task called `tas`, applying the preprocessor called +> > `select_january` to the variable `tas`. +> > - a diagnostic task called `script1`, applying the script +> > `examples/diagnostic.py` to the preprocessed data (`map/tas`). +> > +> > Under the diagnostic `timeseries` we find three tasks: +> > - a preprocessor task called `tas_amsterdam`, applying the preprocessor +> > called `annual_mean_amsterdam` to the variable `tas`. +> > - a preprocessor task called `tas_global`, applying the preprocessor +> > called `annual_mean_global` to the variable `tas`. +> > - a diagnostic task called `script1`, applying the script +> > `examples/diagnostic.py` to the preprocessed data +> > (`timeseries/tas_global` and `timeseries/tas_amsterdam`). +> > +> {: .solution} +{: .challenge} -> ## Ocean surface average temperature -> -> ```diff -> --- data/recipe_example.yml -> +++ data/recipe_example_tos.yml -> @@ -20,12 +20,15 @@ -> - ukesm -> -> datasets: -> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} -> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} -> + - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} -> -> preprocessors: -> prep_timeseries: # For 0D fields -> annual_statistics: -> operator: mean -> + area_statistics: -> + operator: mean -> -> diagnostics: -> # -------------------------------------------------- -> @@ -35,7 +38,7 @@ -> description: simple_time_series -> variables: -> timeseries_variable: -> - short_name: thetaoga -> + short_name: tos -> preprocessor: prep_timeseries -> scripts: -> timeseries_diag: -> ``` -> Note: The unit in the plots is now degrees celsius! There are now 3 plots in the work directory. One for each dataset and one for the multiple dataset overview. +> ## Pro tip: short names and variable groups > -> Complete recipe can be downloaded as [recipe_example_tos.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_tos.yml) -{: .solution} - -> ## Advanced: -> If you want to add a different field, please have a look here: -> http://clipc-services.ceda.ac.uk/dreq/index/CMORvar.html +> The preprocessor tasks in ESMValTool are called 'variable groups'. For the +> diagnostic `timeseries`, we have two variable groups: `tas_amsterdam` and +> `tas_global`. Both of them operate on the variable `tas` (as indicated by the +> `short_name`), but they apply different preprocessors. For the diagnostic +> `map` the variable group itself is named `tas`, and you'll notice that we do +> not explicitly provide the `short_name`. This is a shorthand build into +> ESMValTool. {: .callout} -## Common issues & tips - -> ## esmvaltool not found -> Can you run the command `esmvaltool -h`. If no, then it’s possible that the -> conda environment isn’t activated. Please return to the in -> [installation section]({{ page.root }}{% link _episodes/02-installation.md %}). -{: .solution} +> ## Output files +> +> Have another look at the output directory created by the ESMValTool run. +> +> Which files/folders are created by each task? +> +> > ## Answer +> > +> > - **map/tas**: creates `/preproc/map/tas`, which contains preprocessed data +> > for each of the input datasets, and a file called `metadata.yml` +> > describing the contents of these datasets. +> > - **timeseries/tas_global**: creates `/preproc/timeseries/tas_global`, which +> > contains preprocessed data for each of the input datasets, and +> > `metadata.yml`. +> > - **timeseries/tas_amsterdam**: creates `/preproc/timeseries/tas_amsterdam`, +> > which contains preprocessed data for each of the input datasets, plus a +> > combined `MultiModelMean`, and `metadata.yml`. +> > - **map/script1**: creates `/run/map/script1` with general information and a +> > log of the diagnostic script run. It also creates `/plots/map/script1` and +> > `/work/map/script1`, which contain output figures and output datasets, +> > respectively. For each output file, there is also corresponding provenance +> > information in the form of `.svg`, `.xml`, `.bibtex` and `.txt` files. +> > - **timeseries/script1**: creates `/run/timeseries/script1` with general +> > information and a log of the diagnostic script run. It also creates +> > `/plots/timeseries/script1` and `/work/timeseries/script1`, which contain +> > output figures and output datasets, respectively. For each output file, +> > there is also corresponding provenance information in the form of `.svg`, +> > `.xml`, `.bibtex` and `.txt` files. +> > +> {: .solution} +{: .challenge} -> ## The error message is `esmvalcore._recipe_checks.RecipeError: Missing data` -> ESMValTool can’t locate the data. +> ## Pro tip: diagnostic logs > -> Which computing machine are you using? Does your `user-config.yml` file reflect -> your machine's settings? Is the dataset’s name in the correct order? -{: .solution} - -> ## Diagnostic path problems -> The directory path to your diagnostics code is set relative to the -> `esmvaltool/diag_scripts` subdirectory. Is the code placed in this subdirectory? -> Is it spelled correctly? -{: .solution} - -> ## FX files not found -> There is no FX file for your corresponding dataset. Are your datasets’ names -> spelled correctly? Is there a FX file for this dataset? -{: .solution} - -> ## The preprocessor works but the diagnostic fails -> If your preprocessor works fine but your diagnostic script fails, -> congratulations! A failed diagnostic means that you won’t need to re-run the -> preprocessor. In your `run/main_log.txt` run output, you should see a line -> that reads: “To re-run this diagnostic script, run:”, followed by a line with -> a command that will allow you to re-run your diagnostic script only. Append -> this line with the “-i” option after the python script you call to re-run your -> diagnostic. -{: .solution} - -> ## `ValueError: Tag 'NAME' does not exist in section 'authors' of path/esmvaltool/config-references.yml` -> Your recipe’s name/project/reference isn’t recognised by ESMValTool. +> When you run ESMValTool, any log messages from the diagnostic script are not printed on the terminal. +> But they are written to the `log.txt` files in the folder `/run//log.txt`. > -> Most likely, you added your own name to the recipe in the description section, -> but didn’t add it to the esmvaltool/config-references.yml file, where the -> names are linked to an email address, institute, and ORCID Identity. -{: .solution} +> ESMValTool *does* print a command that can be used to re-run a diagnostic script. When you use this +> the output *will* be printed to the command line. +{: .callout} + +## Modifying the example recipe + +Let's make a small modification to the example recipe. Notice that now that +you have copied and edited the recipe, you can use + +``` +esmvaltool run recipe_example.yml +``` + +to refer to your local file rather than the default version shipped with +ESMValTool. + +> ## Change your location +> +> Modify and run the recipe to analyse the temperature for your own location. +> +> > ## Solution +> > +> > In principle, you only have to modify the latitude and longitude coordinates +> > in the preprocessor called `annual_mean_amsterdam`. However, it is good +> > practice to also replace all instances of `amsterdam` with the correct name +> > of your location. Otherwise the log messages and output will be confusing. +> > You are free to modify the names of preprocessors or diagnostics. +> > +> > In the `diff` file below you will see the changes we have made to the file. +> > The top 2 lines are the filenames and the lines like `@@ -29,10 +29,10 @@` +> > represent the line numbers in the original and modified file, respectively. +> > For more info on this format, see +> > [here](https://en.wikipedia.org/wiki/Diff#Unified_format). +> > +> > ```diff +> > --- recipe_python.yml +> > +++ recipe_python_london.yml +> > @@ -29,10 +29,10 @@ +> > extract_month: +> > month: 1 +> > +> > - annual_mean_amsterdam: +> > + annual_mean_london: +> > extract_point: +> > - latitude: 52.379189 +> > - longitude: 4.899431 +> > + latitude: 51.5074 +> > + longitude: 0.1278 +> > scheme: linear +> > annual_statistics: +> > operator: mean +> > @@ -71,16 +71,16 @@ +> > cmap: Reds +> > +> > timeseries: +> > - description: Annual mean temperature in Amsterdam and global mean since 1850. +> > + description: Annual mean temperature in London and global mean since 1850. +> > themes: +> > - phys +> > realms: +> > - atmos +> > variables: +> > - tas_amsterdam: +> > + tas_london: +> > short_name: tas +> > mip: Amon +> > - preprocessor: annual_mean_amsterdam +> > + preprocessor: annual_mean_london +> > start_year: 1850 +> > end_year: 2000 +> > tas_global: +> > ``` +> > +> {: .solution} +{: .challenge} diff --git a/_episodes/05-preprocessor.md b/_episodes/05-preprocessor.md index 164cfb87..64e9c261 100644 --- a/_episodes/05-preprocessor.md +++ b/_episodes/05-preprocessor.md @@ -1,9 +1,9 @@ --- -title: "Working with preprocessors" +title: "Writing your own recipe" teaching: 15 -exercises: 45 +exercises: 30 questions: -- "How do I set up a preprocessor?" +- "How do I create a new recipe?" - "Can I use different preprocessors for different variables?" - "Can I use different datasets for different variables?" - "How can I combine different preprocessor functions?" @@ -18,391 +18,505 @@ keypoints: variables." --- -## Preprocessors: What are they and how do they work? +## Introduction -Preprocessing is the process of performing a set of modular operations on the -data before applying diagnostics or metrics. In the figure below you see the -preprocessor functions in the light blue box on the right. +One of the key strenghts of ESMValTool is in making complex analyses reusable +and reproducible. But that doesn't mean everything in ESMValTool needs to be +complex. Sometimes, the biggest challenge is in making things simpler. You +probably know the 'warming stripes' visualization by Professor Ed Hawkins. On +the site you can find the same visualization for +many regions in the world. -![figure showing ESMValTool architecture]({{ page.root -}}/fig/esmvaltool_architecture.png) +![Warming stripes](../fig/warming_stripes.png) *Shared by Ed Hawkins under a +Creative Commons 4.0 Attribution International licence. Source: +* -Underneath the hood, each preprocessor is a modular python function that -receives an iris cube and sometimes some arguments. The preprocessor applies -some mathematical or computational transformation to the input iris cube, then -returns the processed iris cube. +In this episode, we will reproduce and extend this functionality with +ESMValTool. We have prepared a small Python script that takes a NetCDF file with +timeseries data, and visualizes it in the form of our desired warming stripes +figure. -## Inspect the example preprocessor +You can find the diagnostic script that we will use [here (`warming_stripes.py`)](../files/warming_stripes.py). -Each preprocessor section includes a preprocessor name, a list of preprocessor -steps to be executed and any arguments needed by the preprocessor steps. +Download the file and store it in your working directory. If you want, you may +also have a look at the contents, but it is not necessary to follow along. + +We will write an ESMValTool recipe that takes some data, performs the necessary +preprocessing, and then runs our Python script. + +> ## Drawing up a plan +> +> In the previous episode, we have seen that ESMValTool executed a number of +> tasks. Write down which tasks we will need to do in this episode. And what does +> each of these tasks do? +> +> > ## Answer +> > +> > In this episode, we will need to do 2 tasks: +> > +> > - A preprocessing task that converts the gridded temperature data to a timeseries +> > of global temperature anomalies +> > - A diagnostic tasks that calls our Python script, taking our preprocessed +> > timeseries data as input. +> > +> {: .solution} +{: .challenge} + +## Building a recipe from scratch + +The easiest way to make a new recipe is to start from an existing one, and +modify it until it does exactly what you need. However, in this episode we will +start from scratch. This forces us to think about all the steps. We will deal +with common errors as they occur throughout the development. + +Remember the basic structure of a recipe, and notice that each of them is +extensively described in the documentation under the header ["The recipe +format"](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html): + +- [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-documentation) +- [datasets](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-datasets) +- [preprocessors](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-preprocessors) +- [diagnostics](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-diagnostics) + +This is the first place to look for help if you get stuck. + +Open a new file called `recipe_warming_stripes.yml`: + +```bash +nano recipe_warming_stripes.yml +``` + +Let's add the standard header comments (these do not do anything), and a first +description. ```yaml -preprocessors: - prep_timeseries: - annual_statistics: - operator: mean +# ESMValTool +# recipe_warming_stripes.yml +--- +documentation: + description: Reproducing Ed Hawkins' warming stripes visualization ``` -For instance, the `annual_statistics` with the `operation: mean` argument -preprocessor receives an iris cube, takes the annual average for each year of -data in the cube, and returns the processed cube. +Notice that `yaml` always requires 2 spaces indentation between the different +levels. Pressing `ctrl+o` will save the file. Verify the filename at the bottom +and press enter. Then use `ctrl+x` to exit the editor. -You may use one or more of several preprocessors listed in the -[documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). -The standardised interface between the preprocessors allows them to be used -modularly -- like lego blocks. Almost any conceivable preprocessing order of -operations can be performed using ESMValTool preprocessors. +We will try to run the recipe after every modification we make, to see if it (still) works. -> ## The 'custom order' command. -> -> If you do not want your preprocessors to be applied in the [default -> order](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html), -> then add the following line to your preprocessor chain: -> ->```yaml -> custom_order: true ->``` -> -> The default preprocessor order is listed in the [ESMValCore preprocessor API -> page](https://docs.esmvaltool.org/projects/ESMValCore/en/latest/api/esmvalcore.preprocessor.html). -> -> Also note that preprocessor operations aren't always commutative - meaning -> that the order of operations matters. For instance, when you run the two -> preprocessors -- 'extract_volume' to extract the top 100m of the ocean -> surface and 'volume_statistics' to calculate the volume-weighted mean of the -> data, your result will differ depending on the order of these two -> preprocessors. In fact, the 'extract_volume' preprocessor will fail if you try -> to run it on a 2D dataset. +```bash +esmvaltool run recipe_warming_stripes.yml +``` + +In this case, it gives an error. Below you see the last few lines of the error message. +``` +... +Error validating data /home/user/esmvaltool_tutorial/recipe_barcodes.yml with schema /home/user/miniconda3/envs/esmvaltool_tutorial/lib/python3.8/site-packages/esmvalcore/recipe_schema.yml + documentation.authors: Required field missing +2020-10-08 15:23:11,162 UTC [19451] INFO If you suspect this is a bug or need help, please open an issue on https://github.com/ESMValGroup/ESMValTool/issues and attach the run/recipe_*.yml and run/main_log_debug.txt files from the output directory. +``` +{: .error} + +Here, ESMValTool is telling us that it is missing a required field, namely the +authors. It is good to know that ESMValTool always tries to validate the recipe +in an early stage. This initial check doesn't catch everything though, so we +should always stay alert. + +Let's add some additional information to the recipe. Open the recipe file again, +and add an authors section below the description. ESMValTool expects the authors +as a list, like so: + +```yaml +authors: + - lastname_firstname +``` + +To bypass a number of similar error messages, add a minimal diagnostics section +below the documentation. The file should now look like: + +```yaml +# ESMValTool +# recipe_warming_stripes.yml +--- +documentation: + description: Reproducing Ed Hawkins' warming stripes visualization + authors: + - doe_john +diagnostics: + dummy_diagnostic_1: + scripts: null +``` + +This is the minimal recipe layout that is required by ESMValTool. If we now run +the recipe again, you will probably see the following error: + +``` +ValueError: Tag 'doe_john' does not exist in section 'authors' of /home/user/miniconda3/envs/esmvaltool_tutorial/python3.8/site-packages/esmvaltool/config-references.yml +``` +{: .error} + +> ## Pro tip: config-references.yml > -> Changing the order of preprocessors can also speed up your processing. For -> instance, if you want to extract a two-dimensional layer from a 3D field and -> re-grid it, the layer extraction should be done first. If you did it the other -> way around, then the regridding function would be applied to all the layers of -> your 3D cube and it would take much more time. +> The error message above points to a file named `config-references.yml`. This +> is where ESMValTool stores all its citation information. {: .callout} -Some preprocessor modules are always applied and do not need to be called. This -includes the preprocessors that load the data, apply any fixes and save the data -file afterwards. These do not need to be explicitly included in recipes. +For now, let's just use one of the existing references. Change the author field to +`righi_mattia`, who cannot receive enough credit for all the effort he put into +ESMValTool. If you now run the recipe again, you should see the final message -> ## Exercise: Adding more preprocessor steps -> -> Edit the [example recipe](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example.yml) to first change the variable to -> `thetao`, using only the years 2000-2005. Then add preprocessors to average over the latitude and longitude -> dimensions and finally average over the depth. Now run the recipe. -> ->> ## Solution ->> ->> In the `diff` file below you will see the changes we have made to the file. The top 2 lines are the filenames and the lines like @@ -20,12 +20,15 @@ indicate the line numbers in the original and modified file, respectively. For more info on this format, see [here](https://en.wikipedia.org/wiki/Diff#Unified_format). ->> ->>```diff ->> --- data/recipe_example.yml ->> --- data/recipe_example_thetao.yml ->> @@ -20,12 +20,15 @@ ->> - ukesm ->> ->> datasets: ->> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1859, end_year: 2005} ->> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} ->> ->> preprocessors: ->> prep_timeseries: # For 0D fields ->> annual_statistics: ->> operator: mean ->> + area_statistics: ->> + operator: mean ->> + depth_integration: ->> ->> diagnostics: ->> # -------------------------------------------------- ->> @@ -35,7 +38,7 @@ ->> description: simple_time_series ->> variables: ->> timeseries_variable: ->> - short_name: thetaoga ->> + short_name: thetao ->> preprocessor: prep_timeseries ->> scripts: ->> timeseries_diag: ->> ``` ->> ->> Complete recipe can be downloaded as [recipe_example_thetao.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_thetao.yml) ->{: .solution} +``` +INFO Run was successful +``` +{: .output} + +## Adding a dataset entry + +Let's add a datasets section. We will reuse the same datasets that we used in +the previous episode. The data files are stored in `~/esmvaltool_tutorial/data`. + +> ## Filling in the dataset keys +> +> Explore the data directory, and look at the explanation of the dataset entry +> in the [ESMValTool +> documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-documentation). +> For both the datasets, write down the following properties: +> +> - project +> - variable (short name) +> - CMIP table +> - dataset (model name or obs/reanalysis dataset) +> - experiment +> - ensemble member +> - grid +> - start year +> - end year +> +> > ## Answers +> > +> > | **key** | **file 1** | **file 2** | +> > | project | CMIP6 | CMIP5 | +> > | short name | tas | tas | +> > | CMIP table | Amon | Amon | +> > | dataset | BCC-ESM1 | CanESM2 | +> > | experiment | historical | historical | +> > | ensemble | r1i1p1f1 | r1i1p1 | +> > | grid | gn (native grid) | N/A | +> > | start year | 1850 | 1850 | +> > | end year | 2014 | 2005 | +> > +> > Note that the grid key is only required for CMIP6 data, and that the extent +> > of the historical period has changed between CMIP5 and CMIP6. +> > +> {: .solution} {: .challenge} -## Using different preprocessors for different variables +We will start with the BCC-ESM1 dataset. Add a datasets section to the recipe, +listing a single dataset, like so: -You can also define different preprocessors with several preprocessor sections -(setting different preprocessor names). In the variable section you call the -specific preprocessor which should be applied. +```yaml +datasets: + - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn, start_year: 1850, end_year: 2014} +``` -> ## Example -> -> ```yaml ->datasets: -> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} -> -> preprocessors: -> prep_timeseries_1: -> annual_statistics: -> operator: mean -> prep_timeseries_2: -> annual_statistics: -> operator: mean -> area_statistics: -> operator: mean -> depth_integration: -> --- -> diagnostics: -> # -------------------------------------------------- -> # Time series diagnostics -> # -------------------------------------------------- -> diag_timeseries_temperature_1: -> description: simple_time_series> -> variables: -> timeseries_variable: -> short_name: thetaoga -> preprocessor: prep_timeseries_1 -> scripts: -> timeseries_diag: -> script: ocean/diagnostic_timeseries.py -> -> diag_timeseries_temperature_2: -> description: simple_time_series -> variables: -> timeseries_variable: -> short_name: thetao -> preprocessor: prep_timeseries_2 -> scripts: -> timeseries_diag: -> script: ocean/diagnostic_timeseries.py -> ``` -> -> Complete recipe can be downloaded as [recipe_example_thetao_thetaoga.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_thetao_thetaoga.yml) -{: .solution} +Verify that the recipe still runs. Note that we have not included the short name +of the variable in this dataset section. This allows us to reuse this dataset +entry with different variable names later on. This is not really necessary for +our simple use case, but it is common practice in ESMValTool. ->## Challenge : How to write a recipe with multiple preprocessors -> ->We now know that a recipe can have more than one diagnostic, variable or ->preprocessor. As we saw in the examples so far, we can group preprocessors with ->a single user defined name and can have more than one such preprocessor group ->in the recipe as well. Write two different preprocessors - one to regrid the ->data to a 1x1 resolution and the second preprocessor to mask out sea and ice ->grid cells before regridding to the same resolution. In the second case, ensure ->you perform the masking first before regridding (hint: custom order your ->operations). Now, use the two preprocessors in different diagnostics within the ->same recipe. You may use any variable(s) of your choice. Once you succeed, try ->to add new datasets to the same recipe. -> -> To complete this exercise, we need to change the following sections in the recipe: -> -> - `preprocessors`: -> - `prep_map`: add a preprocessor to regrid data -> - fill preprocessor details here -> -> - `prep_map_land`: add a preprocessor to mask grid cells and then regrid -> - fill preprocessor details here including ordering -> -> - `diag_simple_plot`: -> - `description`: preprocess a variable for a simple 2D plot -> - `variables`: -> - put your variable of choice here -> - edit mip, and time based on your variable choice -> - apply the first preprocessor i.e. name your preprocessor -> -> - `scripts`: `null` it means that no scripts called. -> -> - `diag_land_only_plot`: second diagnostic -> - `description`: preprocess a variable for a 2D land only plot -> - ``variables``: -> - include a variable and information as in the previous diagnostic -> - include your second preprocessor (masking and regridding) -> - `scripts`: `null` it means that no scripts called. -> ->> ## Solution ->> ->> Here is one solution to complete the challenge above using two different ->> preprocessors: ->> ->>```diff ->> --- data/recipe_example.yml ->> +++ data/recipe_example_multi_preprocessors.yml ->> @@ -20,23 +20,37 @@ ->> - ukesm ->> ->> datasets: ->> - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} ->> + - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} ->> ->> preprocessors: ->> - prep_timeseries: # For 0D fields ->> - annual_statistics: ->> - operator: mean ->> + prep_map: ->> + regrid: #apply the preprocessor to regrid ->> + target_grid: 1x1 # target resolution ->> + scheme: linear #how to interpolate for regridding ->> + ->> + prep_map_land: ->> + custom_order: true #ensure that given order of preprocessing is followed ->> + mask_landsea: #apply a mask ->> + mask_out: sea #mask out sea grid cells ->> + regrid: # now apply the preprocessor to regrid ->> + target_grid: 1x1 # target resolution ->> + scheme: linear #how to interpolate for regridding ->> ->> diagnostics: ->> # -------------------------------------------------- ->> - # Time series diagnostics ->> + # Two Simple diagnostics that illustrate the use of ->> + # different preprocessors ->> # -------------------------------------------------- ->> - diag_timeseries_temperature: ->> - description: simple_time_series ->> + diag_simple_plot: ->> + description: # preprocess a variable for a simple 2D plot ->> + variables: ->> + tas: # surface temperature ->> + preprocessor: prep_map ->> + scripts: null ->> + ->> + diag_land_only_plot: ->> + description: #preprocess a variable for a 2D land only plot ->> variables: ->> - timeseries_variable: ->> - short_name: thetaoga ->> - preprocessor: prep_timeseries ->> - scripts: ->> - timeseries_diag: ->> - script: ocean/diagnostic_timeseries.py ->> + tas: # surface temperature ->> + preprocessor: prep_map_land ->> + scripts: null ->> ``` ->> ->> Complete recipe can be downloaded as ->> [recipe_example_multi_preprocessors.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_multi_preprocessors.yml). +## Adding the preprocessor section + +Above, we already described the preprocessing task that needs to convert the +standard, gridded temperature data to a timeseries of temperature anomalies. + +> ## Defining the preprocessor +> +> Have a look at the available preprocessors in the +> [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/preprocessor.html). +> Write down +> +> - Which preprocessor functions do you think we should use? +> - What are the parameters that we can pass to these functions? +> - What do you think should be the order of the preprocessors? +> - A suitable name for the overall preprocessor +> +> > ## Solution +> > +> > We need to calculate anomalies and global means. There is an `anomalies` +> > preprocessor which needs a granularity, a reference period, and whether or +> > not to standardize the data. The global means can be calculated with the +> > `area_statistics` preprocessor, which takes an operator as argument (in our +> > case we want to compute the `mean`). +> > +> > The default order in which these preprocessors are applied can be seen +> > [here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/api/esmvalcore.preprocessor.html#preprocessor-functions): +> > `area_statistics` comes before `anomalies`. If you want to change this, you +> > can use the `custom_order` preprocessor. We will keep it like this. +> > +> > Let's name our preprocessor `global_anomalies`. > {: .solution} {: .challenge} -## Adding different datasets for different variables +Add the following block to your recipe file: -Sometimes, we may want to include specific datasets only for certain variables. -An example is when we use observations for variables in a -diagnostic. While the CMIP dataset details for the two variables may be common, -the observations will likely not be so. It would be useful to know how to -include different datasets for different variables. Here is an example of a -simple preprocessor and diagnostic setup for that: +```yaml +preprocessors: + global_anomalies: + area_statistics: + operator: mean + anomalies: + period: month + reference: + start_year: 1981 + start_month: 1 + start_day: 1 + end_year: 2010 + end_month: 12 + end_day: 31 + standardize: false +``` -> ## Example -> -> ```yaml -> -> datasets: -> - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, ensemble: r1i1p1} +and verify that the recipe still runs. + +## Completing the diagnostics section + +Now we are ready to finish our diagnostics section. Remember that we want to +make two tasks: a preprocessor task, and a diagnostic task. To illustrate that +we can also pass settings to the diagnostic script, we add the option to specify +a custom colormap. + +> ## Fill in the blanks > -> preprocessors: -> prep_regrid: # regrid to get all data to the same resolution -> regrid: # apply the preprocessor to regrid -> target_grid: 2.5x2.5 # target resolution -> scheme: linear # how to interpolate for regridding +> Extend the diagnostics section in your recipe by filling in the blanks in the +> following template: > +> ```yaml > diagnostics: -> # -------------------------------------------------- -> # Simple diagnostic to illustrate use of different -> # datasets for different variables -> # -------------------------------------------------- -> diag_diff_datasets: -> description: diff_datasets_for_vars +> <... (suitable name for our diagnostic)>: +> description: <...> > variables: -> pr: # first variable is precipitation -> mip: Amon -> start_year: 2000 -> end_year: 2005 -> preprocessor: prep_regrid -> additional_datasets: -> - {dataset: GPCP-SG, project: obs4mips, level: L3, -> version: v2.2, tier: 1} # dataset specific to this variable -> tas: # second variable is surface temperature -> mip: Amon -> start_year: 2000 -> end_year: 2005 -> preprocessor: prep_regrid -> scripts: null +> <... (suitable name for the preprocessed variable)>: +> short_name: <...> +> preprocessor: <...> +> scripts: +> <... (suitable name for our python script)>: +> script: +> colormap: <... choose from matplotlib colormaps> > ``` -> Complete recipe can be downloaded as [recipe_example_pr_tas.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_pr_tas.yml). > -{: .solution} +> > ## Solution +> > +> > ```yaml +> > diagnostics: +> > diagnostic_warming_stripes: +> > description: visualize global temperature anomalies as warming stripes +> > variables: +> > global_temperature_anomalies_global: +> > short_name: tas +> > preprocessor: global_anomalies +> > scripts: +> > warming_stripes_script: +> > script: ~/esmvaltool_tutorial/warming_stripes.py +> > colormap: 'bwr' +> > ``` +> {: .solution} +{: .challenge} -## Creating variable groups +Now you should be able to run the recipe to get your own warming stripes. -Variable grouping can be used to preprocess different clusters of data for the -same variable. For instance, the example below illustrates how we can compute -separate multimodel means for different CMIP5 datasets given the same variable. +Note: for the purpose of simplicity in this episode, we have not added logging +or provenance tracking in the diagnostic script. Once you start to develop your +own diagnostic scripts and want to add them to the ESMValTool repositories, this +will be required. However, writing your own diagnostic script is beyond the +scope of the basic tutorial. -> ## Example ->```yaml -> ->preprocessors: -> prep_mmm: -> custom_order: true -> regrid: -> target_grid: 2.5 x 2.5 -> scheme: linear -> multi_model_statistics: -> span: full -> statistics: [mean, median] -> -> prep_obs: -> mask_landsea: -> mask_out: sea -> regrid: -> target_grid: 2.5 x 2.5 -> scheme: linear -> -># note that there is no field called datasets anymore -># note how multiple ensembles are added by using (1:4) ->cmip5_control: &cmip5_control -> - {dataset: HadGEM2-ES, ensemble: r1i1p1, project: CMIP5} -> - {dataset: MPI-ESM-LR, ensemble: r1i1p1, project: CMIP5} -> ->cmip5_target: &cmip5_target -> - {dataset: CanESM2, ensemble: "r(1:2)i1p1", project: CMIP5} -> ->diagnostics: -> -> diag_variable_groups: -> description: Demonstrate the use of variable groups. -> variables: -> tas_control: &variable_settings # need a key name for the grouping -> short_name: tas # specify variable to look for -> preprocessor: prep_mmm -> mip: Amon -> exp: historical -> start_year: 2000 -> end_year: 2005 -> tag: TAS_CONTROL # tag is optional if you are using these settings just once -> additional_datasets: *cmip5_control -> tas_target: -> <<: *variable_settings -> tag: TAS_TARGET -> additional_datasets: *cmip5_target # nothing changes from cmip5 except the data set -> scripts: null ->``` -> There is no field called datasets anymore. -> Also, note how multiple ensembles are added by using (1:2). -> Complete recipe can be downloaded as -> [recipe_example_tas_control_target.yml](https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/master/files/recipe_example_tas_control_target.yml). -> -{: .solution} +## Bonus exercises + +Below are a couple of exercise to practice modifying the recipe. For your +reference, here's a copy of the [recipe at this +point](../files/recipe_warming_stripes.yml). This will be the point of departure +for each of the modifications we'll make below. + +> ## Specific location +> +> On showyourstripes.org, you can download stripes for specific locations. We +> will reproduce this possibility. Look at the available preprocessors in the +> documentation, and replace the global mean with a suitable alternative. +> +> > ## Solution +> > +> > You could have used `extract_point` or `extract_region`. We used +> > `extract_point`. Here's a copy of the [recipe at this +> > point](../files/recipe_warming_stripes_local.yml) and this is the difference +> > with the previous recipe: +> > +> > ```diff +> > --- recipe_warming_stripes.yml +> > +++ recipe_warming_stripes_local.yml +> > @@ -10,9 +10,11 @@ +> > - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn, start_year: 1850, end_year: 2014} +> > +> > preprocessors: +> > - global_anomalies: +> > - area_statistics: +> > - operator: mean +> > + anomalies_amsterdam: +> > + extract_point: +> > + latitude: 52.379189 +> > + longitude: 4.899431 +> > + scheme: linear +> > anomalies: +> > period: month +> > reference: +> > @@ -27,9 +29,9 @@ +> > diagnostics: +> > diagnostic_warming_stripes: +> > variables: +> > - global_temperature_anomalies: +> > + temperature_anomalies_amsterdam: +> > short_name: tas +> > - preprocessor: global_anomalies +> > + preprocessor: anomalies_amsterdam +> > scripts: +> > warming_stripes_script: +> > script: ~/esmvaltool_tutorial/warming_stripes.py +> > ``` +> > +> {: .solution} +{:.challenge} -You should be able to see the variables grouped under different subdirectories -under your output preproc directory. The different groupings can be accessed in -your diagnostic by selecting the key name of the field -`variable_group` such as `TAS_CONTROL`, or `TAS_TARGET`. +> ## Different periods +> +> Split the diagnostic in 2: the second one should use a different period. +> You're free to choose the periods yourself. For example, 1 could be 'recent', +> the other '20th_century'. For this, you'll have to add a new variable group. +> +> > ## Solution +> > +> > Here's a copy of the [recipe at this point](../files/recipe_warming_stripes_periods.yml) +> > and this is the difference with the previous recipe: +> > +> > ```diff +> > --- recipe_warming_stripes_local.yml +> > +++ recipe_warming_stripes_periods.yml +> > @@ -7,7 +7,7 @@ +> > - righi_mattia +> > +> > datasets: +> > - - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn, start_year: 1850, end_year: 2014} +> > + - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn} +> > +> > preprocessors: +> > anomalies_amsterdam: +> > @@ -29,9 +29,16 @@ +> > diagnostics: +> > diagnostic_warming_stripes: +> > variables: +> > - temperature_anomalies_amsterdam: +> > + temperature_anomalies_recent: +> > short_name: tas +> > preprocessor: anomalies_amsterdam +> > + start_year: 1950 +> > + end_year: 2014 +> > + temperature_anomalies_20th_century: +> > + short_name: tas +> > + preprocessor: anomalies_amsterdam +> > + start_year: 1900 +> > + end_year: 1999 +> > scripts: +> > warming_stripes_script: +> > script: ~/esmvaltool_tutorial/warming_stripes.py +> > ``` +> > +> {: .solution} +{:.challenge} -> ## How to find what CMIP data is available? +> ## Different preprocessors +> +> Now that you have different variable groups, we can also use different +> preprocessors. Add a second preprocessor to add another location of your +> choosing. +> +> Pro-tip: if you want to avoid repetition, you can use YAML anchors. +> +> > ## Solution +> > +> > Here's a copy of the [recipe at this +> > point](../files/recipe_warming_stripes_multiple_locations.yml) and this is +> > the difference with the previous recipe: +> > +> > ```diff +> > --- recipe_warming_stripes_periods.yml +> > +++ recipe_warming_stripes_multiple_locations.yml +> > @@ -15,7 +15,7 @@ +> > latitude: 52.379189 +> > longitude: 4.899431 +> > scheme: linear +> > - anomalies: +> > + anomalies: &anomalies +> > period: month +> > reference: +> > start_year: 1981 +> > @@ -25,18 +25,24 @@ +> > end_month: 12 +> > end_day: 31 +> > standardize: false +> > + anomalies_london: +> > + extract_point: +> > + latitude: 51.5074 +> > + longitude: 0.1278 +> > + scheme: linear +> > + anomalies: *anomalies +> > +> > diagnostics: +> > diagnostic_warming_stripes: +> > variables: +> > - temperature_anomalies_recent: +> > + temperature_anomalies_recent_amsterdam: +> > short_name: tas +> > preprocessor: anomalies_amsterdam +> > start_year: 1950 +> > end_year: 2014 +> > - temperature_anomalies_20th_century: +> > + temperature_anomalies_20th_century_london: +> > short_name: tas +> > - preprocessor: anomalies_amsterdam +> > + preprocessor: anomalies_london +> > start_year: 1900 +> > end_year: 1999 +> > scripts: +> > ``` +> > +> {: .solution} > -> Please see section "Access to CMIP and Observational data" in [Setup]({{ page.root }}{% link setup.md %}). -{: .callout} +{:.challenge} + +> ## Additional datasets +> +> So far we have defined the datasets in the datasets section of the recipe. +> However, it's also possible to add specific datasets only for specific +> variable groups. Look at the documentation to learn about the +> 'additional_datasets' keyword, and add a second dataset only for one of the +> variable groups. +> +> > ## Solution +> > +> > Here's a copy of the [recipe at this +> > point](../files/recipe_warming_stripes_additional_datasets.yml) and this is +> > the difference with the previous recipe: +> > +> > ```diff +> > --- recipe_warming_stripes_multiple_locations.yml +> > +++ recipe_warming_stripes_additional_datasets.yml +> > @@ -45,6 +45,8 @@ +> > preprocessor: anomalies_london +> > start_year: 1900 +> > end_year: 1999 +> > + additional_datasets: +> > + - {dataset: CanESM2, project: CMIP5, mip: Amon, exp: historical, ensemble: r1i1p1} +> > scripts: +> > warming_stripes_script: +> > script: ~/esmvaltool_tutorial/warming_stripes.py +> > ``` +> > +> {: .solution} +{:.challenge} diff --git a/data/dataset.urls b/data/dataset.urls index 945063dd..11fe67e8 100644 --- a/data/dataset.urls +++ b/data/dataset.urls @@ -1,26 +1,4 @@ # Dataset urls required fo tutorial, described at https://esmvalgroup.github.io/ESMValTool_Tutorial/setup.html#using-your-own-machine -# For Running a recipe episode -# Variable = thetaoga, model = HadGEM2-ES -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc -# Variable = ts, model = HadGEM2-ES -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/ts/ts_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc -# Variable = tas, model = HadGEM2-ES -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_195912-198411.nc -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/tas/tas_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc -# Variable = tos, model = HadGEM2-CC -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-CC/historical/mon/ocean/Omon/r1i1p1/v20110930/tos/tos_Omon_HadGEM2-CC_historical_r1i1p1_195912-200511.nc -# Variable = tos, model = HadGEM2-ES -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/tos/tos_Omon_HadGEM2-ES_historical_r1i1p1_195912-200512.nc -# For Working with preprocessors episode -# Variable = thetao, model = HadGEM2-ES -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetao/thetao_Omon_HadGEM2-ES_historical_r1i1p1_199912-200512.nc -# Model = CanESM2, ensemble: "r(1:2)i1p1", project: CMIP5, variable = tas -http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r1i1p1/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc -http://crd-esgf-drc.ec.gc.ca/thredds/fileServer/esg_dataroot/AR5/CMIP5/output/CCCma/CanESM2/historical/mon/atmos/tas/r2i1p1/tas_Amon_CanESM2_historical_r2i1p1_185001-200512.nc -# Model = MPI-ESM-LR, ensemble: r1i1p1", project: CMIP5, variable = tas -http://esgf1.dkrz.de/thredds/fileServer/cmip5/cmip5/output1/MPI-M/MPI-ESM-LR/historical/mon/atmos/Amon/r1i1p1/v20120315/tas/tas_Amon_MPI-ESM-LR_historical_r1i1p1_185001-200512.nc -# Variable = pr, model = GPCP-SG, project= obs4mips -https://dpesgf03.nccs.nasa.gov/thredds/fileServer/obs4MIPs/observations/NASA-GSFC/Obs-GPCP/GPCP/V2.2/atmos/pr/pr_GPCP-SG_L3_v2.2_197901-201312.nc -# Variable = pr, model = HadGEM2-ES, project= CMIP5 -http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/atmos/Amon/r1i1p1/v20120928/pr/pr_Amon_HadGEM2-ES_historical_r1i1p1_198412-200511.nc +# For episodes 4 and 5 +http://esgf3.dkrz.de/thredds/fileServer/cmip6/CMIP/BCC/BCC-ESM1/historical/r1i1p1f1/Amon/tas/gn/v20181214/tas_Amon_BCC-ESM1_historical_r1i1p1f1_gn_185001-201412.nc +http://esgf2.dkrz.de/thredds/fileServer/lta_dataroot/cmip5/output1/CCCma/CanESM2/historical/mon/atmos/Amon/r1i1p1/v20120718/tas/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc diff --git a/fig/warming_stripes.png b/fig/warming_stripes.png new file mode 100644 index 0000000000000000000000000000000000000000..f8b5551b07418e35819ae6d58cac2253ad7a1a2f GIT binary patch literal 25980 zcmeI5Z%k8H7{-sFE2zM*4iu|YHi*km3T{{w1e6A0(lKqO8--dBhJ#UBYU!jPqYX&i zKsFgRL&%mWF*2^@}f9})X@i9Zr=NF_*6p~*{gYJ-klruE0}cSQ-wyx>$1?3 z+nGog)U;t7i33lIRUU-rE`B)4~&>xo35M-QbL`^CAfw}))ori)WZzfel1Y66`Id`a{tvi6S21nn9A8vzyx&`1;}ES1w;!w zi&s__=CnKR^KBUB8r>KmZ768dw7W z0ze?>HLwT(1b{#=pu!?}0SMZDZx-PNfWQfX6KeoK00;zulMulR0w)AZh!KQ5V3dhT zyaXWBXI8q{O5-xFS~Wc6f{uOTU?bZT?`SuBTj5|!JGs}vQwAsD3ko0r1cIi4MF1cG zL^1RlGa>*GxG?|-0D)j+iA4Y)00d0Bum%7GfIu*RB18c5Cro0lfuM>WN7;%Vb)TUZ8^GpKg6@UQ45!S$*2T^l6DdOK=fR|uBAAva*>kB{t2sGz|%*-`}z=E|5AOHmT zY>2=PJ{wE|KmZ6B?-5}EmKiV!0P(*B5%s9|OIyW?sRu`+*Hui{5u8`}QUeG80k=@F z1^@(rKwvn+A^;Eo0-RSwLd0K%)MIsgCw literal 0 HcmV?d00001 diff --git a/files/recipe_example.yml b/files/recipe_example.yml deleted file mode 100644 index 9675a936..00000000 --- a/files/recipe_example.yml +++ /dev/null @@ -1,42 +0,0 @@ -# ESMValTool -# recipe_example.yml ---- -documentation: - description: Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - -datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1900, end_year: 2000} - -preprocessors: - prep_timeseries: # For 0D fields - annual_statistics: - operator: mean - -diagnostics: - # -------------------------------------------------- - # Time series diagnostics - # -------------------------------------------------- - diag_timeseries_temperature: - description: simple_time_series - variables: - timeseries_variable: - short_name: thetaoga - preprocessor: prep_timeseries - scripts: - timeseries_diag: - script: ocean/diagnostic_timeseries.py diff --git a/files/recipe_example_multi_preprocessors.yml b/files/recipe_example_multi_preprocessors.yml deleted file mode 100644 index 8a512910..00000000 --- a/files/recipe_example_multi_preprocessors.yml +++ /dev/null @@ -1,56 +0,0 @@ -# ESMValTool -# recipe_example.yml ---- -documentation: - description: Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - -datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} - -preprocessors: - prep_map: - regrid: #apply the preprocessor to regrid - target_grid: 1x1 # target resolution - scheme: linear #how to interpolate for regridding - - prep_map_land: - custom_order: true #ensure that given order of preprocessing is followed - mask_landsea: #apply a mask - mask_out: sea #mask out sea grid cells - regrid: # now apply the preprocessor to regrid - target_grid: 1x1 # target resolution - scheme: linear #how to interpolate for regridding - -diagnostics: - # -------------------------------------------------- - # Two Simple diagnostics that illustrate the use of - # different preprocessors - # -------------------------------------------------- - diag_simple_plot: - description: # preprocess a variable for a simple 2D plot - variables: - tas: # surface temperature - preprocessor: prep_map - scripts: null - - diag_land_only_plot: - description: #preprocess a variable for a 2D land only plot - variables: - tas: # surface temperature - preprocessor: prep_map_land - scripts: null diff --git a/files/recipe_example_output/log.txt b/files/recipe_example_output/log.txt deleted file mode 100644 index 55c13f0f..00000000 --- a/files/recipe_example_output/log.txt +++ /dev/null @@ -1,53 +0,0 @@ -Starting diagnostic script timeseries_diag with configuration: -auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data -input_data: - ? /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc - : alias: HadGEM2-ES - dataset: HadGEM2-ES - diagnostic: diag_timeseries_temperature - end_year: 2005 - ensemble: r1i1p1 - exp: historical - filename: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc - frequency: mon - institute: - - INPE - - MOHC - long_name: Global Average Sea Water Potential Temperature - mip: Omon - modeling_realm: - - ocean - preprocessor: prep_timeseries - project: CMIP5 - recipe_dataset_index: 0 - short_name: thetaoga - standard_name: sea_water_potential_temperature - start_year: 1859 - units: K - variable_group: timeseries_variable -input_files: -- /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml -log_level: info -output_file_type: png -plot_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag -profile_diagnostic: false -recipe: recipe_example.yml -run_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag -script: timeseries_diag -version: 2.0.0b9 -work_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag -write_netcdf: true -write_plots: true - -Creating /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag -Creating /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag -metadata filename: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml -No handles with labels found to put in legend. -Image path will be: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png -Saving plots to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/MultipleModels__thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_.png ------------------ -model filenames: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc -Image path will be: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png -Saving plots to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag/diag_CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_prep_timeseries_diag_timeseries_temperature_1859_2005_timeseries_0.png -Success -End of diagnostic script run. diff --git a/files/recipe_example_output/main_log.txt b/files/recipe_example_output/main_log.txt deleted file mode 100644 index 1accd0e7..00000000 --- a/files/recipe_example_output/main_log.txt +++ /dev/null @@ -1,80 +0,0 @@ -INFO [33433] -______________________________________________________________________ - _____ ____ __ ____ __ _ _____ _ - | ____/ ___|| \/ \ \ / /_ _| |_ _|__ ___ | | - | _| \___ \| |\/| |\ \ / / _` | | | |/ _ \ / _ \| | - | |___ ___) | | | | \ V / (_| | | | | (_) | (_) | | - |_____|____/|_| |_| \_/ \__,_|_| |_|\___/ \___/|_| -______________________________________________________________________ - -ESMValTool - Earth System Model Evaluation Tool. - -http://www.esmvaltool.org - -CORE DEVELOPMENT TEAM AND CONTACTS: - Veronika Eyring (PI; DLR, Germany - veronika.eyring@dlr.de) - Bouwe Andela (NLESC, Netherlands - b.andela@esciencecenter.nl) - Bjoern Broetz (DLR, Germany - bjoern.broetz@dlr.de) - Lee de Mora (PML, UK - ledm@pml.ac.uk) - Niels Drost (NLESC, Netherlands - n.drost@esciencecenter.nl) - Nikolay Koldunov (AWI, Germany - nikolay.koldunov@awi.de) - Axel Lauer (DLR, Germany - axel.lauer@dlr.de) - Benjamin Mueller (LMU, Germany - b.mueller@iggf.geo.uni-muenchen.de) - Valeriu Predoi (URead, UK - valeriu.predoi@ncas.ac.uk) - Mattia Righi (DLR, Germany - mattia.righi@dlr.de) - Manuel Schlund (DLR, Germany - manuel.schlund@dlr.de) - Javier Vegas-Regidor (BSC, Spain - javier.vegas@bsc.es) - Klaus Zimmermann (SMHI, Sweden - klaus.zimmermann@smhi.se) - -For further help, please read the documentation at -http://esmvaltool.readthedocs.io. Have fun! - -INFO [33433] Using config file /pf/b/b380506/work/config-BM_DKRZ.yml -INFO [33433] Writing program log files to: -/scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/main_log.txt -/scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/main_log_debug.txt -INFO [33433] Starting the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:22:58 UTC -INFO [33433] ---------------------------------------------------------------------- -INFO [33433] RECIPE = /pf/b/b380506/work/recipes/recipe_example.yml -INFO [33433] RUNDIR = /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run -INFO [33433] WORKDIR = /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work -INFO [33433] PREPROCDIR = /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc -INFO [33433] PLOTDIR = /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots -INFO [33433] ---------------------------------------------------------------------- -INFO [33433] Running tasks using at most 8 processes -INFO [33433] If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. -INFO [33433] If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. -INFO [33433] Creating tasks from recipe -INFO [33433] Creating tasks for diagnostic diag_timeseries_temperature -INFO [33433] Creating preprocessor task diag_timeseries_temperature/timeseries_variable -INFO [33433] Creating preprocessor 'prep_timeseries' task for variable 'thetaoga' -INFO [33433] Using input files for variable thetaoga of dataset HadGEM2-ES: -/mnt/lustre01/work/kd0956/CMIP5/data/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc -INFO [33433] PreprocessingTask diag_timeseries_temperature/timeseries_variable created. It will create the files: -/scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc -INFO [33433] Creating diagnostic task diag_timeseries_temperature/timeseries_diag -INFO [33433] These tasks will be executed: diag_timeseries_temperature/timeseries_variable, diag_timeseries_temperature/timeseries_diag -INFO [33433] Running 2 tasks using 2 processes -INFO [39196] Starting task diag_timeseries_temperature/timeseries_variable in process [39196] -INFO [33433] Progress: 1 tasks running, 1 tasks waiting for ancestors, 0/2 done -INFO [39196] Successfully completed task diag_timeseries_temperature/timeseries_variable (priority 0) in 0:00:07.241490 -INFO [33433] Progress: 0 tasks running, 1 tasks waiting for ancestors, 1/2 done -INFO [39197] Starting task diag_timeseries_temperature/timeseries_diag in process [39197] -INFO [39197] Running command ['/pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python', '/mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py', '/scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml'] -INFO [39197] Writing output to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag -INFO [39197] Writing plots to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag -INFO [39197] Writing log to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/log.txt -INFO [39197] To re-run this diagnostic script, run: -cd /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag; MPLBACKEND="Agg" /pf/b/b380506/miniconda3/envs/esmvaltool_pub/bin/python /mnt/lustre01/pf/b/b380506/work/GIT/ESMValTool/esmvaltool/diag_scripts/ocean/diagnostic_timeseries.py /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/settings.yml -INFO [33433] Progress: 1 tasks running, 0 tasks waiting for ancestors, 1/2 done -INFO [39197] Maximum memory used (estimate): 0.2 GB -INFO [39197] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. -WARNING [39197] No provenance information was written to /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag/diagnostic_provenance.yml -INFO [39197] Successfully completed task diag_timeseries_temperature/timeseries_diag (priority 1) in 0:00:07.347165 -INFO [33433] Progress: 0 tasks running, 0 tasks waiting for ancestors, 2/2 done -INFO [33433] Successfully completed all tasks. -INFO [33433] Ending the Earth System Model Evaluation Tool v2.0.0b9 at time: 2020-07-01 08:23:13 UTC -INFO [33433] Time for running the recipe was: 0:00:14.820802 -INFO [33433] Maximum memory used (estimate): 0.7 GB -INFO [33433] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. -INFO [33433] Run was successful diff --git a/files/recipe_example_output/metadata.yml b/files/recipe_example_output/metadata.yml deleted file mode 100644 index 2d3ad5c6..00000000 --- a/files/recipe_example_output/metadata.yml +++ /dev/null @@ -1,24 +0,0 @@ -? /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc -: alias: HadGEM2-ES - dataset: HadGEM2-ES - diagnostic: diag_timeseries_temperature - end_year: 2005 - ensemble: r1i1p1 - exp: historical - filename: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/CMIP5_HadGEM2-ES_Omon_historical_r1i1p1_thetaoga_1859-2005.nc - frequency: mon - institute: - - INPE - - MOHC - long_name: Global Average Sea Water Potential Temperature - mip: Omon - modeling_realm: - - ocean - preprocessor: prep_timeseries - project: CMIP5 - recipe_dataset_index: 0 - short_name: thetaoga - standard_name: sea_water_potential_temperature - start_year: 1859 - units: K - variable_group: timeseries_variable diff --git a/files/recipe_example_output/settings.yml b/files/recipe_example_output/settings.yml deleted file mode 100644 index 5785249d..00000000 --- a/files/recipe_example_output/settings.yml +++ /dev/null @@ -1,14 +0,0 @@ -auxiliary_data_dir: /mnt/lustre01/pf/b/b380506/work/auxiliary_data -input_files: -- /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/preproc/diag_timeseries_temperature/timeseries_variable/metadata.yml -log_level: info -output_file_type: png -plot_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/plots/diag_timeseries_temperature/timeseries_diag -profile_diagnostic: false -recipe: recipe_example.yml -run_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/run/diag_timeseries_temperature/timeseries_diag -script: timeseries_diag -version: 2.0.0b9 -work_dir: /scratch/b/b380506/ESACCISST_test/recipe_example_20200701_082257/work/diag_timeseries_temperature/timeseries_diag -write_netcdf: true -write_plots: true diff --git a/files/recipe_example_pr_tas.yml b/files/recipe_example_pr_tas.yml deleted file mode 100644 index 3948b751..00000000 --- a/files/recipe_example_pr_tas.yml +++ /dev/null @@ -1,52 +0,0 @@ -# ESMValTool -# recipe_example.yml ---- -documentation: - description: Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - -datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, ensemble: r1i1p1} - -preprocessors: - prep_regrid: # regrid to get all data to the same resolution - regrid: # apply the preprocessor to regrid - target_grid: 2.5x2.5 # target resolution - scheme: linear # how to interpolate for regridding - -diagnostics: - # -------------------------------------------------- - # Simple diagnostic to illustrate use of different - # datasets for different variables - # -------------------------------------------------- - diag_diff_datasets: - description: diff_datasets_for_vars - variables: - pr: # first variable is precipitation - mip: Amon - start_year: 2000 - end_year: 2005 - preprocessor: prep_regrid - additional_datasets: - - {dataset: GPCP-SG, project: obs4mips, level: L3, - version: v2.2, tier: 1} # dataset specific to this variable - tas: # second variable is surface temperature - mip: Amon - start_year: 2000 - end_year: 2005 - preprocessor: prep_regrid - scripts: null diff --git a/files/recipe_example_tas.yml b/files/recipe_example_tas.yml deleted file mode 100644 index 1fc6c34e..00000000 --- a/files/recipe_example_tas.yml +++ /dev/null @@ -1,44 +0,0 @@ -# ESMValTool -# recipe_example.yml ---- -documentation: - description: Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - -datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} - -preprocessors: - prep_timeseries: # For 0D fields - annual_statistics: - operator: mean - area_statistics: - operator: mean - -diagnostics: - # -------------------------------------------------- - # Time series diagnostics - # -------------------------------------------------- - diag_timeseries_temperature: - description: simple_time_series - variables: - timeseries_variable: - short_name: tas - preprocessor: prep_timeseries - scripts: - timeseries_diag: - script: ocean/diagnostic_timeseries.py diff --git a/files/recipe_example_tas_control_target.yml b/files/recipe_example_tas_control_target.yml deleted file mode 100644 index 57a837ef..00000000 --- a/files/recipe_example_tas_control_target.yml +++ /dev/null @@ -1,64 +0,0 @@ -# ESMValTool -# recipe_example.yml ---- -documentation: - description: Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - -preprocessors: - prep_mmm: - custom_order: true - regrid: - target_grid: 2.5 x 2.5 - scheme: linear - multi_model_statistics: - span: full - statistics: [mean, median] - - prep_obs: - mask_landsea: - mask_out: sea - regrid: - target_grid: 2.5 x 2.5 - scheme: linear - -cmip5_control: &cmip5_control - - {dataset: HadGEM2-ES, ensemble: r1i1p1, project: CMIP5} - - {dataset: MPI-ESM-LR, ensemble: r1i1p1, project: CMIP5} - -cmip5_target: &cmip5_target - - {dataset: CanESM2, ensemble: "r(1:2)i1p1", project: CMIP5} - -diagnostics: - - diag_variable_groups: - description: Demonstrate the use of variable groups. - variables: - tas_contorl: &variable_settings # need a key name for the grouping - short_name: tas # specify variable to look for - preprocessor: prep_mmm - mip: Amon - exp: historical - start_year: 2000 - end_year: 2005 - tag: TAS_CONTROL # tag is optional if you are using these settings just once - additional_datasets: *cmip5_control - tas_target: - <<: *variable_settings - tag: TAS_TARGET - additional_datasets: *cmip5_target # nothing changes from cmip5 except the data set - scripts: null diff --git a/files/recipe_example_thetao.yml b/files/recipe_example_thetao.yml deleted file mode 100644 index 6afe3f1f..00000000 --- a/files/recipe_example_thetao.yml +++ /dev/null @@ -1,45 +0,0 @@ -# ESMValTool -# recipe_example.yml ---- -documentation: - description: Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - -datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} - -preprocessors: - prep_timeseries: # For 0D fields - annual_statistics: - operator: mean - area_statistics: - operator: mean - depth_integration: - -diagnostics: - # -------------------------------------------------- - # Time series diagnostics - # -------------------------------------------------- - diag_timeseries_temperature: - description: simple_time_series - variables: - timeseries_variable: - short_name: thetao - preprocessor: prep_timeseries - scripts: - timeseries_diag: - script: ocean/diagnostic_timeseries.py diff --git a/files/recipe_example_thetao_thetaoga.yml b/files/recipe_example_thetao_thetaoga.yml deleted file mode 100644 index 58185194..00000000 --- a/files/recipe_example_thetao_thetaoga.yml +++ /dev/null @@ -1,57 +0,0 @@ -# ESMValTool -# recipe_example.yml ---- -documentation: - description: Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - -datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 2000, end_year: 2005} - -preprocessors: - prep_timeseries_1: - annual_statistics: - operator: mean - prep_timeseries_2: # For 0D fields - annual_statistics: - operator: mean - area_statistics: - operator: mean - depth_integration: - -diagnostics: - # -------------------------------------------------- - # Time series diagnostics - # -------------------------------------------------- - diag_timeseries_temperature_1: - description: simple_time_series - variables: - timeseries_variable: - short_name: thetaoga - preprocessor: prep_timeseries_1 - scripts: - timeseries_diag: - script: ocean/diagnostic_timeseries.py - diag_timeseries_temperature_2: - description: simple_time_series - variables: - timeseries_variable: - short_name: thetao - preprocessor: prep_timeseries_2 - scripts: - timeseries_diag: - script: ocean/diagnostic_timeseries.py diff --git a/files/recipe_example_tos.yml b/files/recipe_example_tos.yml deleted file mode 100644 index 718e6fda..00000000 --- a/files/recipe_example_tos.yml +++ /dev/null @@ -1,45 +0,0 @@ -# ESMValTool -# recipe_example.yml ---- -documentation: - description: Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - -datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} - - {dataset: HadGEM2-CC, project: CMIP5, exp: historical, mip: Omon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} - -preprocessors: - prep_timeseries: # For 0D fields - annual_statistics: - operator: mean - area_statistics: - operator: mean - -diagnostics: - # -------------------------------------------------- - # Time series diagnostics - # -------------------------------------------------- - diag_timeseries_temperature: - description: simple_time_series - variables: - timeseries_variable: - short_name: tos - preprocessor: prep_timeseries - scripts: - timeseries_diag: - script: ocean/diagnostic_timeseries.py diff --git a/files/recipe_example_ts.yml b/files/recipe_example_ts.yml deleted file mode 100644 index 03cb81b2..00000000 --- a/files/recipe_example_ts.yml +++ /dev/null @@ -1,44 +0,0 @@ -# ESMValTool -# recipe_example.yml ---- -documentation: - description: Demonstrate basic ESMValTool example - - authors: - - demora_lee - - mueller_benjamin - - swaminathan_ranjini - - maintainer: - - demora_lee - - references: - - demora2018gmd - # Some plots also appear in ESMValTool paper 2. - - projects: - - ukesm - -datasets: - - {dataset: HadGEM2-ES, project: CMIP5, exp: historical, mip: Amon, ensemble: r1i1p1, start_year: 1970, end_year: 2000} - -preprocessors: - prep_timeseries: # For 0D fields - annual_statistics: - operator: mean - area_statistics: - operator: mean - -diagnostics: - # -------------------------------------------------- - # Time series diagnostics - # -------------------------------------------------- - diag_timeseries_temperature: - description: simple_time_series - variables: - timeseries_variable: - short_name: ts - preprocessor: prep_timeseries - scripts: - timeseries_diag: - script: ocean/diagnostic_timeseries.py diff --git a/files/recipe_warming_stripes.yml b/files/recipe_warming_stripes.yml new file mode 100644 index 00000000..228c867f --- /dev/null +++ b/files/recipe_warming_stripes.yml @@ -0,0 +1,36 @@ +# ESMValTool +# recipe_warming_stripes.yml +--- +documentation: + description: Reproducing Ed Hawkins' warming stripes visualization + authors: + - righi_mattia + +datasets: + - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn, start_year: 1850, end_year: 2014} + +preprocessors: + global_anomalies: + area_statistics: + operator: mean + anomalies: + period: month + reference: + start_year: 1981 + start_month: 1 + start_day: 1 + end_year: 2010 + end_month: 12 + end_day: 31 + standardize: false + +diagnostics: + diagnostic_warming_stripes: + variables: + global_temperature_anomalies: + short_name: tas + preprocessor: global_anomalies + scripts: + warming_stripes_script: + script: ~/esmvaltool_tutorial/warming_stripes.py + colormap: 'bwr' diff --git a/files/recipe_warming_stripes_additional_datasets.yml b/files/recipe_warming_stripes_additional_datasets.yml new file mode 100644 index 00000000..b1b9f264 --- /dev/null +++ b/files/recipe_warming_stripes_additional_datasets.yml @@ -0,0 +1,53 @@ +# ESMValTool +# recipe_warming_stripes_additional_datasets.yml +--- +documentation: + description: Reproducing Ed Hawkins' warming stripes visualization + authors: + - righi_mattia + +datasets: + - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn} + +preprocessors: + anomalies_amsterdam: + extract_point: + latitude: 52.379189 + longitude: 4.899431 + scheme: linear + anomalies: &anomalies + period: month + reference: + start_year: 1981 + start_month: 1 + start_day: 1 + end_year: 2010 + end_month: 12 + end_day: 31 + standardize: false + anomalies_london: + extract_point: + latitude: 51.5074 + longitude: 0.1278 + scheme: linear + anomalies: *anomalies + +diagnostics: + diagnostic_warming_stripes: + variables: + temperature_anomalies_recent_amsterdam: + short_name: tas + preprocessor: anomalies_amsterdam + start_year: 1950 + end_year: 2014 + temperature_anomalies_20th_century_london: + short_name: tas + preprocessor: anomalies_london + start_year: 1900 + end_year: 1999 + additional_datasets: + - {dataset: CanESM2, project: CMIP5, mip: Amon, exp: historical, ensemble: r1i1p1} + scripts: + warming_stripes_script: + script: ~/esmvaltool_tutorial/warming_stripes.py + colormap: 'bwr' diff --git a/files/recipe_warming_stripes_local.yml b/files/recipe_warming_stripes_local.yml new file mode 100644 index 00000000..dfa112a5 --- /dev/null +++ b/files/recipe_warming_stripes_local.yml @@ -0,0 +1,38 @@ +# ESMValTool +# recipe_warming_stripes_local.yml +--- +documentation: + description: Reproducing Ed Hawkins' warming stripes visualization + authors: + - righi_mattia + +datasets: + - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn, start_year: 1850, end_year: 2014} + +preprocessors: + anomalies_amsterdam: + extract_point: + latitude: 52.379189 + longitude: 4.899431 + scheme: linear + anomalies: + period: month + reference: + start_year: 1981 + start_month: 1 + start_day: 1 + end_year: 2010 + end_month: 12 + end_day: 31 + standardize: false + +diagnostics: + diagnostic_warming_stripes: + variables: + temperature_anomalies_amsterdam: + short_name: tas + preprocessor: anomalies_amsterdam + scripts: + warming_stripes_script: + script: ~/esmvaltool_tutorial/warming_stripes.py + colormap: 'bwr' diff --git a/files/recipe_warming_stripes_multiple_locations.yml b/files/recipe_warming_stripes_multiple_locations.yml new file mode 100644 index 00000000..ef38b438 --- /dev/null +++ b/files/recipe_warming_stripes_multiple_locations.yml @@ -0,0 +1,51 @@ +# ESMValTool +# recipe_warming_stripes_multiple_locations.yml +--- +documentation: + description: Reproducing Ed Hawkins' warming stripes visualization + authors: + - righi_mattia + +datasets: + - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn} + +preprocessors: + anomalies_amsterdam: + extract_point: + latitude: 52.379189 + longitude: 4.899431 + scheme: linear + anomalies: &anomalies + period: month + reference: + start_year: 1981 + start_month: 1 + start_day: 1 + end_year: 2010 + end_month: 12 + end_day: 31 + standardize: false + anomalies_london: + extract_point: + latitude: 51.5074 + longitude: 0.1278 + scheme: linear + anomalies: *anomalies + +diagnostics: + diagnostic_warming_stripes: + variables: + temperature_anomalies_recent_amsterdam: + short_name: tas + preprocessor: anomalies_amsterdam + start_year: 1950 + end_year: 2014 + temperature_anomalies_20th_century_london: + short_name: tas + preprocessor: anomalies_london + start_year: 1900 + end_year: 1999 + scripts: + warming_stripes_script: + script: ~/esmvaltool_tutorial/warming_stripes.py + colormap: 'bwr' diff --git a/files/recipe_warming_stripes_periods.yml b/files/recipe_warming_stripes_periods.yml new file mode 100644 index 00000000..3215bcb1 --- /dev/null +++ b/files/recipe_warming_stripes_periods.yml @@ -0,0 +1,45 @@ +# ESMValTool +# recipe_warming_stripes_periods.yml +--- +documentation: + description: Reproducing Ed Hawkins' warming stripes visualization + authors: + - righi_mattia + +datasets: + - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn} + +preprocessors: + anomalies_amsterdam: + extract_point: + latitude: 52.379189 + longitude: 4.899431 + scheme: linear + anomalies: + period: month + reference: + start_year: 1981 + start_month: 1 + start_day: 1 + end_year: 2010 + end_month: 12 + end_day: 31 + standardize: false + +diagnostics: + diagnostic_warming_stripes: + variables: + temperature_anomalies_recent: + short_name: tas + preprocessor: anomalies_amsterdam + start_year: 1950 + end_year: 2014 + temperature_anomalies_20th_century: + short_name: tas + preprocessor: anomalies_amsterdam + start_year: 1900 + end_year: 1999 + scripts: + warming_stripes_script: + script: ~/esmvaltool_tutorial/warming_stripes.py + colormap: 'bwr' diff --git a/files/warming_stripes.py b/files/warming_stripes.py new file mode 100644 index 00000000..27afd00e --- /dev/null +++ b/files/warming_stripes.py @@ -0,0 +1,58 @@ +"""Python script that visualizes a timeseries of global temperature anomalies +in the form of the popular warming stripes figure by Ed Hawkins. +""" + +from pathlib import Path + +import iris +import matplotlib.pyplot as plt +import numpy as np + +from esmvaltool.diag_scripts.shared import run_diagnostic +from esmvaltool.diag_scripts.shared._base import get_plot_filename + + +def plot_warming_stripes(cube, name, cmap): + """Plot timeseries of global temperature as warming stripes. + + cube: iris cube of temperature anomalies with only time dimension. + """ + temperature = cube.data.data + nx = len(temperature) + x = np.arange(len(temperature)) + y = np.array([0, 1]) + temperature = np.vstack([temperature, temperature]) + + figure, axes = plt.subplots() + axes.pcolormesh(x, y, temperature, cmap=cmap, shading='auto') + axes.set_axis_off() + axes.set_title(f'Warming stripes for {name}') + return figure + + +def main(cfg): + """Compute the time average for each input dataset.""" + # Get a description of the preprocessed data that we will use as input. + input_data = cfg['input_data'].values() + + # Example of how to loop over variables/datasets in alphabetical order + for dataset in input_data: + # Load the data + input_file = dataset['filename'] + name = dataset['variable_group'] + cube = iris.load_cube(input_file) + + # Plot as warming stripes + cmap = cfg['colormap'] + fig = plot_warming_stripes(cube, name, cmap) + + # Save output + output_file = Path(input_file).stem.replace('tas', name) + output_path = get_plot_filename(output_file, cfg) + fig.savefig(output_path) + + +if __name__ == '__main__': + + with run_diagnostic() as config: + main(config) diff --git a/setup.md b/setup.md index 5913a5fd..b4818349 100644 --- a/setup.md +++ b/setup.md @@ -244,17 +244,6 @@ wget --no-clobber --input-file \ --directory-prefix $HOME/esmvaltool_tutorial/data/ ~~~ -The `dataset.urls` contains the dataset `GPCP-SG` that is a part of -[obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/) project. -To set the correct directory structure for this project, run the following command: - -~~~shell -cd $HOME/esmvaltool_tutorial/data/ -mkdir -p Tier1/GPCP-SG -mv pr_GPCP-SG_*.nc Tier1/GPCP-SG/ -~~~ - -We will learn more about this in the lesson **Configuration** in this tutorial. ## GitHub account (Advanced) From 1f3dfceda0b6540efc4e7a3ca051d1c2d00e19df Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 30 Oct 2020 16:43:43 +0100 Subject: [PATCH 446/647] Update config instructions --- _episodes/03-configuration.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 9b12739e..50166fa7 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -141,7 +141,7 @@ example configuration file. > [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) > and [CMIP6](https://esgf-node.llnl.gov/projects/cmip6). > How can we moodify the `rootpath` to make sure the data path is set correctly -> for both CMIP5 and obs4mips. +> for both CMIP5 and CMIP6? > > Note: > to get the data, check instruction in @@ -198,7 +198,7 @@ information about ``drs``, you can visit the ESMValTool documentation on > > In this lesson, we will work with data from > [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) -> and [obs4mips](https://esgf-node.llnl.gov/projects/obs4mips/). +> and [CMIP6](https://esgf-node.llnl.gov/projects/cmip6/). > How can we set the correct `drs`? > >> ## Solution @@ -209,7 +209,7 @@ information about ``drs``, you can visit the ESMValTool documentation on >>```yaml >> drs: >> CMIP5: default ->> obs4mips: default +>> CMIP6: default >>``` >> >> - Are you working with on a computer cluster like Jasmin or DKRZ? @@ -220,13 +220,13 @@ information about ``drs``, you can visit the ESMValTool documentation on >> # Site-specific entries: Jasmin >> # Uncomment the lines below to locate data on JASMIN >> drs: ->> # CMIP6: BADC +>> CMIP6: BADC >> CMIP5: BADC >> # CMIP3: BADC >> # CORDEX: BADC >> # OBS: BADC >> # OBS6: BADC ->> obs4mips: BADC +>> # obs4mips: BADC >> # ana4mips: BADC >>``` >> From 0521094208ff8eed81b7312dc122bceef9e9f4c7 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 24 Nov 2020 16:10:00 +0100 Subject: [PATCH 447/647] fix two broken links --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 854bfea8..1cc8bc66 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ multiple models. We welcome all contributions to improve the lesson! We'd like to ask you to familiarize yourself with our guide in -[CONTRIBUTING](CONTRIBUTING) and our [Code of Conduct](CODE_OF_CONDUCT). +[CONTRIBUTING](CONTRIBUTING.md) and our [Code of Conduct](CODE_OF_CONDUCT.md). ## Maintainer(s) From e6ced81db97974bcd5d3c1055924e1276903cc09 Mon Sep 17 00:00:00 2001 From: Barbara Vreede Date: Wed, 20 Jan 2021 07:29:11 +0100 Subject: [PATCH 448/647] add fix specifying python version to tutorial --- _episodes/02-installation.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 3f53b484..2fed31df 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -196,18 +196,24 @@ installed in it. > ## Common issues > -> - Installation takes long time +> - Installation takes a long time > - Downloads and compilations can take several minutes to complete, > please be patient. > - You might have bad luck and the dependencies can not be resolved at > the moment, please try again later or [raise an > issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose) +> - If `Solving environment` takes more than 10 minutes, you may need to update +> conda: `conda update -n base conda`. Another fix can be to specify +> the python version: +> ```bash +> conda create -n esmvaltool -c conda-forge -c esmvalgroup esmvaltool-python python=3.8 +> ``` > - If you have an old conda installation you could get a `UnsatisfiableError` > message. Please install a newer version of conda and try again > - Downloads fail due to company proxy, see [conda > docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to > resolve -> - On ``MacOSX``, installation only works fine for ``esmvaltool-python`` and +> - On ``MacOSX``, installation may only work for ``esmvaltool-python`` and > ``esmvaltool-ncl`` with Python 3.7. > {: .callout} From c5a4f3b0f7e0c1c90f5caf6bd0f7651d72366958 Mon Sep 17 00:00:00 2001 From: Barbara Vreede Date: Fri, 22 Jan 2021 12:08:32 +0100 Subject: [PATCH 449/647] Correct python version use for mac: 3.7 required For ESMValTool use on mac, python 3.7 is required. Installation works fine on 3.8, however. The instructions are changed to reflect this. --- _episodes/02-installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 2fed31df..a58feaf8 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -213,8 +213,8 @@ installed in it. > - Downloads fail due to company proxy, see [conda > docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to > resolve -> - On ``MacOSX``, installation may only work for ``esmvaltool-python`` and -> ``esmvaltool-ncl`` with Python 3.7. +> - On ``MacOSX``, ``esmvaltool-python`` and +> ``esmvaltool-ncl`` only work with Python 3.7. Use `python=3.7` instead of `python=3.8` in the installation code above. > {: .callout} From 00850a7f2ece4d77e589bc9ac7fad617079d7fb7 Mon Sep 17 00:00:00 2001 From: Barbara Vreede Date: Mon, 25 Jan 2021 14:25:54 +0100 Subject: [PATCH 450/647] condensed installation fix instructions --- _episodes/02-installation.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index a58feaf8..57247b22 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -203,18 +203,19 @@ installed in it. > the moment, please try again later or [raise an > issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose) > - If `Solving environment` takes more than 10 minutes, you may need to update -> conda: `conda update -n base conda`. Another fix can be to specify +> conda: `conda update -n base conda` +> - You can help conda solve the environment by specifying > the python version: > ```bash > conda create -n esmvaltool -c conda-forge -c esmvalgroup esmvaltool-python python=3.8 > ``` +> - Note that on ``MacOSX``, ``esmvaltool-python`` and +> ``esmvaltool-ncl`` only work with Python 3.7. Use `python=3.7` instead of `python=3.8`. > - If you have an old conda installation you could get a `UnsatisfiableError` > message. Please install a newer version of conda and try again > - Downloads fail due to company proxy, see [conda > docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to -> resolve -> - On ``MacOSX``, ``esmvaltool-python`` and -> ``esmvaltool-ncl`` only work with Python 3.7. Use `python=3.7` instead of `python=3.8` in the installation code above. +> resolve. > {: .callout} From 00c59e0af06c0fab075ec7099c7cd2270f6b470a Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 9 Feb 2021 13:02:22 +0100 Subject: [PATCH 451/647] initial outline --- _episodes/09-cmorization.md | 77 +++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 _episodes/09-cmorization.md diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md new file mode 100644 index 00000000..e66dec2b --- /dev/null +++ b/_episodes/09-cmorization.md @@ -0,0 +1,77 @@ +--- +title: "CMORization: Using observational datasets" +teaching: 15 +exercises: 45 + +questions: +- "What is so challenging about observational data?" +- "How do I use observational datasets in ESMValTool?" +- "How add support for new (observational) datasets?" + +objectives: +- "Understand what CMORization is and why it is necessary." +- "Learn how to write a new CMORizer script." + +keypoints: +- "CMORizers are dataset-specific scripts that can be run once to generate CMOR-compliant data." +- "ESMValTool comes with a set of CMORizers readily available, but you can also add your own." +--- + +## Introduction + +Include some theory and a nice explanatory figure. Point to the +[documentation](https://docs.esmvaltool.org/en/latest/input.html#observations) + +In this lesson, we will re-implement a CMORizer script for .... (include +interesting datasets). We will go through all the steps and explain relevant topics as we go. + +## 1. Check if your variable is CMOR standard + +## 2. Edit your configuration file + +## 3. Store your dataset in the right place + +## 4. Create a CMORizer for the dataset + +ESMValTool can work with CMORizer script written in various programming languages. In the tutorial we will implement our CMORizer script in Python, but the steps would be the same for any other language. + +## 5. Run the CMORizer script + +## 6. Naming convention of the observational data files + +This is quite theoretical. Maybe it should come earlier on in the tutorial? + +## 7. Test the CMORized dataset + +## Conclusion + + +## For development purposes + +Here are some of the elements that we can add + +> ## Example exercise +> +> This is just a reminder on how to implement exercises +> +> > ## Example answer +> > +> > And this is where to add the answer. +> > This box will be collapsed in the page is first loaded. +> > +> {: .solution} +{: .challenge} + +```bash +example command line instruction +``` + +``` +example error message +``` +{: .error} + +> ## Example callout box +> +> This is how to create a callout box +{: .callout} From 01e5e832f66e86ee52e7a6eb704d1de5872f5ee9 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 9 Feb 2021 14:12:59 +0100 Subject: [PATCH 452/647] use ACTIONS_ALLOW_UNSECURE_COMMANDS for ruby --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07c7d702..f9b43034 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,8 @@ jobs: - uses: actions/checkout@v2 - name: Setup Ruby uses: ruby/setup-ruby@v1.38.0 + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: true with: ruby-version: 2.7 - name: Cache Ruby deps From 3d02c70a9e506768f99c5963be173b83f6b3a6dc Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 9 Feb 2021 14:24:05 +0100 Subject: [PATCH 453/647] replace goanpeca with conda-incubator ad upgrade to v2 --- .github/workflows/recipes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 92c2c6d4..d2fc1997 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -17,7 +17,7 @@ jobs: with: path: ~/conda_pkgs_dir key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('files/recipe_example.yml') }} - - uses: goanpeca/setup-miniconda@v1 + - uses: conda-incubator/setup-miniconda@v2 - name: Install esmvaltool run: conda install -n test -y -c esmvalgroup -c conda-forge esmvaltool-python - name: Setup config From ad7cea5f49bfb74daab38ac32c2b5e6502bf4427 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Tue, 9 Feb 2021 15:37:42 +0100 Subject: [PATCH 454/647] Update 09-cmorization.md Copying the pieces of information from the documentation to here. --- _episodes/09-cmorization.md | 188 ++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index e66dec2b..60eae5b8 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -27,22 +27,210 @@ interesting datasets). We will go through all the steps and explain relevant top ## 1. Check if your variable is CMOR standard +Most variables are defined in the CMIP data request and can be found in the +CMOR tables in the folder `/esmvalcore/cmor/tables/cmip6/Tables/ +`, +differentiated according to the ``MIP`` they belong to. The tables are a +copy of the `PCMDI ` guidelines. If you find the +variable in one of these tables, you can proceed to the next section. + +If your variable is not available in the standard CMOR tables, +you need to write a custom CMOR table entry for the variable +as outlined below and add it to `/esmvalcore/cmor/tables/custom/ +`. + +To create a new custom CMOR table you need to follow these +guidelines: + +- Provide the ``variable_entry``; +- Provide the ``modeling_realm``; +- Provide the variable attributes, but leave ``standard_name`` blank. Necessary + variable attributes are: ``units``, ``cell_methods``, ``cell_measures``, + ``long_name``, ``comment``. +- Provide some additional variable attributes. Necessary additional variable + attributes are: ``dimensions``, ``out_name``, ``type``. There are also + additional variable attributes that can be defined here (see the already + available cmorizers). + +It is recommended to use an existing custom table as a template, to edit the +content and save it as ``CMOR_.dat``. + ## 2. Edit your configuration file +Make sure that beside the paths to the model simulations and observations, also +the path to raw observational data to be cmorized (``RAWOBS``) is present in +your configuration file. + ## 3. Store your dataset in the right place +The folder ``RAWOBS`` needs the subdirectories ``Tier1``, ``Tier2`` and +``Tier3``. The different tiers describe the different levels of restrictions +for downloading (e.g. providing contact information, licence agreements) +and using the observations. The unformatted (raw) observations +should then be stored then in the appropriate of these three folders. + ## 4. Create a CMORizer for the dataset ESMValTool can work with CMORizer script written in various programming languages. In the tutorial we will implement our CMORizer script in Python, but the steps would be the same for any other language. +Our example of a cmorizing script here is written for the ``MTE`` dataset +that is available at the MPI for Biogeochemistry in Jena: `cmorize_obs_mte.py +`. +It provides data about the Gross Primary Production (GPP). + +All the necessary information about the dataset to write the filename +correctly, and which variable is of interest, is stored in a seperate +configuration file: `MTE.yml +` +in the directory ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/``. Note +that the name of this configuration file has to be identical to the name of +your data set. It is recommended that you set ``project`` to ``OBS6`` in the +configuration file. That way, the variables defined in the CMIP6 CMOR table, +augmented with the custom variables described above, are available to your script. + +The first part of this configuration file defines the filename of the raw +observations file. The second part defines the common global attributes for +the cmorizer output, e.g. information that is needed to piece together the +final observations file name in the correct structure (see Section `6. Naming convention of the observational data files`). +Another global attribute is ``reference`` which includes a ``doi`` related to the dataset. +Please see the section `adding references +` +on how to add reference tags to the ``reference`` section in the configuration file. +If a single dataset has more than one reference, +it is possible to add tags as a list e.g. ``reference: ['tag1', 'tag2']``. +The third part in the configuration file defines the variables that are supposed to be cmorized. + +The actual cmorizing script ``cmorize_obs_mte.py`` consists of a header with +information on where and how to download the data, and noting the last access +of the data webpage. + +The main body of the CMORizer script must contain a function called + +```python +def cmorization(in_dir, out_dir, cfg, config_user): +``` + +with this exact call signature. Here, ``in_dir`` corresponds to the input +directory of the raw files, ``out_dir`` to the output directory of final +reformatted data set and ``cfg`` to the configuration dictionary given by +the ``.yml`` configuration file. The return value of this function is ignored. All +the work, i.e. loading of the raw files, processing them and saving the final +output, has to be performed inside its body. To simplify this process, ESMValTool +provides a set of predefined utilities.py_, which can be imported into your CMORizer +by + +```python +from . import utilities as utils +``` + +Apart from a function to easily save data, this module contains different kinds +of small fixes to the data attributes, coordinates, and metadata which are +necessary for the data field to be CMOR-compliant. + +Note that this specific CMORizer script contains several subroutines in order +to make the code clearer and more readable (we strongly recommend to follow +that code style). For example, the function ``_get_filepath`` converts the raw +filepath to the correct one and the function ``_extract_variable`` extracts and +saves a single variable from the raw data. + +.. utilities.py: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/utilities.py + + ## 5. Run the CMORizer script +The cmorizing script for the given dataset can be run with: + +```bash +cmorize_obs -c -o +``` + +> ## Note +> +> The output path given in the configuration file is the path where +> your cmorized dataset will be stored. The ESMValTool will create a folder +> with the correct tier information (see Section `2. Edit your configuration file`) if that tier folder is not +> already available, and then a folder named after the data set. In this +> folder the cmorized data set will be stored as a netCDF file. +{: .callout} + +If your run was successful, one or more NetCDF files are produced in your +output directory. + +> ## Check that your cmoriziation was successful +> +> Check your output directory for the freshly produced NetCDF file. +> +> > ## Answers +> > +> > Write the answer here. +> > +> {: .solution} +{: .challenge} + + ## 6. Naming convention of the observational data files This is quite theoretical. Maybe it should come earlier on in the tutorial? +For the ESMValTool to be able to read the observations from the NetCDF file, +the file name needs a very specific structure and order of information parts +(very similar to the naming convention for observations in ESMValTool +v1.0). The file name will be automatically correctly created if a cmorizing +script has been used to create the netCDF file. + +The correct structure of an observational data set is defined in +`config-developer.yml +`, +and looks like the following: + +```bash +OBS_[dataset]_[type]_[version]_[mip]_[short_name]_YYYYMM-YYYYMM.nc +``` + +For the example of the ``CDS-XCH4`` data set, the correct structure of the +file name looks then like this: + +```bash +OBS_CDS-XCH4_sat_L3_Amon_xch4_200301-201612.nc +``` + +The different parts of the name are explained in more detail here: + +- OBS: describes what kind of data can be expected in the file, in this case + ``observations``; +- CDS-XCH4: that is the name of the dataset. It has been named this way for + illustration purposes (so that everybody understands it is the xch4 dataset + downloaded from the CDS), but a better name would indeed be ``ESACCI-XCH4`` + since it is a ESA-CCI dataset; +- sat: describes the source of the data, here we are looking at satellite data + (therefore ``sat``), could also be ``reanaly`` for reanalyses; +- L3: describes the version of the dataset: +- Amon: is the information in which ``mip`` the variable is to be expected, and + what kind of temporal resolution it has; here we expect ``xch4`` to be part + of the atmosphere (``A``) and we have the dataset in a monthly resolution + (``mon``); +- xch4: Is the name of the variable. Each observational data file is supposed + to only include one variable per file; +- 200301-201612: Is the period the dataset spans with ``200301`` being the + start year and month, and ``201612`` being the end year and month; + +> ## Note +> +> There is a different naming convention for ``obs4mips`` data (see the exact +> specifications for the obs4mips data file naming convention in the +> ``config-developer.yml`` file). +{: .callout} + ## 7. Test the CMORized dataset +To verify that the cmorized data file is indeed correctly formatted, you can +run a dedicated test recipe, that does not include any diagnostic, but only +reads in the data file and has it processed in the preprocessor. Such a recipe +is called ``recipes/examples/recipe_check_obs.yml``. You just need to add a +diagnostic for your dataset following the existing entries. +Only the diagnostic of interest needs to be run, the others should be commented +out for testing. + ## Conclusion From d99514545d86275b98eb564b8f8857e5e3839627 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 9 Feb 2021 15:56:02 +0100 Subject: [PATCH 455/647] add python and miniconda-version to speed up esmvaltool installation --- .github/workflows/recipes.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index d2fc1997..8cf81092 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -18,6 +18,9 @@ jobs: path: ~/conda_pkgs_dir key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('files/recipe_example.yml') }} - uses: conda-incubator/setup-miniconda@v2 + with: + python-version: "3.8" + miniconda-version: "latest" - name: Install esmvaltool run: conda install -n test -y -c esmvalgroup -c conda-forge esmvaltool-python - name: Setup config From bd6bbc28c8294f9ca72e85dce3e53672caa7c468 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Tue, 9 Feb 2021 16:31:45 +0100 Subject: [PATCH 456/647] Update 09-cmorization.md Starting to adjust the available text to suit the tutorial. Started with bullet point 1 "Check if your variable is following the CMOR standard" --- _episodes/09-cmorization.md | 68 +++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 60eae5b8..807bf1d9 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -22,22 +22,44 @@ keypoints: Include some theory and a nice explanatory figure. Point to the [documentation](https://docs.esmvaltool.org/en/latest/input.html#observations) -In this lesson, we will re-implement a CMORizer script for .... (include -interesting datasets). We will go through all the steps and explain relevant topics as we go. +In this lesson, we will re-implement a CMORizer script for the MTE dataset that contains observations of the Gross Primary Production (GPP), a variable that is important for calculting components of the carbon cycle. We will go through all the steps and explain relevant topics as we go. -## 1. Check if your variable is CMOR standard +## 1. Check if your variable is following the CMOR standard -Most variables are defined in the CMIP data request and can be found in the -CMOR tables in the folder `/esmvalcore/cmor/tables/cmip6/Tables/ -`, +The very first step we have to do is to check if your data file follows the CMOR standard. Only data files that fully follow this standard can be read by the ESMValTool. + +> ## What is the CMOR standard? +> +> Describe the CMOR standard here. +{: .callout} + +Most variables that we would want to use with the ESMValTool are defined in the Coupled Model Intercomparison Project (CMIP) data request and can be found in the +CMOR tables in the folder ``, differentiated according to the ``MIP`` they belong to. The tables are a -copy of the `PCMDI ` guidelines. If you find the -variable in one of these tables, you can proceed to the next section. +copy of the `PCMDI ` guidelines. + +> ## Find the variable "gpp" in a CMOR table +> +> Check the available CMOR tables to find the variable ``gpp`` with the following characteristics: +> - standard_name: ``gross_primary_productivity_of_biomass_expressed_as_carbon`` +> - frequency: ``mon`` +> - modeling_realm: ``land`` +> +> > ## Answers +> > +> > The variable ``gpp``belongs to the land variables. The temporal resolution that we are looking for is ``monthly``. +> > This information points to the "Lmon" CMIP table. And indeed, the variable ``gpp`` can be found in the file +> > ``. +> > +> {: .solution} +{: .challenge} -If your variable is not available in the standard CMOR tables, -you need to write a custom CMOR table entry for the variable -as outlined below and add it to `/esmvalcore/cmor/tables/custom/ -`. + +If the variable you are interested in is not available in the standard CMOR tables, +you need to write a custom CMOR table entry for the variable. Don't worry! It sounds more complicated than it is! +Examples of custom CMOR table entries are for example the standard error of a specific variable. +For our variable ``gpp`` there is indeed no CMOR definition for the standard error, therefore ``gppStderr`` was defined in the custom CMOR table here: +``, as ``CMOR_gppStderr.dat``. To create a new custom CMOR table you need to follow these guidelines: @@ -52,8 +74,26 @@ guidelines: additional variable attributes that can be defined here (see the already available cmorizers). -It is recommended to use an existing custom table as a template, to edit the -content and save it as ``CMOR_.dat``. +It is easiest to start a new custom CMOR table by using an existing custom table as a template. +You can then edit the content and save it as ``CMOR_.dat``. + +> ## Does the variable ``xxx`` need a costum CMOR table? +> +> Check the available CMOR tables to find the variable ``xxx`` with the following characteristics: +> - standard_name: ``xxx`` +> - frequency: ``we will see`` +> - modeling_realm: ``we will see`` +> +> If it is not available, create a custom CMOR table following the template of the +> custom CMOR table of ``yyy`` + +> > ## Answers +> > +> > The answer depends on the variable that I will come up with. +> > +> {: .solution} +{: .challenge} + ## 2. Edit your configuration file From f43f1d223af52402f1b8d06a17844a2abfe0ee16 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 9 Feb 2021 17:47:35 +0100 Subject: [PATCH 457/647] Skeleten for filling the episode with content --- _episodes/10-diagnostics.md | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 _episodes/10-diagnostics.md diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md new file mode 100644 index 00000000..16d315de --- /dev/null +++ b/_episodes/10-diagnostics.md @@ -0,0 +1,58 @@ +--- +title: "Writing your own diagnostic script" +teaching: 15 +exercises: 45 + +questions: +- "Question 1" +- "Question 2 etc" + +objectives: +- "Objective 1" +- "Obj 2" + +keypoints: +- "Take home message 1" +- "etc ..." +--- + +## Introduction + +This is where the main text comes + +## Another section + +and some more text, etc. + +## Conclusion + + +## For development purposes + +Here are some of the elements that we can add + +> ## Example exercise +> +> This is just a reminder on how to implement exercises +> +> > ## Example answer +> > +> > And this is where to add the answer. +> > This box will be collapsed in the page is first loaded. +> > +> {: .solution} +{: .challenge} + +```bash +example command line instruction +``` + +``` +example error message +``` +{: .error} + +> ## Example callout box +> +> This is how to create a callout box +{: .callout} From fade330e37b4d80c1c06ee0123fca0940886cd85 Mon Sep 17 00:00:00 2001 From: Barbara Vreede Date: Tue, 9 Feb 2021 21:13:52 +0100 Subject: [PATCH 458/647] make environment platform independent (#184) --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index 843216a3..c8ce8bdf 100644 --- a/environment.yml +++ b/environment.yml @@ -2,7 +2,7 @@ name: esmvaltool_tutorial channels: - conda-forge dependencies: - - gxx_linux-64 - python=3 + - compilers - rb-nokogiri - ruby From f471f66d01f0d83b776d2f4daee16bcd07a7e6bf Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Wed, 10 Feb 2021 14:18:20 +0100 Subject: [PATCH 459/647] Update .github/workflows/ci.yml Co-authored-by: Stef Smeets --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f9b43034..da9e00c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Setup Ruby - uses: ruby/setup-ruby@v1.38.0 + uses: ruby/setup-ruby@v1.64.1 env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true with: From 84ca8aff9d1b4c16161f69646353bbac8787a559 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 10 Feb 2021 14:20:41 +0100 Subject: [PATCH 460/647] remove ACTIONS_ALLOW_UNSECURE_COMMANDS to see if it works with upgraded ruby/setup-ruby --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da9e00c2..e870c419 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,8 +11,6 @@ jobs: - uses: actions/checkout@v2 - name: Setup Ruby uses: ruby/setup-ruby@v1.64.1 - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: true with: ruby-version: 2.7 - name: Cache Ruby deps From 54ee105cca46324eb95adcc3dfbd5980164f3f43 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Wed, 10 Feb 2021 14:57:26 +0100 Subject: [PATCH 461/647] Add test recipe section --- _episodes/09-cmorization.md | 95 ++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 13 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 807bf1d9..30125b29 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -36,7 +36,7 @@ The very first step we have to do is to check if your data file follows the CMOR Most variables that we would want to use with the ESMValTool are defined in the Coupled Model Intercomparison Project (CMIP) data request and can be found in the CMOR tables in the folder ``, differentiated according to the ``MIP`` they belong to. The tables are a -copy of the `PCMDI ` guidelines. +copy of the `PCMDI ` guidelines. > ## Find the variable "gpp" in a CMOR table > @@ -47,8 +47,8 @@ copy of the `PCMDI ` guidelines. > > > ## Answers > > -> > The variable ``gpp``belongs to the land variables. The temporal resolution that we are looking for is ``monthly``. -> > This information points to the "Lmon" CMIP table. And indeed, the variable ``gpp`` can be found in the file +> > The variable ``gpp``belongs to the land variables. The temporal resolution that we are looking for is ``monthly``. +> > This information points to the "Lmon" CMIP table. And indeed, the variable ``gpp`` can be found in the file > > ``. > > > {: .solution} @@ -74,7 +74,7 @@ guidelines: additional variable attributes that can be defined here (see the already available cmorizers). -It is easiest to start a new custom CMOR table by using an existing custom table as a template. +It is easiest to start a new custom CMOR table by using an existing custom table as a template. You can then edit the content and save it as ``CMOR_.dat``. > ## Does the variable ``xxx`` need a costum CMOR table? @@ -84,7 +84,7 @@ You can then edit the content and save it as ``CMOR_.dat``. > - frequency: ``we will see`` > - modeling_realm: ``we will see`` > -> If it is not available, create a custom CMOR table following the template of the +> If it is not available, create a custom CMOR table following the template of the > custom CMOR table of ``yyy`` > > ## Answers @@ -261,15 +261,84 @@ The different parts of the name are explained in more detail here: > ``config-developer.yml`` file). {: .callout} -## 7. Test the CMORized dataset +## 7. Make a test recipe -To verify that the cmorized data file is indeed correctly formatted, you can -run a dedicated test recipe, that does not include any diagnostic, but only -reads in the data file and has it processed in the preprocessor. Such a recipe -is called ``recipes/examples/recipe_check_obs.yml``. You just need to add a -diagnostic for your dataset following the existing entries. -Only the diagnostic of interest needs to be run, the others should be commented -out for testing. +Let's start with the end goal: we want to be able to run a recipe that is able +to load our data. So we will make this recipe and try to run it. It will +probably fail, but that's okay. As you will see, the error messages will come in +handy. Moreover, the recipe will serve as a test case. Once we get it to run, we +know we have completed our task. + +> ## Create a test recipe +> +> Create a simple recipe that loads the fluxnet data. It should include a +> datasets section with a single entry for the fluxnet dataset with the correct +> dataset keys, and a diagnostics section with two variables: gpp and gppStderr. +> We won't need any preprocessors or scripts (set `scripts: null`), but you will +> have to add a documentation section with a description, authors and +> maintainer, otherwise the recipe will fail. +> +> > ## Answer +> > +> > Here's an example recipe +> > +> > ```yaml +> > documentation: +> > +> > description: Test recipe for fluxnet data +> > +> > authors: +> > - kalverla_peter +> > +> > maintainer: +> > - kalverla_peter +> > +> > datasets: +> > - {project: OBS6, dataset: fluxnet, mip: Lmon, tier: 3, start_year: 2010, end_year: 2015, type: reanaly, version: latestversion} +> > +> > diagnostics: +> > fluxnet: +> > description: Check that ESMValTool can load the cmorized fluxnet data without errors. +> > variables: +> > gpp: +> > gppStderr: +> > scripts: null +> > +> > ``` +> > +> > Note: a recipe similar to this one is available under +> > `~/path/to/ESMValTool/esmvaltool/recipes/examples/recipe_check_obs.yml`. +> > That recipe includes checks all datasets for which CMORizers are available. +> > +> {: .solution} +{: .challenge} + +Try to run the example recipe with + +```bash +esmvaltool run recipe_check_fluxnet.yml --log_level debug +``` + +The `log_level` flag ensures that all relevant information is included in the +output. We will need this information to find out what needs to be done. Look +carefully through the log messages. You'll probably find something like + +``` +DEBUG Retrieving OBS6 configuration +DEBUG Skipping non-existent /home/peter/default_inputpath/Tier3/fluxnet +DEBUG Looking for files matching ['OBS6_fluxnet_reanaly_latestversion_Lmon_gppStderr[_.]*nc'] in [] +ERROR No input files found for variable {'variable_group': 'gppStderr' ... +... +ERROR Missing data for preprocessor fluxnet/gppStderr +... +ERROR Program terminated abnormally, see stack trace below for more information: +... +``` +{: .error} + +So the output tells us that it cannot find the data, and also where it has been +looking. This makes sense, as we have not yet created a CMORized copy of the data. +But it is always useful to know where ESMValTool will look for it later on. ## Conclusion From d03c926e28906bd24c3fbef17e7a8943ded0ef62 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Thu, 11 Feb 2021 15:05:34 +0100 Subject: [PATCH 462/647] Update 09-cmorization.md Adding more info to the example in bullet point 1. --- _episodes/09-cmorization.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 30125b29..07dbb0f2 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -77,12 +77,12 @@ guidelines: It is easiest to start a new custom CMOR table by using an existing custom table as a template. You can then edit the content and save it as ``CMOR_.dat``. -> ## Does the variable ``xxx`` need a costum CMOR table? +> ## Does the variable ``cVegStderr`` need a costum CMOR table? > -> Check the available CMOR tables to find the variable ``xxx`` with the following characteristics: -> - standard_name: ``xxx`` -> - frequency: ``we will see`` -> - modeling_realm: ``we will see`` +> Check the available CMOR tables to find the variable ``cVegStderr`` with the following characteristics: +> - standard_name: ``vegetation_carbon_content`` +> - frequency: ``mon`` +> - modeling_realm: ``land`` > > If it is not available, create a custom CMOR table following the template of the > custom CMOR table of ``yyy`` From 599af924d6609bd22c77a4fb800ab3a980d5bb48 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 11 Feb 2021 16:31:39 +0100 Subject: [PATCH 463/647] Add figure with some explanation --- _episodes/09-cmorization.md | 61 +++++++++++++++++++++++++++++++----- fig/data_flow.png | Bin 0 -> 84827 bytes 2 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 fig/data_flow.png diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 07dbb0f2..ed8ada8c 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -19,20 +19,63 @@ keypoints: ## Introduction -Include some theory and a nice explanatory figure. Point to the -[documentation](https://docs.esmvaltool.org/en/latest/input.html#observations) +This episode deals with "CMORization". ESMValTool was designed to work with data +that follow the CMOR standards. Unfortunately, not all datasets follow these +standards. In order to use such datasets in ESMValTool we first need to reformat +the data. This process is called "CMORization". + +> ## What are the CMOR standards? +> +> The name "CMOR" originates from a tool: [the Climate Model Output +> Rewriter](https://cmor.llnl.gov/). This tool is used to create "CF-Compliant +> netCDF files for use in the CMIP projects". So CMOR extends the +> [CF-standard](https://cfconventions.org/) with additional requirements for +> the Coupled Model Intercomparison Projects (see e.g. +> [here](https://pcmdi.llnl.gov/CMIP6/Guide/modelers.html#5-model-output-requirements)). +> +> +> Concretely, the CMOR standards dictate e.g. the variable names and units, +coordinate information, how the data should be structured (e.g. 1 variable per +file), additional metadata requirements, but also file naming conventions a.k.a. +the data reference syntax (DRS). All this information is stored in so-called +CMOR tables. As example, the CMOR tables for the CMIP6 project can be found +[here](https://github.com/PCMDI/cmip6-cmor-tables). +{: .callout} -In this lesson, we will re-implement a CMORizer script for the MTE dataset that contains observations of the Gross Primary Production (GPP), a variable that is important for calculting components of the carbon cycle. We will go through all the steps and explain relevant topics as we go. +The Earth System Grid Federation (ESGF) is home to all CMIP data. The data +hosted there typically (mostly) follow the CMIP standards, and therefore +ESMValTool should work with these data without problems. + +Datasets that are *not* part of one of the CMIP projects often don't follow the +CMOR standards. In this case, a reformatting script can be used to create a +CMOR-compliant copy of these datasets. CMORizer scripts for several popular +datasets are included in ESMValTool, and ESMValTool also provides a convenient +way to execute them. + +Occasionally it happens that there are still minor issue with CMIP datasets. In +those cases, it is possible to fix those issues in ESMValCore before any further +processing is done. The same can be done for non-CMIP data. The advantage is +that you don't need to store an additional, reformatted copy of the data. The +disadvantage is that these fixes should be implemented inside ESMValCore. +Writing a CMORizer script is technically is simpler. + +The concepts discussed so far are illustrated in the figure below. +![Data flow with ESMValTool](../fig/data_flow.png) +*Illustration of the data flow in ESMValTool.* + +In this lesson, we will re-implement a CMORizer script for the MTE dataset that +contains observations of the Gross Primary Production (GPP), a variable that is +important for calculating components of the carbon cycle. We will go through all +the steps and explain relevant topics as we go. If you prefer to implement CMOR +fixes, please read the documentation +[here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/develop/fixing_data.html#fixing-data). +While fixes are implemented slightly differently, conceptually the process is +the same and the concepts explained in this episode are still useful. ## 1. Check if your variable is following the CMOR standard The very first step we have to do is to check if your data file follows the CMOR standard. Only data files that fully follow this standard can be read by the ESMValTool. -> ## What is the CMOR standard? -> -> Describe the CMOR standard here. -{: .callout} - Most variables that we would want to use with the ESMValTool are defined in the Coupled Model Intercomparison Project (CMIP) data request and can be found in the CMOR tables in the folder ``, differentiated according to the ``MIP`` they belong to. The tables are a @@ -343,6 +386,8 @@ But it is always useful to know where ESMValTool will look for it later on. ## Conclusion +[documentation](https://docs.esmvaltool.org/en/latest/input.html#observations) + ## For development purposes Here are some of the elements that we can add diff --git a/fig/data_flow.png b/fig/data_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..f441530cb86b0ca4ab3afb0eb32db627d1656eb6 GIT binary patch literal 84827 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 X+^#mg%yc}D3H@WxmZ$5DJmUWcd Date: Thu, 11 Feb 2021 16:43:44 +0100 Subject: [PATCH 464/647] Update 09-cmorization.md Updating Section 1 with the example, working through section 2 and 3 to modify textflow and description. --- _episodes/09-cmorization.md | 128 +++++++++++++++++++++++++++++++----- 1 file changed, 111 insertions(+), 17 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index ed8ada8c..9fe23872 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -63,9 +63,9 @@ The concepts discussed so far are illustrated in the figure below. ![Data flow with ESMValTool](../fig/data_flow.png) *Illustration of the data flow in ESMValTool.* -In this lesson, we will re-implement a CMORizer script for the MTE dataset that +In this lesson, we will re-implement a CMORizer script for the FLUXCOM dataset that contains observations of the Gross Primary Production (GPP), a variable that is -important for calculating components of the carbon cycle. We will go through all +important for calculating components of the global carbon cycle. We will go through all the steps and explain relevant topics as we go. If you prefer to implement CMOR fixes, please read the documentation [here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/develop/fixing_data.html#fixing-data). @@ -122,35 +122,129 @@ You can then edit the content and save it as ``CMOR_.dat``. > ## Does the variable ``cVegStderr`` need a costum CMOR table? > -> Check the available CMOR tables to find the variable ``cVegStderr`` with the following characteristics: +> Check the available CMOR tables to find the variable ``cVegStderr`` with the +> following characteristics: > - standard_name: ``vegetation_carbon_content`` > - frequency: ``mon`` > - modeling_realm: ``land`` > -> If it is not available, create a custom CMOR table following the template of the -> custom CMOR table of ``yyy`` - +> If it is not available, create a custom CMOR table following the template of +> the CMIP6 CMOR table of ``cVeg`` and custom CMOR table of ``gppStderr``. +> > > ## Answers > > -> > The answer depends on the variable that I will come up with. +> > The first step here is to check if the variable ``cVegStderr`` is already +> > listed in a CMOR table. We have the information that the modeling_realm +> > of the variable is ``land`` and that the frequency is ``mon``. This +> > means we have to check the CMOR table ``Lmon`` for an entry. We focus +> > our search on the CMIP6 tables since these are the most recent tables +> > available. You can find the lists here: +> > `` +> > +> > We do not find the variable ``cVegStderr`` in the ``Lmon`` table, which +> > means we will have to write our own custom table for this. +> > There were two examples given which we could use as templates for the +> > new custom table that we have to create. These two examples can be +> > found here: [cVeg](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/cmip6/Tables/CMIP6_Lmon.json) +> > and [gppStderr](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/custom/CMOR_gppStderr.dat) +> > +> > We have to create a new file with the name ``CMOR_cVegStrerr.dat`` in +> > the custom CMOR table folder (https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/custom/). +> > The content of the file should then look like this: > > +> > ``` +> > SOURCE: CMIP6 +> > !============ +> > variable_entry: cVegStderr +> > !============ +> > modeling_realm: land +> > !---------------------------------- +> > ! Variable attributes: +> > !---------------------------------- +> > standard_name: +> > units: kg m-2 +> > cell_methods: area: mean where land time: mean +> > cell_measures: area: areacella +> > long_name: Carbon Mass in Vegetation Error +> > !---------------------------------- +> > ! Additional variable information: +> > !---------------------------------- +> > dimensions: longitude latitude time +> > out_name: cVegStderr +> > type: real +> > !---------------------------------- +> > ! +> > ``` +> > +> > Note that there is no entry for ``standard_name``. This is on purpose. +> > It is a sign for the ESMValTool to not crash although the variable that +> > we are looking for is ok to have no official CMIP6 ``standard_name``. > {: .solution} {: .challenge} -## 2. Edit your configuration file +## 2. Store your dataset in the right place -Make sure that beside the paths to the model simulations and observations, also -the path to raw observational data to be cmorized (``RAWOBS``) is present in -your configuration file. +Now that we have made sure that we have a CMOR definition of our variable +the next step in writing our own cmorizer script is to make sure that the +ESMValTool will be able to find our data file that we want to use. Since +it is not cmorized yet, it cannot be stored in the regular observations +and reanalysis data folders. For that purpose it is great to create a +``RAWOBS`` folder in which you would store all non-cmorized data files. +This folder needs the same sub-folder structure as the OBS folder we already +know. In our case of the ``FLUXCOM`` data, we need a sub-folder called +``Tier3`` in the folder ``RAWOBS`` and then a sub-folder called ``FLUXCOM`` +in the sub-folder ``Tier3``. + +> ## What is the deal with those ``tiers``? +> +> Many observations and reanalysis datasets are restricted in their access. +> This is due to the huge amount of work that goes into creating these datasets +> and the fact that the dataset creators feel a responisbility about what their +> dataset is used for. In many cases "restricted access" just means that one +> has to register with an email address and is adivsed to achnowledge the data +> providers in scientific publications. After that one is free to download the +> data without any other hurdles. +> +> However, there are also datasets available that do not need a registration +> for access, e.g. the "obs4MIPs" or "ana4MIPs" datasets that are specifically +> produced to facilitate comparisons with model simulations. +> +> To reflect these different levels of access restriction, the ESMValTool team +> has created a tier-system with which the different observations and +> reanalysis datasets are described. The definition of the different tiers are +> as follows: +> - Tier1: obs4MIPs and ana4MIPS datasets (they do not need any additional +> cmorization before they can be used with the ESMValTool) +> - Tier2: any other freely available datasets (most of them will need some +> kind of cmorization before they can be used with the ESMValTool) +> - Tier3: any datasets that has an access restriction, meaning someone has to +> register to access the data (most of these datasets will also need some kind +> of cmorization before they can be used with the ESMValTool) +> +> The access restrictions are also the reason why it is not possible to +> providers the ESMValTool routinely during the installation with all +> observations and reanalysis data that are used in all example recipes. +> However, the cmorization scripts for these datasets are provided with the +> ESMValTool so that each user can cmorize their own copy of the access +> restricted datasets if they need them. +> +{: .callout} -## 3. Store your dataset in the right place -The folder ``RAWOBS`` needs the subdirectories ``Tier1``, ``Tier2`` and -``Tier3``. The different tiers describe the different levels of restrictions -for downloading (e.g. providing contact information, licence agreements) -and using the observations. The unformatted (raw) observations -should then be stored then in the appropriate of these three folders. +## 3. Edit your configuration file + +The next step then is to make sure that the ESMValTool will find the +``FLUXCOM`` data in the ``RAWOBS`` folder when it is running the cmorizing +script. For this to happen we have to specify the path to the ``RAWOBS`` +folder in our configuration file. In the same way as the path to the ``OBS`` +folder is defined, we define there our path to the ``RAWOBS`` folder: + +```yaml +rootpath: + OBS: /path/to/my/obs/data + RAWOBS: /path/to/my/rawobs/data +``` ## 4. Create a CMORizer for the dataset From 91a0bcde38f2f96005861664fd6243b2cfba4618 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Thu, 11 Feb 2021 16:47:22 +0100 Subject: [PATCH 465/647] Update 09-cmorization.md --- _episodes/09-cmorization.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 9fe23872..da77925c 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -179,6 +179,7 @@ You can then edit the content and save it as ``CMOR_.dat``. > > Note that there is no entry for ``standard_name``. This is on purpose. > > It is a sign for the ESMValTool to not crash although the variable that > > we are looking for is ok to have no official CMIP6 ``standard_name``. +> > > {: .solution} {: .challenge} From 824ae9555eb28528afefc208c5dc6f4a324960f7 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Thu, 11 Feb 2021 17:27:29 +0100 Subject: [PATCH 466/647] Update 09-cmorization.md Changing some of the order of the parts in the episode, and working on section 4 and 5. --- _episodes/09-cmorization.md | 183 +++++++++++++++++++++--------------- 1 file changed, 108 insertions(+), 75 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index da77925c..8a1cd022 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -247,36 +247,122 @@ rootpath: RAWOBS: /path/to/my/rawobs/data ``` -## 4. Create a CMORizer for the dataset +## 4. Naming convention of the observational data files -ESMValTool can work with CMORizer script written in various programming languages. In the tutorial we will implement our CMORizer script in Python, but the steps would be the same for any other language. +For the ESMValTool to be able to read the observations from the NetCDF file, +the file name needs a very specific structure and order of information parts. +The file name will be automatically correctly created if a cmorizing +script has been used to create the netCDF file. -Our example of a cmorizing script here is written for the ``MTE`` dataset -that is available at the MPI for Biogeochemistry in Jena: `cmorize_obs_mte.py -`. -It provides data about the Gross Primary Production (GPP). +The correct structure of an observational data set is defined in +[config-developer.yml] +(https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-developer.yml), +and looks like the following: -All the necessary information about the dataset to write the filename -correctly, and which variable is of interest, is stored in a seperate -configuration file: `MTE.yml -` -in the directory ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/``. Note -that the name of this configuration file has to be identical to the name of -your data set. It is recommended that you set ``project`` to ``OBS6`` in the -configuration file. That way, the variables defined in the CMIP6 CMOR table, -augmented with the custom variables described above, are available to your script. +```bash +OBS_[dataset]_[type]_[version]_[mip]_[short_name]_YYYYMM-YYYYMM.nc +``` + +For the example of the ``FLUXCOM`` data set, the correct structure of the +file name looks then like this: + +```bash +OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012.nc +``` + +The different parts of the name are explained in more detail here: + +- OBS: describes what kind of data can be expected in the file, in this case + ``observations``; +- FLUXCOM: that is the name of the dataset; +- reanaly: describes the source of the data, here we are looking at reanalysis + data (therefore ``reanaly``), could also be ``sat`` for satellite data; +- ANN-v1: describes the version of the dataset: +- Lmon: is the information in which ``mip`` the variable is to be expected, and + what kind of temporal resolution it has; here we expect ``gpp`` to be part + of the land realm (``L``) and we have the dataset in a monthly resolution + (``mon``); +- gpp: Is the name of the variable. Each observational data file is supposed + to only include one variable per file; +- 198001-198012: Is the period the dataset spans with ``198001`` being the + start year and month, and ``198012`` being the end year and month; + +> ## Note +> +> There is a different naming convention for ``obs4mips`` data (see the exact +> specifications for the obs4mips data file naming convention in the +> ``config-developer.yml`` file). +{: .callout} + + +## 5. Create a CMORizer for the new dataset + +ESMValTool can work with CMORizer scripts written in various programming +languages, but most of them are written in either Python or NCL. In this +tutorial we will implement our CMORizer script in Python, but the steps +that one needs to consider when writing a cmorizer are the same for any +other language. + +As mentioned before, we will re-implement the cmorizing script for the +``FLUXCOM`` dataset that is available at the MPI for Biogeochemistry in Jena: +[cmorize_obs_fluxcom.py] +(https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py). + +In a first step we need to create a configuration file for the dataset. This +is necessary to allow the ESMValTool to retrieve all necessary information +about the datasets, and to write the filename of the cmorized variable from +this dataset correctly. This configutation file needs to be stored in the +following folder: +``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/`` +It is imporant to note that the name of the configuration file has to be +identical to the name of our dataset. For our example the configuration file +therefore must be called ``FLUXCOM.yml``, and it can be found here: +[FLUXCOM.yml] +(https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml) + +Let's have a closer look what that configuration file contains: + +```yaml +--- +# Filename +filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' + +# Common global attributes for Cmorizer output +attributes: + dataset_id: FLUXCOM + version: 'ANN-v1' + tier: 3 + modeling_realm: reanaly + project_id: OBS + source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' + reference: 'fluxcom' + comment: '' + +# Variables to cmorize +variables: + gpp: + mip: Lmon +``` The first part of this configuration file defines the filename of the raw observations file. The second part defines the common global attributes for the cmorizer output, e.g. information that is needed to piece together the -final observations file name in the correct structure (see Section `6. Naming convention of the observational data files`). -Another global attribute is ``reference`` which includes a ``doi`` related to the dataset. -Please see the section `adding references +final observations file name in the correct structure +(see Section `6. Naming convention of the observational data files`). +Another global attribute is ``reference`` which includes a ``doi`` related to +the dataset. Please see the section `adding references ` -on how to add reference tags to the ``reference`` section in the configuration file. -If a single dataset has more than one reference, +on how to add reference tags to the ``reference`` section in the configuration +file. If a single dataset has more than one reference, it is possible to add tags as a list e.g. ``reference: ['tag1', 'tag2']``. -The third part in the configuration file defines the variables that are supposed to be cmorized. +The third part in the configuration file defines the variables that are +supposed to be cmorized. + +in the directory ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/``. Note +that the name of this configuration file has to be identical to the name of +your data set. It is recommended that you set ``project`` to ``OBS6`` in the +configuration file. That way, the variables defined in the CMIP6 CMOR table, +augmented with the custom variables described above, are available to your script. The actual cmorizing script ``cmorize_obs_mte.py`` consists of a header with information on where and how to download the data, and noting the last access @@ -314,7 +400,7 @@ saves a single variable from the raw data. .. utilities.py: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/utilities.py -## 5. Run the CMORizer script +## 6. Run the CMORizer script The cmorizing script for the given dataset can be run with: @@ -346,59 +432,6 @@ output directory. {: .challenge} -## 6. Naming convention of the observational data files - -This is quite theoretical. Maybe it should come earlier on in the tutorial? - -For the ESMValTool to be able to read the observations from the NetCDF file, -the file name needs a very specific structure and order of information parts -(very similar to the naming convention for observations in ESMValTool -v1.0). The file name will be automatically correctly created if a cmorizing -script has been used to create the netCDF file. - -The correct structure of an observational data set is defined in -`config-developer.yml -`, -and looks like the following: - -```bash -OBS_[dataset]_[type]_[version]_[mip]_[short_name]_YYYYMM-YYYYMM.nc -``` - -For the example of the ``CDS-XCH4`` data set, the correct structure of the -file name looks then like this: - -```bash -OBS_CDS-XCH4_sat_L3_Amon_xch4_200301-201612.nc -``` - -The different parts of the name are explained in more detail here: - -- OBS: describes what kind of data can be expected in the file, in this case - ``observations``; -- CDS-XCH4: that is the name of the dataset. It has been named this way for - illustration purposes (so that everybody understands it is the xch4 dataset - downloaded from the CDS), but a better name would indeed be ``ESACCI-XCH4`` - since it is a ESA-CCI dataset; -- sat: describes the source of the data, here we are looking at satellite data - (therefore ``sat``), could also be ``reanaly`` for reanalyses; -- L3: describes the version of the dataset: -- Amon: is the information in which ``mip`` the variable is to be expected, and - what kind of temporal resolution it has; here we expect ``xch4`` to be part - of the atmosphere (``A``) and we have the dataset in a monthly resolution - (``mon``); -- xch4: Is the name of the variable. Each observational data file is supposed - to only include one variable per file; -- 200301-201612: Is the period the dataset spans with ``200301`` being the - start year and month, and ``201612`` being the end year and month; - -> ## Note -> -> There is a different naming convention for ``obs4mips`` data (see the exact -> specifications for the obs4mips data file naming convention in the -> ``config-developer.yml`` file). -{: .callout} - ## 7. Make a test recipe Let's start with the end goal: we want to be able to run a recipe that is able From b2ba27a82def74855306942c902700aee8d8e854 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 12 Feb 2021 09:47:16 +0100 Subject: [PATCH 467/647] Update 09-cmorization.md Fixing some text here and there. --- _episodes/09-cmorization.md | 96 ++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 8a1cd022..0ba3d33c 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -74,35 +74,42 @@ the same and the concepts explained in this episode are still useful. ## 1. Check if your variable is following the CMOR standard -The very first step we have to do is to check if your data file follows the CMOR standard. Only data files that fully follow this standard can be read by the ESMValTool. +The very first step we have to do is to check if your data file follows the CMOR standard. +Only data files that fully follow this standard can be read by the ESMValTool. -Most variables that we would want to use with the ESMValTool are defined in the Coupled Model Intercomparison Project (CMIP) data request and can be found in the -CMOR tables in the folder ``, -differentiated according to the ``MIP`` they belong to. The tables are a -copy of the `PCMDI ` guidelines. +Most variables that we would want to use with the ESMValTool are defined in the Coupled +Model Intercomparison Project (CMIP) data request and can be found in the +CMOR tables in the folder +[cmip6/Tables](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/cmip6/Tables), +differentiated according to the "MIP" they belong to. The tables are a +copy of the [PCMDI](https://github.com/PCMDI) guidelines. > ## Find the variable "gpp" in a CMOR table > -> Check the available CMOR tables to find the variable ``gpp`` with the following characteristics: +> Check the available CMOR tables to find the variable "gpp" with the following characteristics: > - standard_name: ``gross_primary_productivity_of_biomass_expressed_as_carbon`` > - frequency: ``mon`` > - modeling_realm: ``land`` > > > ## Answers > > -> > The variable ``gpp``belongs to the land variables. The temporal resolution that we are looking for is ``monthly``. -> > This information points to the "Lmon" CMIP table. And indeed, the variable ``gpp`` can be found in the file -> > ``. +> > The variable "gpp" belongs to the land variables. The temporal resolution that we are looking +> > for is "monthly". This information points to the "Lmon" CMIP table. And indeed, the variable +> > "gpp" can be found in the file +> > [here](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/cmip6/Tables/CMIP6_Lmon.json). > > > {: .solution} {: .challenge} If the variable you are interested in is not available in the standard CMOR tables, -you need to write a custom CMOR table entry for the variable. Don't worry! It sounds more complicated than it is! -Examples of custom CMOR table entries are for example the standard error of a specific variable. -For our variable ``gpp`` there is indeed no CMOR definition for the standard error, therefore ``gppStderr`` was defined in the custom CMOR table here: -``, as ``CMOR_gppStderr.dat``. +you need to write a custom CMOR table entry for the variable. Don't worry! It sounds +more complicated than it is! Examples of custom CMOR table entries are for example +the standard error of a specific variable. +For our variable "gpp" there is indeed no CMOR definition for the standard error, +therefore "gppStderr" was defined in the custom CMOR table +[here](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/custom), +as ``CMOR_gppStderr.dat``. To create a new custom CMOR table you need to follow these guidelines: @@ -117,31 +124,32 @@ guidelines: additional variable attributes that can be defined here (see the already available cmorizers). -It is easiest to start a new custom CMOR table by using an existing custom table as a template. +It is easiest to start a new custom CMOR table by using an existing custom table +as a template. You can then edit the content and save it as ``CMOR_.dat``. -> ## Does the variable ``cVegStderr`` need a costum CMOR table? +> ## Does the variable "cVegStderr" need a costum CMOR table? > -> Check the available CMOR tables to find the variable ``cVegStderr`` with the +> Check the available CMOR tables to find the variable "cVegStderr" with the > following characteristics: > - standard_name: ``vegetation_carbon_content`` > - frequency: ``mon`` > - modeling_realm: ``land`` > > If it is not available, create a custom CMOR table following the template of -> the CMIP6 CMOR table of ``cVeg`` and custom CMOR table of ``gppStderr``. +> the CMIP6 CMOR table of "cVeg" and custom CMOR table of "gppStderr". > > > ## Answers > > -> > The first step here is to check if the variable ``cVegStderr`` is already +> > The first step here is to check if the variable "cVegStderr" is already > > listed in a CMOR table. We have the information that the modeling_realm > > of the variable is ``land`` and that the frequency is ``mon``. This -> > means we have to check the CMOR table ``Lmon`` for an entry. We focus +> > means we have to check the CMOR table "Lmon" for an entry. We focus > > our search on the CMIP6 tables since these are the most recent tables > > available. You can find the lists here: > > `` > > -> > We do not find the variable ``cVegStderr`` in the ``Lmon`` table, which +> > We do not find the variable "cVegStderr" in the "Lmon" table, which > > means we will have to write our own custom table for this. > > There were two examples given which we could use as templates for the > > new custom table that we have to create. These two examples can be @@ -193,11 +201,11 @@ it is not cmorized yet, it cannot be stored in the regular observations and reanalysis data folders. For that purpose it is great to create a ``RAWOBS`` folder in which you would store all non-cmorized data files. This folder needs the same sub-folder structure as the OBS folder we already -know. In our case of the ``FLUXCOM`` data, we need a sub-folder called -``Tier3`` in the folder ``RAWOBS`` and then a sub-folder called ``FLUXCOM`` +know. In our case of the "FLUXCOM" data, we need a sub-folder called +``Tier3`` in the folder ``RAWOBS`` and then a sub-folder called "FLUXCOM" in the sub-folder ``Tier3``. -> ## What is the deal with those ``tiers``? +> ## What is the deal with those "tiers"? > > Many observations and reanalysis datasets are restricted in their access. > This is due to the huge amount of work that goes into creating these datasets @@ -236,7 +244,7 @@ in the sub-folder ``Tier3``. ## 3. Edit your configuration file The next step then is to make sure that the ESMValTool will find the -``FLUXCOM`` data in the ``RAWOBS`` folder when it is running the cmorizing +"FLUXCOM" data in the ``RAWOBS`` folder when it is running the cmorizing script. For this to happen we have to specify the path to the ``RAWOBS`` folder in our configuration file. In the same way as the path to the ``OBS`` folder is defined, we define there our path to the ``RAWOBS`` folder: @@ -263,7 +271,7 @@ and looks like the following: OBS_[dataset]_[type]_[version]_[mip]_[short_name]_YYYYMM-YYYYMM.nc ``` -For the example of the ``FLUXCOM`` data set, the correct structure of the +For the example of the "FLUXCOM" data set, the correct structure of the file name looks then like this: ```bash @@ -273,23 +281,23 @@ OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012.nc The different parts of the name are explained in more detail here: - OBS: describes what kind of data can be expected in the file, in this case - ``observations``; + "observations"; - FLUXCOM: that is the name of the dataset; - reanaly: describes the source of the data, here we are looking at reanalysis - data (therefore ``reanaly``), could also be ``sat`` for satellite data; + data (therefore "reanaly"), could also be "sat" for satellite data; - ANN-v1: describes the version of the dataset: -- Lmon: is the information in which ``mip`` the variable is to be expected, and - what kind of temporal resolution it has; here we expect ``gpp`` to be part - of the land realm (``L``) and we have the dataset in a monthly resolution - (``mon``); +- Lmon: is the information in which "mip" the variable is to be expected, and + what kind of temporal resolution it has; here we expect "gpp" to be part + of the land realm ("L") and we have the dataset in a monthly resolution + ("mon"); - gpp: Is the name of the variable. Each observational data file is supposed to only include one variable per file; -- 198001-198012: Is the period the dataset spans with ``198001`` being the - start year and month, and ``198012`` being the end year and month; +- 198001-198012: Is the period the dataset spans with "198001" being the + start year and month, and "198012" being the end year and month; > ## Note > -> There is a different naming convention for ``obs4mips`` data (see the exact +> There is a different naming convention for "obs4mips" data (see the exact > specifications for the obs4mips data file naming convention in the > ``config-developer.yml`` file). {: .callout} @@ -304,7 +312,7 @@ that one needs to consider when writing a cmorizer are the same for any other language. As mentioned before, we will re-implement the cmorizing script for the -``FLUXCOM`` dataset that is available at the MPI for Biogeochemistry in Jena: +"FLUXCOM" dataset that is available at the MPI for Biogeochemistry in Jena: [cmorize_obs_fluxcom.py] (https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py). @@ -442,8 +450,8 @@ know we have completed our task. > ## Create a test recipe > -> Create a simple recipe that loads the fluxnet data. It should include a -> datasets section with a single entry for the fluxnet dataset with the correct +> Create a simple recipe that loads the "FLUXCOM" data. It should include a +> datasets section with a single entry for the "FLUXCOM" dataset with the correct > dataset keys, and a diagnostics section with two variables: gpp and gppStderr. > We won't need any preprocessors or scripts (set `scripts: null`), but you will > have to add a documentation section with a description, authors and @@ -456,7 +464,7 @@ know we have completed our task. > > ```yaml > > documentation: > > -> > description: Test recipe for fluxnet data +> > description: Test recipe for FLUXCOM data > > > > authors: > > - kalverla_peter @@ -465,11 +473,11 @@ know we have completed our task. > > - kalverla_peter > > > > datasets: -> > - {project: OBS6, dataset: fluxnet, mip: Lmon, tier: 3, start_year: 2010, end_year: 2015, type: reanaly, version: latestversion} +> > - {project: OBS6, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2010, end_year: 2015, type: reanaly, version: latestversion} > > > > diagnostics: -> > fluxnet: -> > description: Check that ESMValTool can load the cmorized fluxnet data without errors. +> > FLUXCOM: +> > description: Check that ESMValTool can load the cmorized FLUXCOM data without errors. > > variables: > > gpp: > > gppStderr: @@ -496,11 +504,11 @@ carefully through the log messages. You'll probably find something like ``` DEBUG Retrieving OBS6 configuration -DEBUG Skipping non-existent /home/peter/default_inputpath/Tier3/fluxnet -DEBUG Looking for files matching ['OBS6_fluxnet_reanaly_latestversion_Lmon_gppStderr[_.]*nc'] in [] +DEBUG Skipping non-existent /home/peter/default_inputpath/Tier3/FLUXCOM +DEBUG Looking for files matching ['OBS6_FLUXCOM_reanaly_latestversion_Lmon_gppStderr[_.]*nc'] in [] ERROR No input files found for variable {'variable_group': 'gppStderr' ... ... -ERROR Missing data for preprocessor fluxnet/gppStderr +ERROR Missing data for preprocessor FLUXCOM/gppStderr ... ERROR Program terminated abnormally, see stack trace below for more information: ... From d2a2a0252a658f6b3fbf3d176517910b6b8c975b Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 12 Feb 2021 09:55:22 +0100 Subject: [PATCH 468/647] Update 09-cmorization.md --- _episodes/09-cmorization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 0ba3d33c..da6ce183 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -343,7 +343,7 @@ attributes: modeling_realm: reanaly project_id: OBS source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' - reference: 'fluxcom' + reference: 'doi:10.17871/FLUXCOM_RS_METEO_CRUNCEPv6_1980_2013_v1' comment: '' # Variables to cmorize From efbc7433b2de1eb9f60ae286ae55612b30548d65 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 12 Feb 2021 11:08:56 +0100 Subject: [PATCH 469/647] Restructure the episode --- _episodes/09-cmorization.md | 461 ++++++++++++++++++------------------ 1 file changed, 231 insertions(+), 230 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index da6ce183..6e675e93 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -72,14 +72,205 @@ fixes, please read the documentation While fixes are implemented slightly differently, conceptually the process is the same and the concepts explained in this episode are still useful. -## 1. Check if your variable is following the CMOR standard +## Download the data (and store in the right place) -The very first step we have to do is to check if your data file follows the CMOR standard. +Now that we have made sure that we have a CMOR definition of our variable +the next step in writing our own cmorizer script is to make sure that the +ESMValTool will be able to find our data file that we want to use. Since +it is not cmorized yet, it cannot be stored in the regular observations +and reanalysis data folders. For that purpose it is great to create a +``RAWOBS`` folder in which you would store all non-cmorized data files. +This folder needs the same sub-folder structure as the OBS folder we already +know. In our case of the "FLUXCOM" data, we need a sub-folder called +``Tier3`` in the folder ``RAWOBS`` and then a sub-folder called "FLUXCOM" +in the sub-folder ``Tier3``. + +> ## What is the deal with those "tiers"? +> +> Many observations and reanalysis datasets are restricted in their access. +> This is due to the huge amount of work that goes into creating these datasets +> and the fact that the dataset creators feel a responisbility about what their +> dataset is used for. In many cases "restricted access" just means that one +> has to register with an email address and is adivsed to achnowledge the data +> providers in scientific publications. After that one is free to download the +> data without any other hurdles. +> +> However, there are also datasets available that do not need a registration +> for access, e.g. the "obs4MIPs" or "ana4MIPs" datasets that are specifically +> produced to facilitate comparisons with model simulations. +> +> To reflect these different levels of access restriction, the ESMValTool team +> has created a tier-system with which the different observations and +> reanalysis datasets are described. The definition of the different tiers are +> as follows: +> - Tier1: obs4MIPs and ana4MIPS datasets (they do not need any additional +> cmorization before they can be used with the ESMValTool) +> - Tier2: any other freely available datasets (most of them will need some +> kind of cmorization before they can be used with the ESMValTool) +> - Tier3: any datasets that has an access restriction, meaning someone has to +> register to access the data (most of these datasets will also need some kind +> of cmorization before they can be used with the ESMValTool) +> +> The access restrictions are also the reason why it is not possible to +> providers the ESMValTool routinely during the installation with all +> observations and reanalysis data that are used in all example recipes. +> However, the cmorization scripts for these datasets are provided with the +> ESMValTool so that each user can cmorize their own copy of the access +> restricted datasets if they need them. +> +{: .callout} + + +### Edit your configuration file + +The next step then is to make sure that the ESMValTool will find the +"FLUXCOM" data in the ``RAWOBS`` folder when it is running the cmorizing +script. For this to happen we have to specify the path to the ``RAWOBS`` +folder in our configuration file. In the same way as the path to the ``OBS`` +folder is defined, we define there our path to the ``RAWOBS`` folder: + +```yaml +rootpath: + OBS: /path/to/my/obs/data + RAWOBS: /path/to/my/rawobs/data +``` + +### Naming convention of the observational data files + +For the ESMValTool to be able to read the observations from the NetCDF file, +the file name needs a very specific structure and order of information parts. +The file name will be automatically correctly created if a cmorizing +script has been used to create the netCDF file. + +The correct structure of an observational data set is defined in +[config-developer.yml] +(https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-developer.yml), +and looks like the following: + +```bash +OBS_[dataset]_[type]_[version]_[mip]_[short_name]_YYYYMM-YYYYMM.nc +``` + +For the example of the "FLUXCOM" data set, the correct structure of the +file name looks then like this: + +```bash +OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012.nc +``` + +The different parts of the name are explained in more detail here: + +- OBS: describes what kind of data can be expected in the file, in this case + "observations"; +- FLUXCOM: that is the name of the dataset; +- reanaly: describes the source of the data, here we are looking at reanalysis + data (therefore "reanaly"), could also be "sat" for satellite data; +- ANN-v1: describes the version of the dataset: +- Lmon: is the information in which "mip" the variable is to be expected, and + what kind of temporal resolution it has; here we expect "gpp" to be part + of the land realm ("L") and we have the dataset in a monthly resolution + ("mon"); +- gpp: Is the name of the variable. Each observational data file is supposed + to only include one variable per file; +- 198001-198012: Is the period the dataset spans with "198001" being the + start year and month, and "198012" being the end year and month; + +> ## Note +> +> There is a different naming convention for "obs4mips" data (see the exact +> specifications for the obs4mips data file naming convention in the +> ``config-developer.yml`` file). +{: .callout} + + +## Make a test recipe + +Let's start with the end goal: we want to be able to run a recipe that is able +to load our data. So we will make this recipe and try to run it. It will +probably fail, but that's okay. As you will see, the error messages will come in +handy. Moreover, the recipe will serve as a test case. Once we get it to run, we +know we have completed our task. + +> ## Create a test recipe +> +> Create a simple recipe that loads the "FLUXCOM" data. It should include a +> datasets section with a single entry for the "FLUXCOM" dataset with the correct +> dataset keys, and a diagnostics section with two variables: gpp and gppStderr. +> We won't need any preprocessors or scripts (set `scripts: null`), but you will +> have to add a documentation section with a description, authors and +> maintainer, otherwise the recipe will fail. +> +> > ## Answer +> > +> > Here's an example recipe +> > +> > ```yaml +> > documentation: +> > +> > description: Test recipe for FLUXCOM data +> > +> > authors: +> > - kalverla_peter +> > +> > maintainer: +> > - kalverla_peter +> > +> > datasets: +> > - {project: OBS6, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2010, end_year: 2015, type: reanaly, version: latestversion} +> > +> > diagnostics: +> > FLUXCOM: +> > description: Check that ESMValTool can load the cmorized FLUXCOM data without errors. +> > variables: +> > gpp: +> > gppStderr: +> > scripts: null +> > +> > ``` +> > +> > Note: a recipe similar to this one is available under +> > `~/path/to/ESMValTool/esmvaltool/recipes/examples/recipe_check_obs.yml`. +> > That recipe includes checks all datasets for which CMORizers are available. +> > +> {: .solution} +{: .challenge} + +Try to run the example recipe with + +```bash +esmvaltool run recipe_check_fluxnet.yml --log_level debug +``` + +The `log_level` flag ensures that all relevant information is included in the +output. We will need this information to find out what needs to be done. Look +carefully through the log messages. You'll probably find something like + +``` +DEBUG Retrieving OBS6 configuration +DEBUG Skipping non-existent /home/peter/default_inputpath/Tier3/FLUXCOM +DEBUG Looking for files matching ['OBS6_FLUXCOM_reanaly_latestversion_Lmon_gppStderr[_.]*nc'] in [] +ERROR No input files found for variable {'variable_group': 'gppStderr' ... +... +ERROR Missing data for preprocessor FLUXCOM/gppStderr +... +ERROR Program terminated abnormally, see stack trace below for more information: +... +``` +{: .error} + +So the output tells us that it cannot find the data, and also where it has been +looking. This makes sense, as we have not yet created a CMORized copy of the data. +But it is always useful to know where ESMValTool will look for it later on. + + +## Check if your variable is following the CMOR standard / Check if it's in a CMOR table + +The very first step we have to do is to check if your data file follows the CMOR standard. Only data files that fully follow this standard can be read by the ESMValTool. -Most variables that we would want to use with the ESMValTool are defined in the Coupled +Most variables that we would want to use with the ESMValTool are defined in the Coupled Model Intercomparison Project (CMIP) data request and can be found in the -CMOR tables in the folder +CMOR tables in the folder [cmip6/Tables](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/cmip6/Tables), differentiated according to the "MIP" they belong to. The tables are a copy of the [PCMDI](https://github.com/PCMDI) guidelines. @@ -93,8 +284,8 @@ copy of the [PCMDI](https://github.com/PCMDI) guidelines. > > > ## Answers > > -> > The variable "gpp" belongs to the land variables. The temporal resolution that we are looking -> > for is "monthly". This information points to the "Lmon" CMIP table. And indeed, the variable +> > The variable "gpp" belongs to the land variables. The temporal resolution that we are looking +> > for is "monthly". This information points to the "Lmon" CMIP table. And indeed, the variable > > "gpp" can be found in the file > > [here](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/cmip6/Tables/CMIP6_Lmon.json). > > @@ -103,11 +294,11 @@ copy of the [PCMDI](https://github.com/PCMDI) guidelines. If the variable you are interested in is not available in the standard CMOR tables, -you need to write a custom CMOR table entry for the variable. Don't worry! It sounds -more complicated than it is! Examples of custom CMOR table entries are for example +you need to write a custom CMOR table entry for the variable. Don't worry! It sounds +more complicated than it is! Examples of custom CMOR table entries are for example the standard error of a specific variable. -For our variable "gpp" there is indeed no CMOR definition for the standard error, -therefore "gppStderr" was defined in the custom CMOR table +For our variable "gpp" there is indeed no CMOR definition for the standard error, +therefore "gppStderr" was defined in the custom CMOR table [here](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/custom), as ``CMOR_gppStderr.dat``. @@ -124,7 +315,7 @@ guidelines: additional variable attributes that can be defined here (see the already available cmorizers). -It is easiest to start a new custom CMOR table by using an existing custom table +It is easiest to start a new custom CMOR table by using an existing custom table as a template. You can then edit the content and save it as ``CMOR_.dat``. @@ -142,22 +333,22 @@ You can then edit the content and save it as ``CMOR_.dat``. > > ## Answers > > > > The first step here is to check if the variable "cVegStderr" is already -> > listed in a CMOR table. We have the information that the modeling_realm -> > of the variable is ``land`` and that the frequency is ``mon``. This +> > listed in a CMOR table. We have the information that the modeling_realm +> > of the variable is ``land`` and that the frequency is ``mon``. This > > means we have to check the CMOR table "Lmon" for an entry. We focus > > our search on the CMIP6 tables since these are the most recent tables -> > available. You can find the lists here: +> > available. You can find the lists here: > > `` > > > > We do not find the variable "cVegStderr" in the "Lmon" table, which -> > means we will have to write our own custom table for this. -> > There were two examples given which we could use as templates for the -> > new custom table that we have to create. These two examples can be -> > found here: [cVeg](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/cmip6/Tables/CMIP6_Lmon.json) +> > means we will have to write our own custom table for this. +> > There were two examples given which we could use as templates for the +> > new custom table that we have to create. These two examples can be +> > found here: [cVeg](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/cmip6/Tables/CMIP6_Lmon.json) > > and [gppStderr](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/custom/CMOR_gppStderr.dat) > > -> > We have to create a new file with the name ``CMOR_cVegStrerr.dat`` in -> > the custom CMOR table folder (https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/custom/). +> > We have to create a new file with the name ``CMOR_cVegStrerr.dat`` in +> > the custom CMOR table folder (https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/custom/). > > The content of the file should then look like this: > > > > ``` @@ -169,7 +360,7 @@ You can then edit the content and save it as ``CMOR_.dat``. > > !---------------------------------- > > ! Variable attributes: > > !---------------------------------- -> > standard_name: +> > standard_name: > > units: kg m-2 > > cell_methods: area: mean where land time: mean > > cell_measures: area: areacella @@ -184,145 +375,33 @@ You can then edit the content and save it as ``CMOR_.dat``. > > ! > > ``` > > -> > Note that there is no entry for ``standard_name``. This is on purpose. -> > It is a sign for the ESMValTool to not crash although the variable that +> > Note that there is no entry for ``standard_name``. This is on purpose. +> > It is a sign for the ESMValTool to not crash although the variable that > > we are looking for is ok to have no official CMIP6 ``standard_name``. > > > {: .solution} {: .challenge} +## 5. Creating a CMORizer script for the new dataset -## 2. Store your dataset in the right place - -Now that we have made sure that we have a CMOR definition of our variable -the next step in writing our own cmorizer script is to make sure that the -ESMValTool will be able to find our data file that we want to use. Since -it is not cmorized yet, it cannot be stored in the regular observations -and reanalysis data folders. For that purpose it is great to create a -``RAWOBS`` folder in which you would store all non-cmorized data files. -This folder needs the same sub-folder structure as the OBS folder we already -know. In our case of the "FLUXCOM" data, we need a sub-folder called -``Tier3`` in the folder ``RAWOBS`` and then a sub-folder called "FLUXCOM" -in the sub-folder ``Tier3``. - -> ## What is the deal with those "tiers"? -> -> Many observations and reanalysis datasets are restricted in their access. -> This is due to the huge amount of work that goes into creating these datasets -> and the fact that the dataset creators feel a responisbility about what their -> dataset is used for. In many cases "restricted access" just means that one -> has to register with an email address and is adivsed to achnowledge the data -> providers in scientific publications. After that one is free to download the -> data without any other hurdles. -> -> However, there are also datasets available that do not need a registration -> for access, e.g. the "obs4MIPs" or "ana4MIPs" datasets that are specifically -> produced to facilitate comparisons with model simulations. -> -> To reflect these different levels of access restriction, the ESMValTool team -> has created a tier-system with which the different observations and -> reanalysis datasets are described. The definition of the different tiers are -> as follows: -> - Tier1: obs4MIPs and ana4MIPS datasets (they do not need any additional -> cmorization before they can be used with the ESMValTool) -> - Tier2: any other freely available datasets (most of them will need some -> kind of cmorization before they can be used with the ESMValTool) -> - Tier3: any datasets that has an access restriction, meaning someone has to -> register to access the data (most of these datasets will also need some kind -> of cmorization before they can be used with the ESMValTool) -> -> The access restrictions are also the reason why it is not possible to -> providers the ESMValTool routinely during the installation with all -> observations and reanalysis data that are used in all example recipes. -> However, the cmorization scripts for these datasets are provided with the -> ESMValTool so that each user can cmorize their own copy of the access -> restricted datasets if they need them. -> -{: .callout} - - -## 3. Edit your configuration file - -The next step then is to make sure that the ESMValTool will find the -"FLUXCOM" data in the ``RAWOBS`` folder when it is running the cmorizing -script. For this to happen we have to specify the path to the ``RAWOBS`` -folder in our configuration file. In the same way as the path to the ``OBS`` -folder is defined, we define there our path to the ``RAWOBS`` folder: - -```yaml -rootpath: - OBS: /path/to/my/obs/data - RAWOBS: /path/to/my/rawobs/data -``` - -## 4. Naming convention of the observational data files - -For the ESMValTool to be able to read the observations from the NetCDF file, -the file name needs a very specific structure and order of information parts. -The file name will be automatically correctly created if a cmorizing -script has been used to create the netCDF file. - -The correct structure of an observational data set is defined in -[config-developer.yml] -(https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-developer.yml), -and looks like the following: - -```bash -OBS_[dataset]_[type]_[version]_[mip]_[short_name]_YYYYMM-YYYYMM.nc -``` - -For the example of the "FLUXCOM" data set, the correct structure of the -file name looks then like this: - -```bash -OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012.nc -``` - -The different parts of the name are explained in more detail here: - -- OBS: describes what kind of data can be expected in the file, in this case - "observations"; -- FLUXCOM: that is the name of the dataset; -- reanaly: describes the source of the data, here we are looking at reanalysis - data (therefore "reanaly"), could also be "sat" for satellite data; -- ANN-v1: describes the version of the dataset: -- Lmon: is the information in which "mip" the variable is to be expected, and - what kind of temporal resolution it has; here we expect "gpp" to be part - of the land realm ("L") and we have the dataset in a monthly resolution - ("mon"); -- gpp: Is the name of the variable. Each observational data file is supposed - to only include one variable per file; -- 198001-198012: Is the period the dataset spans with "198001" being the - start year and month, and "198012" being the end year and month; - -> ## Note -> -> There is a different naming convention for "obs4mips" data (see the exact -> specifications for the obs4mips data file naming convention in the -> ``config-developer.yml`` file). -{: .callout} - - -## 5. Create a CMORizer for the new dataset - -ESMValTool can work with CMORizer scripts written in various programming -languages, but most of them are written in either Python or NCL. In this -tutorial we will implement our CMORizer script in Python, but the steps -that one needs to consider when writing a cmorizer are the same for any +ESMValTool can work with CMORizer scripts written in various programming +languages, but most of them are written in either Python or NCL. In this +tutorial we will implement our CMORizer script in Python, but the steps +that one needs to consider when writing a cmorizer are the same for any other language. -As mentioned before, we will re-implement the cmorizing script for the -"FLUXCOM" dataset that is available at the MPI for Biogeochemistry in Jena: +As mentioned before, we will re-implement the cmorizing script for the +"FLUXCOM" dataset that is available at the MPI for Biogeochemistry in Jena: [cmorize_obs_fluxcom.py] (https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py). In a first step we need to create a configuration file for the dataset. This -is necessary to allow the ESMValTool to retrieve all necessary information -about the datasets, and to write the filename of the cmorized variable from -this dataset correctly. This configutation file needs to be stored in the -following folder: +is necessary to allow the ESMValTool to retrieve all necessary information +about the datasets, and to write the filename of the cmorized variable from +this dataset correctly. This configutation file needs to be stored in the +following folder: ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/`` -It is imporant to note that the name of the configuration file has to be +It is imporant to note that the name of the configuration file has to be identical to the name of our dataset. For our example the configuration file therefore must be called ``FLUXCOM.yml``, and it can be found here: [FLUXCOM.yml] @@ -332,7 +411,7 @@ Let's have a closer look what that configuration file contains: ```yaml --- -# Filename +# Filename filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' # Common global attributes for Cmorizer output @@ -355,15 +434,15 @@ variables: The first part of this configuration file defines the filename of the raw observations file. The second part defines the common global attributes for the cmorizer output, e.g. information that is needed to piece together the -final observations file name in the correct structure +final observations file name in the correct structure (see Section `6. Naming convention of the observational data files`). -Another global attribute is ``reference`` which includes a ``doi`` related to +Another global attribute is ``reference`` which includes a ``doi`` related to the dataset. Please see the section `adding references ` -on how to add reference tags to the ``reference`` section in the configuration +on how to add reference tags to the ``reference`` section in the configuration file. If a single dataset has more than one reference, it is possible to add tags as a list e.g. ``reference: ['tag1', 'tag2']``. -The third part in the configuration file defines the variables that are +The third part in the configuration file defines the variables that are supposed to be cmorized. in the directory ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/``. Note @@ -440,84 +519,6 @@ output directory. {: .challenge} -## 7. Make a test recipe - -Let's start with the end goal: we want to be able to run a recipe that is able -to load our data. So we will make this recipe and try to run it. It will -probably fail, but that's okay. As you will see, the error messages will come in -handy. Moreover, the recipe will serve as a test case. Once we get it to run, we -know we have completed our task. - -> ## Create a test recipe -> -> Create a simple recipe that loads the "FLUXCOM" data. It should include a -> datasets section with a single entry for the "FLUXCOM" dataset with the correct -> dataset keys, and a diagnostics section with two variables: gpp and gppStderr. -> We won't need any preprocessors or scripts (set `scripts: null`), but you will -> have to add a documentation section with a description, authors and -> maintainer, otherwise the recipe will fail. -> -> > ## Answer -> > -> > Here's an example recipe -> > -> > ```yaml -> > documentation: -> > -> > description: Test recipe for FLUXCOM data -> > -> > authors: -> > - kalverla_peter -> > -> > maintainer: -> > - kalverla_peter -> > -> > datasets: -> > - {project: OBS6, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2010, end_year: 2015, type: reanaly, version: latestversion} -> > -> > diagnostics: -> > FLUXCOM: -> > description: Check that ESMValTool can load the cmorized FLUXCOM data without errors. -> > variables: -> > gpp: -> > gppStderr: -> > scripts: null -> > -> > ``` -> > -> > Note: a recipe similar to this one is available under -> > `~/path/to/ESMValTool/esmvaltool/recipes/examples/recipe_check_obs.yml`. -> > That recipe includes checks all datasets for which CMORizers are available. -> > -> {: .solution} -{: .challenge} - -Try to run the example recipe with - -```bash -esmvaltool run recipe_check_fluxnet.yml --log_level debug -``` - -The `log_level` flag ensures that all relevant information is included in the -output. We will need this information to find out what needs to be done. Look -carefully through the log messages. You'll probably find something like - -``` -DEBUG Retrieving OBS6 configuration -DEBUG Skipping non-existent /home/peter/default_inputpath/Tier3/FLUXCOM -DEBUG Looking for files matching ['OBS6_FLUXCOM_reanaly_latestversion_Lmon_gppStderr[_.]*nc'] in [] -ERROR No input files found for variable {'variable_group': 'gppStderr' ... -... -ERROR Missing data for preprocessor FLUXCOM/gppStderr -... -ERROR Program terminated abnormally, see stack trace below for more information: -... -``` -{: .error} - -So the output tells us that it cannot find the data, and also where it has been -looking. This makes sense, as we have not yet created a CMORized copy of the data. -But it is always useful to know where ESMValTool will look for it later on. ## Conclusion From adb884be998f5a24139d5df0b67c205ac21d910a Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 12 Feb 2021 12:53:44 +0000 Subject: [PATCH 470/647] First batch of content added to the enw diagnostics episode --- _episodes/10-diagnostics.md | 227 ++++++++++++++++++++++++++++++++++-- 1 file changed, 220 insertions(+), 7 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 16d315de..5a3aebd6 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -1,15 +1,15 @@ --- title: "Writing your own diagnostic script" -teaching: 15 -exercises: 45 +teaching: TBD +exercises: TBD questions: -- "Question 1" -- "Question 2 etc" +- "How to read preprocessor output from a Python diagnsotics?" +- "How to write a new diagnostic in ESMValTool?" objectives: -- "Objective 1" -- "Obj 2" +- "Understanding the interface between the ESMValCore preprocessor and a diagnostic script." +- "Writing a new Python diagnostic" keypoints: - "Take home message 1" @@ -18,7 +18,220 @@ keypoints: ## Introduction -This is where the main text comes +The diagnostic script is an important component of ESMValTool where the actual +scientific analysis or performance metric is implemented. With ESMValTool, you +can reuse an existing diagnostic, adapt and existing one for your needs or +write your own new diagnostic. Diagnostics can be written in one or more open +source languages such as Python, R, Julia or NCL but we will focus on understanding +and writing Python diagnostics in this lesson. In order to access existing diagnostics or +to write your own, please install ESMValTool in the development mode on your +machine using the instructions from [here](https://esmvalgroup.github.io/ESMValTool_Tutorial/08-development-setup/index.html). + +## Understanding an existing Python diagnostic +We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) and the diagnostic script called by this recipe -- [diag_scripts/examples/diagnostic.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py). For reference, we have the diagnostic file in the dropdown box below. + +> ## diagnostic.py +> +>~~~ +>"""Python example diagnostic.""" +>import logging +>from pathlib import Path +>from pprint import pformat +> +>import iris +> +>from esmvaltool.diag_scripts.shared import ( +> group_metadata, +> run_diagnostic, +> save_data, +> save_figure, +> select_metadata, +> sorted_metadata, +>) +>from esmvaltool.diag_scripts.shared.plot import quickplot +> +>logger = logging.getLogger(Path(__file__).stem) +> +> +>def get_provenance_record(attributes, ancestor_files): +> """Create a provenance record describing the diagnostic data and plot.""" +> caption = ("Average {long_name} between {start_year} and {end_year} " +> "according to {dataset}.".format(**attributes)) +> +> record = { +> 'caption': caption, +> 'statistics': ['mean'], +> 'domains': ['global'], +> 'plot_types': ['zonal'], +> 'authors': [ +> 'andela_bouwe', +> 'righi_mattia', +> +> +> ], +> 'references': [ +> 'acknow_project', +> ], +> 'ancestors': ancestor_files, +> } +> return record +> +> +>def compute_diagnostic(filename): +> """Compute an example diagnostic.""" +> logger.debug("Loading %s", filename) +> cube = iris.load_cube(filename) +> +> logger.debug("Running example computation") +> cube = iris.util.squeeze(cube) +> return cube +> +> +>def plot_diagnostic(cube, basename, provenance_record, cfg): +> """Create diagnostic data and plot it.""" +> +> # Save the data used for the plot +> save_data(basename, provenance_record, cfg, cube) +> +> if cfg.get('quickplot'): +> # Create the plot +> quickplot(cube, **cfg['quickplot']) +> # And save the plot +> save_figure(basename, provenance_record, cfg) +> +> +>def main(cfg): +> """Compute the time average for each input dataset.""" +> # Get a description of the preprocessed data that we will use as input. +> input_data = cfg['input_data'].values() +> +> # Demonstrate use of metadata access convenience functions. +> selection = select_metadata(input_data, short_name='tas', project='CMIP5') +> logger.info("Example of how to select only CMIP5 temperature data:\n%s", +> pformat(selection)) +> +> selection = sorted_metadata(selection, sort='dataset') +> logger.info("Example of how to sort this selection by dataset:\n%s", +> pformat(selection)) +> +> grouped_input_data = group_metadata(input_data, +> 'variable_group', +> sort='dataset') +> logger.info( +> "Example of how to group and sort input data by variable groups from " +> "the recipe:\n%s", pformat(grouped_input_data)) +> +> # Example of how to loop over variables/datasets in alphabetical order +> groups = group_metadata(input_data, 'variable_group', sort='dataset') +> for group_name in groups: +> logger.info("Processing variable %s", group_name) +> for attributes in groups[group_name]: +> logger.info("Processing dataset %s", attributes['dataset']) +> input_file = attributes['filename'] +> cube = compute_diagnostic(input_file) +> +> output_basename = Path(input_file).stem +> if group_name != attributes['short_name']: +> output_basename = group_name + '_' + output_basename +> provenance_record = get_provenance_record( +> attributes, ancestor_files=[input_file]) +> plot_diagnostic(cube, output_basename, provenance_record, cfg) +> +> +>if __name__ == '__main__': +> +> with run_diagnostic() as config: +> main(config) +> +>~~~ +>{: .language-python} +> +{:.solution} + +> ## What is the starting point of the diagnostic? +> +> Can you spot the main function in the Python code above? How many references +>do you see to this function? +> +> > ## Answer +> > +> > The main function is defined in the middle of this script and is called near the very +>>end. The function *run_diagnostic* which you also see at the end of the file is what +>>is called a context manager provided with ESMValTool and is the +>>main entry point for most Python diagnostics. The variable *cfg* is a Python dictionary +>>loaded with all the +>>necessary information needed to run the diagnostic script including location of +>> input data and various settings. +>>In the *main* function, we will next parse this *cfg* variable and extract +>>information as needed to do our analyses. +> > +> {: .solution} +{: .challenge} + +## What information do I need for my analyses? +The very first thing passed to the diagnostic via the *cfg* dictionary is a path to a file +called *settings.yml*. It is found at the lowest level of your directory structure under +the *run* directory. An example path would be */path_to_recipe_output/run/diag_name/script_name/settings.yml*. + +> ## What is in the settings.yml file? +> The ESMValTool documentation page provides a generic overview of what is in the +>settings.yml file [here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html). +> +{: .callout} + +> ## Challenge : digging in deeper to understand the preprocesor-diagnostic interface +> +> Can you find one example of the settings.yml file when you run this recipe? +> Take a look at the *input_files* list in your settings.yml file. Do you see a mention of +> a second yml file called *metadat.yml*? +> What information do you think is saved in metadat.yml? +> +> +> > ## Answer +> >Congratulations on finding an example each of the *settings.yml* and *metadata.yml* +>>files! You will have noticed that metadat.yml has information on your preprocessed +>>data. There is one file for each variable and it has detailed information on your data +>> including project (e.g., CMIP6, OBS), dataset names (e.g., MIROC-6, UKESM-0-1-LL), +>>variable attributes (e.g., standard_name, units), preprocessor applied and time range +>> of the data. You are now ready to access all of this information for your evaluation! +> > +> > +> {: .solution} +{: .challenge} + +## Extracting information needed for analyses +In the *main* function of the diagnostic, you will see that *input_data* values are read +from the *cfg* Python dictionary. Typically, users will now need to group this input data +according to some criteria such as by model or experiment and select specifics to analyse. +ESMValTool prvides a whole host of convenience functions that can do this for you. +A list of available functions and their description is provided [here](https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html). In our example, you will see several +of these imported right at the beginning of the file and used after input data is read. + +> ## ESMValTool Diagnostic Interface Functions +> +> Can you spot the functions used for selecting and grouping data in the example? +>After running this example, how can you tell what the functions do? +> +> > ## Answer +> > +> > If you look carefully, you can see that there is a statement after each use of the +>> select and group functions that starts with *logger.info*. These lines print output to +>> the log files. If you looked at the content of your log files under the run directory, you +>> should see the selected and grouped output. This is how you access preprocessed +>> information within your diagnostic. +> > +> {: .solution} +{: .challenge} + +Finally, after grouping we read individual attributes such as the filename which gives us +the specific name of the preprocessed data file we want to read and analyse. +Following this, we see the call to a function called *compute_diagnostic*. +In this example, this is where the analyses on the data is done. +If you were writing your own diagnostic, this is the function you would put your own +analyses code in. + + + ## Another section From f7ba1be67bbe74144cb940bef96e06f7f2aac6f3 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 12 Feb 2021 14:23:10 +0100 Subject: [PATCH 471/647] Update first half of the episode --- _episodes/09-cmorization.md | 222 ++++++++++++++++++------------------ 1 file changed, 112 insertions(+), 110 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 6e675e93..14bf8750 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -63,130 +63,64 @@ The concepts discussed so far are illustrated in the figure below. ![Data flow with ESMValTool](../fig/data_flow.png) *Illustration of the data flow in ESMValTool.* -In this lesson, we will re-implement a CMORizer script for the FLUXCOM dataset that -contains observations of the Gross Primary Production (GPP), a variable that is -important for calculating components of the global carbon cycle. We will go through all -the steps and explain relevant topics as we go. If you prefer to implement CMOR -fixes, please read the documentation +In this lesson, we will re-implement a CMORizer script for the FLUXCOM dataset +that contains observations of the Gross Primary Production (GPP), a variable +that is important for calculating components of the global carbon cycle. We will +go through all the steps and explain relevant topics as we go. If you prefer to +implement CMOR fixes, please read the documentation [here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/develop/fixing_data.html#fixing-data). While fixes are implemented slightly differently, conceptually the process is the same and the concepts explained in this episode are still useful. -## Download the data (and store in the right place) - -Now that we have made sure that we have a CMOR definition of our variable -the next step in writing our own cmorizer script is to make sure that the -ESMValTool will be able to find our data file that we want to use. Since -it is not cmorized yet, it cannot be stored in the regular observations -and reanalysis data folders. For that purpose it is great to create a -``RAWOBS`` folder in which you would store all non-cmorized data files. -This folder needs the same sub-folder structure as the OBS folder we already -know. In our case of the "FLUXCOM" data, we need a sub-folder called -``Tier3`` in the folder ``RAWOBS`` and then a sub-folder called "FLUXCOM" -in the sub-folder ``Tier3``. +## Obtaining the data + +> ## Get the data +> The data for this episode is available via the [FluxCom Data +> Portal](http://www.bgc-jena.mpg.de/geodb/BGI/Home). First you'll need to +> register. After registration, in the dropdown boxes, select FLUXCOM as the data +> choice and click download. Three files will be displayed. Click the download +> button on the "FLUXCOM (RS+METEO) Global Land Carbon Fluxes using CRUNCEP +> climate data". You'll be send an FTP address to access the server. Connect +> to the server, follow the path in your email, and look for the file +> `raw/monthly/GPP.ANN.CRUNCEPv6.monthly.2000.nc`. Download that file and save in +> in a folder called `/RAWOBS/Tier3/`. +> +> Note: you'll need a user-friendly ftp client. On Linux, `ncftp` works okay. +{: .challenge} > ## What is the deal with those "tiers"? > -> Many observations and reanalysis datasets are restricted in their access. -> This is due to the huge amount of work that goes into creating these datasets -> and the fact that the dataset creators feel a responisbility about what their -> dataset is used for. In many cases "restricted access" just means that one -> has to register with an email address and is adivsed to achnowledge the data -> providers in scientific publications. After that one is free to download the -> data without any other hurdles. +> Many datasets come with access restrictions. In this way the data providers +> can keep track of how their data is used. In many cases "restricted access" +> just means that one has to register with an email address and accept the terms +> of use, which typically ask that you acknowledge the data providers. > -> However, there are also datasets available that do not need a registration -> for access, e.g. the "obs4MIPs" or "ana4MIPs" datasets that are specifically -> produced to facilitate comparisons with model simulations. +> There are also datasets available that do not need a registration. The +> "obs4MIPs" or "ana4MIPs" datasets, for example, are specifically produced to +> facilitate comparisons with model simulations. > > To reflect these different levels of access restriction, the ESMValTool team -> has created a tier-system with which the different observations and -> reanalysis datasets are described. The definition of the different tiers are +> has created a tier-system. The definition of the different tiers are > as follows: -> - Tier1: obs4MIPs and ana4MIPS datasets (they do not need any additional -> cmorization before they can be used with the ESMValTool) -> - Tier2: any other freely available datasets (most of them will need some -> kind of cmorization before they can be used with the ESMValTool) -> - Tier3: any datasets that has an access restriction, meaning someone has to -> register to access the data (most of these datasets will also need some kind -> of cmorization before they can be used with the ESMValTool) > -> The access restrictions are also the reason why it is not possible to -> providers the ESMValTool routinely during the installation with all -> observations and reanalysis data that are used in all example recipes. -> However, the cmorization scripts for these datasets are provided with the -> ESMValTool so that each user can cmorize their own copy of the access -> restricted datasets if they need them. +> - **Tier1**: obs4MIPs and ana4MIPS datasets (can be used directly with the ESMValTool) +> - **Tier2**: other freely available datasets (most of them will need some kind of +> cmorization) +> - **Tier3**: datasets with access restrictions (most of these datasets will also +> need some kind of cmorization) > -{: .callout} - - -### Edit your configuration file - -The next step then is to make sure that the ESMValTool will find the -"FLUXCOM" data in the ``RAWOBS`` folder when it is running the cmorizing -script. For this to happen we have to specify the path to the ``RAWOBS`` -folder in our configuration file. In the same way as the path to the ``OBS`` -folder is defined, we define there our path to the ``RAWOBS`` folder: - -```yaml -rootpath: - OBS: /path/to/my/obs/data - RAWOBS: /path/to/my/rawobs/data -``` - -### Naming convention of the observational data files - -For the ESMValTool to be able to read the observations from the NetCDF file, -the file name needs a very specific structure and order of information parts. -The file name will be automatically correctly created if a cmorizing -script has been used to create the netCDF file. - -The correct structure of an observational data set is defined in -[config-developer.yml] -(https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-developer.yml), -and looks like the following: - -```bash -OBS_[dataset]_[type]_[version]_[mip]_[short_name]_YYYYMM-YYYYMM.nc -``` - -For the example of the "FLUXCOM" data set, the correct structure of the -file name looks then like this: - -```bash -OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012.nc -``` - -The different parts of the name are explained in more detail here: - -- OBS: describes what kind of data can be expected in the file, in this case - "observations"; -- FLUXCOM: that is the name of the dataset; -- reanaly: describes the source of the data, here we are looking at reanalysis - data (therefore "reanaly"), could also be "sat" for satellite data; -- ANN-v1: describes the version of the dataset: -- Lmon: is the information in which "mip" the variable is to be expected, and - what kind of temporal resolution it has; here we expect "gpp" to be part - of the land realm ("L") and we have the dataset in a monthly resolution - ("mon"); -- gpp: Is the name of the variable. Each observational data file is supposed - to only include one variable per file; -- 198001-198012: Is the period the dataset spans with "198001" being the - start year and month, and "198012" being the end year and month; - -> ## Note +> These access restrictions are also the reason why the ESMValTool developers +> cannot distribute copies or automate downloading of all observations and +> reanalysis data used in the recipes. As a compromise we provide the +> CMORization scripts so that each user can CMORize their own copy of the access +> restricted datasets if they need them. > -> There is a different naming convention for "obs4mips" data (see the exact -> specifications for the obs4mips data file naming convention in the -> ``config-developer.yml`` file). {: .callout} - ## Make a test recipe -Let's start with the end goal: we want to be able to run a recipe that is able -to load our data. So we will make this recipe and try to run it. It will +Now that we have downloaded the data, our end goal is to run a recipe that can +load it and work with it. So we will make this recipe and try to run it. It will probably fail, but that's okay. As you will see, the error messages will come in handy. Moreover, the recipe will serve as a test case. Once we get it to run, we know we have completed our task. @@ -200,6 +134,20 @@ know we have completed our task. > have to add a documentation section with a description, authors and > maintainer, otherwise the recipe will fail. > +> Use the following dataset keys: +> +> - project: OBS6 +> - dataset: FLUXCOM +> - type: reanaly +> - version: ANN-v1 +> - mip: Lmon +> - start_year: 2000 +> - end_year: 2000 +> - tier: 3 +> +> Some of these dataset keys are further explained in the callout boxes in this +> episode. +> > > ## Answer > > > > Here's an example recipe @@ -216,7 +164,7 @@ know we have completed our task. > > - kalverla_peter > > > > datasets: -> > - {project: OBS6, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2010, end_year: 2015, type: reanaly, version: latestversion} +> > - {project: OBS6, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2000, end_year: 2000, type: reanaly, version: ANN-v1} > > > > diagnostics: > > FLUXCOM: @@ -248,7 +196,7 @@ carefully through the log messages. You'll probably find something like ``` DEBUG Retrieving OBS6 configuration DEBUG Skipping non-existent /home/peter/default_inputpath/Tier3/FLUXCOM -DEBUG Looking for files matching ['OBS6_FLUXCOM_reanaly_latestversion_Lmon_gppStderr[_.]*nc'] in [] +DEBUG Looking for files matching ['OBS6_FLUXCOM_reanaly_ANN-v1_Lmon_gppStderr[_.]*nc'] in [] ERROR No input files found for variable {'variable_group': 'gppStderr' ... ... ERROR Missing data for preprocessor FLUXCOM/gppStderr @@ -259,8 +207,62 @@ ERROR Program terminated abnormally, see stack trace below for more informatio {: .error} So the output tells us that it cannot find the data, and also where it has been -looking. This makes sense, as we have not yet created a CMORized copy of the data. -But it is always useful to know where ESMValTool will look for it later on. +looking. Let's try to understand what's going on. + +## Location, location, location + +The error messages above tell you that ESMValTool cannot find the data. That +makes total sense, because we have not yet created our CMORized copy of the +data. Our data is located in the `RAWOBS` folder, but ESMValTool is looking in +`OBS6`. So the first thing our CMORizer will need to do is copy the data over +from one folder to the other. To do end, we need to tell ESMValTool where our +data may be found. + +> ## Set the correct paths in your user configuration file: +> +> This information is set in `config-user.yml`. Modify your +> configuration file so that it has the correct paths +> +> ```yaml +> rootpath: +> OBS6: /path/to/my/obs6/data +> RAWOBS: /path/to/my/rawobs/data +> ``` +{: .challenge} + +> ## RAWOBS, OBS, OBS6!? +> +> ESMValTool uses project IDs to find the data on your hard drive, and also to +> find more information about the data. The `RAWOBS` and `OBS` projects were +> created for external data before and after CMORization, respectively. These +> names can be misleading, though, since not all external datasets are +> observations. +> +> Then, in going from CMIP5 to CMIP6, the CMOR standards changed a bit. Some +> variables are named differently in CMIP5 and CMIP6. This posed a dilemma: +> should CMORization reformat to the CMIP5 or CMIP6 definition? To solve this, +> the `OBS6` project was created. So data in the `OBS6` follow the CMIP6 +> standards. +> +{: .callout} + +Looking closer at the path that ESMValTool told us it went looking for the data, +we see that it has a very specific structure: + +`OBS6_FLUXCOM_reanaly_ANN-v1_Lmon_gppStderr[_.]*nc` + +Note that all components in the filename correspond to one of the dataset keys +defined in our test recipe. By replacing them with the original tags, we can +see the general structure for the OBS6 data: + +`[project]_[dataset]_[type]_[version]_[mip]_[short_name]_*.nc` + +This is the Data Reference Syntax (DRS) for OBS6 data. Each project has its own +DRS, and some project IDs even have multiple different options. These settings +can be found in the file +[config-developer.yml](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-developer.yml). +Luckily, we don't need to worry about that. This file name will be automatically +correctly created when we run our CMORizer script. ## Check if your variable is following the CMOR standard / Check if it's in a CMOR table From cbcf35c309e9b94751a61be138bfa5751ba5e980 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 12 Feb 2021 14:45:27 +0100 Subject: [PATCH 472/647] Update 09-cmorization.md Implementation of the new structure for section 5. --- _episodes/09-cmorization.md | 134 +++++++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 25 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 14bf8750..4819fcc0 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -384,26 +384,110 @@ You can then edit the content and save it as ``CMOR_.dat``. > {: .solution} {: .challenge} -## 5. Creating a CMORizer script for the new dataset - -ESMValTool can work with CMORizer scripts written in various programming -languages, but most of them are written in either Python or NCL. In this -tutorial we will implement our CMORizer script in Python, but the steps -that one needs to consider when writing a cmorizer are the same for any -other language. - -As mentioned before, we will re-implement the cmorizing script for the -"FLUXCOM" dataset that is available at the MPI for Biogeochemistry in Jena: -[cmorize_obs_fluxcom.py] -(https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py). - -In a first step we need to create a configuration file for the dataset. This -is necessary to allow the ESMValTool to retrieve all necessary information -about the datasets, and to write the filename of the cmorized variable from -this dataset correctly. This configutation file needs to be stored in the -following folder: +## 5. Create a CMORizer for the new dataset + +Now that we have the data ready, have told the ESMValTool where to look +for it, and have made sure that our variable of choice is listed either +on a pre-existing or custom CMOR table, let's test if the data is actually +following the necessary CMOR standard already, or if we have to do some +reformatting for the dataset. + +> ## Run the test recipe again +> +> Run the test recipe again from earlier where you wanted to check if the +> ESMValTool can already find and read the freshly downloaded FLUXCOM data. +> +> > ## Answers +> > +> > ```bash +> > esmvaltool run recipe_check_fluxnet.yml --log_level debug +> > ``` +> > +> > The ESMValTool should now find your FLUXCOM datafile, and the error +> > message that the ESMValTool can't find the data should now not be present +> > anymore. However, there are plenty of other error messages around. +> > Somewhere within the many messages, you should see this: +> > +> > ```bash +> > ... +> > esmvalcore.cmor.check.CMORCheckError: There were errors in variable GPP: +> > Variable GPP units unknown can not be converted to kg m-2 s-1 +> > lon: standard_name should be longitude, not None +> > lat: standard_name should be latitude, not None +> > lon longitude coordinate has values < -360 degrees +> > lon longitude coordinate has values > 720 degrees +> > lat: has values < valid_min = -90.0 +> > lat: has values > valid_max = 90.0 +> > GPP: does not match coordinate rank +> > in cube: +> > gross_primary_productivity_of_carbon / (unknown) (time: 12; lat: 360; lon: 720) +> > Dimension coordinates: +> > time x - - +> > lat - x - +> > lon - - x +> > Attributes: +> > created_by: Fabian Gans [fgans@bgc-jena.mpg.de], Ulrich Weber [uweber@bgc-jena.mpg... +> > flux: GPP +> > forcing: CRUNCEPv6 +> > institution: MPI-BGC-BGI +> > invalid_units: gC m-2 day-1 +> > method: Artificial Neural Networks +> > provided_by: Martin Jung [mjung@bgc-jena.mpg.de] on behalf of FLUXCOM team +> > reference: Jung et al. 2016, Nature; Tramontana et al. 2016, Biogeosciences +> > source_file: /mnt/lustre02/work/bd0854/b309143/Data/Tier3/FLUXCOM/OBS_FLUXCOM_reana... +> > temporal_resolution: monthly +> > title: GPP based on FLUXCOM RS+METEO with CRUNCEPv6 climate +> > version: v1 +> > ... +> > ``` + +> {: .solution} +{: .challenge} + +The error messages that we see tell us that we do have to reformat the dataset +slightly to have it follow the CMOR standard. It seems like the variable "gpp" +does not have the correct unit that is given in the CMOR table where it is +[defined](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/cmip6/Tables). +It also seems like the "latitude" and "longitude" coordinates have some +problems. So let's start writing a short python script that will fix these +problems. + +The first step now is to create a file in the right folder that will contain +the short python script. The home of all CMORizer scripts for observations +and reanalysis datasets is +[here](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/cmorizers/obs). +Add a file with the name ``cmorize_obs_fluxcom.py`` to this folder. + +> ## Note +> +> Always, always, when modifying or creating new code for the ESMValTool +> repositories, work on your *own, local* branch of the ESMValTool. Optimally, +> you have forked that branch directly from the most up-to-date version of +> the "master" branch to avoid conflicts later when you want to merge your +> code with the "master" branch of the ESMValTool. +> +{: .callout} + +Within our python script we have to make sure that we cover three main +aspects of the reformatting: +- We need to be able to locate and read the data to be CMORized +- We have to CMORize the data (fix the CMOR problems that the ESMValTool +had so nicely pointed out for us) +- We need to store the data with the correct filename so that the ESMValTool +will be able to identify it later + + + + + + +In a next step we need to create a configuration file for the dataset. This +is necessary to allow the ESMValTool to retrieve all necessary information +about the datasets, and to write the filename of the cmorized variable from +this dataset correctly. This configutation file needs to be stored in the +following folder: ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/`` -It is imporant to note that the name of the configuration file has to be +It is imporant to note that the name of the configuration file has to be identical to the name of our dataset. For our example the configuration file therefore must be called ``FLUXCOM.yml``, and it can be found here: [FLUXCOM.yml] @@ -413,7 +497,7 @@ Let's have a closer look what that configuration file contains: ```yaml --- -# Filename +# Filename filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' # Common global attributes for Cmorizer output @@ -424,7 +508,7 @@ attributes: modeling_realm: reanaly project_id: OBS source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' - reference: 'doi:10.17871/FLUXCOM_RS_METEO_CRUNCEPv6_1980_2013_v1' + reference: 'fluxcom' comment: '' # Variables to cmorize @@ -436,15 +520,15 @@ variables: The first part of this configuration file defines the filename of the raw observations file. The second part defines the common global attributes for the cmorizer output, e.g. information that is needed to piece together the -final observations file name in the correct structure +final observations file name in the correct structure (see Section `6. Naming convention of the observational data files`). -Another global attribute is ``reference`` which includes a ``doi`` related to +Another global attribute is ``reference`` which includes a ``doi`` related to the dataset. Please see the section `adding references ` -on how to add reference tags to the ``reference`` section in the configuration +on how to add reference tags to the ``reference`` section in the configuration file. If a single dataset has more than one reference, it is possible to add tags as a list e.g. ``reference: ['tag1', 'tag2']``. -The third part in the configuration file defines the variables that are +The third part in the configuration file defines the variables that are supposed to be cmorized. in the directory ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/``. Note From f638fb0c252f3d7bbb271aba16a5abfb1add1080 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 12 Feb 2021 14:21:33 +0000 Subject: [PATCH 473/647] Update _episodes/10-diagnostics.md Co-authored-by: Niels Drost --- _episodes/10-diagnostics.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 5a3aebd6..8fd38d7f 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -4,8 +4,9 @@ teaching: TBD exercises: TBD questions: -- "How to read preprocessor output from a Python diagnsotics?" -- "How to write a new diagnostic in ESMValTool?" +- "How do I write a new diagnostic in ESMValTool?" +- "How do I read preprocessor output in a Python diagnostic?" + objectives: - "Understanding the interface between the ESMValCore preprocessor and a diagnostic script." From 32334227418cab834c71e23576b5c3079c5f9dcf Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 12 Feb 2021 14:21:54 +0000 Subject: [PATCH 474/647] Update _episodes/10-diagnostics.md Co-authored-by: Niels Drost --- _episodes/10-diagnostics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 8fd38d7f..38a3cf43 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -9,8 +9,8 @@ questions: objectives: -- "Understanding the interface between the ESMValCore preprocessor and a diagnostic script." - "Writing a new Python diagnostic" +- "Understanding the interface between the ESMValCore preprocessor and a diagnostic script." keypoints: - "Take home message 1" From 4bf4d063c66c5893392501e0c6e3da8a59d31e7f Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 12 Feb 2021 14:22:19 +0000 Subject: [PATCH 475/647] Update _episodes/10-diagnostics.md Co-authored-by: Niels Drost --- _episodes/10-diagnostics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 38a3cf43..df4228b5 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -19,7 +19,7 @@ keypoints: ## Introduction -The diagnostic script is an important component of ESMValTool where the actual +The diagnostic script is an important component of ESMValTool where the scientific analysis or performance metric is implemented. With ESMValTool, you can reuse an existing diagnostic, adapt and existing one for your needs or write your own new diagnostic. Diagnostics can be written in one or more open From b49d2f2b114d82d36bc5305c7e725048e5666d48 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 12 Feb 2021 14:22:31 +0000 Subject: [PATCH 476/647] Update _episodes/10-diagnostics.md Co-authored-by: Niels Drost --- _episodes/10-diagnostics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index df4228b5..44d2c555 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -22,7 +22,7 @@ keypoints: The diagnostic script is an important component of ESMValTool where the scientific analysis or performance metric is implemented. With ESMValTool, you can reuse an existing diagnostic, adapt and existing one for your needs or -write your own new diagnostic. Diagnostics can be written in one or more open +write your own new diagnostic. Diagnostics can be written in a number of open source languages such as Python, R, Julia or NCL but we will focus on understanding and writing Python diagnostics in this lesson. In order to access existing diagnostics or to write your own, please install ESMValTool in the development mode on your From 4f59ccb4f8b4a10c7887fcf532ecabeae4c80ad4 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 12 Feb 2021 14:22:44 +0000 Subject: [PATCH 477/647] Update _episodes/10-diagnostics.md Co-authored-by: Niels Drost --- _episodes/10-diagnostics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 44d2c555..941d61eb 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -23,7 +23,7 @@ The diagnostic script is an important component of ESMValTool where the scientific analysis or performance metric is implemented. With ESMValTool, you can reuse an existing diagnostic, adapt and existing one for your needs or write your own new diagnostic. Diagnostics can be written in a number of open -source languages such as Python, R, Julia or NCL but we will focus on understanding +source languages such as Python, R, Julia and NCL but we will focus on understanding and writing Python diagnostics in this lesson. In order to access existing diagnostics or to write your own, please install ESMValTool in the development mode on your machine using the instructions from [here](https://esmvalgroup.github.io/ESMValTool_Tutorial/08-development-setup/index.html). From bcbe6d4a876b0769def75e973afea8cb0066a6f4 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 12 Feb 2021 14:22:59 +0000 Subject: [PATCH 478/647] Update _episodes/10-diagnostics.md Co-authored-by: Niels Drost --- _episodes/10-diagnostics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 941d61eb..29313734 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -26,7 +26,7 @@ write your own new diagnostic. Diagnostics can be written in a number of open source languages such as Python, R, Julia and NCL but we will focus on understanding and writing Python diagnostics in this lesson. In order to access existing diagnostics or to write your own, please install ESMValTool in the development mode on your -machine using the instructions from [here](https://esmvalgroup.github.io/ESMValTool_Tutorial/08-development-setup/index.html). +machine using the instructions from [this episode](08-development-setup/index.html). ## Understanding an existing Python diagnostic We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) and the diagnostic script called by this recipe -- [diag_scripts/examples/diagnostic.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py). For reference, we have the diagnostic file in the dropdown box below. From 9e505ff2ffa029d9a9c918dfedd80f366f99143b Mon Sep 17 00:00:00 2001 From: Barbara Vreede Date: Fri, 12 Feb 2021 16:27:03 +0100 Subject: [PATCH 479/647] fix indentation and typos --- CONTRIBUTING.md | 2 +- _episodes/01-introduction.md | 2 +- _episodes/02-installation.md | 2 +- _episodes/03-configuration.md | 80 +++++++++++++++++++---------------- _episodes/04-recipe.md | 4 +- 5 files changed, 48 insertions(+), 42 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 14fe2003..8a60fd19 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -83,7 +83,7 @@ Episodes are [Markdown](https://en.wikipedia.org/wiki/Markdown) files. If you are making a new episode or contributing to existing ones, please make sure the content conforms to the [Carpentries lesson formatting][swc-lesson-formatting]. -We also, recommend using a linter to check errors in Markdown files. For +We also recommend using a linter to check errors in Markdown files. For example, a [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) can be installed as an extension in [Visual Studio diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index a21c1c98..aa91494c 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -45,7 +45,7 @@ technical steps, let's talk about what ESMValTool is all about. ESMValTool takes care of finding, opening, checking, fixing, concatenating, and preprocessing CMIP data and several other supported datasets. -The central componnent of ESMValTool that we will see in this tutorial is the +The central component of ESMValTool that we will see in this tutorial is the **recipe**. Any ESMValTool recipe is basically a set of instructions to reproduce a certain result. The basic structure of a recipe is as follows: diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 57247b22..64dad7c6 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -19,7 +19,7 @@ The instructions help with the installation of ESMValTool on operating systems like Linux/MacOSX/Windows. We use the [Conda](https://conda.io/projects/conda/en/latest/index.html) package manager to -install the ESMValTool. Other installation methods are also available, they can +install the ESMValTool. Other installation methods are also available; they can be found in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). We will first install Conda, and then ESMValTool. We end this chapter by testing diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 50166fa7..8200277d 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -71,9 +71,12 @@ For example, `write_plots: true` means that diagnostics create plots. > ## Saving preprocessed data > -> Later in this tutorial, we will want to look at the contents of the `preproc` folder. -> This folder contains preprocessed data and is removed by default when ESMValTool is run. -> In the configuration file, which settings can be modified to prevent this from happening? +> Later in this tutorial, we will want to look at the contents of the +> `preproc` folder. +> This folder contains preprocessed data and is removed by default when +> ESMValTool is run. +> In the configuration file, which settings can be modified to prevent +> this from happening? > >> ## Solution >> @@ -89,10 +92,11 @@ For example, `write_plots: true` means that diagnostics create plots. ## Destination directory -The destination directory is the rootpath where ESMValTool will store its output folders containing -e.g. figures, data, logs, etc. With every run, ESMValTool automatically generates -a new output folder determined by recipe name, and date and time using -the format: YYYYMMDD_HHMMSS. +The destination directory is the rootpath where ESMValTool will store its +output folders containing +e.g. figures, data, logs, etc. With every run, ESMValTool automatically +generates a new output folder determined by recipe name, and date and time +using the format: YYYYMMDD_HHMMSS. > ## Set the destination directory > @@ -153,28 +157,29 @@ example configuration file. >> You need to add the root path of the folder where the data is available >> to the `config-user.yml` file as: >>```yaml ->> rootpath: ->> ... ->> CMIP5: ~/esmvaltool_tutorial/data ->> CMIP6: ~/esmvaltool_tutorial/data +>> rootpath: +>> ... +>> CMIP5: ~/esmvaltool_tutorial/data +>> CMIP6: ~/esmvaltool_tutorial/data >>``` >> >> - Are you working with on a computer cluster like Jasmin or DKRZ? >> Site-specific path to the data are already listed at the end of the >> `config-user.yml` file. You need to uncomment the related lines. >> For example, on Jasmin: +>> >>```yaml ->> # Site-specific entries: Jasmin ->> # Uncomment the lines below to locate data on JASMIN ->> rootpath: ->> CMIP6: /badc/cmip6/data/CMIP6 ->> CMIP5: /badc/cmip5/data/cmip5/output1 ->> # CMIP3: /badc/cmip3_drs/data/cmip3/output ->> # OBS: /group_workspaces/jasmin4/esmeval/obsdata-v2 ->> # OBS6: /group_workspaces/jasmin4/esmeval/obsdata-v2 ->> # obs4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 ->> # ana4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 ->> # CORDEX: /badc/cordex/data/CORDEX/output +>> # Site-specific entries: Jasmin +>> # Uncomment the lines below to locate data on JASMIN +>> rootpath: +>> CMIP6: /badc/cmip6/data/CMIP6 +>> CMIP5: /badc/cmip5/data/cmip5/output1 +>> # CMIP3: /badc/cmip3_drs/data/cmip3/output +>> # OBS: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> # OBS6: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> # obs4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> # ana4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> # CORDEX: /badc/cordex/data/CORDEX/output >>``` >> >> - For more information about setting the rootpath, see also the ESMValTool @@ -217,17 +222,17 @@ information about ``drs``, you can visit the ESMValTool documentation on >> `config-user.yml` file. You need to uncomment the related lines. >> For example, on Jasmin: >>```yaml ->> # Site-specific entries: Jasmin ->> # Uncomment the lines below to locate data on JASMIN ->> drs: ->> CMIP6: BADC ->> CMIP5: BADC ->> # CMIP3: BADC ->> # CORDEX: BADC ->> # OBS: BADC ->> # OBS6: BADC ->> # obs4mips: BADC ->> # ana4mips: BADC +>> # Site-specific entries: Jasmin +>> # Uncomment the lines below to locate data on JASMIN +>> drs: +>> CMIP6: BADC +>> CMIP5: BADC +>> # CMIP3: BADC +>> # CORDEX: BADC +>> # OBS: BADC +>> # OBS6: BADC +>> # obs4mips: BADC +>> # ana4mips: BADC >>``` >> > {: .solution} @@ -236,10 +241,10 @@ information about ``drs``, you can visit the ESMValTool documentation on > ## Explain the default drs (if working on local machine) > > 1. In the previous exercise, we set the `drs` of CMIP5 data to `default`. -> Can you explain why? -> +> Can you explain why? + > 2. Have a look at the directory structure of the data. -> There is the folder `Tier1`. What does it mean? +> There is the folder `Tier1`. What does it mean? > >> ## Solution >> @@ -288,7 +293,8 @@ the tutorial, please set ESMValTool use only 1 cpu: Then, check the amount of memory you need for that by inspecting the file ``run/resource_usage.txt`` in the output directory. Using the number there you can increase the number of parallel tasks again to a reasonable number for the -amount of memory available in your system. {: .callout} +amount of memory available in your system. +{: .callout} > ## Make your own configuration file > diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index bb898037..81971544 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -239,7 +239,7 @@ distinguished in the log messages: > > Just after 'creating tasks' and before 'executing tasks', we find the > > following line in the output: > > -> > ```sh +> > ``` > > INFO [29586] These tasks will be executed: timeseries/tas_global, timeseries/tas_amsterdam, map/tas, map/script1, timeseries/script1 > > ``` > > @@ -427,7 +427,7 @@ Do you recognize the basic recipe structure that was introduced in episode 1? > `tas_global`. Both of them operate on the variable `tas` (as indicated by the > `short_name`), but they apply different preprocessors. For the diagnostic > `map` the variable group itself is named `tas`, and you'll notice that we do -> not explicitly provide the `short_name`. This is a shorthand build into +> not explicitly provide the `short_name`. This is a shorthand built into > ESMValTool. {: .callout} From 4fcd2a5848aa096951c9cb0bb0cc4fb5f6048bef Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 12 Feb 2021 15:32:21 +0000 Subject: [PATCH 480/647] Example using xarray for computing diagnostics --- _episodes/10-diagnostics.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 29313734..bf51b481 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -228,9 +228,37 @@ Finally, after grouping we read individual attributes such as the filename which the specific name of the preprocessed data file we want to read and analyse. Following this, we see the call to a function called *compute_diagnostic*. In this example, this is where the analyses on the data is done. -If you were writing your own diagnostic, this is the function you would put your own -analyses code in. +If you were writing your own diagnostic, this is the function you would write your +own code in. +## Diagnostic Computation +The *compute_diagnostic* function in this example uses a software called [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read +data from a *netCDF* file and perform the simple computation of removing any dimension +of length one. This is just an illustrative example. Iris reads data into data structures called +[cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). The data in +these cubes can be modified, combined with other cubes' data or plotted. Two +other possible ways of reading netcdf files using [xarrays](http://xarray.pydata.org/en/stable/) or [SciPy's netCDF library](https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html) +for your own diagnostics are given below. + +>## Example with xarray +> +>~~~ +>import xarray as xr #import statement at the beginning of the file +> +> +>def compute_diagnostic(filename): +> """Compute an example diagnostic.""" +> logger.debug("Loading %s", filename) +> ds = xr.open_dataset(filename) +> +> #do your analyses on the data here +> +> return ds +> +>~~~ +>{: .language-python} +> +{: .solution} From 8758f341c990c41a982d754ca97a81c19e5c33dc Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 12 Feb 2021 17:00:16 +0100 Subject: [PATCH 481/647] fix some typos --- _episodes/08-development-setup.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index f389cace..ccfe0b13 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -4,9 +4,9 @@ teaching: 10 exercises: 20 questions: - "What are the prerequisites for installing ESMValTool from source?" -- "How do I confirm that the installation was succesful?" +- "How do I confirm that the installation was successful?" objectives: -- "Execute a succesful ESMValTool installation from source" +- "Execute a successful ESMValTool installation from the source code" keypoints: - "ESMValTool is installed from source code that lives in the [GitHub repository](https://github.com/ESMValGroup/ESMValTool)" @@ -47,11 +47,11 @@ git clone https://github.com/ESMValGroup/ESMValTool.git By default, this command will create a folder called ESMValTool containing the source code of the tool. -Move into the directory to continue installation. +Move into the directory to continue the installation. > ## Attention > -> Make sure that the master branch is checked out before continuing intallation: +> Make sure that the master branch is checked out before continuing installation: > ~~~bash > git checkout master > ~~~ @@ -105,7 +105,7 @@ pip install --editable '.[develop]' ~~~ This will add the `esmvaltool` directory to the Python path in editable mode and -install the developemnt dependencies. +install the development dependencies. ## Test the installation From d4d88e01b86d4f85ded4facf4c22fd3f0cf7e3df Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 12 Feb 2021 17:50:09 +0100 Subject: [PATCH 482/647] revise questions and objectives --- _episodes/08-development-setup.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index ccfe0b13..77b9d78c 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -1,12 +1,14 @@ --- -title: "Development Setup" +title: "Development and contributions" teaching: 10 exercises: 20 questions: -- "What are the prerequisites for installing ESMValTool from source?" +- "What are the prerequisites for installing ESMValTool from the source code?" - "How do I confirm that the installation was successful?" +- "How can I incorporate new or improved codes to esmvaltool?" objectives: -- "Execute a successful ESMValTool installation from the source code" +- "Execute a successful ESMValTool installation from the source code." +- "Contribute to esmvaltool development." keypoints: - "ESMValTool is installed from source code that lives in the [GitHub repository](https://github.com/ESMValGroup/ESMValTool)" From 3d77794a8194732a8f3128fd84e61b2837b1aaeb Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 12 Feb 2021 17:53:12 +0100 Subject: [PATCH 483/647] Update 09-cmorization.md More text added to section 5. --- _episodes/09-cmorization.md | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 4819fcc0..24ecddaa 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -476,6 +476,63 @@ had so nicely pointed out for us) - We need to store the data with the correct filename so that the ESMValTool will be able to identify it later +But the very first part of the CMORizing script is a header. The header +contains information about where to obtain the data, when it was accessed +the last time, which ESMValTool "tier" it is associated with, and more +detailed information about the necessary downloading and processing steps. + +> ## Fill out the header for the "FLUXCOM" dataset +> +> Fill out the information that is necessary in the header of a CMORizing +> script for the dataset "FLUXCOM". The different parts that need to be +> present in the header are the following: +> - caption: " """ESMValTool CMORizer for FLUXCOM GPP data." +> - Tier +> - Source +> - Last access +> - Download and processing instructions +> +> > ## Answers +> > +> > The header for the "FLUXCOM" dataset could look something like this: +> > +> > ```python +> > """ESMValTool CMORizer for FLUXCOM GPP data. +> > +> > Tier +> > Tier 3: restricted dataset. +> > +> > Source +> > http://www.bgc-jena.mpg.de/geodb/BGI/Home +> > +> > Last access +> > 20190727 +> > +> > Download and processing instructions +> > From the website, select FLUXCOM as the data choice and click download. +> > Two files will be displayed. One for Land Carbon Fluxes and one for +> > Land Energy fluxes. The Land Carbon Flux file (RS + METEO) using +> > CRUNCEP data file has several data files for different variables. +> > The data for GPP generated using the +> > Artificial Neural Network Method will be in files with name: +> > GPP.ANN.CRUNCEPv6.monthly.\*.nc +> > A registration is required for downloading the data. +> > Users in the UK with a CEDA-JASMIN account may request access to the jules +> > workspace and access the data. +> > Note : This data may require rechunking of the netcdf files. +> > This constraint will not exist once iris is updated to +> > version 2.3.0 Aug 2019 +> > """ +> > ``` +> > +> > This is the header of the "FLUXCOM" CMORizer that is available with the +> > ESMValTool already. It is therefore entirely possible that your entries for +> > the section "Last access" and "Download and processing instructions" +> > differ from the example here since the entries for these sections are +> > somewhat subjective. +> > +> {: .solution} +{: .challenge} From b128c25e2d2a17f2aa20a447401c2c0bf1443f30 Mon Sep 17 00:00:00 2001 From: Barbara Vreede Date: Mon, 15 Feb 2021 10:03:39 +0100 Subject: [PATCH 484/647] remove empty line that breaks block --- _episodes/03-configuration.md | 1 - 1 file changed, 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 8200277d..095a2824 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -242,7 +242,6 @@ information about ``drs``, you can visit the ESMValTool documentation on > > 1. In the previous exercise, we set the `drs` of CMIP5 data to `default`. > Can you explain why? - > 2. Have a look at the directory structure of the data. > There is the folder `Tier1`. What does it mean? > From 725f1f877d1bcf449bddb296a97287172fb54858 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Wed, 17 Feb 2021 17:33:10 +0100 Subject: [PATCH 485/647] Update 09-cmorization.md More steps on writing the cmorizer are added (section 5). --- _episodes/09-cmorization.md | 364 +++++++++++++++++++++++++++++------- 1 file changed, 295 insertions(+), 69 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 24ecddaa..236fca94 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -534,71 +534,110 @@ detailed information about the necessary downloading and processing steps. > {: .solution} {: .challenge} - - - - -In a next step we need to create a configuration file for the dataset. This -is necessary to allow the ESMValTool to retrieve all necessary information -about the datasets, and to write the filename of the cmorized variable from -this dataset correctly. This configutation file needs to be stored in the +Now that we have made sure, that it is clear where our dataset comes from, and +how we can obtain it, the next step is to add the python code to actually read +the data. + +As we learned earlier, the DRS of the ESMValTool needs some very specific +pieces of information to build the name for each data file. Since we are now +trying to introduce a new dataset to the ESMValTool, we will have to specify +some things to make sure the dataset name can be correctly created, and +ultimately the ESMValTool knows how to look for the new dataset. + +Therefore it is necessary to create a configuration file for the new dataset. +This configutation file needs to be stored in the following folder: -``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/`` -It is imporant to note that the name of the configuration file has to be -identical to the name of our dataset. For our example the configuration file -therefore must be called ``FLUXCOM.yml``, and it can be found here: -[FLUXCOM.yml] -(https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml) - -Let's have a closer look what that configuration file contains: -```yaml ---- -# Filename -filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' - -# Common global attributes for Cmorizer output -attributes: - dataset_id: FLUXCOM - version: 'ANN-v1' - tier: 3 - modeling_realm: reanaly - project_id: OBS - source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' - reference: 'fluxcom' - comment: '' - -# Variables to cmorize -variables: - gpp: - mip: Lmon +```bash +ESMValTool/esmvaltool/cmorizers/obs/cmor_config/ ``` +It is imporant to note that the name of the configuration file has to be +identical to the name of the dataset. For our example the configuration file, +traditionally written in the ``yaml`` format, therefore must be called +``FLUXCOM.yml``. + +Let's have a closer look what that configuration file needs to contain: +- information about the filenames of the raw observation files (stored in the +"RAWOBS" folder) +- information about "global attributes" for the netCDF file that will be +created (both for the name of the file and the metadata that the file needs to +contain) +- information about the variables that need to be cmorized -The first part of this configuration file defines the filename of the raw -observations file. The second part defines the common global attributes for -the cmorizer output, e.g. information that is needed to piece together the -final observations file name in the correct structure -(see Section `6. Naming convention of the observational data files`). -Another global attribute is ``reference`` which includes a ``doi`` related to -the dataset. Please see the section `adding references -` -on how to add reference tags to the ``reference`` section in the configuration -file. If a single dataset has more than one reference, -it is possible to add tags as a list e.g. ``reference: ['tag1', 'tag2']``. -The third part in the configuration file defines the variables that are -supposed to be cmorized. - -in the directory ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/``. Note -that the name of this configuration file has to be identical to the name of -your data set. It is recommended that you set ``project`` to ``OBS6`` in the -configuration file. That way, the variables defined in the CMIP6 CMOR table, -augmented with the custom variables described above, are available to your script. - -The actual cmorizing script ``cmorize_obs_mte.py`` consists of a header with -information on where and how to download the data, and noting the last access -of the data webpage. - -The main body of the CMORizer script must contain a function called +> ## Let's create the configuration file for the "FLUXCOM" dataset +> +> Here is the skeleton of the "FLUXCOM" configuration file as it exists in +> the ESMValTool framework. Try to fill in all missing pieces of information +> for this configuration file that are marked with ``???``. +> +> ```yaml +> --- +> # Filename +> filename: ??? +> +> # Common global attributes for Cmorizer output +> attributes: +> dataset_id: ??? +> version: ??? +> tier: ??? +> modeling_realm: ??? +> project_id: ??? +> source: ??? +> reference: ??? +> comment: ??? +> +> # Variables to cmorize +> variables: +> ???: +> mip: ??? +> ``` +> +> > ## Answers +> > +> > The configuration file for the "FLUXCOM" dataset with all necessary pieces +> > of information looks like this: +> > +> > ```yaml +> > --- +> > # Filename +> > filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' +> > +> > # Common global attributes for Cmorizer output +> > attributes: +> > dataset_id: FLUXCOM +> > version: 'ANN-v1' +> > tier: 3 +> > modeling_realm: reanaly +> > project_id: OBS +> > source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' +> > reference: 'fluxcom' +> > comment: '' +> > +> > # Variables to cmorize +> > variables: +> > gpp: +> > mip: Lmon +> > ``` +> > +> > The original configuration file for the "FLUXCOM" dataset can be +> > found here: +> > [FLUXCOM.yml] +> > (https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml) +> > +> > Note the attribute "reference" here: it should include a ``doi`` related +> > to the dataset. For more information on how to add references to the +> > ``reference`` section of the configuration file, see the section in the +> > documentation about this: [adding references] +> > (https://docs.esmvaltool.org/en/latest/community/diagnostic.html#adding-references) +> > +> > If a single dataset has more than one reference, it is possible to add +> > tags as a list e.g. ``reference: ['tag1', 'tag2']``. +> {: .solution} +{: .challenge} + +Now that we have defined the configuration file for our "FLUXCOM" data, we can +finally start writing the actual code for the CMORizer script. The main body +of the CMORizer script must contain a function called ```python def cmorization(in_dir, out_dir, cfg, config_user): @@ -607,19 +646,20 @@ def cmorization(in_dir, out_dir, cfg, config_user): with this exact call signature. Here, ``in_dir`` corresponds to the input directory of the raw files, ``out_dir`` to the output directory of final reformatted data set and ``cfg`` to the configuration dictionary given by -the ``.yml`` configuration file. The return value of this function is ignored. All -the work, i.e. loading of the raw files, processing them and saving the final -output, has to be performed inside its body. To simplify this process, ESMValTool -provides a set of predefined utilities.py_, which can be imported into your CMORizer -by +the ``.yml`` configuration file. The return value of this function is ignored. +All the work, i.e. loading of the raw files, processing them and saving the +final output, has to be performed inside its body. To simplify this process, +ESMValTool provides a set of predefined utilities.py_, which can be imported +into your CMORizer by ```python from . import utilities as utils ``` -Apart from a function to easily save data, this module contains different kinds -of small fixes to the data attributes, coordinates, and metadata which are -necessary for the data field to be CMOR-compliant. +Apart from a function to easily save data, this module contains different +kinds of small fixes to the data attributes, coordinates, and metadata which +are necessary for the data field to be CMOR-compliant. We will come back to +these functionalities in a bit. Note that this specific CMORizer script contains several subroutines in order to make the code clearer and more readable (we strongly recommend to follow @@ -627,6 +667,192 @@ that code style). For example, the function ``_get_filepath`` converts the raw filepath to the correct one and the function ``_extract_variable`` extracts and saves a single variable from the raw data. +After all that theory, let's have a look at the actualy python code of the +existing "FLUXCOM" CMORizer script. For now, we only want to read in the data +and then store it in a new file. + +```python +"""ESMValTool CMORizer for FLUXCOM GPP data. + +Tier + Tier 3: restricted dataset. + +Source + http://www.bgc-jena.mpg.de/geodb/BGI/Home + +Last access + 20190727 + +Download and processing instructions + From the website, select FLUXCOM as the data choice and click download. + Two files will be displayed. One for Land Carbon Fluxes and one for + Land Energy fluxes. The Land Carbon Flux file (RS + METEO) using + CRUNCEP data file has several data files for different variables. + The data for GPP generated using the + Artificial Neural Network Method will be in files with name: + GPP.ANN.CRUNCEPv6.monthly.*.nc + A registration is required for downloading the data. + Users in the UK with a CEDA-JASMIN account may request access to the jules + workspace and access the data. + Note : This data may require rechunking of the netcdf files. + This constraint will not exist once iris is updated to + version 2.3.0 Aug 2019 +""" +import logging +import os +import re +import numpy as np +import iris +from . import utilities as utils + +logger = logging.getLogger(__name__) + + +def _get_filepath(in_dir, basename): + """Find correct name of file (extend basename with timestamp).""" + regex = re.compile(basename) + + all_files = [ + f for f in os.listdir(in_dir) + if os.path.isfile(os.path.join(in_dir, f)) + ] + for filename in all_files: + if regex.match(filename): + return os.path.join(in_dir, basename) + raise OSError( + f"Cannot find input file matching pattern '{basename}' in '{in_dir}'") + + +def _extract_variable(cmor_info, attrs, filepath, out_dir): + """Extract variable.""" + var = cmor_info.short_name + logger.info("Var is %s", var) + cubes = iris.load(filepath) + for cube in cubes: + logger.info("Saving file") + utils.save_variable(cube, + var, + out_dir, + attrs, + unlimited_dimensions=['time']) + + +def cmorization(in_dir, out_dir, cfg, _): + """Cmorization func call.""" + glob_attrs = cfg['attributes'] + cmor_table = cfg['cmor_table'] + filepath = _get_filepath(in_dir, cfg['filename']) + logger.info("Found input file '%s'", filepath) + + # Run the cmorization + for (var, var_info) in cfg['variables'].items(): + logger.info("CMORizing variable '%s'", var) + glob_attrs['mip'] = var_info['mip'] + logger.info(var_info['mip']) + cmor_info = cmor_table.get_variable(var_info['mip'], var) + _extract_variable(cmor_info, glob_attrs, filepath, out_dir) +``` + +Let's run this CMORizing script to see if the dataset is read correctly, and +what kind of file is written out. Tere is a specific command available in the +ESMValTool to run the CMORizing scripts: + +```bash +cmorize_obs -c -o +``` + +The ``config-user-yml`` is the file in which we define the different data +paths, e.g. where the ESMValTool would find the "RAWOBS" folder. The +``dataset-name`` needs to be idential to the folder name that was created +to store the raw observation data files, in our case this would be "FLUXCOM". +The ESMValTool will create a folder with the correct tier information in your +defined output directory if that tier folder is not already available, and +then a folder named after the data set. In this folder the cmorized data set +will be stored as a netCDF file. If your run was successful, one or more +NetCDF files are produced in your output directory. + +> ## Was the CMORization successful so far?! +> +> If you check the folders in your output path, you should see the following +> folder structure: +> ```bash +> /Tier3/FLUXCOM/ +> ``` +> +> Within the "FLUXCOM" folder there should be a NetCDF file with the name: +> ```bash +> OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_xxxx01-xxxx12.nc +> ``` +> +> The "xxxx" represents the start year of the data period you wanted to +> CMORize, and the "yyyy" represents the end year. +> +{: .callout} + +Great! +So we have produced a NetCDF file with the CMORizer that follows the naming +convention for ESMValTool datasets. Let's have a look at the NetCDF file as +it was written with the very basic CMORizer from above (note, we are only +looking at the year 1980 in our example). + +```bash +netcdf OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012 { +dimensions: + time = UNLIMITED ; // (12 currently) + lat = 360 ; + lon = 720 ; +variables: + float GPP(time, lat, lon) ; + GPP:_FillValue = 1.e+20f ; + GPP:long_name = "GPP" ; + double time(time) ; + time:axis = "T" ; + time:units = "days since 1582-10-15 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "gregorian" ; + double lat(lat) ; + double lon(lon) ; + +// global attributes: + :_NCProperties = "version=2,netcdf=4.7.4,hdf5=1.10.6" ; + :created_by = "Fabian Gans [fgans@bgc-jena.mpg.de], Ulrich Weber [uweber@bgc-jena.mpg.de]" ; + :flux = "GPP" ; + :forcing = "CRUNCEPv6" ; + :institution = "MPI-BGC-BGI" ; + :invalid_units = "gC m-2 day-1" ; + :method = "Artificial Neural Networks" ; + :provided_by = "Martin Jung [mjung@bgc-jena.mpg.de] on behalf of FLUXCOM team" ; + :reference = "Jung et al. 2016, Nature; Tramontana et al. 2016, Biogeosciences" ; + :temporal_resolution = "monthly" ; + :title = "GPP based on FLUXCOM RS+METEO with CRUNCEPv6 climate " ; + :version = "v1" ; + :Conventions = "CF-1.7" ; +} +``` + +The file contains a variable named "GPP" that contains three dimensions: +"time", "lat", "lon". The units for this variable are not defined yet. +The ESMValTool did not know how to convert from the +original units to the units that are defined in the CMOR table for the +variable "gpp". The original units are therefore listed in the "global +attributes" section as ``invalid_units``. The ESMValTool recognized that the +units given in the original file did not match the units given in the CMOR +table and therefore put the information about the units in the metadata. + +If we test this NetCDF file now with our CMOR checker +```bash +esmvaltool run recipe_check_fluxcom.yml --log_level debug +``` +we will encounter an error again. The dataset is not correctly CMORized, and +the first thing that the ESMValTool complains about is: +```bash +iris.exceptions.UnitConversionError: Cannot convert from unknown units. The +"units" attribute may be set directly. +``` + +Ok, so let's fix the units of the "GPP" variable in the CMORizer. + + .. utilities.py: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/utilities.py From c4a26f28d71f83e68132325b2eaa339efb34a79e Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 18 Feb 2021 09:12:58 +0100 Subject: [PATCH 486/647] Updata data flow figure --- fig/data_flow.png | Bin 84827 -> 84052 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/fig/data_flow.png b/fig/data_flow.png index f441530cb86b0ca4ab3afb0eb32db627d1656eb6..99d7efa2e4ee7ee8285fc4b116ff1e6625599443 100644 GIT binary patch literal 84052 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 Jg@*lu{{cj1HUIzs literal 84827 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 X+^#mg%yc}D3H@WxmZ$5DJmUWcd Date: Thu, 18 Feb 2021 13:48:26 +0100 Subject: [PATCH 487/647] revise title, questions, and keypoints --- _episodes/08-development-setup.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 77b9d78c..3b193947 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -1,22 +1,22 @@ --- -title: "Development and contributions" +title: "Development and contribution" teaching: 10 exercises: 20 questions: -- "What are the prerequisites for installing ESMValTool from the source code?" -- "How do I confirm that the installation was successful?" +- "What is a development installation?" +- "How can I test new or improved codes?" - "How can I incorporate new or improved codes to esmvaltool?" + objectives: - "Execute a successful ESMValTool installation from the source code." - "Contribute to esmvaltool development." + keypoints: -- "ESMValTool is installed from source code that lives in the [GitHub - repository](https://github.com/ESMValGroup/ESMValTool)" -- "All the required packages can be installed using conda and the - [environment.yml - file](https://github.com/ESMValGroup/ESMValTool/blob/master/environment.yml)" -- "You can find more information about installation in the - [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html)" +- "A development installation is needed if you want latest features or to incorporate your codes." +- "Contributions include adding a new or improved script or helping with a review process." +- "There are several tools to check te quality of your code." +- "It is possible to run tests on your machine." +- "You can build documentations locally." --- So you want to contribute code to ESMValTool. What follows describes a From 1169a074a5f1368f64a354776c0e01eb8c0cf786 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Thu, 18 Feb 2021 14:53:27 +0100 Subject: [PATCH 488/647] Update 09-cmorization.md Finishing touches on Section 5, and combining Section 5 with Section 6. --- _episodes/09-cmorization.md | 168 +++++++++++++++++++++++++++++++----- 1 file changed, 148 insertions(+), 20 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 236fca94..b44cb7c9 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -186,7 +186,7 @@ know we have completed our task. Try to run the example recipe with ```bash -esmvaltool run recipe_check_fluxnet.yml --log_level debug +esmvaltool run recipe_check_fluxcom.yml --log_level debug ``` The `log_level` flag ensures that all relevant information is included in the @@ -850,43 +850,171 @@ iris.exceptions.UnitConversionError: Cannot convert from unknown units. The "units" attribute may be set directly. ``` -Ok, so let's fix the units of the "GPP" variable in the CMORizer. +Ok, so let's fix the units of the "GPP" variable in the CMORizer. For that +we add the following three lines to the code in the section +``_extract_variable``: +```python +# convert data from gc/m2/day to kg/m2/s +cube = cube / (1000 * 86400) +cube.units = 'kg m-2 s-1' +``` -.. utilities.py: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/utilities.py +The whole section should not look then look like this: +```python +def _extract_variable(cmor_info, attrs, filepath, out_dir): + """Extract variable.""" + var = cmor_info.short_name + logger.info("Var is %s", var) + cubes = iris.load(filepath) + for cube in cubes: + # convert data from gc/m2/day to kg/m2/s + cube = cube / (1000 * 86400) + cube.units = 'kg m-2 s-1' -## 6. Run the CMORizer script + logger.info("Saving file") + utils.save_variable(cube, + var, + out_dir, + attrs, + unlimited_dimensions=['time']) -The cmorizing script for the given dataset can be run with: +``` + +If we run the CMORizer script now again with the ``cmorize_obs`` call we +get a NetCDF file that has fixed units, but has an "unknown" variable name. ```bash -cmorize_obs -c -o +... +variables: + float unknown(time, lat, lon) ; + unknown:_FillValue = 1.e+20f ; + unknown:units = "kg m-2 s-1" ; + double time(time) ; + time:axis = "T" ; + time:units = "days since 1582-10-15 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "gregorian" ; + double lat(lat) ; + double lon(lon) ; +... ``` -> ## Note +We will have to do some more code tweaking then. But we also have not fixed +the problem with the coordinates ``lat`` and ``lon`` yet. There is no "units" +or "standard_name" given for either of these coordinates which will cause a +problem for the ESMValTool. Such some smaller formatting problems can occur +relatively often for coordinates like ``lat``, ``lon`` or ``time``. This means +that these problems need fixing in many CMORizers. Therefore there are common +functions available within the ESMValTool that one can import and use in the +new CMORizer script. The functions, written in python, are stored in the folder +[utilities.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/utilities.py) + +> ## Finalizing the "FLUXCOM" CMORizer > -> The output path given in the configuration file is the path where -> your cmorized dataset will be stored. The ESMValTool will create a folder -> with the correct tier information (see Section `2. Edit your configuration file`) if that tier folder is not -> already available, and then a folder named after the data set. In this -> folder the cmorized data set will be stored as a netCDF file. -{: .callout} - -If your run was successful, one or more NetCDF files are produced in your -output directory. - -> ## Check that your cmoriziation was successful +> The task is now to work with the functions in the file "utilities.py" to +> complete the CMORizer for the "FLUXCOM" dataset so that it can be read by +> the ESMValTool. The definitions of the coordinates and the variable "gpp" +> should look like the following after the successful CMORization: +> +> ```bash +> variables: +> float gpp(time, lat, lon) ; +> gpp:_FillValue = 1.e+20f ; +> gpp:standard_name = "gross_primary_productivity_of_carbon" ; +> gpp:long_name = "Carbon Mass Flux out of Atmosphere due to Gross Primary Production on Land" ; +> gpp:units = "kg m-2 s-1" ; +> double time(time) ; +> time:axis = "T" ; +> time:bounds = "time_bnds" ; +> time:units = "days since 1950-1-1 00:00:00" ; +> time:standard_name = "time" ; +> time:calendar = "gregorian" ; +> double time_bnds(time, bnds) ; +> double lat(lat) ; +> lat:axis = "Y" ; +> lat:bounds = "lat_bnds" ; +> lat:units = "degrees_north" ; +> lat:standard_name = "latitude" ; +> lat:long_name = "latitude coordinate" ; +> double lat_bnds(lat, bnds) ; +> double lon(lon) ; +> lon:axis = "X" ; +> lon:bounds = "lon_bnds" ; +> lon:units = "degrees_east" ; +> lon:standard_name = "longitude" ; +> lon:long_name = "longitude coordinate" ; +> double lon_bnds(lon, bnds) ; +> ``` > -> Check your output directory for the freshly produced NetCDF file. +> For that to happen, you will have to fix/work on the following things: +> - adding standard names to the dimensions ``lat`` and ``lon`` +> - fix the metadata for the variable "gpp" +> - change the time units to start in the year 1950 +> - make the coordinates CMOR-compliant +> - set global attributes for the data file > > > ## Answers > > -> > Write the answer here. +> > To fully CMORize the "FLUXCOM" dataset, you need to add the following +> > lines of code to the ``_extract_variable`` function of your CMORizer +> > script: +> > +> > ```python +> > def _extract_variable(cmor_info, attrs, filepath, out_dir): +> > """Extract variable.""" +> > var = cmor_info.short_name +> > logger.info("Var is %s", var) +> > cubes = iris.load(filepath) +> > for cube in cubes: +> > # convert data from gc/m2/day to kg/m2/s +> > cube = cube / (1000 * 86400) +> > cube.units = 'kg m-2 s-1' +> > +> > # The following two lines are needed for iris.util.guess_coord_axis +> > cube.coord('lat').standard_name = 'latitude' +> > cube.coord('lon').standard_name = 'longitude' +> > utils.fix_var_metadata(cube, cmor_info) +> > utils.convert_timeunits(cube, 1950) +> > utils.fix_coords(cube) +> > utils.set_global_atts(cube, attrs) +> > utils.flip_dim_coord(cube, 'latitude') +> > coord = cube.coord('latitude') +> > coord.bounds = np.flip(coord.bounds, axis=1) +> > logger.info("Saving file") +> > utils.save_variable(cube, +> > var, +> > out_dir, +> > attrs, +> > unlimited_dimensions=['time']) +> > +> > ``` > > > {: .solution} {: .challenge} +So now we can finally run our new CMORizing script to produce an ESMValTool +readable datafile of the "FLUXCOM" dataset. As already mentioned, the call +to run a CMORizing script is as follows: + +```bash +cmorize_obs -c -o +``` + +If your run was successful, you should have gotten no error message in the +ESMValTool logging information and one or more NetCDF files should have been +produced in your output directory. + +To make sure that the CMORization has really worked as planned, we run the +CMOR checker on this newly produced NetCDF file. If the ESMValTool can read +the data without problems, you should see as one of the last lines of +ESMValTool output: + +```bash +INFO Run was successful +``` + ## Conclusion From e7216b415bd12c4bf9a7ebf55b9dbcbd9cf3d10d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 18 Feb 2021 17:35:06 +0100 Subject: [PATCH 489/647] revise installation section, add contribution --- _episodes/08-development-setup.md | 142 ++++++++++++++---------------- 1 file changed, 66 insertions(+), 76 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 3b193947..a3bbc565 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -5,11 +5,11 @@ exercises: 20 questions: - "What is a development installation?" - "How can I test new or improved codes?" -- "How can I incorporate new or improved codes to esmvaltool?" +- "How can I incorporate new or improved codes to ESMValTool?" objectives: - "Execute a successful ESMValTool installation from the source code." -- "Contribute to esmvaltool development." +- "Contribute to ESMValTool development." keypoints: - "A development installation is needed if you want latest features or to incorporate your codes." @@ -19,122 +19,112 @@ keypoints: - "You can build documentations locally." --- -So you want to contribute code to ESMValTool. What follows describes a -development installation to help you get going. +We now know how ESMValTool works, but how do we develop it? +This lesson helps to run your own codes with ESMValTool and +illustrates how to incorporate your codes into the tool. -> ## Attention +> ## Git knowledge > -> - This episode is based on the ESMValTool installation instructions, for -> more information and advanced cases you can visit the ESMValTool -> [documentation](https://esmvaltool.readthedocs.io/en/latest/getting_started/install.html). -> -> - For this episode it is assumed you have knowledge of -> [git](https://git-scm.com/). You can refresh your knowledge in the -> corresponding [git carpentries -> course](http://swcarpentry.github.io/git-novice/). +> For this episode you need some knowledge of +> [Git](https://git-scm.com/). You can refresh your knowledge in the +> corresponding [Git carpentries course](http://swcarpentry.github.io/git-novice/). {: .callout} -## Obtaining the source code +## Development installation + +To run new codes by ESMValTool, we need to install it in a ``develop`` mode. +Let’s get started. + +### 1 Source code The ESMValTool source code is available on a public GitHub repository: [https://github.com/ESMValGroup/ESMValTool](https://github.com/ESMValGroup/ESMValTool) - -The easiest way to obtain it is to clone the repository using git. To clone the -public repository open a terminal window and type: +To obtain the code, the easiest way is to clone the repository: ~~~bash git clone https://github.com/ESMValGroup/ESMValTool.git ~~~ -By default, this command will create a folder called ESMValTool containing the -source code of the tool. +This command will create a folder called ESMValTool containing +the source code of the tool. To continue the installation, move into the directory +and check out the ``master`` branch: -Move into the directory to continue the installation. - -> ## Attention -> -> Make sure that the master branch is checked out before continuing installation: -> ~~~bash -> git checkout master -> ~~~ -{: .callout} +~~~bash +cd ESMValTool +git checkout master +~~~ -## Prerequisites +### 2 ESMValTool dependencies It is recommended to use conda to manage ESMValTool dependencies. For a minimal -conda installation go to -[https://conda.io/miniconda.html](https://conda.io/miniconda.html). To simplify -the installation process, an environment definition file is provided in the -repository (``environment.yml`` in the root folder). - -> ## Attention -> It is preferable to use a local, fully user-controlled conda installation. If -> you have conda installed already, make sure it is up to date by running -> ``conda update -n base conda``. -{: .callout} - -From now on, we will assume that the installation is going to be done through -conda. - -Ideally, you should create a dedicated conda environment for ESMValTool, so it -is independent from any other Python tools present in the system. - -To create an environment, go to the directory containing the ESMValTool source -code (called ESMValTool if you did not choose a different name) and run +conda installation, see section **Install Conda**, in lesson +[Installation]({{ page.root }}{% link _episodes/02-installation.md %}). +To simplify the installation process, an environment file ``environment.yml`` is +provided in the ESMValTool direcotry. To create an environment run: ~~~bash -conda env create --name esmvaltool --file environment.yml +conda env create --file environment.yml ~~~ -The environment is called ``esmvaltool`` by default, but it is possible to use -the option ``--name ENVIRONMENT_NAME`` to define a custom name. You can activate -the environment using the command: +The environment is called ``esmvaltool`` by default. Let's activate the environment: ~~~bash conda activate esmvaltool ~~~ -If you run into trouble, please try recreating the environment. More information -can be found in the [conda documentation](https://docs.conda.io/en/latest/). - -## Software installation +### 3 ESMValTool installation -Once all prerequisites are fulfilled, ESMValTool can be installed by running -the following commands in the directory containing the ESMValTool source code: +ESMValTool can be installed in a ``develop`` mode by running: ~~~bash pip install --editable '.[develop]' ~~~ This will add the `esmvaltool` directory to the Python path in editable mode and -install the development dependencies. - -## Test the installation - -The next step is to check that the installation works properly. -To do this, run the tool with: +install the development dependencies. We should check if the installation +works properly. To do this, run the tool with: ~~~bash esmvaltool --help ~~~ If everything was installed properly, ESMValTool should have printed a -help message to the console. - -For a more complete installation verification, run the automated tests and -confirm that no errors are reported: +help message to the console. For a more complete installation verification, +we can run the automated tests: ~~~bash python setup.py test --installation ~~~ -> ## ESMValCore -> -> Most core functionality for the ESMValTool is available in the -> [ESMValCore](https://github.com/ESMValGroup/ESMValCore) Python package. If -> your contribution in ESMValTool needs changes to ESMValCore please follow [its -> contribution -> guide](https://github.com/ESMValGroup/ESMValCore/blob/master/CONTRIBUTING.md). -{: .callout} +## Contribution + +ESMValTool is an open-source project in ESMValGroup. +You can contribute to its development by: + +- a new or updated recipe script, see lesson on +[Writing your own recipe] +- a new or updated diagnostics script, see lesson on +[Writing your own diagnostic script] +- a new or updated cmorizer script, see lesson on +[CMORization: Using observational datasets] +- helping with reviewing process of pull requests, see documentation on +[Review of pull requests](https://docs.esmvaltool.org/en/latest/community/review.html) + +If you would like to add what is already discussed in an +[issue](https://github.com/ESMValGroup/ESMValTool/issues) in ESMValTool repository, +you need to create a new branch locally and checkout it. To do this, follow the commands: + +~~~bash +cd ESMValTool +git checkout master +git pull +git checkout -b your_branch_name +~~~ + +## Run tests + +## Build documentation + + {% include links.md %} From 390706b109c23fa6ed9e3682943ae6a271eb4769 Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 19 Feb 2021 10:00:21 +0100 Subject: [PATCH 490/647] Update 09-cmorization.md Finishing the first draft of this episode. --- _episodes/09-cmorization.md | 61 ++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index b44cb7c9..148ff725 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -1015,39 +1015,32 @@ ESMValTool output: INFO Run was successful ``` - - -## Conclusion - - +## Last steps + +Congratulations! You have successfully CMORized a new dataset! +Since you have gone through all the trouble to reformat the dataset so that +the ESMValTool can work with it, it would be great if you could provide the +CMORizer, und ultimately with that the dataset, to the rest of the community. +To do that there are a few more steps you have to do: +1. Open a pull request in the ESMValTool repository describing the dataset briefly +2. Add the info of your dataset to the User Guide so that people know it is available for the ESMValTool [Obtaining input data](https://github.com/ESMValGroup/ESMValTool/blob/master/doc/sphinx/source/input.rst) +3. Make sure that there is a reference file available for the dataset [BibTeX info file](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) + +More information about working with pull requests are available in the ESMValTool +documentation under [Contributing a review](https://esmvaltool--1920.org.readthedocs.build/en/1920/community/review.html) + +## Some last comments + +Adding a new CMORizer to the ESMValTool is definitely already an advanced task +when working with the ESMValTool. You have to have a basic understanding of +how the ESMValTool works and how it's internal structure looks like. In +addition, you need to have a basic understanding of NetCDF files and a +programming language. In our example we used python for the CMORizing script +since we advocate for focusing the code development on only a few different +programming languages. This helps to maintain the code and to ensure the +compatibility of the code with possible fundamental changes to the structure +of the ESMValTool and ESMValCore. + +More information about adding observations to the ESMValTool can be found in the [documentation](https://docs.esmvaltool.org/en/latest/input.html#observations) -## For development purposes - -Here are some of the elements that we can add - -> ## Example exercise -> -> This is just a reminder on how to implement exercises -> -> > ## Example answer -> > -> > And this is where to add the answer. -> > This box will be collapsed in the page is first loaded. -> > -> {: .solution} -{: .challenge} - -```bash -example command line instruction -``` - -``` -example error message -``` -{: .error} - -> ## Example callout box -> -> This is how to create a callout box -{: .callout} From 193e1484f008f4ab03bf68bfc38929ab981bf96c Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Fri, 19 Feb 2021 10:01:00 +0100 Subject: [PATCH 491/647] Update 09-cmorization.md --- _episodes/09-cmorization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 148ff725..1e18959b 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -1029,7 +1029,7 @@ To do that there are a few more steps you have to do: More information about working with pull requests are available in the ESMValTool documentation under [Contributing a review](https://esmvaltool--1920.org.readthedocs.build/en/1920/community/review.html) -## Some last comments +## Some final comments Adding a new CMORizer to the ESMValTool is definitely already an advanced task when working with the ESMValTool. You have to have a basic understanding of From 0cab5511a01635d83c6885ee58250f9ed500acce Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Mon, 22 Feb 2021 14:50:39 +0100 Subject: [PATCH 492/647] Update 09-cmorization.md Fixing some minor things. --- _episodes/09-cmorization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 1e18959b..5aeac638 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -384,7 +384,7 @@ You can then edit the content and save it as ``CMOR_.dat``. > {: .solution} {: .challenge} -## 5. Create a CMORizer for the new dataset +## Create a CMORizer for the new dataset Now that we have the data ready, have told the ESMValTool where to look for it, and have made sure that our variable of choice is listed either @@ -400,7 +400,7 @@ reformatting for the dataset. > > ## Answers > > > > ```bash -> > esmvaltool run recipe_check_fluxnet.yml --log_level debug +> > esmvaltool run recipe_check_fluxcom.yml --log_level debug > > ``` > > > > The ESMValTool should now find your FLUXCOM datafile, and the error From 810c4fdcfe03243f13bc0aa2245ecde14a806aae Mon Sep 17 00:00:00 2001 From: Birgit Hassler <33543691+hb326@users.noreply.github.com> Date: Mon, 22 Feb 2021 15:01:31 +0100 Subject: [PATCH 493/647] Update 09-cmorization.md Adjusting some explanations to make the story line clearer. --- _episodes/09-cmorization.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 5aeac638..91a3348e 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -386,11 +386,20 @@ You can then edit the content and save it as ``CMOR_.dat``. ## Create a CMORizer for the new dataset -Now that we have the data ready, have told the ESMValTool where to look -for it, and have made sure that our variable of choice is listed either -on a pre-existing or custom CMOR table, let's test if the data is actually -following the necessary CMOR standard already, or if we have to do some -reformatting for the dataset. +Now that we have the data ready, our first assumption would be that the data +is already following the CMOR standard. So we store the file in the "OBS6" +folder of our data path, and rename it manually to an ESMValTool readable +name. For our example of the "FLUXCOM" data that we downloaded (which is +from the year 2000) the name of the dataset would then be: + +```bash +OBS6_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_200001-200012.nc +``` + +We also have made sure that our variable of choice is listed either +on a pre-existing or custom CMOR table. So now we are ready to test +if the data is actually following the necessary CMOR standard already, +or if we have to do some reformatting for the dataset. > ## Run the test recipe again > From 36ad014ec6a55bf5c232d87841df2f1853aeaaff Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 22 Feb 2021 16:35:39 +0100 Subject: [PATCH 494/647] polish the text --- _episodes/08-development-setup.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index a3bbc565..b7bf88d8 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -12,27 +12,29 @@ objectives: - "Contribute to ESMValTool development." keypoints: -- "A development installation is needed if you want latest features or to incorporate your codes." +- "A development installation is needed if you want to incorporate your codes." - "Contributions include adding a new or improved script or helping with a review process." -- "There are several tools to check te quality of your code." +- "There are several tools to check the quality of your code." - "It is possible to run tests on your machine." - "You can build documentations locally." --- We now know how ESMValTool works, but how do we develop it? -This lesson helps to run your own codes with ESMValTool and -illustrates how to incorporate your codes into the tool. +This lesson helps to run your own codes with ESMValTool. +It also illustrates how to incorporate your codes into the tool. > ## Git knowledge > -> For this episode you need some knowledge of +> For this episode, you need some knowledge of > [Git](https://git-scm.com/). You can refresh your knowledge in the > corresponding [Git carpentries course](http://swcarpentry.github.io/git-novice/). {: .callout} ## Development installation -To run new codes by ESMValTool, we need to install it in a ``develop`` mode. +We’ll explore how ESMValTool can be installed it in a ``develop`` mode. +Even if you aren’t collaborating with the community, this installation is needed +to run your new codes by ESMValTool. Let’s get started. ### 1 Source code @@ -88,7 +90,7 @@ works properly. To do this, run the tool with: esmvaltool --help ~~~ -If everything was installed properly, ESMValTool should have printed a +If everything is installed properly, ESMValTool prints a help message to the console. For a more complete installation verification, we can run the automated tests: @@ -102,7 +104,7 @@ ESMValTool is an open-source project in ESMValGroup. You can contribute to its development by: - a new or updated recipe script, see lesson on -[Writing your own recipe] +[Writing your own recipe]({{ page.root }}{% link _episodes/05-preprocessor.md %}) - a new or updated diagnostics script, see lesson on [Writing your own diagnostic script] - a new or updated cmorizer script, see lesson on @@ -110,8 +112,8 @@ You can contribute to its development by: - helping with reviewing process of pull requests, see documentation on [Review of pull requests](https://docs.esmvaltool.org/en/latest/community/review.html) -If you would like to add what is already discussed in an -[issue](https://github.com/ESMValGroup/ESMValTool/issues) in ESMValTool repository, +If you would like to add **what is already discussed in an +[issue](https://github.com/ESMValGroup/ESMValTool/issues)** in ESMValTool repository, you need to create a new branch locally and checkout it. To do this, follow the commands: ~~~bash @@ -121,6 +123,9 @@ git pull git checkout -b your_branch_name ~~~ +## Check code quality + + ## Run tests ## Build documentation From 45dea2728f9190f54f1952e3bc6df2a4d94658f0 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 23 Feb 2021 13:06:08 +0100 Subject: [PATCH 495/647] revise the GitHUb workflow section --- _episodes/08-development-setup.md | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index b7bf88d8..1db5e48f 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -101,7 +101,7 @@ python setup.py test --installation ## Contribution ESMValTool is an open-source project in ESMValGroup. -You can contribute to its development by: +We can contribute to its development by: - a new or updated recipe script, see lesson on [Writing your own recipe]({{ page.root }}{% link _episodes/05-preprocessor.md %}) @@ -112,9 +112,22 @@ You can contribute to its development by: - helping with reviewing process of pull requests, see documentation on [Review of pull requests](https://docs.esmvaltool.org/en/latest/community/review.html) -If you would like to add **what is already discussed in an -[issue](https://github.com/ESMValGroup/ESMValTool/issues)** in ESMValTool repository, -you need to create a new branch locally and checkout it. To do this, follow the commands: +The next sections will explore the ways we can achieve this. + +### GitHub workflow + +We first discuss our idea in an +**[issue](https://github.com/ESMValGroup/ESMValTool/issues)** in ESMValTool repository. + +Then, we create a new ``branch`` locally and start developing new codes. +Once our development is finished, we can initiate a ``pull request``. +The pull request will then be tested, discussed and merged. This is called "**review process**". +For a full description of the workflow, please see ESMValTool documentation on +[Contributing to the community » GitHub Workflow](https://docs.esmvaltool.org/en/latest/community/repository.html#github-workflow). + +Using the workflow will take some effort and time to learn. +However, a few “tools” i.e. command lines gets you a long way, +and we’ll cover those essentials in this lesson. ~~~bash cd ESMValTool @@ -123,12 +136,12 @@ git pull git checkout -b your_branch_name ~~~ -## Check code quality +### Check code quality -## Run tests +### Run tests -## Build documentation +### Build documentation From bbc30fc11868ea4253cba908195a65f1c121c158 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 23 Feb 2021 13:49:34 +0100 Subject: [PATCH 496/647] revise section code quality --- _episodes/08-development-setup.md | 45 ++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 1db5e48f..07e5f6af 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -122,22 +122,49 @@ We first discuss our idea in an Then, we create a new ``branch`` locally and start developing new codes. Once our development is finished, we can initiate a ``pull request``. The pull request will then be tested, discussed and merged. This is called "**review process**". -For a full description of the workflow, please see ESMValTool documentation on -[Contributing to the community » GitHub Workflow](https://docs.esmvaltool.org/en/latest/community/repository.html#github-workflow). Using the workflow will take some effort and time to learn. However, a few “tools” i.e. command lines gets you a long way, and we’ll cover those essentials in this lesson. - -~~~bash -cd ESMValTool -git checkout master -git pull -git checkout -b your_branch_name -~~~ +For a full description of the workflow, please see ESMValTool documentation on +[Contributing to the community » GitHub Workflow](https://docs.esmvaltool.org/en/latest/community/repository.html#github-workflow). ### Check code quality +We aim to adhere to best practices and coding standards. The good news is that there are +several tools that we can use to check our code against those standards. + +As an example, ``Pre-commit`` is a tool that checks your code for any invalid syntax and formatting errors. +To explore other tools, have a look at ESMValTool documentation on +[Code style](https://docs.esmvaltool.org/en/latest/community/introduction.html#code-style). + +> ## Using Pre-commit +> +> Let's checkout our local branch and add the script +> [warming_stripes.py](../files/warming_stripes.py) to the ``example`` directory. +> +> ~~~bash +> cd ESMValTool +> git checkout your_branch_name +> cp path_of_warming_stripes.py esmvaltool/diag_scripts/examples/ +> ~~~ +> +> By default, ``pre-commit`` only runs on the files that have been changed, and staged in git: +> +> ~~~bash +> git status +> git add esmvaltool/diag_scripts/examples/warming_stripes.py +> pre-commit run --files esmvaltool/diag_scripts/examples/warming_stripes.py +> ~~~ +> +> Inspect the output of ``pre-commit`` and fix the errors. +> +> > ## Answers +> > +> > +> {: .solution} +{: .challenge} + ### Run tests From 2df6994b08860040bdc691c95060d5b900611585 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 23 Feb 2021 13:59:39 +0100 Subject: [PATCH 497/647] revise section review process --- _episodes/08-development-setup.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 07e5f6af..98b30d41 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -114,20 +114,19 @@ We can contribute to its development by: The next sections will explore the ways we can achieve this. -### GitHub workflow +### Review process We first discuss our idea in an **[issue](https://github.com/ESMValGroup/ESMValTool/issues)** in ESMValTool repository. - Then, we create a new ``branch`` locally and start developing new codes. Once our development is finished, we can initiate a ``pull request``. -The pull request will then be tested, discussed and merged. This is called "**review process**". +For a full description of the GitHub workflow, please see ESMValTool documentation on +[GitHub Workflow](https://docs.esmvaltool.org/en/latest/community/repository.html#github-workflow). -Using the workflow will take some effort and time to learn. +The pull request will be tested, discussed and merged. This is called "**review process**". +The process will take some effort and time to learn. However, a few “tools” i.e. command lines gets you a long way, and we’ll cover those essentials in this lesson. -For a full description of the workflow, please see ESMValTool documentation on -[Contributing to the community » GitHub Workflow](https://docs.esmvaltool.org/en/latest/community/repository.html#github-workflow). ### Check code quality @@ -165,9 +164,9 @@ To explore other tools, have a look at ESMValTool documentation on > {: .solution} {: .challenge} - ### Run tests + ### Build documentation From 46d60fe6e084e4e1db88ae67f1aec159f4d9815d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 23 Feb 2021 14:18:47 +0100 Subject: [PATCH 498/647] revise section run unit tests --- _episodes/08-development-setup.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 98b30d41..4b1bdc5c 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -164,8 +164,19 @@ To explore other tools, have a look at ESMValTool documentation on > {: .solution} {: .challenge} -### Run tests +### Run unit tests +Previous section introduced some tools to check code style and quality. +What it hasen’t done is show us how to tell whether our code is getting the right answer. +To achieve that, we can run tests using ``pytest`` locally: + +> ~~~bash +> cd ESMValTool +> git checkout your_branch_name +> pytest +> ~~~ + +Tests will also be run automatically by [CircleCI](https://circleci.com/), when you submit a pull request. ### Build documentation From c91a94d62d22b4918525cb920f5b8dd680cc1af9 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 23 Feb 2021 14:26:06 +0100 Subject: [PATCH 499/647] fix section installation --- _episodes/08-development-setup.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 4b1bdc5c..d5bbcf1e 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -90,13 +90,7 @@ works properly. To do this, run the tool with: esmvaltool --help ~~~ -If everything is installed properly, ESMValTool prints a -help message to the console. For a more complete installation verification, -we can run the automated tests: - -~~~bash -python setup.py test --installation -~~~ +If everything is installed properly, ESMValTool prints a help message to the console. ## Contribution From 3afcc171ff5d383681af91b6c8d67b5e2e8117d9 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 23 Feb 2021 18:34:07 +0100 Subject: [PATCH 500/647] revise section build documentation --- _episodes/08-development-setup.md | 97 ++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index d5bbcf1e..53e7619c 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -152,7 +152,7 @@ To explore other tools, have a look at ESMValTool documentation on > > Inspect the output of ``pre-commit`` and fix the errors. > -> > ## Answers +> > ## Solution > > > > > {: .solution} @@ -165,6 +165,7 @@ What it hasen’t done is show us how to tell whether our code is getting the ri To achieve that, we can run tests using ``pytest`` locally: > ~~~bash +> conda activate esmvaltool > cd ESMValTool > git checkout your_branch_name > pytest @@ -174,6 +175,100 @@ Tests will also be run automatically by [CircleCI](https://circleci.com/), when ### Build documentation +Documentations are available on [docs.esmvaltool.org](https://docs.esmvaltool.org/en/latest/index.html). +The source files are located in ``ESMValTool/doc/sphinx/source/``. +To build documentations locally, we run: + +> ~~~bash +> conda activate esmvaltool +> cd ESMValTool +> git checkout your_branch_name +> python setup.py build_sphinx -Ea +> ~~~ + +Similar to codes, documentations should be well written and adhere to standards. +If documentations are buit properly, the previous command prints a message to the console: + +> ~~~bash +> build succeeded. +> +> The HTML pages are in doc/sphinx/build/html. +> ~~~ + +The main page of the documentation as been built into ``index.html`` +in ``doc/sphinx/build/html`` directory. +To preview this page locally, we open the file in a web browser: + +> ~~~bash +> xdg-open doc/sphinx/build/html/index.html +> ~~~ + +> ## Creating a documenation +> +> Let's checkout our local branch and add the recipe +> [recipe_warming_stripes.yml](../files/recipe_warming_stripes.yml) +> to the the ``example`` directory: +> +> ~~~bash +> cd ESMValTool +> git checkout your_branch_name +> cp path_of_recipe_warming_stripes.yml esmvaltool/recipes/examples/ +> ~~~ +> +> Then, we create a documentation file ``recipe_warming_stripes.rst`` for this recipe: +> +> ~~~bash +> nano doc/sphinx/source/recipes/recipe_warming_stripes.rst +> ~~~ +> +> Add a reference i.e. ``.. _recipe_warming_stripes:``, a section title +> and some text about the recipe: +> +> ~~~rst +> .. _recipe_warming_stripes: +> +> Reproducing Ed Hawkins' warming stripes visualization +> ====================================================== +> +> This recipe produces warming stripes plots. +> ~~~ +> +> We can think of this file as one page of a book. +> Then, we need to decide where this page should be located inside the book. +> The table of content is defined by ``index.rst``: +> +> ~~~bash +> nano doc/sphinx/source/recipes/index.rst +> ~~~ +> +> Add the name of the recipe ``recipe_warming_stripes`` to +> the section ``Other`` in this file and +> preview the recipe documentation page locally. +> +>> ## Solution +>> +>> First, add the name of the recipe ``recipe_warming_stripes`` to +>> the section ``Other``: +>> +>> ~~~rst +>> Other +>> ^^^^^ +>> .. toctree:: +>> :maxdepth: 1 +>> ... +>> ... +>> recipe_warming_stripes +>> ~~~ +>> +>> Then, build and preview the documentation page: +>> +>> ~~~bash +>> python setup.py build_sphinx -Ea +>> xdg-open doc/sphinx/build/html/recipes/recipe_warming_stripes.html +>> ~~~ +>> +> {: .solution} +{: .challenge} {% include links.md %} From ca358adb278c562799dd2b3a6a1f56facf2c0602 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Feb 2021 11:58:33 +0100 Subject: [PATCH 501/647] fix exercise of pre-commit --- _episodes/08-development-setup.md | 50 ++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 53e7619c..a4aa33f2 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -127,11 +127,12 @@ and we’ll cover those essentials in this lesson. We aim to adhere to best practices and coding standards. The good news is that there are several tools that we can use to check our code against those standards. -As an example, ``Pre-commit`` is a tool that checks your code for any invalid syntax and formatting errors. +As an example, ``Pre-commit`` is a tool that checks your code for any invalid syntax +and formatting errors. It also fixes some of those errors. To explore other tools, have a look at ESMValTool documentation on [Code style](https://docs.esmvaltool.org/en/latest/community/introduction.html#code-style). -> ## Using Pre-commit +> ## Using pre-commit > > Let's checkout our local branch and add the script > [warming_stripes.py](../files/warming_stripes.py) to the ``example`` directory. @@ -142,7 +143,7 @@ To explore other tools, have a look at ESMValTool documentation on > cp path_of_warming_stripes.py esmvaltool/diag_scripts/examples/ > ~~~ > -> By default, ``pre-commit`` only runs on the files that have been changed, and staged in git: +> By default, ``pre-commit`` only runs on the files that have been staged in git: > > ~~~bash > git status @@ -150,11 +151,44 @@ To explore other tools, have a look at ESMValTool documentation on > pre-commit run --files esmvaltool/diag_scripts/examples/warming_stripes.py > ~~~ > -> Inspect the output of ``pre-commit`` and fix the errors. +> Inspect the output of ``pre-commit`` and fix the remaining errors. > -> > ## Solution -> > -> > +>> ## Solution +>> +>> The output of ``pre-commit``: +>> +>> ~~~ bash +>> Check for added large files..............................................Passed +>> Check python ast.........................................................Passed +>> Check for case conflicts.................................................Passed +>> Check for merge conflicts................................................Passed +>> Debug Statements (Python)................................................Passed +>> Fix End of Files.........................................................Passed +>> Trim Trailing Whitespace.................................................Passed +>> yamllint.............................................(no files to check)Skipped +>> nclcodestyle.........................................(no files to check)Skipped +>> style-files..........................................(no files to check)Skipped +>> lintr................................................(no files to check)Skipped +>> codespell................................................................Passed +>> isort....................................................................Passed +>> yapf.....................................................................Passed +>> docformatter.............................................................Failed +>> - hook id: docformatter +>> - files were modified by this hook +>> flake8...................................................................Failed +>> - hook id: flake8 +>> - exit code: 1 +>> +>> esmvaltool/diag_scripts/examples/warming_stripes.py:20:5: F841 local variable 'nx' is assigned to but never used +>> ~~~ +>> +>> As can be seen above, there are two ``Failed`` check: +>> +>> 1. ``docformatter``: it is mentioned that "files were modified by this hook". +>> We run ``git diff`` to see the modifications. +>> 2. ``flake8``: the error message is about an unused local variable ``nx``. +>> We should remove this variable from the script. +>> > {: .solution} {: .challenge} @@ -196,7 +230,7 @@ If documentations are buit properly, the previous command prints a message to th > The HTML pages are in doc/sphinx/build/html. > ~~~ -The main page of the documentation as been built into ``index.html`` +The main page of the documentation has been built into ``index.html`` in ``doc/sphinx/build/html`` directory. To preview this page locally, we open the file in a web browser: From 737b5d887254b66eb5d602861a0ad9ca72473bd7 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Feb 2021 12:19:51 +0100 Subject: [PATCH 502/647] add an exercise for installation --- _episodes/08-development-setup.md | 36 +++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index a4aa33f2..77a3ac0b 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -74,6 +74,15 @@ The environment is called ``esmvaltool`` by default. Let's activate the environm conda activate esmvaltool ~~~ +> ## environment name +> +> If an ``esmvaltool`` environment is already created following the lesson +> [Installation]({{ page.root }}{% link _episodes/02-installation.md %}), +> first delet that environment or choose another name for the new environment in this lesson. +> For more information see +> [Conda Managing environments](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html). +{: .callout} + ### 3 ESMValTool installation ESMValTool can be installed in a ``develop`` mode by running: @@ -82,7 +91,7 @@ ESMValTool can be installed in a ``develop`` mode by running: pip install --editable '.[develop]' ~~~ -This will add the `esmvaltool` directory to the Python path in editable mode and +This will add the ``esmvaltool`` directory to the Python path in editable mode and install the development dependencies. We should check if the installation works properly. To do this, run the tool with: @@ -90,7 +99,30 @@ works properly. To do this, run the tool with: esmvaltool --help ~~~ -If everything is installed properly, ESMValTool prints a help message to the console. +If installation is successful, ESMValTool prints a help message to the console. + +> ## Checking the development installation +> +> We can use the command ``conda list`` to list installed packages in the ``esmvaltool`` environment. +> Use this command to check that ESMValTool is installed in a ``develop`` mode. +> Tips: see the [documentation on conda list](https://docs.conda.io/projects/conda/en/latest/commands/list.html). +> +>> ## Solution +>> +>> Run: +>> +>> ~~~bash +>> conda list esmvaltool +>>~~~ +>> +>> ~~~bash +>> # Name Version Build Channel +>> esmvaltool 2.1.1 dev_0 +>>~~~ +>> +>> As can be seen, it is mentioned ```` under the ``Channel``. +> {: .solution} +{: .challenge} ## Contribution From abebd8f91129fe9664e0e660f916cab408d4ee62 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Feb 2021 13:48:54 +0100 Subject: [PATCH 503/647] polish the lesson --- _episodes/08-development-setup.md | 35 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 77a3ac0b..61a42923 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -12,11 +12,11 @@ objectives: - "Contribute to ESMValTool development." keypoints: -- "A development installation is needed if you want to incorporate your codes." +- "A development installation is needed if you want to incorporate your codes to ESMValTool." - "Contributions include adding a new or improved script or helping with a review process." - "There are several tools to check the quality of your code." - "It is possible to run tests on your machine." -- "You can build documentations locally." +- "You can preview documentation pages locally." --- We now know how ESMValTool works, but how do we develop it? @@ -40,15 +40,18 @@ Let’s get started. ### 1 Source code The ESMValTool source code is available on a public GitHub repository: -[https://github.com/ESMValGroup/ESMValTool](https://github.com/ESMValGroup/ESMValTool) +[https://github.com/ESMValGroup/ESMValTool](https://github.com/ESMValGroup/ESMValTool). To obtain the code, the easiest way is to clone the repository: ~~~bash git clone https://github.com/ESMValGroup/ESMValTool.git ~~~ -This command will create a folder called ESMValTool containing -the source code of the tool. To continue the installation, move into the directory +This command will ask your GitHub username and a personal **token** as password. Please follow instructions on +[GitHub token authentication requirements](https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/#what-you-need-to-do-today) to create a personal access token. +After the authentication, a folder called ``ESMValTool`` is created in your working directory. +This folder contains the source code of the tool. +To continue the installation, we move into the ``ESMValTool`` directory and check out the ``master`` branch: ~~~bash @@ -59,16 +62,16 @@ git checkout master ### 2 ESMValTool dependencies It is recommended to use conda to manage ESMValTool dependencies. For a minimal -conda installation, see section **Install Conda**, in lesson +conda installation, see section **Install Conda** in lesson [Installation]({{ page.root }}{% link _episodes/02-installation.md %}). To simplify the installation process, an environment file ``environment.yml`` is -provided in the ESMValTool direcotry. To create an environment run: +provided in the ESMValTool directory. We create an environment by running: ~~~bash conda env create --file environment.yml ~~~ -The environment is called ``esmvaltool`` by default. Let's activate the environment: +The environment is called ``esmvaltool`` by default. Now, we should activate the environment: ~~~bash conda activate esmvaltool @@ -78,9 +81,9 @@ conda activate esmvaltool > > If an ``esmvaltool`` environment is already created following the lesson > [Installation]({{ page.root }}{% link _episodes/02-installation.md %}), -> first delet that environment or choose another name for the new environment in this lesson. +> first delete it or choose another name for the new environment in this lesson. > For more information see -> [Conda Managing environments](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html). +> [conda managing environments](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html). {: .callout} ### 3 ESMValTool installation @@ -100,6 +103,8 @@ esmvaltool --help ~~~ If installation is successful, ESMValTool prints a help message to the console. +For more details about development installation, see ESMValTool documentation on +[install from source](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#install-from-source). > ## Checking the development installation > @@ -135,7 +140,7 @@ We can contribute to its development by: [Writing your own diagnostic script] - a new or updated cmorizer script, see lesson on [CMORization: Using observational datasets] -- helping with reviewing process of pull requests, see documentation on +- helping with reviewing process of pull requests, see ESMValTool documentation on [Review of pull requests](https://docs.esmvaltool.org/en/latest/community/review.html) The next sections will explore the ways we can achieve this. @@ -152,7 +157,7 @@ For a full description of the GitHub workflow, please see ESMValTool documentati The pull request will be tested, discussed and merged. This is called "**review process**". The process will take some effort and time to learn. However, a few “tools” i.e. command lines gets you a long way, -and we’ll cover those essentials in this lesson. +and we’ll cover those essentials in the next sections. ### Check code quality @@ -217,9 +222,10 @@ To explore other tools, have a look at ESMValTool documentation on >> As can be seen above, there are two ``Failed`` check: >> >> 1. ``docformatter``: it is mentioned that "files were modified by this hook". ->> We run ``git diff`` to see the modifications. +>> We run ``git diff`` to see the modifications. The syntax ``"""`` at the end of docstring is moved +>> by one line. >> 2. ``flake8``: the error message is about an unused local variable ``nx``. ->> We should remove this variable from the script. +>> We should check our codes regarding the usage of ``nx``. >> > {: .solution} {: .challenge} @@ -243,7 +249,6 @@ Tests will also be run automatically by [CircleCI](https://circleci.com/), when Documentations are available on [docs.esmvaltool.org](https://docs.esmvaltool.org/en/latest/index.html). The source files are located in ``ESMValTool/doc/sphinx/source/``. - To build documentations locally, we run: > ~~~bash From eb55c4b2b7f2cbc163d4efdf596b33ac7bb4b7a4 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Feb 2021 14:20:15 +0100 Subject: [PATCH 504/647] add an exercise for running tests --- _episodes/08-development-setup.md | 53 ++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 61a42923..9828cca6 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -226,7 +226,7 @@ To explore other tools, have a look at ESMValTool documentation on >> by one line. >> 2. ``flake8``: the error message is about an unused local variable ``nx``. >> We should check our codes regarding the usage of ``nx``. ->> +>> For now, let's assume that it is added by mistake and remove it. > {: .solution} {: .challenge} @@ -245,6 +245,43 @@ To achieve that, we can run tests using ``pytest`` locally: Tests will also be run automatically by [CircleCI](https://circleci.com/), when you submit a pull request. +> ## Running tests +> +> Let's checkout our local branch and add the recipe +> [recipe_warming_stripes.yml](../files/recipe_warming_stripes.yml) +> to the the ``example`` directory: +> +> ~~~bash +> cd ESMValTool +> git checkout your_branch_name +> cp path_of_recipe_warming_stripes.yml esmvaltool/recipes/examples/ +> ~~~ +> +> Run ``pytest`` and inspect the results. If a test is failed, try to fix it. +> +>> ## Solution +>> +>> When ``pytest`` run is complete, you can inspect the test reports +>> that are printed in the console. Have a look at the second section of the report +>> ``FAILURES``: +>> +>> ~~~ bash +>> ===================================================================================== FAILURES ====================================================================================== +>> ______________________________________________________________ test_recipe_valid[examples/recipe_warming_stripes.yml] _______________________________________________________________ +>>~~~ +>> +>> The test message shows that the recipe ``recipe_warming_stripes.yml`` has a problem. +>> Look for a line that starts with an ``E`` in the rest of the message: +>> +>> ~~~ bash +>> +>> E esmvalcore._task.DiagnosticError: Cannot execute script '~/esmvaltool_tutorial/warming_stripes.py' (~/esmvaltool_tutorial/warming_stripes.py): file does not exist. +>>~~~ +>> +>> It seems that we need to set a correct path for the diagnostic script ``warming_stripes.py`` in our recipe! +> {: .solution} +{: .challenge} + ### Build documentation Documentations are available on [docs.esmvaltool.org](https://docs.esmvaltool.org/en/latest/index.html). @@ -277,17 +314,9 @@ To preview this page locally, we open the file in a web browser: > ## Creating a documenation > -> Let's checkout our local branch and add the recipe -> [recipe_warming_stripes.yml](../files/recipe_warming_stripes.yml) -> to the the ``example`` directory: -> -> ~~~bash -> cd ESMValTool -> git checkout your_branch_name -> cp path_of_recipe_warming_stripes.yml esmvaltool/recipes/examples/ -> ~~~ -> -> Then, we create a documentation file ``recipe_warming_stripes.rst`` for this recipe: +> In previous exercises, we added the recipe +> [recipe_warming_stripes.yml](../files/recipe_warming_stripes.yml) to ESMValTool. +> Now, we create a documentation file ``recipe_warming_stripes.rst`` for this recipe: > > ~~~bash > nano doc/sphinx/source/recipes/recipe_warming_stripes.rst From b77a643ed07a057e7fea5b79460aa9ccbec4bd08 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Feb 2021 14:31:15 +0100 Subject: [PATCH 505/647] polish the lesson --- _episodes/08-development-setup.md | 35 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 9828cca6..2e6f3443 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -172,7 +172,8 @@ To explore other tools, have a look at ESMValTool documentation on > ## Using pre-commit > > Let's checkout our local branch and add the script -> [warming_stripes.py](../files/warming_stripes.py) to the ``example`` directory. +> [warming_stripes.py](../files/warming_stripes.py) to the +> ``esmvaltool/diag_scripts/example`` directory. > > ~~~bash > cd ESMValTool @@ -249,7 +250,7 @@ Tests will also be run automatically by [CircleCI](https://circleci.com/), when > > Let's checkout our local branch and add the recipe > [recipe_warming_stripes.yml](../files/recipe_warming_stripes.yml) -> to the the ``example`` directory: +> to the the ``esmvaltool/recipes/example`` directory: > > ~~~bash > cd ESMValTool @@ -261,16 +262,22 @@ Tests will also be run automatically by [CircleCI](https://circleci.com/), when > >> ## Solution >> +>> Run: +>> +>> ~~~bash +>> pytest +>> ~~~ +>> >> When ``pytest`` run is complete, you can inspect the test reports >> that are printed in the console. Have a look at the second section of the report >> ``FAILURES``: >> >> ~~~ bash ->> ===================================================================================== FAILURES ====================================================================================== ->> ______________________________________________________________ test_recipe_valid[examples/recipe_warming_stripes.yml] _______________________________________________________________ ->>~~~ +>> ================================ FAILURES ========================================== +>> ______________ test_recipe_valid[examples/recipe_warming_stripes.yml] ______________ +>> ~~~ >> ->> The test message shows that the recipe ``recipe_warming_stripes.yml`` has a problem. +>> The test message shows that the recipe ``recipe_warming_stripes.yml`` is not a valid recipe. >> Look for a line that starts with an ``E`` in the rest of the message: >> >> ~~~ bash @@ -323,7 +330,7 @@ To preview this page locally, we open the file in a web browser: > ~~~ > > Add a reference i.e. ``.. _recipe_warming_stripes:``, a section title -> and some text about the recipe: +> and some text about the recipe like: > > ~~~rst > .. _recipe_warming_stripes: @@ -334,22 +341,20 @@ To preview this page locally, we open the file in a web browser: > This recipe produces warming stripes plots. > ~~~ > -> We can think of this file as one page of a book. +> Save and close the file. We can think of this file as one page of a book. > Then, we need to decide where this page should be located inside the book. -> The table of content is defined by ``index.rst``: +> The table of content is defined by ``index.rst``. Let's have a look at the content: > > ~~~bash > nano doc/sphinx/source/recipes/index.rst > ~~~ > -> Add the name of the recipe ``recipe_warming_stripes`` to -> the section ``Other`` in this file and -> preview the recipe documentation page locally. +> Add the recipe name i.e. ``recipe_warming_stripes`` to the section ``Other`` in this file +> and preview the recipe documentation page locally. > >> ## Solution >> ->> First, add the name of the recipe ``recipe_warming_stripes`` to ->> the section ``Other``: +>> First, we add the recipe name ``recipe_warming_stripes`` to the section ``Other``: >> >> ~~~rst >> Other @@ -361,7 +366,7 @@ To preview this page locally, we open the file in a web browser: >> recipe_warming_stripes >> ~~~ >> ->> Then, build and preview the documentation page: +>> Then, we build and preview the documentation page: >> >> ~~~bash >> python setup.py build_sphinx -Ea From b3b985d42a0655fda710a99e54f7a76613d8a82a Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Feb 2021 15:13:30 +0100 Subject: [PATCH 506/647] fix some CI errors --- _episodes/08-development-setup.md | 85 ++++++++++++++++++------------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 2e6f3443..990c4788 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -47,8 +47,10 @@ To obtain the code, the easiest way is to clone the repository: git clone https://github.com/ESMValGroup/ESMValTool.git ~~~ -This command will ask your GitHub username and a personal **token** as password. Please follow instructions on -[GitHub token authentication requirements](https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/#what-you-need-to-do-today) to create a personal access token. +This command will ask your GitHub username and a personal **token** as password. +Please follow instructions on +[GitHub token authentication requirements][token-authentication-requirements] +to create a personal access token. After the authentication, a folder called ``ESMValTool`` is created in your working directory. This folder contains the source code of the tool. To continue the installation, we move into the ``ESMValTool`` directory @@ -83,7 +85,7 @@ conda activate esmvaltool > [Installation]({{ page.root }}{% link _episodes/02-installation.md %}), > first delete it or choose another name for the new environment in this lesson. > For more information see -> [conda managing environments](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html). +> [conda managing environments][manage-environments]. {: .callout} ### 3 ESMValTool installation @@ -104,13 +106,16 @@ esmvaltool --help If installation is successful, ESMValTool prints a help message to the console. For more details about development installation, see ESMValTool documentation on -[install from source](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#install-from-source). +[install from source][install-from-source]. > ## Checking the development installation > -> We can use the command ``conda list`` to list installed packages in the ``esmvaltool`` environment. +> We can use the command ``conda list`` to list installed packages in +> the ``esmvaltool`` environment. > Use this command to check that ESMValTool is installed in a ``develop`` mode. -> Tips: see the [documentation on conda list](https://docs.conda.io/projects/conda/en/latest/commands/list.html). +> +> **Tips**: see the +> [documentation on conda list](https://docs.conda.io/projects/conda/en/latest/commands/list.html). > >> ## Solution >> @@ -217,14 +222,15 @@ To explore other tools, have a look at ESMValTool documentation on >> - hook id: flake8 >> - exit code: 1 >> ->> esmvaltool/diag_scripts/examples/warming_stripes.py:20:5: F841 local variable 'nx' is assigned to but never used +>> esmvaltool/diag_scripts/examples/warming_stripes.py:20:5: +>> F841 local variable 'nx' is assigned to but never used >> ~~~ >> >> As can be seen above, there are two ``Failed`` check: >> >> 1. ``docformatter``: it is mentioned that "files were modified by this hook". ->> We run ``git diff`` to see the modifications. The syntax ``"""`` at the end of docstring is moved ->> by one line. +>> We run ``git diff`` to see the modifications. +>> The syntax ``"""`` at the end of docstring is moved by one line. >> 2. ``flake8``: the error message is about an unused local variable ``nx``. >> We should check our codes regarding the usage of ``nx``. >> For now, let's assume that it is added by mistake and remove it. @@ -237,14 +243,15 @@ Previous section introduced some tools to check code style and quality. What it hasen’t done is show us how to tell whether our code is getting the right answer. To achieve that, we can run tests using ``pytest`` locally: -> ~~~bash -> conda activate esmvaltool -> cd ESMValTool -> git checkout your_branch_name -> pytest -> ~~~ +~~~bash +conda activate esmvaltool +cd ESMValTool +git checkout your_branch_name +pytest +~~~ -Tests will also be run automatically by [CircleCI](https://circleci.com/), when you submit a pull request. +Tests will also be run automatically by [CircleCI](https://circleci.com/), +when you submit a pull request. > ## Running tests > @@ -282,42 +289,46 @@ Tests will also be run automatically by [CircleCI](https://circleci.com/), when >> >> ~~~ bash >> ->> E esmvalcore._task.DiagnosticError: Cannot execute script '~/esmvaltool_tutorial/warming_stripes.py' (~/esmvaltool_tutorial/warming_stripes.py): file does not exist. +>> E esmvalcore._task.DiagnosticError: Cannot execute script +>> '~/esmvaltool_tutorial/warming_stripes.py' (~/esmvaltool_tutorial/warming_stripes.py): +>> file does not exist. >>~~~ >> ->> It seems that we need to set a correct path for the diagnostic script ``warming_stripes.py`` in our recipe! +>> It seems that we need to set a correct path for the diagnostic script +>> ``warming_stripes.py`` in our recipe! > {: .solution} {: .challenge} ### Build documentation -Documentations are available on [docs.esmvaltool.org](https://docs.esmvaltool.org/en/latest/index.html). +Documentations are available on +[docs.esmvaltool.org](https://docs.esmvaltool.org/en/latest/index.html). The source files are located in ``ESMValTool/doc/sphinx/source/``. To build documentations locally, we run: -> ~~~bash -> conda activate esmvaltool -> cd ESMValTool -> git checkout your_branch_name -> python setup.py build_sphinx -Ea -> ~~~ +~~~bash +conda activate esmvaltool +cd ESMValTool +git checkout your_branch_name +python setup.py build_sphinx -Ea +~~~ Similar to codes, documentations should be well written and adhere to standards. If documentations are buit properly, the previous command prints a message to the console: -> ~~~bash -> build succeeded. -> -> The HTML pages are in doc/sphinx/build/html. -> ~~~ +~~~bash +build succeeded. + +The HTML pages are in doc/sphinx/build/html. +~~~ The main page of the documentation has been built into ``index.html`` in ``doc/sphinx/build/html`` directory. To preview this page locally, we open the file in a web browser: -> ~~~bash -> xdg-open doc/sphinx/build/html/index.html -> ~~~ +~~~bash +xdg-open doc/sphinx/build/html/index.html +~~~ > ## Creating a documenation > @@ -332,7 +343,7 @@ To preview this page locally, we open the file in a web browser: > Add a reference i.e. ``.. _recipe_warming_stripes:``, a section title > and some text about the recipe like: > -> ~~~rst +> ~~~markdown > .. _recipe_warming_stripes: > > Reproducing Ed Hawkins' warming stripes visualization @@ -356,7 +367,7 @@ To preview this page locally, we open the file in a web browser: >> >> First, we add the recipe name ``recipe_warming_stripes`` to the section ``Other``: >> ->> ~~~rst +>> ~~~markdown >> Other >> ^^^^^ >> .. toctree:: @@ -377,3 +388,7 @@ To preview this page locally, we open the file in a web browser: {: .challenge} {% include links.md %} + +[token-authentication-requirements]: https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/#what-you-need-to-do-today +[manage-environments]: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html +[install-from-source]: https://docs.esmvaltool.org/en/latest/quickstart/installation.html#install-from-source From 53a82fed85578720ad5caa9d2e54326daf3ae741 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Feb 2021 15:23:44 +0100 Subject: [PATCH 507/647] fix more CI errors --- _episodes/08-development-setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 990c4788..0a684a0a 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -343,7 +343,7 @@ xdg-open doc/sphinx/build/html/index.html > Add a reference i.e. ``.. _recipe_warming_stripes:``, a section title > and some text about the recipe like: > -> ~~~markdown +> ~~~source > .. _recipe_warming_stripes: > > Reproducing Ed Hawkins' warming stripes visualization @@ -367,7 +367,7 @@ xdg-open doc/sphinx/build/html/index.html >> >> First, we add the recipe name ``recipe_warming_stripes`` to the section ``Other``: >> ->> ~~~markdown +>> ~~~source >> Other >> ^^^^^ >> .. toctree:: From 147aa819520da8174010d4074a0d84f4103537e6 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Feb 2021 15:41:40 +0100 Subject: [PATCH 508/647] fix block code language --- _episodes/08-development-setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 0a684a0a..990c4788 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -343,7 +343,7 @@ xdg-open doc/sphinx/build/html/index.html > Add a reference i.e. ``.. _recipe_warming_stripes:``, a section title > and some text about the recipe like: > -> ~~~source +> ~~~markdown > .. _recipe_warming_stripes: > > Reproducing Ed Hawkins' warming stripes visualization @@ -367,7 +367,7 @@ xdg-open doc/sphinx/build/html/index.html >> >> First, we add the recipe name ``recipe_warming_stripes`` to the section ``Other``: >> ->> ~~~source +>> ~~~markdown >> Other >> ^^^^^ >> .. toctree:: From ad2de5d31695530858a49754240f5e7c95c96bcf Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 25 Feb 2021 09:31:23 +0100 Subject: [PATCH 509/647] Some formatting fixes --- _episodes/09-cmorization.md | 170 ++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 86 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 91a3348e..cb12679c 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -388,7 +388,7 @@ You can then edit the content and save it as ``CMOR_.dat``. Now that we have the data ready, our first assumption would be that the data is already following the CMOR standard. So we store the file in the "OBS6" -folder of our data path, and rename it manually to an ESMValTool readable +folder of our data path, and rename it manually to an ESMValTool readable name. For our example of the "FLUXCOM" data that we downloaded (which is from the year 2000) the name of the dataset would then be: @@ -397,8 +397,8 @@ OBS6_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_200001-200012.nc ``` We also have made sure that our variable of choice is listed either -on a pre-existing or custom CMOR table. So now we are ready to test -if the data is actually following the necessary CMOR standard already, +on a pre-existing or custom CMOR table. So now we are ready to test +if the data is actually following the necessary CMOR standard already, or if we have to do some reformatting for the dataset. > ## Run the test recipe again @@ -410,13 +410,13 @@ or if we have to do some reformatting for the dataset. > > > > ```bash > > esmvaltool run recipe_check_fluxcom.yml --log_level debug -> > ``` -> > +> > ``` +> > > > The ESMValTool should now find your FLUXCOM datafile, and the error > > message that the ESMValTool can't find the data should now not be present -> > anymore. However, there are plenty of other error messages around. +> > anymore. However, there are plenty of other error messages around. > > Somewhere within the many messages, you should see this: -> > +> > > > ```bash > > ... > > esmvalcore.cmor.check.CMORCheckError: There were errors in variable GPP: @@ -448,36 +448,35 @@ or if we have to do some reformatting for the dataset. > > title: GPP based on FLUXCOM RS+METEO with CRUNCEPv6 climate > > version: v1 > > ... -> > ``` - +> > ``` > {: .solution} {: .challenge} The error messages that we see tell us that we do have to reformat the dataset slightly to have it follow the CMOR standard. It seems like the variable "gpp" -does not have the correct unit that is given in the CMOR table where it is +does not have the correct unit that is given in the CMOR table where it is [defined](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/cmip6/Tables). -It also seems like the "latitude" and "longitude" coordinates have some -problems. So let's start writing a short python script that will fix these +It also seems like the "latitude" and "longitude" coordinates have some +problems. So let's start writing a short python script that will fix these problems. The first step now is to create a file in the right folder that will contain -the short python script. The home of all CMORizer scripts for observations -and reanalysis datasets is -[here](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/cmorizers/obs). +the short python script. The home of all CMORizer scripts for observations +and reanalysis datasets is +[here](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/cmorizers/obs). Add a file with the name ``cmorize_obs_fluxcom.py`` to this folder. > ## Note > -> Always, always, when modifying or creating new code for the ESMValTool +> Always, always, when modifying or creating new code for the ESMValTool > repositories, work on your *own, local* branch of the ESMValTool. Optimally, -> you have forked that branch directly from the most up-to-date version of +> you have forked that branch directly from the most up-to-date version of > the "master" branch to avoid conflicts later when you want to merge your -> code with the "master" branch of the ESMValTool. +> code with the "master" branch of the ESMValTool. > {: .callout} -Within our python script we have to make sure that we cover three main +Within our python script we have to make sure that we cover three main aspects of the reformatting: - We need to be able to locate and read the data to be CMORized - We have to CMORize the data (fix the CMOR problems that the ESMValTool @@ -485,9 +484,9 @@ had so nicely pointed out for us) - We need to store the data with the correct filename so that the ESMValTool will be able to identify it later -But the very first part of the CMORizing script is a header. The header +But the very first part of the CMORizing script is a header. The header contains information about where to obtain the data, when it was accessed -the last time, which ESMValTool "tier" it is associated with, and more +the last time, which ESMValTool "tier" it is associated with, and more detailed information about the necessary downloading and processing steps. > ## Fill out the header for the "FLUXCOM" dataset @@ -507,16 +506,16 @@ detailed information about the necessary downloading and processing steps. > > > > ```python > > """ESMValTool CMORizer for FLUXCOM GPP data. -> > +> > > > Tier > > Tier 3: restricted dataset. -> > +> > > > Source > > http://www.bgc-jena.mpg.de/geodb/BGI/Home -> > +> > > > Last access > > 20190727 -> > +> > > > Download and processing instructions > > From the website, select FLUXCOM as the data choice and click download. > > Two files will be displayed. One for Land Carbon Fluxes and one for @@ -533,13 +532,13 @@ detailed information about the necessary downloading and processing steps. > > version 2.3.0 Aug 2019 > > """ > > ``` -> > +> > > > This is the header of the "FLUXCOM" CMORizer that is available with the > > ESMValTool already. It is therefore entirely possible that your entries for -> > the section "Last access" and "Download and processing instructions" +> > the section "Last access" and "Download and processing instructions" > > differ from the example here since the entries for these sections are > > somewhat subjective. -> > +> > > {: .solution} {: .challenge} @@ -554,15 +553,15 @@ some things to make sure the dataset name can be correctly created, and ultimately the ESMValTool knows how to look for the new dataset. Therefore it is necessary to create a configuration file for the new dataset. -This configutation file needs to be stored in the -following folder: +This configutation file needs to be stored in the +following folder: ```bash ESMValTool/esmvaltool/cmorizers/obs/cmor_config/ ``` -It is imporant to note that the name of the configuration file has to be +It is imporant to note that the name of the configuration file has to be identical to the name of the dataset. For our example the configuration file, -traditionally written in the ``yaml`` format, therefore must be called +traditionally written in the ``yaml`` format, therefore must be called ``FLUXCOM.yml``. Let's have a closer look what that configuration file needs to contain: @@ -575,15 +574,15 @@ contain) > ## Let's create the configuration file for the "FLUXCOM" dataset > -> Here is the skeleton of the "FLUXCOM" configuration file as it exists in +> Here is the skeleton of the "FLUXCOM" configuration file as it exists in > the ESMValTool framework. Try to fill in all missing pieces of information > for this configuration file that are marked with ``???``. > > ```yaml > --- -> # Filename +> # Filename > filename: ??? -> +> > # Common global attributes for Cmorizer output > attributes: > dataset_id: ??? @@ -594,7 +593,7 @@ contain) > source: ??? > reference: ??? > comment: ??? -> +> > # Variables to cmorize > variables: > ???: @@ -608,9 +607,9 @@ contain) > > > > ```yaml > > --- -> > # Filename +> > # Filename > > filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' -> > +> > > > # Common global attributes for Cmorizer output > > attributes: > > dataset_id: FLUXCOM @@ -621,31 +620,31 @@ contain) > > source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' > > reference: 'fluxcom' > > comment: '' -> > +> > > > # Variables to cmorize > > variables: > > gpp: > > mip: Lmon > > ``` -> > +> > > > The original configuration file for the "FLUXCOM" dataset can be > > found here: > > [FLUXCOM.yml] > > (https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml) -> > -> > Note the attribute "reference" here: it should include a ``doi`` related -> > to the dataset. For more information on how to add references to the +> > +> > Note the attribute "reference" here: it should include a ``doi`` related +> > to the dataset. For more information on how to add references to the > > ``reference`` section of the configuration file, see the section in the > > documentation about this: [adding references] > > (https://docs.esmvaltool.org/en/latest/community/diagnostic.html#adding-references) -> > -> > If a single dataset has more than one reference, it is possible to add +> > +> > If a single dataset has more than one reference, it is possible to add > > tags as a list e.g. ``reference: ['tag1', 'tag2']``. > {: .solution} {: .challenge} - + Now that we have defined the configuration file for our "FLUXCOM" data, we can -finally start writing the actual code for the CMORizer script. The main body +finally start writing the actual code for the CMORizer script. The main body of the CMORizer script must contain a function called ```python @@ -656,19 +655,19 @@ with this exact call signature. Here, ``in_dir`` corresponds to the input directory of the raw files, ``out_dir`` to the output directory of final reformatted data set and ``cfg`` to the configuration dictionary given by the ``.yml`` configuration file. The return value of this function is ignored. -All the work, i.e. loading of the raw files, processing them and saving the -final output, has to be performed inside its body. To simplify this process, -ESMValTool provides a set of predefined utilities.py_, which can be imported +All the work, i.e. loading of the raw files, processing them and saving the +final output, has to be performed inside its body. To simplify this process, +ESMValTool provides a set of predefined utilities.py_, which can be imported into your CMORizer by ```python from . import utilities as utils ``` -Apart from a function to easily save data, this module contains different -kinds of small fixes to the data attributes, coordinates, and metadata which -are necessary for the data field to be CMOR-compliant. We will come back to -these functionalities in a bit. +Apart from a function to easily save data, this module contains different +kinds of small fixes to the data attributes, coordinates, and metadata which +are necessary for the data field to be CMOR-compliant. We will come back to +these functionalities in a bit. Note that this specific CMORizer script contains several subroutines in order to make the code clearer and more readable (we strongly recommend to follow @@ -676,7 +675,7 @@ that code style). For example, the function ``_get_filepath`` converts the raw filepath to the correct one and the function ``_extract_variable`` extracts and saves a single variable from the raw data. -After all that theory, let's have a look at the actualy python code of the +After all that theory, let's have a look at the actualy python code of the existing "FLUXCOM" CMORizer script. For now, we only want to read in the data and then store it in a new file. @@ -770,14 +769,14 @@ ESMValTool to run the CMORizing scripts: cmorize_obs -c -o ``` -The ``config-user-yml`` is the file in which we define the different data -paths, e.g. where the ESMValTool would find the "RAWOBS" folder. The +The ``config-user-yml`` is the file in which we define the different data +paths, e.g. where the ESMValTool would find the "RAWOBS" folder. The ``dataset-name`` needs to be idential to the folder name that was created to store the raw observation data files, in our case this would be "FLUXCOM". The ESMValTool will create a folder with the correct tier information in your -defined output directory if that tier folder is not already available, and -then a folder named after the data set. In this folder the cmorized data set -will be stored as a netCDF file. If your run was successful, one or more +defined output directory if that tier folder is not already available, and +then a folder named after the data set. In this folder the cmorized data set +will be stored as a netCDF file. If your run was successful, one or more NetCDF files are produced in your output directory. > ## Was the CMORization successful so far?! @@ -791,19 +790,19 @@ NetCDF files are produced in your output directory. > Within the "FLUXCOM" folder there should be a NetCDF file with the name: > ```bash > OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_xxxx01-xxxx12.nc -> ``` +> ``` > -> The "xxxx" represents the start year of the data period you wanted to +> The "xxxx" represents the start year of the data period you wanted to > CMORize, and the "yyyy" represents the end year. -> +> {: .callout} -Great! +Great! So we have produced a NetCDF file with the CMORizer that follows the naming -convention for ESMValTool datasets. Let's have a look at the NetCDF file as -it was written with the very basic CMORizer from above (note, we are only +convention for ESMValTool datasets. Let's have a look at the NetCDF file as +it was written with the very basic CMORizer from above (note, we are only looking at the year 1980 in our example). - + ```bash netcdf OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012 { dimensions: @@ -842,7 +841,7 @@ variables: The file contains a variable named "GPP" that contains three dimensions: "time", "lat", "lon". The units for this variable are not defined yet. The ESMValTool did not know how to convert from the -original units to the units that are defined in the CMOR table for the +original units to the units that are defined in the CMOR table for the variable "gpp". The original units are therefore listed in the "global attributes" section as ``invalid_units``. The ESMValTool recognized that the units given in the original file did not match the units given in the CMOR @@ -855,12 +854,12 @@ esmvaltool run recipe_check_fluxcom.yml --log_level debug we will encounter an error again. The dataset is not correctly CMORized, and the first thing that the ESMValTool complains about is: ```bash -iris.exceptions.UnitConversionError: Cannot convert from unknown units. The +iris.exceptions.UnitConversionError: Cannot convert from unknown units. The "units" attribute may be set directly. ``` Ok, so let's fix the units of the "GPP" variable in the CMORizer. For that -we add the following three lines to the code in the section +we add the following three lines to the code in the section ``_extract_variable``: ```python @@ -890,7 +889,7 @@ def _extract_variable(cmor_info, attrs, filepath, out_dir): unlimited_dimensions=['time']) ``` - + If we run the CMORizer script now again with the ``cmorize_obs`` call we get a NetCDF file that has fixed units, but has an "unknown" variable name. @@ -912,11 +911,11 @@ variables: We will have to do some more code tweaking then. But we also have not fixed the problem with the coordinates ``lat`` and ``lon`` yet. There is no "units" -or "standard_name" given for either of these coordinates which will cause a +or "standard_name" given for either of these coordinates which will cause a problem for the ESMValTool. Such some smaller formatting problems can occur relatively often for coordinates like ``lat``, ``lon`` or ``time``. This means that these problems need fixing in many CMORizers. Therefore there are common -functions available within the ESMValTool that one can import and use in the +functions available within the ESMValTool that one can import and use in the new CMORizer script. The functions, written in python, are stored in the folder [utilities.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/utilities.py) @@ -924,9 +923,9 @@ new CMORizer script. The functions, written in python, are stored in the folder > > The task is now to work with the functions in the file "utilities.py" to > complete the CMORizer for the "FLUXCOM" dataset so that it can be read by -> the ESMValTool. The definitions of the coordinates and the variable "gpp" +> the ESMValTool. The definitions of the coordinates and the variable "gpp" > should look like the following after the successful CMORization: -> +> > ```bash > variables: > float gpp(time, lat, lon) ; @@ -962,14 +961,14 @@ new CMORizer script. The functions, written in python, are stored in the folder > - fix the metadata for the variable "gpp" > - change the time units to start in the year 1950 > - make the coordinates CMOR-compliant -> - set global attributes for the data file +> - set global attributes for the data file > > > ## Answers > > > > To fully CMORize the "FLUXCOM" dataset, you need to add the following > > lines of code to the ``_extract_variable`` function of your CMORizer > > script: -> > +> > > > ```python > > def _extract_variable(cmor_info, attrs, filepath, out_dir): > > """Extract variable.""" @@ -980,7 +979,7 @@ new CMORizer script. The functions, written in python, are stored in the folder > > # convert data from gc/m2/day to kg/m2/s > > cube = cube / (1000 * 86400) > > cube.units = 'kg m-2 s-1' -> > +> > > > # The following two lines are needed for iris.util.guess_coord_axis > > cube.coord('lat').standard_name = 'latitude' > > cube.coord('lon').standard_name = 'longitude' @@ -997,7 +996,7 @@ new CMORizer script. The functions, written in python, are stored in the folder > > out_dir, > > attrs, > > unlimited_dimensions=['time']) -> > +> > > > ``` > > > {: .solution} @@ -1011,13 +1010,13 @@ to run a CMORizing script is as follows: cmorize_obs -c -o ``` -If your run was successful, you should have gotten no error message in the +If your run was successful, you should have gotten no error message in the ESMValTool logging information and one or more NetCDF files should have been produced in your output directory. -To make sure that the CMORization has really worked as planned, we run the +To make sure that the CMORization has really worked as planned, we run the CMOR checker on this newly produced NetCDF file. If the ESMValTool can read -the data without problems, you should see as one of the last lines of +the data without problems, you should see as one of the last lines of ESMValTool output: ```bash @@ -1029,7 +1028,7 @@ INFO Run was successful Congratulations! You have successfully CMORized a new dataset! Since you have gone through all the trouble to reformat the dataset so that the ESMValTool can work with it, it would be great if you could provide the -CMORizer, und ultimately with that the dataset, to the rest of the community. +CMORizer, and ultimately with that the dataset, to the rest of the community. To do that there are a few more steps you have to do: 1. Open a pull request in the ESMValTool repository describing the dataset briefly 2. Add the info of your dataset to the User Guide so that people know it is available for the ESMValTool [Obtaining input data](https://github.com/ESMValGroup/ESMValTool/blob/master/doc/sphinx/source/input.rst) @@ -1044,12 +1043,11 @@ Adding a new CMORizer to the ESMValTool is definitely already an advanced task when working with the ESMValTool. You have to have a basic understanding of how the ESMValTool works and how it's internal structure looks like. In addition, you need to have a basic understanding of NetCDF files and a -programming language. In our example we used python for the CMORizing script +programming language. In our example we used python for the CMORizing script since we advocate for focusing the code development on only a few different -programming languages. This helps to maintain the code and to ensure the +programming languages. This helps to maintain the code and to ensure the compatibility of the code with possible fundamental changes to the structure of the ESMValTool and ESMValCore. More information about adding observations to the ESMValTool can be found in the [documentation](https://docs.esmvaltool.org/en/latest/input.html#observations) - From 730208b07b5b16c23499a533250e82de49e58598 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 25 Feb 2021 09:32:06 +0100 Subject: [PATCH 510/647] two typos --- _episodes/09-cmorization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index cb12679c..c250c9e2 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -553,13 +553,13 @@ some things to make sure the dataset name can be correctly created, and ultimately the ESMValTool knows how to look for the new dataset. Therefore it is necessary to create a configuration file for the new dataset. -This configutation file needs to be stored in the +This configuration file needs to be stored in the following folder: ```bash ESMValTool/esmvaltool/cmorizers/obs/cmor_config/ ``` -It is imporant to note that the name of the configuration file has to be +It is important to note that the name of the configuration file has to be identical to the name of the dataset. For our example the configuration file, traditionally written in the ``yaml`` format, therefore must be called ``FLUXCOM.yml``. From de3b7673c870debdcd31afc7515e50d259a96fb0 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:51:59 +0100 Subject: [PATCH 511/647] remove word codes Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 990c4788..21983d5c 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -4,8 +4,8 @@ teaching: 10 exercises: 20 questions: - "What is a development installation?" -- "How can I test new or improved codes?" -- "How can I incorporate new or improved codes to ESMValTool?" +- "How can I test new or improved code?" +- "How can I incorporate my contributions into ESMValTool?" objectives: - "Execute a successful ESMValTool installation from the source code." From e5e85cce219e1726b7d45ed1918968ac2e4a4c1e Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:53:36 +0100 Subject: [PATCH 512/647] rephrase the introductory sentence Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 21983d5c..3f631ea3 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -20,8 +20,9 @@ keypoints: --- We now know how ESMValTool works, but how do we develop it? -This lesson helps to run your own codes with ESMValTool. -It also illustrates how to incorporate your codes into the tool. +In this lesson you will set up a development installation of ESMValTool, so you can +make modifications or add new recipes or diagnostic scripts, and contribute them +back to the community. > ## Git knowledge > From c16a4fcbbfdde385aaf4aec974311b70d2d2b44d Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:55:56 +0100 Subject: [PATCH 513/647] add an explanation why we submit an issue, as suggested by Peter Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 3f631ea3..78263f08 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -153,8 +153,9 @@ The next sections will explore the ways we can achieve this. ### Review process -We first discuss our idea in an -**[issue](https://github.com/ESMValGroup/ESMValTool/issues)** in ESMValTool repository. +We first discuss our ideas in an +**[issue](https://github.com/ESMValGroup/ESMValTool/issues)** in ESMValTool repository. This can avoid disappointment at a later stage, for example if more people are doing the same thing. It also gives other +people an early opportunity to provide input and suggestions, which usually results in more valuable contributions. Then, we create a new ``branch`` locally and start developing new codes. Once our development is finished, we can initiate a ``pull request``. For a full description of the GitHub workflow, please see ESMValTool documentation on From 51eec9572613f85e6c2852ea1318894751a0e746 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:57:25 +0100 Subject: [PATCH 514/647] fix typo Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 78263f08..c76ee101 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -316,7 +316,7 @@ python setup.py build_sphinx -Ea ~~~ Similar to codes, documentations should be well written and adhere to standards. -If documentations are buit properly, the previous command prints a message to the console: +If the documentation is built properly, the previous command prints a message to the console: ~~~bash build succeeded. From 58a175f0e8786d14aa4dddcf0fc9f31b3fa1a644 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:58:34 +0100 Subject: [PATCH 515/647] revise the text Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index c76ee101..a81a1cc0 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -14,7 +14,7 @@ objectives: keypoints: - "A development installation is needed if you want to incorporate your codes to ESMValTool." - "Contributions include adding a new or improved script or helping with a review process." -- "There are several tools to check the quality of your code." +- "There are several tools to help improve the quality of your code." - "It is possible to run tests on your machine." - "You can preview documentation pages locally." --- From bfdc2fd72bb59fdb7c0f38e998ce83929adcd0fc Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Thu, 25 Feb 2021 15:59:09 +0100 Subject: [PATCH 516/647] fix typo Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index a81a1cc0..b879bcba 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -12,7 +12,7 @@ objectives: - "Contribute to ESMValTool development." keypoints: -- "A development installation is needed if you want to incorporate your codes to ESMValTool." +- "A development installation is needed if you want to incorporate your code into ESMValTool." - "Contributions include adding a new or improved script or helping with a review process." - "There are several tools to help improve the quality of your code." - "It is possible to run tests on your machine." From fdb1e58c284e66ac3dc4d5a18e74f1306ce9ee04 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 26 Feb 2021 13:08:38 +0100 Subject: [PATCH 517/647] implement some of Peter's suggestions --- _episodes/08-development-setup.md | 110 +++++++++++++++++------------- 1 file changed, 63 insertions(+), 47 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index b879bcba..7fbdf8aa 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -20,9 +20,20 @@ keypoints: --- We now know how ESMValTool works, but how do we develop it? -In this lesson you will set up a development installation of ESMValTool, so you can -make modifications or add new recipes or diagnostic scripts, and contribute them -back to the community. +ESMValTool is an open-source project in ESMValGroup. We can contribute to its development by: + +- a new or updated recipe script, see lesson on +[Writing your own recipe]({{ page.root }}{% link _episodes/05-preprocessor.md %}) +- a new or updated diagnostics script, see lesson on +[Writing your own diagnostic script] +- a new or updated cmorizer script, see lesson on +[CMORization: Using observational datasets] +- helping with reviewing process of pull requests, see ESMValTool documentation on +[Review of pull requests](https://docs.esmvaltool.org/en/latest/community/review.html) + +In this lesson, we first show how to set up a development installation of ESMValTool. So, you can +make modifications. Then, we explain the process of how to contribute your changes or additions +to the community. > ## Git knowledge > @@ -54,14 +65,14 @@ Please follow instructions on to create a personal access token. After the authentication, a folder called ``ESMValTool`` is created in your working directory. This folder contains the source code of the tool. -To continue the installation, we move into the ``ESMValTool`` directory -and check out the ``master`` branch: +To continue the installation, we move into the ``ESMValTool`` directory: ~~~bash cd ESMValTool -git checkout master ~~~ +Note that the ``master`` branch is checked out by default. + ### 2 ESMValTool dependencies It is recommended to use conda to manage ESMValTool dependencies. For a minimal @@ -74,20 +85,21 @@ provided in the ESMValTool directory. We create an environment by running: conda env create --file environment.yml ~~~ -The environment is called ``esmvaltool`` by default. Now, we should activate the environment: +The environment is called ``esmvaltool`` by default. +If an ``esmvaltool`` environment is already created following the lesson +[Installation]({{ page.root }}{% link _episodes/02-installation.md %}), +we should choose another name for the new environment in this lesson by: ~~~bash -conda activate esmvaltool +conda env create -n a_new_name --file environment.yml ~~~ -> ## environment name -> -> If an ``esmvaltool`` environment is already created following the lesson -> [Installation]({{ page.root }}{% link _episodes/02-installation.md %}), -> first delete it or choose another name for the new environment in this lesson. -> For more information see -> [conda managing environments][manage-environments]. -{: .callout} +For more information see [conda managing environments][manage-environments]. +Now, we should activate the environment: + +~~~bash +conda activate esmvaltool +~~~ ### 3 ESMValTool installation @@ -137,25 +149,17 @@ For more details about development installation, see ESMValTool documentation on ## Contribution -ESMValTool is an open-source project in ESMValGroup. -We can contribute to its development by: - -- a new or updated recipe script, see lesson on -[Writing your own recipe]({{ page.root }}{% link _episodes/05-preprocessor.md %}) -- a new or updated diagnostics script, see lesson on -[Writing your own diagnostic script] -- a new or updated cmorizer script, see lesson on -[CMORization: Using observational datasets] -- helping with reviewing process of pull requests, see ESMValTool documentation on -[Review of pull requests](https://docs.esmvaltool.org/en/latest/community/review.html) - -The next sections will explore the ways we can achieve this. +We have seen how to install ESMValTool in a ``develop`` mode. +Now, we try to contribute to its development. Let's see how we can achieve this. ### Review process We first discuss our ideas in an -**[issue](https://github.com/ESMValGroup/ESMValTool/issues)** in ESMValTool repository. This can avoid disappointment at a later stage, for example if more people are doing the same thing. It also gives other -people an early opportunity to provide input and suggestions, which usually results in more valuable contributions. +**[issue](https://github.com/ESMValGroup/ESMValTool/issues)** in ESMValTool repository. +This can avoid disappointment at a later stage, for example, if more people are doing the same thing. +It also gives other people an early opportunity to provide input and suggestions, +which results in more valuable contributions. + Then, we create a new ``branch`` locally and start developing new codes. Once our development is finished, we can initiate a ``pull request``. For a full description of the GitHub workflow, please see ESMValTool documentation on @@ -166,13 +170,24 @@ The process will take some effort and time to learn. However, a few “tools” i.e. command lines gets you a long way, and we’ll cover those essentials in the next sections. +**Tips**: we encourage you to keep the pull requests small. +Reviewing small incremental changes are more efficient. + ### Check code quality -We aim to adhere to best practices and coding standards. The good news is that there are -several tools that we can use to check our code against those standards. +We aim to adhere to best practices and coding standards. There are +several tools that check our code against those standards like: -As an example, ``Pre-commit`` is a tool that checks your code for any invalid syntax -and formatting errors. It also fixes some of those errors. +- flake8 for checking against the PEP8 style guide +- yapf to ensure consistent formatting for the whole project +- isort to consistently sort the import statements +- yamllint to ensure there are no syntax errors in our recipes and config files +- lintr for diagnostic scripts written in R +- codespell to check grammar + +The good news is that ``pre-commit`` has been already installed +when we chose development installation. +``pre-commit`` is a command line and runs all of those tools. It also fixes some of those errors. To explore other tools, have a look at ESMValTool documentation on [Code style](https://docs.esmvaltool.org/en/latest/community/introduction.html#code-style). @@ -243,12 +258,13 @@ To explore other tools, have a look at ESMValTool documentation on Previous section introduced some tools to check code style and quality. What it hasen’t done is show us how to tell whether our code is getting the right answer. -To achieve that, we can run tests using ``pytest`` locally: +To achieve that, we need to write and run tests for widely-used functions. +ESMValTool comes with a lot of tests that are in the folder ``tests``. + +To run tests, first we make sure that the working directory is ``ESMValTool`` +and our local branch is checked out. Then, we can run tests using ``pytest`` locally: ~~~bash -conda activate esmvaltool -cd ESMValTool -git checkout your_branch_name pytest ~~~ @@ -303,15 +319,15 @@ when you submit a pull request. ### Build documentation +When we add or update a code, we also update its corresponding documentation. Documentations are available on [docs.esmvaltool.org](https://docs.esmvaltool.org/en/latest/index.html). The source files are located in ``ESMValTool/doc/sphinx/source/``. -To build documentations locally, we run: + +To build documentations locally, first we make sure that the working directory is ``ESMValTool`` +and our local branch is checked out. Then, we run: ~~~bash -conda activate esmvaltool -cd ESMValTool -git checkout your_branch_name python setup.py build_sphinx -Ea ~~~ @@ -345,14 +361,14 @@ xdg-open doc/sphinx/build/html/index.html > Add a reference i.e. ``.. _recipe_warming_stripes:``, a section title > and some text about the recipe like: > -> ~~~markdown +> ``` > .. _recipe_warming_stripes: > > Reproducing Ed Hawkins' warming stripes visualization > ====================================================== > > This recipe produces warming stripes plots. -> ~~~ +> ``` > > Save and close the file. We can think of this file as one page of a book. > Then, we need to decide where this page should be located inside the book. @@ -369,7 +385,7 @@ xdg-open doc/sphinx/build/html/index.html >> >> First, we add the recipe name ``recipe_warming_stripes`` to the section ``Other``: >> ->> ~~~markdown +>> ``` >> Other >> ^^^^^ >> .. toctree:: @@ -377,7 +393,7 @@ xdg-open doc/sphinx/build/html/index.html >> ... >> ... >> recipe_warming_stripes ->> ~~~ +>> ``` >> >> Then, we build and preview the documentation page: >> From 115251c8d68a037f047da122849c4b91f7c712e5 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 26 Feb 2021 13:25:58 +0100 Subject: [PATCH 518/647] add output for git clone --- _episodes/08-development-setup.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 7fbdf8aa..5e95394f 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -62,8 +62,21 @@ git clone https://github.com/ESMValGroup/ESMValTool.git This command will ask your GitHub username and a personal **token** as password. Please follow instructions on [GitHub token authentication requirements][token-authentication-requirements] -to create a personal access token. -After the authentication, a folder called ``ESMValTool`` is created in your working directory. +to create a personal access token. After the authentication, +the output might look like: + +~~~ +Cloning into 'ESMValTool'... +remote: Enumerating objects: 163, done. +remote: Counting objects: 100% (163/163), done. +remote: Compressing objects: 100% (125/125), done. +remote: Total 95049 (delta 84), reused 76 (delta 30), pack-reused 94886 +Receiving objects: 100% (95049/95049), 175.16 MiB | 5.48 MiB/s, done. +Resolving deltas: 100% (68808/68808), done. +~~~ +{: .output} + +Now, a folder called ``ESMValTool`` has been created in your working directory. This folder contains the source code of the tool. To continue the installation, we move into the ``ESMValTool`` directory: @@ -72,6 +85,19 @@ cd ESMValTool ~~~ Note that the ``master`` branch is checked out by default. +We can see this if we run: + +~~~bash +git status +~~~ + +~~~ +On branch master +Your branch is up to date with 'origin/master'. + +nothing to commit, working tree clean +~~~ +{: .output} ### 2 ESMValTool dependencies From c055e70eb210b2bc8808dabe002c96d5f30270d7 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 26 Feb 2021 13:53:57 +0100 Subject: [PATCH 519/647] Address small comments and suggestions --- _episodes/09-cmorization.md | 178 ++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 100 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index c250c9e2..a09bb953 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -1,16 +1,17 @@ --- -title: "CMORization: Using observational datasets" +title: "CMORization: adding new datasets to ESMValTool" teaching: 15 exercises: 45 questions: -- "What is so challenging about observational data?" -- "How do I use observational datasets in ESMValTool?" +- "CMORization: what is it and why do we need it?" +- "How to use the existing CMORizer scripts shipped with ESMValTool?" - "How add support for new (observational) datasets?" objectives: - "Understand what CMORization is and why it is necessary." -- "Learn how to write a new CMORizer script." +- "Use existing scripts to CMORize your data." +- "Write a new CMORizer script to support additional data." keypoints: - "CMORizers are dataset-specific scripts that can be run once to generate CMOR-compliant data." @@ -19,11 +20,14 @@ keypoints: ## Introduction -This episode deals with "CMORization". ESMValTool was designed to work with data +This episode deals with "CMORization". ESMValTool is designed to work with data that follow the CMOR standards. Unfortunately, not all datasets follow these standards. In order to use such datasets in ESMValTool we first need to reformat the data. This process is called "CMORization". +In this episode we assume that you are using a development installation of +ESMValTool as explained in the [previous episode](/08-development-setup). + > ## What are the CMOR standards? > > The name "CMOR" originates from a tool: [the Climate Model Output @@ -38,7 +42,7 @@ the data. This process is called "CMORization". coordinate information, how the data should be structured (e.g. 1 variable per file), additional metadata requirements, but also file naming conventions a.k.a. the data reference syntax (DRS). All this information is stored in so-called -CMOR tables. As example, the CMOR tables for the CMIP6 project can be found +CMOR tables. As an example, the CMOR tables for the CMIP6 project can be found [here](https://github.com/PCMDI/cmip6-cmor-tables). {: .callout} @@ -52,12 +56,12 @@ CMOR-compliant copy of these datasets. CMORizer scripts for several popular datasets are included in ESMValTool, and ESMValTool also provides a convenient way to execute them. -Occasionally it happens that there are still minor issue with CMIP datasets. In +Occasionally it happens that there are still minor issues with CMIP datasets. In those cases, it is possible to fix those issues in ESMValCore before any further processing is done. The same can be done for non-CMIP data. The advantage is that you don't need to store an additional, reformatted copy of the data. The disadvantage is that these fixes should be implemented inside ESMValCore. -Writing a CMORizer script is technically is simpler. +Development of ESMValCore is is beyond the scope of this tutorial. The concepts discussed so far are illustrated in the figure below. ![Data flow with ESMValTool](../fig/data_flow.png) @@ -69,24 +73,22 @@ that is important for calculating components of the global carbon cycle. We will go through all the steps and explain relevant topics as we go. If you prefer to implement CMOR fixes, please read the documentation [here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/develop/fixing_data.html#fixing-data). -While fixes are implemented slightly differently, conceptually the process is -the same and the concepts explained in this episode are still useful. +While fixes are implemented in a different way, the objective is exactly the +same, and the concepts explained in this episode are still useful. ## Obtaining the data -> ## Get the data -> The data for this episode is available via the [FluxCom Data -> Portal](http://www.bgc-jena.mpg.de/geodb/BGI/Home). First you'll need to -> register. After registration, in the dropdown boxes, select FLUXCOM as the data -> choice and click download. Three files will be displayed. Click the download -> button on the "FLUXCOM (RS+METEO) Global Land Carbon Fluxes using CRUNCEP -> climate data". You'll be send an FTP address to access the server. Connect -> to the server, follow the path in your email, and look for the file -> `raw/monthly/GPP.ANN.CRUNCEPv6.monthly.2000.nc`. Download that file and save in -> in a folder called `/RAWOBS/Tier3/`. -> -> Note: you'll need a user-friendly ftp client. On Linux, `ncftp` works okay. -{: .challenge} +The data for this episode is available via the [FluxCom Data +Portal](http://www.bgc-jena.mpg.de/geodb/BGI/Home). First you'll need to +register. After registration, in the dropdown boxes, select FLUXCOM as the data +choice and click download. Three files will be displayed. Click the download +button on the "FLUXCOM (RS+METEO) Global Land Carbon Fluxes using CRUNCEP +climate data". You'll receive an email with the FTP address to access the +server. Connect to the server, follow the path in your email, and look for the +file `raw/monthly/GPP.ANN.CRUNCEPv6.monthly.2000.nc`. Download that file and +save in in a folder called `/RAWOBS/Tier3/`. + +Note: you'll need a user-friendly ftp client. On Linux, `ncftp` works okay. > ## What is the deal with those "tiers"? > @@ -127,12 +129,12 @@ know we have completed our task. > ## Create a test recipe > -> Create a simple recipe that loads the "FLUXCOM" data. It should include a -> datasets section with a single entry for the "FLUXCOM" dataset with the correct -> dataset keys, and a diagnostics section with two variables: gpp and gppStderr. -> We won't need any preprocessors or scripts (set `scripts: null`), but you will -> have to add a documentation section with a description, authors and -> maintainer, otherwise the recipe will fail. +> Create a simple recipe called `recipe_check_fluxnet.yml` that loads the +> "FLUXCOM" data. It should include a datasets section with a single entry for +> the "FLUXCOM" dataset with the correct dataset keys, and a diagnostics section +> with two variables: gpp and gppStderr. We don't need any preprocessors or +> scripts (set `scripts: null`), but we have to add a documentation section with +> a description, authors and maintainer, otherwise the recipe will fail. > > Use the following dataset keys: > @@ -176,9 +178,7 @@ know we have completed our task. > > > > ``` > > -> > Note: a recipe similar to this one is available under -> > `~/path/to/ESMValTool/esmvaltool/recipes/examples/recipe_check_obs.yml`. -> > That recipe includes checks all datasets for which CMORizers are available. +> > To learn more about writing a recipe, please refer to [Writing your own recipe](/05-preprocessor). > > > {: .solution} {: .challenge} @@ -218,17 +218,14 @@ data. Our data is located in the `RAWOBS` folder, but ESMValTool is looking in from one folder to the other. To do end, we need to tell ESMValTool where our data may be found. -> ## Set the correct paths in your user configuration file: -> -> This information is set in `config-user.yml`. Modify your -> configuration file so that it has the correct paths -> -> ```yaml -> rootpath: -> OBS6: /path/to/my/obs6/data -> RAWOBS: /path/to/my/rawobs/data -> ``` -{: .challenge} +## Set the correct paths in your user configuration file: +This information is set in `config-user.yml`. Modify your +configuration file so that it has the correct paths +```yaml +rootpath: + OBS6: /path/to/my/obs6/data + RAWOBS: /path/to/my/rawobs/data +``` > ## RAWOBS, OBS, OBS6!? > @@ -295,12 +292,11 @@ copy of the [PCMDI](https://github.com/PCMDI) guidelines. {: .challenge} -If the variable you are interested in is not available in the standard CMOR tables, -you need to write a custom CMOR table entry for the variable. Don't worry! It sounds -more complicated than it is! Examples of custom CMOR table entries are for example -the standard error of a specific variable. -For our variable "gpp" there is indeed no CMOR definition for the standard error, -therefore "gppStderr" was defined in the custom CMOR table +If the variable you are interested in is not available in the standard CMOR +tables, you need to write a custom CMOR table entry for the variable. Examples +of custom CMOR table entries are for example the standard error of a specific +variable. For our variable "gpp" there is indeed no CMOR definition for the +standard error, therefore "gppStderr" was defined in the custom CMOR table [here](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/custom), as ``CMOR_gppStderr.dat``. @@ -463,16 +459,14 @@ problems. The first step now is to create a file in the right folder that will contain the short python script. The home of all CMORizer scripts for observations and reanalysis datasets is -[here](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/cmorizers/obs). +[esmvaltool/cmorizers/obs](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/cmorizers/obs). Add a file with the name ``cmorize_obs_fluxcom.py`` to this folder. > ## Note > > Always, always, when modifying or creating new code for the ESMValTool -> repositories, work on your *own, local* branch of the ESMValTool. Optimally, -> you have forked that branch directly from the most up-to-date version of -> the "master" branch to avoid conflicts later when you want to merge your -> code with the "master" branch of the ESMValTool. +> repositories, work on your *own, local* branch of the ESMValTool. For more +> information see [Development and contribution](/08-development-setup) > {: .callout} @@ -554,11 +548,8 @@ ultimately the ESMValTool knows how to look for the new dataset. Therefore it is necessary to create a configuration file for the new dataset. This configuration file needs to be stored in the -following folder: +following folder: ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/``. -```bash -ESMValTool/esmvaltool/cmorizers/obs/cmor_config/ -``` It is important to note that the name of the configuration file has to be identical to the name of the dataset. For our example the configuration file, traditionally written in the ``yaml`` format, therefore must be called @@ -627,19 +618,15 @@ contain) > > mip: Lmon > > ``` > > -> > The original configuration file for the "FLUXCOM" dataset can be -> > found here: -> > [FLUXCOM.yml] -> > (https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml) +> > The original configuration file for the "FLUXCOM" dataset can be found here: +> > [FLUXCOM.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml) > > -> > Note the attribute "reference" here: it should include a ``doi`` related -> > to the dataset. For more information on how to add references to the +> > Note the attribute "reference" here: it should include a ``doi`` related to +> > the dataset. For more information on how to add references to the > > ``reference`` section of the configuration file, see the section in the -> > documentation about this: [adding references] -> > (https://docs.esmvaltool.org/en/latest/community/diagnostic.html#adding-references) +> > documentation about this: [adding +> > references](https://docs.esmvaltool.org/en/latest/community/diagnostic.html#adding-references) > > -> > If a single dataset has more than one reference, it is possible to add -> > tags as a list e.g. ``reference: ['tag1', 'tag2']``. > {: .solution} {: .challenge} @@ -653,12 +640,12 @@ def cmorization(in_dir, out_dir, cfg, config_user): with this exact call signature. Here, ``in_dir`` corresponds to the input directory of the raw files, ``out_dir`` to the output directory of final -reformatted data set and ``cfg`` to the configuration dictionary given by -the ``.yml`` configuration file. The return value of this function is ignored. -All the work, i.e. loading of the raw files, processing them and saving the -final output, has to be performed inside its body. To simplify this process, -ESMValTool provides a set of predefined utilities.py_, which can be imported -into your CMORizer by +reformatted data set and ``cfg`` to the configuration dictionary given by the +``.yml`` configuration file. The return value of this function is ignored. All +the work, i.e. loading of the raw files, processing them and saving the final +output, has to be performed inside its body. To simplify this process, +ESMValTool provides some convenience functions in ``utilities.py`` , which +can be imported into your CMORizer by ```python from . import utilities as utils @@ -675,7 +662,7 @@ that code style). For example, the function ``_get_filepath`` converts the raw filepath to the correct one and the function ``_extract_variable`` extracts and saves a single variable from the raw data. -After all that theory, let's have a look at the actualy python code of the +After all that theory, let's have a look at the python code of the existing "FLUXCOM" CMORizer script. For now, we only want to read in the data and then store it in a new file. @@ -762,7 +749,7 @@ def cmorization(in_dir, out_dir, cfg, _): ``` Let's run this CMORizing script to see if the dataset is read correctly, and -what kind of file is written out. Tere is a specific command available in the +what kind of file is written out. There is a specific command available in the ESMValTool to run the CMORizing scripts: ```bash @@ -782,15 +769,10 @@ NetCDF files are produced in your output directory. > ## Was the CMORization successful so far?! > > If you check the folders in your output path, you should see the following -> folder structure: -> ```bash -> /Tier3/FLUXCOM/ -> ``` +> folder structure: ``/Tier3/FLUXCOM/`` > -> Within the "FLUXCOM" folder there should be a NetCDF file with the name: -> ```bash -> OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_xxxx01-xxxx12.nc -> ``` +> Within the "FLUXCOM" folder there should be a NetCDF file named +> ``OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_xxxx01-xxxx12.nc``. > > The "xxxx" represents the start year of the data period you wanted to > CMORize, and the "yyyy" represents the end year. @@ -868,7 +850,7 @@ cube = cube / (1000 * 86400) cube.units = 'kg m-2 s-1' ``` -The whole section should not look then look like this: +The whole section should then look like this: ```python def _extract_variable(cmor_info, attrs, filepath, out_dir): @@ -914,11 +896,7 @@ the problem with the coordinates ``lat`` and ``lon`` yet. There is no "units" or "standard_name" given for either of these coordinates which will cause a problem for the ESMValTool. Such some smaller formatting problems can occur relatively often for coordinates like ``lat``, ``lon`` or ``time``. This means -that these problems need fixing in many CMORizers. Therefore there are common -functions available within the ESMValTool that one can import and use in the -new CMORizer script. The functions, written in python, are stored in the folder -[utilities.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/utilities.py) - +that these problems need fixing in many CMORizers. > ## Finalizing the "FLUXCOM" CMORizer > > The task is now to work with the functions in the file "utilities.py" to @@ -956,7 +934,7 @@ new CMORizer script. The functions, written in python, are stored in the folder > double lon_bnds(lon, bnds) ; > ``` > -> For that to happen, you will have to fix/work on the following things: +> For that to happen, you have to fix the following things: > - adding standard names to the dimensions ``lat`` and ``lon`` > - fix the metadata for the variable "gpp" > - change the time units to start in the year 1950 @@ -1030,17 +1008,17 @@ Since you have gone through all the trouble to reformat the dataset so that the ESMValTool can work with it, it would be great if you could provide the CMORizer, and ultimately with that the dataset, to the rest of the community. To do that there are a few more steps you have to do: -1. Open a pull request in the ESMValTool repository describing the dataset briefly -2. Add the info of your dataset to the User Guide so that people know it is available for the ESMValTool [Obtaining input data](https://github.com/ESMValGroup/ESMValTool/blob/master/doc/sphinx/source/input.rst) -3. Make sure that there is a reference file available for the dataset [BibTeX info file](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) - -More information about working with pull requests are available in the ESMValTool -documentation under [Contributing a review](https://esmvaltool--1920.org.readthedocs.build/en/1920/community/review.html) - +1. Check out the previous episode on [Contributing to ESMValTool](/08-development-setup) +1. Make sure that you have added the info of your dataset to the User Guide so + that people know it is available for the ESMValTool [Obtaining input + data](https://github.com/ESMValGroup/ESMValTool/blob/master/doc/sphinx/source/input.rst) +1. Make sure that there is a reference file available for the dataset [BibTeX + info + file](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) ## Some final comments Adding a new CMORizer to the ESMValTool is definitely already an advanced task -when working with the ESMValTool. You have to have a basic understanding of +when working with the ESMValTool. You need to have a basic understanding of how the ESMValTool works and how it's internal structure looks like. In addition, you need to have a basic understanding of NetCDF files and a programming language. In our example we used python for the CMORizing script @@ -1050,4 +1028,4 @@ compatibility of the code with possible fundamental changes to the structure of the ESMValTool and ESMValCore. More information about adding observations to the ESMValTool can be found in the -[documentation](https://docs.esmvaltool.org/en/latest/input.html#observations) +[documentation](https://docs.esmvaltool.org/en/latest/input.html#observations). From b817941ef1449437a1a7f205fd76a2faabe52d73 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 26 Feb 2021 14:13:59 +0100 Subject: [PATCH 520/647] add a background section and revise exercise of runnin test --- _episodes/08-development-setup.md | 48 ++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 5e95394f..54ceda3a 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -199,6 +199,20 @@ and we’ll cover those essentials in the next sections. **Tips**: we encourage you to keep the pull requests small. Reviewing small incremental changes are more efficient. +### Background + +We saw 'warming stripes' in lesson +[Writing your own recipe]({{ page.root }}{% link _episodes/05-preprocessor.md %}). +Imagine the following task: you want to contribute warming stripes recipe and diagnostics +to ESMValTool. You have to add the diagnostics +[warming_stripes.py](../files/warming_stripes.py) and the recipe +[recipe_warming_stripes.yml](../files/recipe_warming_stripes.yml) +to their locations in ESMValTool directory. +After these changes, you should also check if everthing works fine. +This is where we take advantage of the tools that are introduced later. + +Let’s get started. + ### Check code quality We aim to adhere to best practices and coding standards. There are @@ -221,20 +235,20 @@ To explore other tools, have a look at ESMValTool documentation on > > Let's checkout our local branch and add the script > [warming_stripes.py](../files/warming_stripes.py) to the -> ``esmvaltool/diag_scripts/example`` directory. +> ``esmvaltool/diag_scripts`` directory. > > ~~~bash > cd ESMValTool > git checkout your_branch_name -> cp path_of_warming_stripes.py esmvaltool/diag_scripts/examples/ +> cp path_of_warming_stripes.py esmvaltool/diag_scripts/ > ~~~ > > By default, ``pre-commit`` only runs on the files that have been staged in git: > > ~~~bash > git status -> git add esmvaltool/diag_scripts/examples/warming_stripes.py -> pre-commit run --files esmvaltool/diag_scripts/examples/warming_stripes.py +> git add esmvaltool/diag_scripts/warming_stripes.py +> pre-commit run --files esmvaltool/diag_scripts/warming_stripes.py > ~~~ > > Inspect the output of ``pre-commit`` and fix the remaining errors. @@ -265,7 +279,7 @@ To explore other tools, have a look at ESMValTool documentation on >> - hook id: flake8 >> - exit code: 1 >> ->> esmvaltool/diag_scripts/examples/warming_stripes.py:20:5: +>> esmvaltool/diag_scripts/warming_stripes.py:20:5: >> F841 local variable 'nx' is assigned to but never used >> ~~~ >> @@ -301,12 +315,10 @@ when you submit a pull request. > > Let's checkout our local branch and add the recipe > [recipe_warming_stripes.yml](../files/recipe_warming_stripes.yml) -> to the the ``esmvaltool/recipes/example`` directory: +> to the the ``esmvaltool/recipes`` directory: > > ~~~bash -> cd ESMValTool -> git checkout your_branch_name -> cp path_of_recipe_warming_stripes.yml esmvaltool/recipes/examples/ +> cp path_of_recipe_warming_stripes.yml esmvaltool/recipes/ > ~~~ > > Run ``pytest`` and inspect the results. If a test is failed, try to fix it. @@ -325,7 +337,7 @@ when you submit a pull request. >> >> ~~~ bash >> ================================ FAILURES ========================================== ->> ______________ test_recipe_valid[examples/recipe_warming_stripes.yml] ______________ +>> ______________ test_recipe_valid[recipe_warming_stripes.yml] ______________ >> ~~~ >> >> The test message shows that the recipe ``recipe_warming_stripes.yml`` is not a valid recipe. @@ -336,10 +348,20 @@ when you submit a pull request. >> E esmvalcore._task.DiagnosticError: Cannot execute script >> '~/esmvaltool_tutorial/warming_stripes.py' (~/esmvaltool_tutorial/warming_stripes.py): >> file does not exist. ->>~~~ +>> ~~~ +>> +>> To fix the recipe, we need to edit the path of the diagnostic script +>> as ``warming_stripes.py``: +>> +>> ~~~yml +>> scripts: +>> warming_stripes_script: +>> script: warming_stripes.py +>> ~~~ +>> +>> For details, see lesson +>> [Writing your own diagnostic script]. >> ->> It seems that we need to set a correct path for the diagnostic script ->> ``warming_stripes.py`` in our recipe! > {: .solution} {: .challenge} From 9c379a2e5a143cbe76f17711e6b14cead1c149d4 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 26 Feb 2021 14:39:56 +0100 Subject: [PATCH 521/647] fix a line length --- _episodes/08-development-setup.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 54ceda3a..20cd9781 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -182,7 +182,8 @@ Now, we try to contribute to its development. Let's see how we can achieve this. We first discuss our ideas in an **[issue](https://github.com/ESMValGroup/ESMValTool/issues)** in ESMValTool repository. -This can avoid disappointment at a later stage, for example, if more people are doing the same thing. +This can avoid disappointment at a later stage, for example, +if more people are doing the same thing. It also gives other people an early opportunity to provide input and suggestions, which results in more valuable contributions. From 02438e8a1130c7f92ff1e3509da708a17f252a36 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 26 Feb 2021 17:12:30 +0100 Subject: [PATCH 522/647] WIP: try to restructure the episode --- _episodes/09-cmorization.md | 677 ++++++++++++++++++---------------- files/recipe_test_fluxcom.yml | 19 + 2 files changed, 371 insertions(+), 325 deletions(-) create mode 100644 files/recipe_test_fluxcom.yml diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index a09bb953..06c663d8 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -18,6 +18,8 @@ keypoints: - "ESMValTool comes with a set of CMORizers readily available, but you can also add your own." --- +![Data flow with ESMValTool](../fig/data_flow.png) + ## Introduction This episode deals with "CMORization". ESMValTool is designed to work with data @@ -25,9 +27,6 @@ that follow the CMOR standards. Unfortunately, not all datasets follow these standards. In order to use such datasets in ESMValTool we first need to reformat the data. This process is called "CMORization". -In this episode we assume that you are using a development installation of -ESMValTool as explained in the [previous episode](/08-development-setup). - > ## What are the CMOR standards? > > The name "CMOR" originates from a tool: [the Climate Model Output @@ -46,35 +45,23 @@ CMOR tables. As an example, the CMOR tables for the CMIP6 project can be found [here](https://github.com/PCMDI/cmip6-cmor-tables). {: .callout} -The Earth System Grid Federation (ESGF) is home to all CMIP data. The data -hosted there typically (mostly) follow the CMIP standards, and therefore -ESMValTool should work with these data without problems. - -Datasets that are *not* part of one of the CMIP projects often don't follow the -CMOR standards. In this case, a reformatting script can be used to create a -CMOR-compliant copy of these datasets. CMORizer scripts for several popular -datasets are included in ESMValTool, and ESMValTool also provides a convenient -way to execute them. - -Occasionally it happens that there are still minor issues with CMIP datasets. In -those cases, it is possible to fix those issues in ESMValCore before any further -processing is done. The same can be done for non-CMIP data. The advantage is -that you don't need to store an additional, reformatted copy of the data. The -disadvantage is that these fixes should be implemented inside ESMValCore. -Development of ESMValCore is is beyond the scope of this tutorial. - -The concepts discussed so far are illustrated in the figure below. -![Data flow with ESMValTool](../fig/data_flow.png) -*Illustration of the data flow in ESMValTool.* +ESMValTool offers two ways to CMORize data: +1. A reformatting script can be used to create a CMOR-compliant copy. CMORizer + scripts for several popular datasets are included in ESMValTool, and + ESMValTool also provides a convenient way to execute them. +2. ESMValCore can execute CMOR fixes '[on the + fly](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/develop/fixing_data.html#fixing-data)'. + The advantage is that you don't need to store an additional, reformatted copy + of the data. The disadvantage is that these fixes should be implemented + inside ESMValCore, which is beyond the scope of this tutorial. In this lesson, we will re-implement a CMORizer script for the FLUXCOM dataset that contains observations of the Gross Primary Production (GPP), a variable -that is important for calculating components of the global carbon cycle. We will -go through all the steps and explain relevant topics as we go. If you prefer to -implement CMOR fixes, please read the documentation -[here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/develop/fixing_data.html#fixing-data). -While fixes are implemented in a different way, the objective is exactly the -same, and the concepts explained in this episode are still useful. +that is important for calculating components of the global carbon cycle. + +We will assume that you are using a development installation of ESMValTool as +explained in the [previous episode](/08-development-setup). + ## Obtaining the data @@ -86,7 +73,7 @@ button on the "FLUXCOM (RS+METEO) Global Land Carbon Fluxes using CRUNCEP climate data". You'll receive an email with the FTP address to access the server. Connect to the server, follow the path in your email, and look for the file `raw/monthly/GPP.ANN.CRUNCEPv6.monthly.2000.nc`. Download that file and -save in in a folder called `/RAWOBS/Tier3/`. +save in in a folder called `/RAWOBS/Tier3/FLUXCOM`. Note: you'll need a user-friendly ftp client. On Linux, `ncftp` works okay. @@ -119,26 +106,80 @@ Note: you'll need a user-friendly ftp client. On Linux, `ncftp` works okay. > {: .callout} +## Run the existing CMORizer script + +Before we develop our own CMORizer script, let's first see what happens when we +run the existing one. There is a specific command available in the ESMValTool to +run the CMORizer scripts: + +```bash +cmorize_obs -c -o +``` + +If everything is okay, the output should look something like this: + +~~~ +... +... Starting the CMORization Tool at time: 2021-02-26 14:02:16 UTC +... ---------------------------------------------------------------------- +... input_dir = /home/peter/data/RAWOBS +... output_dir = /home/peter/esmvaltool_output/cmorize_obs_20210226_140216 +... ---------------------------------------------------------------------- +... Running the CMORization scripts. +... Using cmorizer scripts repository: /home/peter/miniconda3/envs/esmvaltool/lib/python3.8/site-packages/esmvaltool/cmorizers/obs +... Processing datasets {'Tier3': ['FLUXCOM']} +... Input data from: /home/peter/data/RAWOBS/Tier3/FLUXCOM +... Output will be written to: /home/peter/esmvaltool_output/cmorize_obs_20210226_140216/Tier3/FLUXCOM +... Reformat script: /home/peter/miniconda3/envs/esmvaltool/lib/python3.8/site-packages/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom +... CMORizing dataset FLUXCOM using Python script /home/peter/miniconda3/envs/esmvaltool/lib/python3.8/site-packages/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py +... Found input file '/home/peter/data/RAWOBS/Tier3/FLUXCOM/GPP.ANN.CRUNCEPv6.monthly.*.nc' +... CMORizing variable 'gpp' +... Lmon +... Var is gpp +... ... UserWarning: Ignoring netCDF variable 'GPP' invalid units 'gC m-2 day-1' + warnings.warn(msg) +... Fixing time... +... Fixing latitude... +... Fixing longitude... +... Flipping dimensional coordinate latitude... +... Saving file +... Converting data type of data from 'float64' to 'float32' +... Saving: /home/peter/esmvaltool_output/cmorize_obs_20210226_140216/Tier3/FLUXCOM/OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_200001-200012.nc +... Cube has lazy data [lazy is preferred] +... Ending the CMORization Tool at time: 2021-02-26 14:02:16 UTC +... Time for running the CMORization scripts was: 0:00:00.605970 +~~~ +{: .output} + +So you can see that several fixes are applied, and the CMORized file is written +to the ESMValTool output directory. In order to use it, we'll have to copy it +from the output directory to a folder called +`/OBS/Tier3/FLUXCOM` and make sure the path to ``OBS`` is set +correctly in our config-user file. + +You can also see the path where ESMValTool stores the reformatting script: +`/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py`. You may +have a look at this file if you want. The script also uses a configuration file: +`/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml`. + ## Make a test recipe -Now that we have downloaded the data, our end goal is to run a recipe that can -load it and work with it. So we will make this recipe and try to run it. It will -probably fail, but that's okay. As you will see, the error messages will come in -handy. Moreover, the recipe will serve as a test case. Once we get it to run, we -know we have completed our task. +Our end goal is to run a recipe that can load the data and work with it. So we +will start by making a simple recipe that can serve as a test case. Once we get +it to run, we know we have completed our task. > ## Create a test recipe > -> Create a simple recipe called `recipe_check_fluxnet.yml` that loads the +> Create a simple recipe called `recipe_check_fluxcom.yml` that loads the > "FLUXCOM" data. It should include a datasets section with a single entry for > the "FLUXCOM" dataset with the correct dataset keys, and a diagnostics section -> with two variables: gpp and gppStderr. We don't need any preprocessors or +> with two variables: gpp. We don't need any preprocessors or > scripts (set `scripts: null`), but we have to add a documentation section with > a description, authors and maintainer, otherwise the recipe will fail. > > Use the following dataset keys: > -> - project: OBS6 +> - project: OBS > - dataset: FLUXCOM > - type: reanaly > - version: ANN-v1 @@ -166,14 +207,13 @@ know we have completed our task. > > - kalverla_peter > > > > datasets: -> > - {project: OBS6, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2000, end_year: 2000, type: reanaly, version: ANN-v1} +> > - {project: OBS, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2000, end_year: 2000, type: reanaly, version: ANN-v1} > > > > diagnostics: -> > FLUXCOM: -> > description: Check that ESMValTool can load the cmorized FLUXCOM data without errors. +> > check_fluxcom: +> > description: Check that ESMValTool can load the cmorized fluxnet data without errors. > > variables: > > gpp: -> > gppStderr: > > scripts: null > > > > ``` @@ -189,213 +229,163 @@ Try to run the example recipe with esmvaltool run recipe_check_fluxcom.yml --log_level debug ``` -The `log_level` flag ensures that all relevant information is included in the -output. We will need this information to find out what needs to be done. Look -carefully through the log messages. You'll probably find something like +If everything is okay, the recipe should run without problems. -``` -DEBUG Retrieving OBS6 configuration -DEBUG Skipping non-existent /home/peter/default_inputpath/Tier3/FLUXCOM -DEBUG Looking for files matching ['OBS6_FLUXCOM_reanaly_ANN-v1_Lmon_gppStderr[_.]*nc'] in [] -ERROR No input files found for variable {'variable_group': 'gppStderr' ... -... -ERROR Missing data for preprocessor FLUXCOM/gppStderr -... -ERROR Program terminated abnormally, see stack trace below for more information: -... -``` -{: .error} +## Starting from scratch -So the output tells us that it cannot find the data, and also where it has been -looking. Let's try to understand what's going on. - -## Location, location, location - -The error messages above tell you that ESMValTool cannot find the data. That -makes total sense, because we have not yet created our CMORized copy of the -data. Our data is located in the `RAWOBS` folder, but ESMValTool is looking in -`OBS6`. So the first thing our CMORizer will need to do is copy the data over -from one folder to the other. To do end, we need to tell ESMValTool where our -data may be found. - -## Set the correct paths in your user configuration file: -This information is set in `config-user.yml`. Modify your -configuration file so that it has the correct paths -```yaml -rootpath: - OBS6: /path/to/my/obs6/data - RAWOBS: /path/to/my/rawobs/data +Now that you've seen how to use an existing CMORizer script, let's think about +adding a new one. We will remove the existing CMORizer script, and re-implement +it from scratch. This exercise allows us to point out all the details of what's +going on. We'll also remove the CMORized data that we've just created, so our +test recipe will not be able to use it anymore. + +```bash +rm /OBS/Tier3/FLUXCOM/OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_200001-200012.nc +rm /esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.nc +rm /esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml ``` -> ## RAWOBS, OBS, OBS6!? -> -> ESMValTool uses project IDs to find the data on your hard drive, and also to -> find more information about the data. The `RAWOBS` and `OBS` projects were -> created for external data before and after CMORization, respectively. These -> names can be misleading, though, since not all external datasets are -> observations. -> -> Then, in going from CMIP5 to CMIP6, the CMOR standards changed a bit. Some -> variables are named differently in CMIP5 and CMIP6. This posed a dilemma: -> should CMORization reformat to the CMIP5 or CMIP6 definition? To solve this, -> the `OBS6` project was created. So data in the `OBS6` follow the CMIP6 -> standards. -> -{: .callout} +If you now run the test recipe again it should fail, and somewhere in the output you should find something like: -Looking closer at the path that ESMValTool told us it went looking for the data, -we see that it has a very specific structure: +~~~ +No input files found for ... +Looking for files matching ['OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp[_.]*nc'] in ['/home/peter/data/OBS/Tier3/FLUXCOM'] +~~~ +{: .error} -`OBS6_FLUXCOM_reanaly_ANN-v1_Lmon_gppStderr[_.]*nc` +From this we can see that the first thing our CMORizer should do is to rename +the file so that it follows the CMOR filename conventions. -Note that all components in the filename correspond to one of the dataset keys -defined in our test recipe. By replacing them with the original tags, we can -see the general structure for the OBS6 data: +## Create a new CMORizer script -`[project]_[dataset]_[type]_[version]_[mip]_[short_name]_*.nc` +The first step now is to create a new file in the right folder that will contain +our new CMORizer instructions. Create a file called ``cmorize_obs_fluxcom.py`` -This is the Data Reference Syntax (DRS) for OBS6 data. Each project has its own -DRS, and some project IDs even have multiple different options. These settings -can be found in the file -[config-developer.yml](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/config-developer.yml). -Luckily, we don't need to worry about that. This file name will be automatically -correctly created when we run our CMORizer script. +```bash +nano /esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py +``` +and fill it with the following boilerplate code: -## Check if your variable is following the CMOR standard / Check if it's in a CMOR table +```python +"""ESMValTool CMORizer for FLUXCOM GPP data. -The very first step we have to do is to check if your data file follows the CMOR standard. -Only data files that fully follow this standard can be read by the ESMValTool. + +""" +import logging +from . import utilities as utils -Most variables that we would want to use with the ESMValTool are defined in the Coupled -Model Intercomparison Project (CMIP) data request and can be found in the -CMOR tables in the folder -[cmip6/Tables](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/cmip6/Tables), -differentiated according to the "MIP" they belong to. The tables are a -copy of the [PCMDI](https://github.com/PCMDI) guidelines. +logger = logging.getLogger(__name__) -> ## Find the variable "gpp" in a CMOR table -> -> Check the available CMOR tables to find the variable "gpp" with the following characteristics: -> - standard_name: ``gross_primary_productivity_of_biomass_expressed_as_carbon`` -> - frequency: ``mon`` -> - modeling_realm: ``land`` -> -> > ## Answers -> > -> > The variable "gpp" belongs to the land variables. The temporal resolution that we are looking -> > for is "monthly". This information points to the "Lmon" CMIP table. And indeed, the variable -> > "gpp" can be found in the file -> > [here](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/cmip6/Tables/CMIP6_Lmon.json). -> > -> {: .solution} -{: .challenge} +def cmorization(in_dir, out_dir, cfg, _): + """Cmorize the dataset.""" + # This is where you'll add the cmorization code + # 1. find the input data + # 2. apply the necessary fixes + # 3. store the data with the correct filename +``` -If the variable you are interested in is not available in the standard CMOR -tables, you need to write a custom CMOR table entry for the variable. Examples -of custom CMOR table entries are for example the standard error of a specific -variable. For our variable "gpp" there is indeed no CMOR definition for the -standard error, therefore "gppStderr" was defined in the custom CMOR table -[here](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/custom), -as ``CMOR_gppStderr.dat``. +> ## Note +> +> Always, always, when modifying or creating new code for the ESMValTool +> repositories, work on your *own, local* branch of the ESMValTool. For more +> information see [Development and contribution](/08-development-setup) +> +{: .callout} -To create a new custom CMOR table you need to follow these -guidelines: +### 1. Finding the input data -- Provide the ``variable_entry``; -- Provide the ``modeling_realm``; -- Provide the variable attributes, but leave ``standard_name`` blank. Necessary - variable attributes are: ``units``, ``cell_methods``, ``cell_measures``, - ``long_name``, ``comment``. -- Provide some additional variable attributes. Necessary additional variable - attributes are: ``dimensions``, ``out_name``, ``type``. There are also - additional variable attributes that can be defined here (see the already - available cmorizers). +Since the original data does not follow CMOR filename conventions, we need to +tell ESMValTool what the filename for this new dataset looks like. We supply +this information via a dataset configuration file. It is important to note that +the name of the configuration file has to be identical to the name of the +dataset. Thus, we will create a file called +`/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml`. -It is easiest to start a new custom CMOR table by using an existing custom table -as a template. -You can then edit the content and save it as ``CMOR_.dat``. +In addition to the filename information, the configuration file also contains +information about "global attributes" for the netCDF file that will be +created and information about the variables that need to be CMORized. -> ## Does the variable "cVegStderr" need a costum CMOR table? +> ## Let's create the configuration file for the "FLUXCOM" dataset > -> Check the available CMOR tables to find the variable "cVegStderr" with the -> following characteristics: -> - standard_name: ``vegetation_carbon_content`` -> - frequency: ``mon`` -> - modeling_realm: ``land`` +> Here is the skeleton of the "FLUXCOM" configuration file as it exists in +> the ESMValTool framework. Try to fill in all missing pieces of information +> for this configuration file that are marked with ``???``. > -> If it is not available, create a custom CMOR table following the template of -> the CMIP6 CMOR table of "cVeg" and custom CMOR table of "gppStderr". +> ```yaml +> --- +> # Filename +> filename: ??? +> +> # Common global attributes for Cmorizer output +> attributes: +> dataset_id: ??? +> version: ??? +> tier: ??? +> modeling_realm: ??? +> project_id: ??? +> source: ??? +> reference: ??? +> comment: ??? +> +> # Variables to cmorize +> variables: +> ???: +> mip: ??? +> ``` > > > ## Answers > > -> > The first step here is to check if the variable "cVegStderr" is already -> > listed in a CMOR table. We have the information that the modeling_realm -> > of the variable is ``land`` and that the frequency is ``mon``. This -> > means we have to check the CMOR table "Lmon" for an entry. We focus -> > our search on the CMIP6 tables since these are the most recent tables -> > available. You can find the lists here: -> > `` +> > The configuration file for the "FLUXCOM" dataset with all necessary pieces +> > of information looks like this: > > -> > We do not find the variable "cVegStderr" in the "Lmon" table, which -> > means we will have to write our own custom table for this. -> > There were two examples given which we could use as templates for the -> > new custom table that we have to create. These two examples can be -> > found here: [cVeg](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/cmip6/Tables/CMIP6_Lmon.json) -> > and [gppStderr](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/custom/CMOR_gppStderr.dat) +> > ```yaml +> > --- +> > # Filename +> > filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' > > -> > We have to create a new file with the name ``CMOR_cVegStrerr.dat`` in -> > the custom CMOR table folder (https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/custom/). -> > The content of the file should then look like this: +> > # Common global attributes for Cmorizer output +> > attributes: +> > dataset_id: FLUXCOM +> > version: 'ANN-v1' +> > tier: 3 +> > modeling_realm: reanaly +> > project_id: OBS +> > source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' +> > reference: 'fluxcom' +> > comment: '' > > -> > ``` -> > SOURCE: CMIP6 -> > !============ -> > variable_entry: cVegStderr -> > !============ -> > modeling_realm: land -> > !---------------------------------- -> > ! Variable attributes: -> > !---------------------------------- -> > standard_name: -> > units: kg m-2 -> > cell_methods: area: mean where land time: mean -> > cell_measures: area: areacella -> > long_name: Carbon Mass in Vegetation Error -> > !---------------------------------- -> > ! Additional variable information: -> > !---------------------------------- -> > dimensions: longitude latitude time -> > out_name: cVegStderr -> > type: real -> > !---------------------------------- -> > ! +> > # Variables to cmorize +> > variables: +> > gpp: +> > mip: Lmon > > ``` > > -> > Note that there is no entry for ``standard_name``. This is on purpose. -> > It is a sign for the ESMValTool to not crash although the variable that -> > we are looking for is ok to have no official CMIP6 ``standard_name``. +> > The original configuration file for the "FLUXCOM" dataset can be found here: +> > [FLUXCOM.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml) +> > +> > Note the attribute "reference" here: it should include a ``doi`` related to +> > the dataset. For more information on how to add references to the +> > ``reference`` section of the configuration file, see the section in the +> > documentation about this: [adding +> > references](https://docs.esmvaltool.org/en/latest/community/diagnostic.html#adding-references) > > > {: .solution} {: .challenge} -## Create a CMORizer for the new dataset -Now that we have the data ready, our first assumption would be that the data -is already following the CMOR standard. So we store the file in the "OBS6" -folder of our data path, and rename it manually to an ESMValTool readable -name. For our example of the "FLUXCOM" data that we downloaded (which is -from the year 2000) the name of the dataset would then be: +### 2. Implementing additional fixes + -```bash -OBS6_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_200001-200012.nc -``` -We also have made sure that our variable of choice is listed either -on a pre-existing or custom CMOR table. So now we are ready to test -if the data is actually following the necessary CMOR standard already, -or if we have to do some reformatting for the dataset. +### 3. Finalizing the CMORizer + +Once everything works as expected, there's a couple of things that we can still do. + +- Add header info +- Make sure the metadata are added to the config file +- Maybe go through a checklist???? > ## Run the test recipe again > @@ -456,28 +446,8 @@ It also seems like the "latitude" and "longitude" coordinates have some problems. So let's start writing a short python script that will fix these problems. -The first step now is to create a file in the right folder that will contain -the short python script. The home of all CMORizer scripts for observations -and reanalysis datasets is -[esmvaltool/cmorizers/obs](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/cmorizers/obs). -Add a file with the name ``cmorize_obs_fluxcom.py`` to this folder. - -> ## Note -> -> Always, always, when modifying or creating new code for the ESMValTool -> repositories, work on your *own, local* branch of the ESMValTool. For more -> information see [Development and contribution](/08-development-setup) -> -{: .callout} - -Within our python script we have to make sure that we cover three main -aspects of the reformatting: -- We need to be able to locate and read the data to be CMORized -- We have to CMORize the data (fix the CMOR problems that the ESMValTool -had so nicely pointed out for us) -- We need to store the data with the correct filename so that the ESMValTool -will be able to identify it later +*PK: I'd suggest doing the header last, as it's not needed or relevant in the beginning*. But the very first part of the CMORizing script is a header. The header contains information about where to obtain the data, when it was accessed the last time, which ESMValTool "tier" it is associated with, and more @@ -536,99 +506,7 @@ detailed information about the necessary downloading and processing steps. > {: .solution} {: .challenge} -Now that we have made sure, that it is clear where our dataset comes from, and -how we can obtain it, the next step is to add the python code to actually read -the data. - -As we learned earlier, the DRS of the ESMValTool needs some very specific -pieces of information to build the name for each data file. Since we are now -trying to introduce a new dataset to the ESMValTool, we will have to specify -some things to make sure the dataset name can be correctly created, and -ultimately the ESMValTool knows how to look for the new dataset. - -Therefore it is necessary to create a configuration file for the new dataset. -This configuration file needs to be stored in the -following folder: ``ESMValTool/esmvaltool/cmorizers/obs/cmor_config/``. - -It is important to note that the name of the configuration file has to be -identical to the name of the dataset. For our example the configuration file, -traditionally written in the ``yaml`` format, therefore must be called -``FLUXCOM.yml``. - -Let's have a closer look what that configuration file needs to contain: -- information about the filenames of the raw observation files (stored in the -"RAWOBS" folder) -- information about "global attributes" for the netCDF file that will be -created (both for the name of the file and the metadata that the file needs to -contain) -- information about the variables that need to be cmorized -> ## Let's create the configuration file for the "FLUXCOM" dataset -> -> Here is the skeleton of the "FLUXCOM" configuration file as it exists in -> the ESMValTool framework. Try to fill in all missing pieces of information -> for this configuration file that are marked with ``???``. -> -> ```yaml -> --- -> # Filename -> filename: ??? -> -> # Common global attributes for Cmorizer output -> attributes: -> dataset_id: ??? -> version: ??? -> tier: ??? -> modeling_realm: ??? -> project_id: ??? -> source: ??? -> reference: ??? -> comment: ??? -> -> # Variables to cmorize -> variables: -> ???: -> mip: ??? -> ``` -> -> > ## Answers -> > -> > The configuration file for the "FLUXCOM" dataset with all necessary pieces -> > of information looks like this: -> > -> > ```yaml -> > --- -> > # Filename -> > filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' -> > -> > # Common global attributes for Cmorizer output -> > attributes: -> > dataset_id: FLUXCOM -> > version: 'ANN-v1' -> > tier: 3 -> > modeling_realm: reanaly -> > project_id: OBS -> > source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' -> > reference: 'fluxcom' -> > comment: '' -> > -> > # Variables to cmorize -> > variables: -> > gpp: -> > mip: Lmon -> > ``` -> > -> > The original configuration file for the "FLUXCOM" dataset can be found here: -> > [FLUXCOM.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml) -> > -> > Note the attribute "reference" here: it should include a ``doi`` related to -> > the dataset. For more information on how to add references to the -> > ``reference`` section of the configuration file, see the section in the -> > documentation about this: [adding -> > references](https://docs.esmvaltool.org/en/latest/community/diagnostic.html#adding-references) -> > -> {: .solution} -{: .challenge} Now that we have defined the configuration file for our "FLUXCOM" data, we can finally start writing the actual code for the CMORizer script. The main body @@ -1029,3 +907,152 @@ of the ESMValTool and ESMValCore. More information about adding observations to the ESMValTool can be found in the [documentation](https://docs.esmvaltool.org/en/latest/input.html#observations). + + + + + + + + + + + + + + + diff --git a/files/recipe_test_fluxcom.yml b/files/recipe_test_fluxcom.yml new file mode 100644 index 00000000..7d983a88 --- /dev/null +++ b/files/recipe_test_fluxcom.yml @@ -0,0 +1,19 @@ +documentation: + + description: Test recipe for FLUXCOM data + + authors: + - kalverla_peter + + maintainer: + - kalverla_peter + +datasets: + - {project: OBS, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2000, end_year: 2000, type: reanaly, version: ANN-v1} + +diagnostics: + check_fluxcom: + description: Check that ESMValTool can load the cmorized fluxnet data without errors. + variables: + gpp: + scripts: null From 040d3a75b20348c6c5a493ad7fbd48decbcde792 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 26 Feb 2021 17:47:31 +0100 Subject: [PATCH 523/647] More restructuring (still WIP) --- _episodes/09-cmorization.md | 201 ++++++++---------------------------- 1 file changed, 44 insertions(+), 157 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 06c663d8..02d4b785 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -116,6 +116,11 @@ run the CMORizer scripts: cmorize_obs -c -o ``` +The ``config-user-yml`` is the file in which we define the different data +paths, e.g. where the ESMValTool would find the "RAWOBS" folder. The +``dataset-name`` needs to be identical to the folder name that was created +to store the raw observation data files, in our case this would be "FLUXCOM". + If everything is okay, the output should look something like this: ~~~ @@ -286,6 +291,13 @@ def cmorization(in_dir, out_dir, cfg, _): # 3. store the data with the correct filename ``` +Here, ``in_dir`` corresponds to the input directory of the raw files, +``out_dir`` to the output directory of final reformatted data set and ``cfg`` to +a configuration dictionary given by a configuration file that we will get to shortly. + +When you type the command ``cmorize_obs`` in the terminal, ESMValTool will call +this function with the settings found in your configuration files. + > ## Note > > Always, always, when modifying or creating new code for the ESMValTool @@ -294,20 +306,17 @@ def cmorization(in_dir, out_dir, cfg, _): > {: .callout} -### 1. Finding the input data +### 1. Find the input data and store it under the right name. Since the original data does not follow CMOR filename conventions, we need to -tell ESMValTool what the filename for this new dataset looks like. We supply -this information via a dataset configuration file. It is important to note that -the name of the configuration file has to be identical to the name of the -dataset. Thus, we will create a file called +tell ESMValTool what the filename for this new dataset looks like. Also, we need +to provide the relevant information so ESMValTool can set the correct filename +for the cmorized data. We supply this information via a dataset configuration +file. It is important to note that the name of the configuration file has to be +identical to the name of the dataset. Thus, we will create a file called `/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml`. -In addition to the filename information, the configuration file also contains -information about "global attributes" for the netCDF file that will be -created and information about the variables that need to be CMORized. - -> ## Let's create the configuration file for the "FLUXCOM" dataset +> ## Create the configuration file for the "FLUXCOM" dataset > > Here is the skeleton of the "FLUXCOM" configuration file as it exists in > the ESMValTool framework. Try to fill in all missing pieces of information @@ -362,9 +371,7 @@ created and information about the variables that need to be CMORized. > > mip: Lmon > > ``` > > -> > The original configuration file for the "FLUXCOM" dataset can be found here: -> > [FLUXCOM.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml) -> > +> > *Suggestion: maybe add the reference under step 3 (additional but not strictly necessary steps)* > > Note the attribute "reference" here: it should include a ``doi`` related to > > the dataset. For more information on how to add references to the > > ``reference`` section of the configuration file, see the section in the @@ -374,18 +381,14 @@ created and information about the variables that need to be CMORized. > {: .solution} {: .challenge} +###### Here we need to add python code to the cmorizer script -### 2. Implementing additional fixes +so that we can run it and see whether it was able to find the correct input and create the right output. -### 3. Finalizing the CMORizer - -Once everything works as expected, there's a couple of things that we can still do. +### 2. Implementing additional fixes -- Add header info -- Make sure the metadata are added to the config file -- Maybe go through a checklist???? > ## Run the test recipe again > @@ -447,10 +450,27 @@ problems. So let's start writing a short python script that will fix these problems. -*PK: I'd suggest doing the header last, as it's not needed or relevant in the beginning*. -But the very first part of the CMORizing script is a header. The header -contains information about where to obtain the data, when it was accessed -the last time, which ESMValTool "tier" it is associated with, and more +To simplify this process, ESMValTool provides some convenience functions in +``utilities.py`` , which we already included in the boilerplate code above. + +Apart from a function to easily save data, this module contains different +kinds of small fixes to the data attributes, coordinates, and metadata which +are necessary for the data field to be CMOR-compliant. We will come back to +these functionalities in a bit. + + +### 3. Finalizing the CMORizer + +Once everything works as expected, there's a couple of things that we can still do. + +- Add header info +- Make sure the metadata are added to the config file +- Maybe go through a checklist???? +- add an entry to config-references? + + +The header contains information about where to obtain the data, when it was +accessed the last time, which ESMValTool "tier" it is associated with, and more detailed information about the necessary downloading and processing steps. > ## Fill out the header for the "FLUXCOM" dataset @@ -508,141 +528,8 @@ detailed information about the necessary downloading and processing steps. -Now that we have defined the configuration file for our "FLUXCOM" data, we can -finally start writing the actual code for the CMORizer script. The main body -of the CMORizer script must contain a function called - -```python -def cmorization(in_dir, out_dir, cfg, config_user): -``` - -with this exact call signature. Here, ``in_dir`` corresponds to the input -directory of the raw files, ``out_dir`` to the output directory of final -reformatted data set and ``cfg`` to the configuration dictionary given by the -``.yml`` configuration file. The return value of this function is ignored. All -the work, i.e. loading of the raw files, processing them and saving the final -output, has to be performed inside its body. To simplify this process, -ESMValTool provides some convenience functions in ``utilities.py`` , which -can be imported into your CMORizer by - -```python -from . import utilities as utils -``` - -Apart from a function to easily save data, this module contains different -kinds of small fixes to the data attributes, coordinates, and metadata which -are necessary for the data field to be CMOR-compliant. We will come back to -these functionalities in a bit. - -Note that this specific CMORizer script contains several subroutines in order -to make the code clearer and more readable (we strongly recommend to follow -that code style). For example, the function ``_get_filepath`` converts the raw -filepath to the correct one and the function ``_extract_variable`` extracts and -saves a single variable from the raw data. - -After all that theory, let's have a look at the python code of the -existing "FLUXCOM" CMORizer script. For now, we only want to read in the data -and then store it in a new file. - -```python -"""ESMValTool CMORizer for FLUXCOM GPP data. - -Tier - Tier 3: restricted dataset. - -Source - http://www.bgc-jena.mpg.de/geodb/BGI/Home - -Last access - 20190727 - -Download and processing instructions - From the website, select FLUXCOM as the data choice and click download. - Two files will be displayed. One for Land Carbon Fluxes and one for - Land Energy fluxes. The Land Carbon Flux file (RS + METEO) using - CRUNCEP data file has several data files for different variables. - The data for GPP generated using the - Artificial Neural Network Method will be in files with name: - GPP.ANN.CRUNCEPv6.monthly.*.nc - A registration is required for downloading the data. - Users in the UK with a CEDA-JASMIN account may request access to the jules - workspace and access the data. - Note : This data may require rechunking of the netcdf files. - This constraint will not exist once iris is updated to - version 2.3.0 Aug 2019 -""" -import logging -import os -import re -import numpy as np -import iris -from . import utilities as utils - -logger = logging.getLogger(__name__) - - -def _get_filepath(in_dir, basename): - """Find correct name of file (extend basename with timestamp).""" - regex = re.compile(basename) - - all_files = [ - f for f in os.listdir(in_dir) - if os.path.isfile(os.path.join(in_dir, f)) - ] - for filename in all_files: - if regex.match(filename): - return os.path.join(in_dir, basename) - raise OSError( - f"Cannot find input file matching pattern '{basename}' in '{in_dir}'") - - -def _extract_variable(cmor_info, attrs, filepath, out_dir): - """Extract variable.""" - var = cmor_info.short_name - logger.info("Var is %s", var) - cubes = iris.load(filepath) - for cube in cubes: - logger.info("Saving file") - utils.save_variable(cube, - var, - out_dir, - attrs, - unlimited_dimensions=['time']) - - -def cmorization(in_dir, out_dir, cfg, _): - """Cmorization func call.""" - glob_attrs = cfg['attributes'] - cmor_table = cfg['cmor_table'] - filepath = _get_filepath(in_dir, cfg['filename']) - logger.info("Found input file '%s'", filepath) - - # Run the cmorization - for (var, var_info) in cfg['variables'].items(): - logger.info("CMORizing variable '%s'", var) - glob_attrs['mip'] = var_info['mip'] - logger.info(var_info['mip']) - cmor_info = cmor_table.get_variable(var_info['mip'], var) - _extract_variable(cmor_info, glob_attrs, filepath, out_dir) -``` -Let's run this CMORizing script to see if the dataset is read correctly, and -what kind of file is written out. There is a specific command available in the -ESMValTool to run the CMORizing scripts: - -```bash -cmorize_obs -c -o -``` -The ``config-user-yml`` is the file in which we define the different data -paths, e.g. where the ESMValTool would find the "RAWOBS" folder. The -``dataset-name`` needs to be idential to the folder name that was created -to store the raw observation data files, in our case this would be "FLUXCOM". -The ESMValTool will create a folder with the correct tier information in your -defined output directory if that tier folder is not already available, and -then a folder named after the data set. In this folder the cmorized data set -will be stored as a netCDF file. If your run was successful, one or more -NetCDF files are produced in your output directory. > ## Was the CMORization successful so far?! > From c84986f717220235d470f6cbc3302cadf81a8880 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:28:51 +0100 Subject: [PATCH 524/647] correct grammar Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 20cd9781..f425f987 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -46,7 +46,7 @@ to the community. We’ll explore how ESMValTool can be installed it in a ``develop`` mode. Even if you aren’t collaborating with the community, this installation is needed -to run your new codes by ESMValTool. +to run your new codes with ESMValTool. Let’s get started. ### 1 Source code From 989c139808df59e7abb9b7ef7979cb15390b65bf Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:29:02 +0100 Subject: [PATCH 525/647] correct grammar Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index f425f987..f4775301 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -153,7 +153,7 @@ For more details about development installation, see ESMValTool documentation on > the ``esmvaltool`` environment. > Use this command to check that ESMValTool is installed in a ``develop`` mode. > -> **Tips**: see the +> **Tip**: see the > [documentation on conda list](https://docs.conda.io/projects/conda/en/latest/commands/list.html). > >> ## Solution From b0ab020ab6c41a9c3607b0cf847efd03ccde709a Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:29:25 +0100 Subject: [PATCH 526/647] fix typo Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index f4775301..3a982e2f 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -197,7 +197,7 @@ The process will take some effort and time to learn. However, a few “tools” i.e. command lines gets you a long way, and we’ll cover those essentials in the next sections. -**Tips**: we encourage you to keep the pull requests small. +**Tip**: we encourage you to keep the pull requests small. Reviewing small incremental changes are more efficient. ### Background From a52f3e49f8e5ab5759dd71eb6f8bf1a31b559b8a Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:30:03 +0100 Subject: [PATCH 527/647] re-phrase text Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 3a982e2f..bf522a6b 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -194,7 +194,7 @@ For a full description of the GitHub workflow, please see ESMValTool documentati The pull request will be tested, discussed and merged. This is called "**review process**". The process will take some effort and time to learn. -However, a few “tools” i.e. command lines gets you a long way, +However, a few (command line) tools can get you a long way, and we’ll cover those essentials in the next sections. **Tip**: we encourage you to keep the pull requests small. From 3b693ff6a6747d9f3c83bcda25be3115f1faca69 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:30:31 +0100 Subject: [PATCH 528/647] correct grammar Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index bf522a6b..4e48541a 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -369,7 +369,7 @@ when you submit a pull request. ### Build documentation When we add or update a code, we also update its corresponding documentation. -Documentations are available on +The ESMValTool documentation is available on [docs.esmvaltool.org](https://docs.esmvaltool.org/en/latest/index.html). The source files are located in ``ESMValTool/doc/sphinx/source/``. From f4354b48ffb2f6a52c63d834f80f0df626d0069a Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:30:48 +0100 Subject: [PATCH 529/647] correct grammar Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 4e48541a..322b0ef2 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -373,7 +373,7 @@ The ESMValTool documentation is available on [docs.esmvaltool.org](https://docs.esmvaltool.org/en/latest/index.html). The source files are located in ``ESMValTool/doc/sphinx/source/``. -To build documentations locally, first we make sure that the working directory is ``ESMValTool`` +To build documentation locally, first we make sure that the working directory is ``ESMValTool`` and our local branch is checked out. Then, we run: ~~~bash From 45b10dd808ee9a5a6f302bdec631bb13da1559ff Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:31:11 +0100 Subject: [PATCH 530/647] correct grammar Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 322b0ef2..1d60db2b 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -380,7 +380,7 @@ and our local branch is checked out. Then, we run: python setup.py build_sphinx -Ea ~~~ -Similar to codes, documentations should be well written and adhere to standards. +Similar to code, documentation should be well written and adhere to standards. If the documentation is built properly, the previous command prints a message to the console: ~~~bash From ac835c9758224f04417d054ba8abdd5ff482c196 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:31:33 +0100 Subject: [PATCH 531/647] remove bash from code block Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 1d60db2b..c0d27f00 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -383,11 +383,12 @@ python setup.py build_sphinx -Ea Similar to code, documentation should be well written and adhere to standards. If the documentation is built properly, the previous command prints a message to the console: -~~~bash +~~~ build succeeded. The HTML pages are in doc/sphinx/build/html. ~~~ +{: .output} The main page of the documentation has been built into ``index.html`` in ``doc/sphinx/build/html`` directory. From 5bb44418b9229d80093b4037dfa39ba95cbb4d81 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:32:03 +0100 Subject: [PATCH 532/647] add a closing remark Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index c0d27f00..d405f7a3 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -455,6 +455,8 @@ xdg-open doc/sphinx/build/html/index.html > {: .solution} {: .challenge} +Congratulations! You are now ready to make a pull request. + {% include links.md %} [token-authentication-requirements]: https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/#what-you-need-to-do-today From 49fd746786b63e070ca84123a74e958b7d62d300 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:32:41 +0100 Subject: [PATCH 533/647] add links to the tools Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index d405f7a3..b122a412 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -219,12 +219,12 @@ Let’s get started. We aim to adhere to best practices and coding standards. There are several tools that check our code against those standards like: -- flake8 for checking against the PEP8 style guide -- yapf to ensure consistent formatting for the whole project -- isort to consistently sort the import statements -- yamllint to ensure there are no syntax errors in our recipes and config files -- lintr for diagnostic scripts written in R -- codespell to check grammar +- [flake8](https://flake8.pycqa.org/en/latest/#) for checking against the PEP8 style guide +- [yapf](https://pypi.org/project/yapf/) to ensure consistent formatting for the whole project +- [isort](https://pypi.org/project/isort/) to consistently sort the import statements +- [yamllint](https://yamllint.readthedocs.io/en/stable/#) to ensure there are no syntax errors in our recipes and config files +- [lintr](https://github.com/jimhester/lintr) for diagnostic scripts written in R +- [codespell](https://pypi.org/project/codespell/) to check grammar The good news is that ``pre-commit`` has been already installed when we chose development installation. From 34069b27330a726148d6d1d89b50e0245b1b2f6d Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:33:02 +0100 Subject: [PATCH 534/647] fix typo Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index b122a412..b1c20154 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -298,7 +298,7 @@ To explore other tools, have a look at ESMValTool documentation on ### Run unit tests Previous section introduced some tools to check code style and quality. -What it hasen’t done is show us how to tell whether our code is getting the right answer. +What it hasn’t done is show us how to tell whether our code is getting the right answer. To achieve that, we need to write and run tests for widely-used functions. ESMValTool comes with a lot of tests that are in the folder ``tests``. From bf3d7f424add788dc3dfe4403a0d4105025d4a19 Mon Sep 17 00:00:00 2001 From: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> Date: Mon, 1 Mar 2021 15:55:13 +0100 Subject: [PATCH 535/647] fix link Co-authored-by: Peter Kalverla --- _episodes/08-development-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index b1c20154..bd3ed77e 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -361,7 +361,7 @@ when you submit a pull request. >> ~~~ >> >> For details, see lesson ->> [Writing your own diagnostic script]. +>> [Writing your own diagnostic script](#). >> > {: .solution} {: .challenge} From 0bf53ebfb848369759417b28d10e7c5a14cea937 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 1 Mar 2021 16:00:49 +0100 Subject: [PATCH 536/647] remove link to source installation --- _episodes/08-development-setup.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index bd3ed77e..aadddd50 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -143,9 +143,7 @@ works properly. To do this, run the tool with: esmvaltool --help ~~~ -If installation is successful, ESMValTool prints a help message to the console. -For more details about development installation, see ESMValTool documentation on -[install from source][install-from-source]. +If the installation is successful, ESMValTool prints a help message to the console. > ## Checking the development installation > From 4ab14cfdd86bc0541b189c5f27198800fc8705d0 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Mon, 1 Mar 2021 18:24:34 +0100 Subject: [PATCH 537/647] Continue reshuffling the episode --- _episodes/09-cmorization.md | 452 ++++++++++++++++++++++-------------- 1 file changed, 284 insertions(+), 168 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 02d4b785..a9928cc5 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -6,7 +6,7 @@ exercises: 45 questions: - "CMORization: what is it and why do we need it?" - "How to use the existing CMORizer scripts shipped with ESMValTool?" -- "How add support for new (observational) datasets?" +- "How to add support for new (observational) datasets?" objectives: - "Understand what CMORization is and why it is necessary." @@ -169,14 +169,15 @@ have a look at this file if you want. The script also uses a configuration file: ## Make a test recipe -Our end goal is to run a recipe that can load the data and work with it. So we -will start by making a simple recipe that can serve as a test case. Once we get -it to run, we know we have completed our task. +To verify that the data is correctly CMORized, we will make a simple test +recipe. As illustrated in the figure at the top of this episode, one of the +steps that ESMValTool executes is a CMOR-check. If the data is not correctly +CMORized, ESMValTool will give a warning or error. > ## Create a test recipe > > Create a simple recipe called `recipe_check_fluxcom.yml` that loads the -> "FLUXCOM" data. It should include a datasets section with a single entry for +> FLUXCOM data. It should include a datasets section with a single entry for > the "FLUXCOM" dataset with the correct dataset keys, and a diagnostics section > with two variables: gpp. We don't need any preprocessors or > scripts (set `scripts: null`), but we have to add a documentation section with @@ -250,7 +251,8 @@ rm /esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.nc rm /esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml ``` -If you now run the test recipe again it should fail, and somewhere in the output you should find something like: +If you now run the test recipe again it should fail, and somewhere in the output +you should find something like: ~~~ No input files found for ... @@ -261,7 +263,7 @@ Looking for files matching ['OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp[_.]*nc'] in ['/ From this we can see that the first thing our CMORizer should do is to rename the file so that it follows the CMOR filename conventions. -## Create a new CMORizer script +## Create a new CMORizer script and a corresponding config file The first step now is to create a new file in the right folder that will contain our new CMORizer instructions. Create a file called ``cmorize_obs_fluxcom.py`` @@ -293,101 +295,270 @@ def cmorization(in_dir, out_dir, cfg, _): Here, ``in_dir`` corresponds to the input directory of the raw files, ``out_dir`` to the output directory of final reformatted data set and ``cfg`` to -a configuration dictionary given by a configuration file that we will get to shortly. +a configuration dictionary given by a configuration file that we will get to +shortly. When you type the command ``cmorize_obs`` in the terminal, ESMValTool +will call this function with the settings found in your configuration files. -When you type the command ``cmorize_obs`` in the terminal, ESMValTool will call -this function with the settings found in your configuration files. +The ESMValTool CMORizer also needs a dataset configuration file. Create a file +called `/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml` +and fill it with the following boilerplate: -> ## Note +```yaml +--- +# filename: ??? + +attributes: + project_id: OBS6 +# dataset_id: ??? +# version: ??? +# tier: ??? +# modeling_realm: ??? +# source: ??? +# reference: ??? +# comment: ??? + +# variables: +# ???: +# mip: ??? +``` + + **Note**: the name of this file *must* be identical to dataset name. + +As you can see, the configuration file contains information about the original +filename of the dataset, and some additional metadata that you might recognize +from the CMOR filename structure. It also contains a list of variables that's +available for this dataset. We'll add this information step by step in the +following sections. + +> ## RAWOBS, OBS, OBS6!? +> +> In the configuration above we've already filled in the `project_id`. +> ESMValTool uses these project IDs to find the data on your hard drive, and +> also to find more information about the data. The `RAWOBS` and `OBS` projects +> refer to *external* data before and after CMORization, respectively. +> Historically, most external data were observations, hence the naming. > -> Always, always, when modifying or creating new code for the ESMValTool -> repositories, work on your *own, local* branch of the ESMValTool. For more -> information see [Development and contribution](/08-development-setup) +> In going from CMIP5 to CMIP6, the CMOR standards changed a bit. For example, +> some variables were renamed, which posed a dilemma: should CMORization +> reformat to the CMIP5 or CMIP6 definition? To solve this, the `OBS6` project +> was created. So `OBS6` data follow the CMIP6 standards, and that's what we'll +> use for the new CMORizer. > {: .callout} -### 1. Find the input data and store it under the right name. - -Since the original data does not follow CMOR filename conventions, we need to -tell ESMValTool what the filename for this new dataset looks like. Also, we need -to provide the relevant information so ESMValTool can set the correct filename -for the cmorized data. We supply this information via a dataset configuration -file. It is important to note that the name of the configuration file has to be -identical to the name of the dataset. Thus, we will create a file called -`/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml`. - -> ## Create the configuration file for the "FLUXCOM" dataset -> -> Here is the skeleton of the "FLUXCOM" configuration file as it exists in -> the ESMValTool framework. Try to fill in all missing pieces of information -> for this configuration file that are marked with ``???``. -> -> ```yaml -> --- -> # Filename -> filename: ??? -> -> # Common global attributes for Cmorizer output -> attributes: -> dataset_id: ??? -> version: ??? -> tier: ??? -> modeling_realm: ??? -> project_id: ??? -> source: ??? -> reference: ??? -> comment: ??? -> -> # Variables to cmorize -> variables: -> ???: -> mip: ??? -> ``` +You can try running the CMORizer at this point, and it should work without +errors. However, it doesn't produce any output yet: + +```bash +cmorize_obs -c -o FLUXCOM +``` + +### 1. Find the input data + +First we'll get the CMORizer script to locate our FLUXCOM data. We can use the +information from the `in_dir` and `cfg` variables. Add the following snippet to your CMORizer script: + +```python + # 1. find the input data + logger.info("in_dir: '%s'", in_dir) + logger.info("cfg: '%s'", cfg) +``` + +If you run the CMORizer again, it will print out the content of these variables. + +> ## Load the data +> +> Try to locate the input data inside the CMORizer script and load it (we'll use +> `iris` because ESMValTool includes helper utilities for iris cubes). Confirm +> that you've loaded the data by logging the correct path and (part of the) file +> content. +> +> > ## Solution +> > +> > There are many ways to do it. In any case, you should have added the +> > original filename to the configuration file (and un-commented this line): +> > `filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc'`. Note the `*`: this is a useful +> > shorthand to find multiple files for different years. In a similar way we +> > can also look for multiple variables, etc. +> > +> > Here's an example solution (inserted directly under the original comment): +> > +> > ```python +> > # 1. find the input data +> > filename_pattern = cfg['filename'] +> > matches = Path(in_dir).glob(filename_pattern) +> > +> > for match in matches: +> > input_file = str(match) +> > logger.info("found: %s", input_file) +> > cube = iris.load_cube(input_file) +> > logger.info("content: %s", cube) +> > ``` +> > +> > To make this work we've added `import iris` and `from pathlib import Path` +> > at the top of the file. Note that we've started a loop, since we may find +> > multiple files if there's more than one year of data available. +> > +> {: .solution} +{: .challenge} + +### 2. Save the data with the correct filename + +Before we start adding fixes, we'll first make sure that our CMORizer can also +write output files with the correct name. This will enable us to use the test +recipe for the CMOR compatibility check. + +We can use the `save` function from the `utils` that we imported at the top. The +call signature looks like this: +`utils.save_variables(cube, var, outdir, attrs, **kwargs)`. + +We already have the `cube` and the `outdir`. The variable short name (`var`) and +attributes (`attrs`) are set through the configuration file. + + + +> ## Fill the configuration file +> +> Uncomment the following entries in your configuration file and fill them with appropriate values: +> +> - dataset_id +> - version +> - tier +> - modeling_realm +> - short_name (the ??? immediately under `variables`) +> - mip > > > ## Answers > > -> > The configuration file for the "FLUXCOM" dataset with all necessary pieces -> > of information looks like this: +> > The configuration file now look something like this: > > > > ```yaml > > --- -> > # Filename > > filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' > > -> > # Common global attributes for Cmorizer output > > attributes: +> > project_id: OBS > > dataset_id: FLUXCOM > > version: 'ANN-v1' > > tier: 3 > > modeling_realm: reanaly -> > project_id: OBS -> > source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' -> > reference: 'fluxcom' +> > source: '' +> > reference: '' > > comment: '' > > -> > # Variables to cmorize > > variables: > > gpp: > > mip: Lmon > > ``` > > -> > *Suggestion: maybe add the reference under step 3 (additional but not strictly necessary steps)* -> > Note the attribute "reference" here: it should include a ``doi`` related to -> > the dataset. For more information on how to add references to the -> > ``reference`` section of the configuration file, see the section in the -> > documentation about this: [adding -> > references](https://docs.esmvaltool.org/en/latest/community/diagnostic.html#adding-references) -> > > {: .solution} {: .challenge} -###### Here we need to add python code to the cmorizer script +Now that we have set this information correctly in the config file, we can call +the save function. Add the following python code to your CMORizer script: + +```python +# 3. store the data with the correct filename +attributes = cfg['attributes'] +variables = cfg['variables'] + +for short_name, variable_info in variables.items(): + all_attributes = {**attributes, **variable_info} # add the mip to the other attributes + utils.save_variable(cube=cube, var=short_name, outdir=out_dir, attrs=all_attributes) +``` + +Since we only have one variable (gpp), the loop is not strictly necessary. +However, this makes it possible to add more variables later on. + +> ## Was the CMORization successful so far? +> +> If you run the CMORizer again, you should see that it creates an output file named +> ``OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_xxxx01-xxxx12.nc``. +> +> The "xxxx" and "yyyy" represent the start and end year of the data. +> +{: .callout} + +Great! +So we have produced a NetCDF file with the CMORizer that follows the naming +convention for ESMValTool datasets. Let's have a look at the NetCDF file as +it was written with the very basic CMORizer from above. -so that we can run it and see whether it was able to find the correct input and create the right output. +```bash +ncdump -h OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012.nc +``` +~~~ +netcdf OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012 { +dimensions: + time = UNLIMITED ; // (12 currently) + lat = 360 ; + lon = 720 ; +variables: + float GPP(time, lat, lon) ; + GPP:_FillValue = 1.e+20f ; + GPP:long_name = "GPP" ; + double time(time) ; + time:axis = "T" ; + time:units = "days since 1582-10-15 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "gregorian" ; + double lat(lat) ; + double lon(lon) ; +// global attributes: + :_NCProperties = "version=2,netcdf=4.7.4,hdf5=1.10.6" ; + :created_by = "Fabian Gans [fgans@bgc-jena.mpg.de], Ulrich Weber [uweber@bgc-jena.mpg.de]" ; + :flux = "GPP" ; + :forcing = "CRUNCEPv6" ; + :institution = "MPI-BGC-BGI" ; + :invalid_units = "gC m-2 day-1" ; + :method = "Artificial Neural Networks" ; + :provided_by = "Martin Jung [mjung@bgc-jena.mpg.de] on behalf of FLUXCOM team" ; + :reference = "Jung et al. 2016, Nature; Tramontana et al. 2016, Biogeosciences" ; + :temporal_resolution = "monthly" ; + :title = "GPP based on FLUXCOM RS+METEO with CRUNCEPv6 climate " ; + :version = "v1" ; + :Conventions = "CF-1.7" ; +} +~~~ +{: .output} -### 2. Implementing additional fixes +The file contains a variable named "GPP" that contains three dimensions: +"time", "lat", "lon". The units for this variable are not defined yet. +The ESMValTool did not know how to convert from the +original units to the units that are defined in the CMOR table for the +variable "gpp". The original units are therefore listed in the "global +attributes" section as ``invalid_units``. The ESMValTool recognized that the +units given in the original file did not match the units given in the CMOR +table and therefore put the information about the units in the metadata. + + +Copy the output of the CMORizer to your folder `/OBS6/Tier3/` +and change the test recipe to look for OBS6 data instead of OBS (note that we're +upgrading the CMORizer to newer standards here). + + +## Possible duplication! +the following paragraphs are the same as the first challenge in the subsequent section 3. + +If we test this NetCDF file now with our CMOR checker + +```bash +esmvaltool run recipe_check_fluxcom.yml --log_level debug +``` + +it should be able to find the correct file. Unfortunately, we're not done yet. +The first thing that the ESMValTool CMOR checker brings up is: + +```bash +iris.exceptions.UnitConversionError: Cannot convert from unknown units. The +"units" attribute may be set directly. +``` + +So now we're ready to start implementing the additional fixes. + +### 3. Implementing additional fixes > ## Run the test recipe again @@ -529,82 +700,6 @@ detailed information about the necessary downloading and processing steps. - - -> ## Was the CMORization successful so far?! -> -> If you check the folders in your output path, you should see the following -> folder structure: ``/Tier3/FLUXCOM/`` -> -> Within the "FLUXCOM" folder there should be a NetCDF file named -> ``OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_xxxx01-xxxx12.nc``. -> -> The "xxxx" represents the start year of the data period you wanted to -> CMORize, and the "yyyy" represents the end year. -> -{: .callout} - -Great! -So we have produced a NetCDF file with the CMORizer that follows the naming -convention for ESMValTool datasets. Let's have a look at the NetCDF file as -it was written with the very basic CMORizer from above (note, we are only -looking at the year 1980 in our example). - -```bash -netcdf OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012 { -dimensions: - time = UNLIMITED ; // (12 currently) - lat = 360 ; - lon = 720 ; -variables: - float GPP(time, lat, lon) ; - GPP:_FillValue = 1.e+20f ; - GPP:long_name = "GPP" ; - double time(time) ; - time:axis = "T" ; - time:units = "days since 1582-10-15 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "gregorian" ; - double lat(lat) ; - double lon(lon) ; - -// global attributes: - :_NCProperties = "version=2,netcdf=4.7.4,hdf5=1.10.6" ; - :created_by = "Fabian Gans [fgans@bgc-jena.mpg.de], Ulrich Weber [uweber@bgc-jena.mpg.de]" ; - :flux = "GPP" ; - :forcing = "CRUNCEPv6" ; - :institution = "MPI-BGC-BGI" ; - :invalid_units = "gC m-2 day-1" ; - :method = "Artificial Neural Networks" ; - :provided_by = "Martin Jung [mjung@bgc-jena.mpg.de] on behalf of FLUXCOM team" ; - :reference = "Jung et al. 2016, Nature; Tramontana et al. 2016, Biogeosciences" ; - :temporal_resolution = "monthly" ; - :title = "GPP based on FLUXCOM RS+METEO with CRUNCEPv6 climate " ; - :version = "v1" ; - :Conventions = "CF-1.7" ; -} -``` - -The file contains a variable named "GPP" that contains three dimensions: -"time", "lat", "lon". The units for this variable are not defined yet. -The ESMValTool did not know how to convert from the -original units to the units that are defined in the CMOR table for the -variable "gpp". The original units are therefore listed in the "global -attributes" section as ``invalid_units``. The ESMValTool recognized that the -units given in the original file did not match the units given in the CMOR -table and therefore put the information about the units in the metadata. - -If we test this NetCDF file now with our CMOR checker -```bash -esmvaltool run recipe_check_fluxcom.yml --log_level debug -``` -we will encounter an error again. The dataset is not correctly CMORized, and -the first thing that the ESMValTool complains about is: -```bash -iris.exceptions.UnitConversionError: Cannot convert from unknown units. The -"units" attribute may be set directly. -``` - Ok, so let's fix the units of the "GPP" variable in the CMORizer. For that we add the following three lines to the code in the section ``_extract_variable``: @@ -780,6 +875,7 @@ To do that there are a few more steps you have to do: 1. Make sure that there is a reference file available for the dataset [BibTeX info file](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) + ## Some final comments Adding a new CMORizer to the ESMValTool is definitely already an advanced task @@ -798,29 +894,6 @@ More information about adding observations to the ESMValTool can be found in the - - - - - @@ -943,3 +1016,46 @@ You can then edit the content and save it as ``CMOR_.dat``. > > > {: .solution} {: .challenge} --> + + + +> > *Suggestion: maybe add the reference under step 3 (additional but not strictly necessary steps)* +> > Note the attribute "reference" here: it should include a ``doi`` related to +> > the dataset. For more information on how to add references to the +> > ``reference`` section of the configuration file, see the section in the +> > documentation about this: [adding +> > references](https://docs.esmvaltool.org/en/latest/community/diagnostic.html#adding-references) + + + + + +> > ## Answers +> > +> > The configuration file for the "FLUXCOM" dataset with all necessary pieces +> > of information looks like this: +> > +> > ```yaml +> > --- +> > # Filename +> > filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' +> > +> > # Common global attributes for Cmorizer output +> > attributes: +> > project_id: OBS +> > dataset_id: FLUXCOM +> > version: 'ANN-v1' +> > tier: 3 +> > modeling_realm: reanaly +> > source: 'http://www.bgc-jena.mpg.de/geodb/BGI/Home' +> > reference: 'fluxcom' +> > comment: '' +> > +> > # Variables to cmorize +> > variables: +> > gpp: +> > mip: Lmon +> > ``` +> > +> {: .solution} +{: .challenge} From 49c7d1487cf4976ab134f52ad7fa7be7abed5972 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 2 Mar 2021 12:26:45 +0100 Subject: [PATCH 538/647] Further restructuring --- _episodes/09-cmorization.md | 396 +++++++++++++--------------------- files/recipe_test_fluxcom.yml | 2 +- 2 files changed, 154 insertions(+), 244 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index a9928cc5..8f64a3b5 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -356,12 +356,13 @@ cmorize_obs -c -o FLUXCOM ### 1. Find the input data First we'll get the CMORizer script to locate our FLUXCOM data. We can use the -information from the `in_dir` and `cfg` variables. Add the following snippet to your CMORizer script: +information from the `in_dir` and `cfg` variables. Add the following snippet to +your CMORizer script: ```python - # 1. find the input data - logger.info("in_dir: '%s'", in_dir) - logger.info("cfg: '%s'", cfg) +# 1. find the input data +logger.info("in_dir: '%s'", in_dir) +logger.info("cfg: '%s'", cfg) ``` If you run the CMORizer again, it will print out the content of these variables. @@ -413,9 +414,33 @@ call signature looks like this: `utils.save_variables(cube, var, outdir, attrs, **kwargs)`. We already have the `cube` and the `outdir`. The variable short name (`var`) and -attributes (`attrs`) are set through the configuration file. +attributes (`attrs`) are set through the configuration file. So we need to find out what the correct short name and attributes are. +The standard attributes for CMIP variables are defined in the [CMIP +tables](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/cmip6/Tables). +These tables are differentiated according to the "MIP" they belong to. The +tables are a copy of the [PCMDI](https://github.com/PCMDI) guidelines. +> ## Find the variable "gpp" in a CMOR table +> +> Check the available CMOR tables to find the variable "gpp" with the following characteristics: +> - standard_name: ``gross_primary_productivity_of_biomass_expressed_as_carbon`` +> - frequency: ``mon`` +> - modeling_realm: ``land`` +> +> > ## Answers +> > +> > The variable "gpp" belongs to the land variables. The temporal resolution that we are looking +> > for is "monthly". This information points to the "Lmon" CMIP table. And indeed, the variable +> > "gpp" can be found in the file +> > [here](https://github.com/ESMValGroup/ESMValCore/blob/master/esmvalcore/cmor/tables/cmip6/Tables/CMIP6_Lmon.json). +> > +> {: .solution} +{: .challenge} + +If the variable you are interested in is not available in the standard CMOR +tables, you could write a custom CMOR table entry for the variable. This, +however, is beyond the scope of this tutorial. > ## Fill the configuration file > @@ -472,17 +497,15 @@ However, this makes it possible to add more variables later on. > ## Was the CMORization successful so far? > -> If you run the CMORizer again, you should see that it creates an output file named -> ``OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_xxxx01-xxxx12.nc``. -> -> The "xxxx" and "yyyy" represent the start and end year of the data. +> If you run the CMORizer again, you should see that it creates an output file +> named ``OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_xxxx01-xxxx12.nc``. The "xxxx" and +> "yyyy" represent the start and end year of the data. > {: .callout} -Great! -So we have produced a NetCDF file with the CMORizer that follows the naming -convention for ESMValTool datasets. Let's have a look at the NetCDF file as -it was written with the very basic CMORizer from above. +Great! So we have produced a NetCDF file with the CMORizer that follows the +naming convention for ESMValTool datasets. Let's have a look at the NetCDF file +as it was written with the very basic CMORizer from above. ```bash ncdump -h OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012.nc @@ -491,7 +514,7 @@ ncdump -h OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012.nc ~~~ netcdf OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012 { dimensions: - time = UNLIMITED ; // (12 currently) + time = 12 ; lat = 360 ; lon = 720 ; variables: @@ -524,113 +547,135 @@ variables: ~~~ {: .output} -The file contains a variable named "GPP" that contains three dimensions: -"time", "lat", "lon". The units for this variable are not defined yet. -The ESMValTool did not know how to convert from the -original units to the units that are defined in the CMOR table for the -variable "gpp". The original units are therefore listed in the "global -attributes" section as ``invalid_units``. The ESMValTool recognized that the -units given in the original file did not match the units given in the CMOR -table and therefore put the information about the units in the metadata. +The file contains a variable named "GPP" that contains three dimensions: "time", +"lat", "lon". Notice the strange time units, and the `invalid_units` in the +global attributes section. Also it seems that there is not information available +about the lat and lon coordinates. These are just some of the things we'll +address in the next section. +### 3. Implementing additional fixes Copy the output of the CMORizer to your folder `/OBS6/Tier3/` -and change the test recipe to look for OBS6 data instead of OBS (note that we're -upgrading the CMORizer to newer standards here). +and change the test recipe to look for OBS6 data instead of OBS (note: we're +upgrading the CMORizer to newer standards here!). - -## Possible duplication! -the following paragraphs are the same as the first challenge in the subsequent section 3. - -If we test this NetCDF file now with our CMOR checker +If we now run the test recipe on our newly 'CMORized' data, ```bash esmvaltool run recipe_check_fluxcom.yml --log_level debug ``` -it should be able to find the correct file. Unfortunately, we're not done yet. -The first thing that the ESMValTool CMOR checker brings up is: +it should be able to find the correct file, but it does not succeed yet. The first +thing that the ESMValTool CMOR checker brings up is: -```bash +~~~ iris.exceptions.UnitConversionError: Cannot convert from unknown units. The "units" attribute may be set directly. +~~~ +{: .error} + +If you look closely at the error messages, you can see that this error concerns +the units of the coordinates. ESMValTool tries to fix them automatically, +but since no units are defined on the coordinates, this fails. + +The cmorizer utilities also include a function called `fix_coords`, but before +we can use it, we'll also need to make sure the coordinates have the correct +standard name. Add the following code to your cmorizer: + +```python +# Fix/add coordinate information and metadata +cube.coord('lat').standard_name = 'latitude' +cube.coord('lon').standard_name = 'longitude' +utils.fix_coords(cube) ``` -So now we're ready to start implementing the additional fixes. +With some additional refactoring, our cmorization function might then look +something like this: -### 3. Implementing additional fixes +```python +def cmorization(in_dir, out_dir, cfg, _): + """Cmorize the dataset.""" + # Get general information from the config file + attributes = cfg['attributes'] + variables = cfg['variables'] -> ## Run the test recipe again -> -> Run the test recipe again from earlier where you wanted to check if the -> ESMValTool can already find and read the freshly downloaded FLUXCOM data. -> -> > ## Answers -> > -> > ```bash -> > esmvaltool run recipe_check_fluxcom.yml --log_level debug -> > ``` -> > -> > The ESMValTool should now find your FLUXCOM datafile, and the error -> > message that the ESMValTool can't find the data should now not be present -> > anymore. However, there are plenty of other error messages around. -> > Somewhere within the many messages, you should see this: -> > -> > ```bash -> > ... -> > esmvalcore.cmor.check.CMORCheckError: There were errors in variable GPP: -> > Variable GPP units unknown can not be converted to kg m-2 s-1 -> > lon: standard_name should be longitude, not None -> > lat: standard_name should be latitude, not None -> > lon longitude coordinate has values < -360 degrees -> > lon longitude coordinate has values > 720 degrees -> > lat: has values < valid_min = -90.0 -> > lat: has values > valid_max = 90.0 -> > GPP: does not match coordinate rank -> > in cube: -> > gross_primary_productivity_of_carbon / (unknown) (time: 12; lat: 360; lon: 720) -> > Dimension coordinates: -> > time x - - -> > lat - x - -> > lon - - x -> > Attributes: -> > created_by: Fabian Gans [fgans@bgc-jena.mpg.de], Ulrich Weber [uweber@bgc-jena.mpg... -> > flux: GPP -> > forcing: CRUNCEPv6 -> > institution: MPI-BGC-BGI -> > invalid_units: gC m-2 day-1 -> > method: Artificial Neural Networks -> > provided_by: Martin Jung [mjung@bgc-jena.mpg.de] on behalf of FLUXCOM team -> > reference: Jung et al. 2016, Nature; Tramontana et al. 2016, Biogeosciences -> > source_file: /mnt/lustre02/work/bd0854/b309143/Data/Tier3/FLUXCOM/OBS_FLUXCOM_reana... -> > temporal_resolution: monthly -> > title: GPP based on FLUXCOM RS+METEO with CRUNCEPv6 climate -> > version: v1 -> > ... -> > ``` -> {: .solution} -{: .challenge} + for short_name, variable_info in variables.items(): + logger.info("CMORizing variable: %s", short_name) + + # 1a. Find the input data (one file for each year) + filename_pattern = cfg['filename'] + matches = Path(in_dir).glob(filename_pattern) + + for match in matches: + # 1b. Load the input data + input_file = str(match) + logger.info("found: %s", input_file) + cube = iris.load_cube(input_file) + + # 2. Apply the necessary fixes + # 2a. Fix/add coordinate information and metadata + cube.coord('lat').standard_name = 'latitude' + cube.coord('lon').standard_name = 'longitude' + utils.fix_coords(cube) + + # 3. Save the CMORized data + all_attributes = {**attributes, **variable_info} + utils.save_variable(cube=cube, var=short_name, outdir=out_dir, attrs=all_attributes) +``` + +Have a look at the netCDF file, and confirm that the coordinates now have much +more metadata added to them. Then, run the test recipe again with the latest +CMORizer output. The next error is: + +~~~ +esmvalcore.cmor.check.CMORCheckError: There were errors in variable GPP: +Variable GPP units unknown can not be converted to kg m-2 s-1 in cube: +~~~ +{: .error} + +Okay, so let's fix the units of the "GPP" variable in the CMORizer. Remember +that you can find the correct units in the CMOR table. Add the following three +lines to our CMORizer: + +```python +# 2b. Fix gpp units +logger.info("Changing units for gpp from gc/m2/day to kg/m2/s") +cube.data = cube.core_data() / (1000 * 86400) +cube.units = 'kg m-2 s-1' +``` + +If everything is okay, the test recipe should now pass. We're getting there. +Looking through the output though, there's still a warning. -The error messages that we see tell us that we do have to reformat the dataset -slightly to have it follow the CMOR standard. It seems like the variable "gpp" -does not have the correct unit that is given in the CMOR table where it is -[defined](https://github.com/ESMValGroup/ESMValCore/tree/master/esmvalcore/cmor/tables/cmip6/Tables). -It also seems like the "latitude" and "longitude" coordinates have some -problems. So let's start writing a short python script that will fix these -problems. +~~~ +WARNING There were warnings in variable GPP: +Standard name for GPP changed from None to gross_primary_productivity_of_biomass_expressed_as_carbon +Long name for GPP changed from GPP to Carbon Mass Flux out of Atmosphere Due to Gross Primary Production on Land [kgC m-2 s-1] +~~~ +{: .output} + +ESMValTool is able to apply automatic fixes here, but if we are running a +CMORizer script anyway, we might as well fix it immediately. +Add the following snippet: + +```python +# 2c. Fix metadata +cmor_table = cfg['cmor_table'] +cmor_info = cmor_table.get_variable(variable_info['mip'], short_name) +utils.fix_var_metadata(cube, cmor_info) +``` -To simplify this process, ESMValTool provides some convenience functions in -``utilities.py`` , which we already included in the boilerplate code above. +You can see that we're using the CMOR table here. This was passed on by +ESMValTool as part of the `CFG` input variable. So here we're making sure that +we're updating the cubes metadata to conform to the CMOR table. -Apart from a function to easily save data, this module contains different -kinds of small fixes to the data attributes, coordinates, and metadata which -are necessary for the data field to be CMOR-compliant. We will come back to -these functionalities in a bit. +Finally, the test recipe should run without errors or warnings. +## QUESTION: why is there no warning/error about the latitude direction. Should we not have to flip it? -### 3. Finalizing the CMORizer +### 4. Finalizing the CMORizer Once everything works as expected, there's a couple of things that we can still do. @@ -638,6 +683,12 @@ Once everything works as expected, there's a couple of things that we can still - Make sure the metadata are added to the config file - Maybe go through a checklist???? - add an entry to config-references? +- Add additional cmorizer step: + +```python +# 2d. Update the cubes metadata with all info from the config file +utils.set_global_atts(cube, attributes) +``` The header contains information about where to obtain the data, when it was @@ -700,157 +751,16 @@ detailed information about the necessary downloading and processing steps. -Ok, so let's fix the units of the "GPP" variable in the CMORizer. For that -we add the following three lines to the code in the section -``_extract_variable``: -```python -# convert data from gc/m2/day to kg/m2/s -cube = cube / (1000 * 86400) -cube.units = 'kg m-2 s-1' -``` -The whole section should then look like this: -```python -def _extract_variable(cmor_info, attrs, filepath, out_dir): - """Extract variable.""" - var = cmor_info.short_name - logger.info("Var is %s", var) - cubes = iris.load(filepath) - for cube in cubes: - # convert data from gc/m2/day to kg/m2/s - cube = cube / (1000 * 86400) - cube.units = 'kg m-2 s-1' - - logger.info("Saving file") - utils.save_variable(cube, - var, - out_dir, - attrs, - unlimited_dimensions=['time']) -``` -If we run the CMORizer script now again with the ``cmorize_obs`` call we -get a NetCDF file that has fixed units, but has an "unknown" variable name. -```bash -... -variables: - float unknown(time, lat, lon) ; - unknown:_FillValue = 1.e+20f ; - unknown:units = "kg m-2 s-1" ; - double time(time) ; - time:axis = "T" ; - time:units = "days since 1582-10-15 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "gregorian" ; - double lat(lat) ; - double lon(lon) ; -... -``` -We will have to do some more code tweaking then. But we also have not fixed -the problem with the coordinates ``lat`` and ``lon`` yet. There is no "units" -or "standard_name" given for either of these coordinates which will cause a -problem for the ESMValTool. Such some smaller formatting problems can occur -relatively often for coordinates like ``lat``, ``lon`` or ``time``. This means -that these problems need fixing in many CMORizers. -> ## Finalizing the "FLUXCOM" CMORizer -> -> The task is now to work with the functions in the file "utilities.py" to -> complete the CMORizer for the "FLUXCOM" dataset so that it can be read by -> the ESMValTool. The definitions of the coordinates and the variable "gpp" -> should look like the following after the successful CMORization: -> -> ```bash -> variables: -> float gpp(time, lat, lon) ; -> gpp:_FillValue = 1.e+20f ; -> gpp:standard_name = "gross_primary_productivity_of_carbon" ; -> gpp:long_name = "Carbon Mass Flux out of Atmosphere due to Gross Primary Production on Land" ; -> gpp:units = "kg m-2 s-1" ; -> double time(time) ; -> time:axis = "T" ; -> time:bounds = "time_bnds" ; -> time:units = "days since 1950-1-1 00:00:00" ; -> time:standard_name = "time" ; -> time:calendar = "gregorian" ; -> double time_bnds(time, bnds) ; -> double lat(lat) ; -> lat:axis = "Y" ; -> lat:bounds = "lat_bnds" ; -> lat:units = "degrees_north" ; -> lat:standard_name = "latitude" ; -> lat:long_name = "latitude coordinate" ; -> double lat_bnds(lat, bnds) ; -> double lon(lon) ; -> lon:axis = "X" ; -> lon:bounds = "lon_bnds" ; -> lon:units = "degrees_east" ; -> lon:standard_name = "longitude" ; -> lon:long_name = "longitude coordinate" ; -> double lon_bnds(lon, bnds) ; -> ``` -> -> For that to happen, you have to fix the following things: -> - adding standard names to the dimensions ``lat`` and ``lon`` -> - fix the metadata for the variable "gpp" -> - change the time units to start in the year 1950 -> - make the coordinates CMOR-compliant -> - set global attributes for the data file -> -> > ## Answers -> > -> > To fully CMORize the "FLUXCOM" dataset, you need to add the following -> > lines of code to the ``_extract_variable`` function of your CMORizer -> > script: -> > -> > ```python -> > def _extract_variable(cmor_info, attrs, filepath, out_dir): -> > """Extract variable.""" -> > var = cmor_info.short_name -> > logger.info("Var is %s", var) -> > cubes = iris.load(filepath) -> > for cube in cubes: -> > # convert data from gc/m2/day to kg/m2/s -> > cube = cube / (1000 * 86400) -> > cube.units = 'kg m-2 s-1' -> > -> > # The following two lines are needed for iris.util.guess_coord_axis -> > cube.coord('lat').standard_name = 'latitude' -> > cube.coord('lon').standard_name = 'longitude' -> > utils.fix_var_metadata(cube, cmor_info) -> > utils.convert_timeunits(cube, 1950) -> > utils.fix_coords(cube) -> > utils.set_global_atts(cube, attrs) -> > utils.flip_dim_coord(cube, 'latitude') -> > coord = cube.coord('latitude') -> > coord.bounds = np.flip(coord.bounds, axis=1) -> > logger.info("Saving file") -> > utils.save_variable(cube, -> > var, -> > out_dir, -> > attrs, -> > unlimited_dimensions=['time']) -> > -> > ``` -> > -> {: .solution} -{: .challenge} -So now we can finally run our new CMORizing script to produce an ESMValTool -readable datafile of the "FLUXCOM" dataset. As already mentioned, the call -to run a CMORizing script is as follows: -```bash -cmorize_obs -c -o -``` -If your run was successful, you should have gotten no error message in the -ESMValTool logging information and one or more NetCDF files should have been -produced in your output directory. To make sure that the CMORization has really worked as planned, we run the CMOR checker on this newly produced NetCDF file. If the ESMValTool can read @@ -1019,17 +929,17 @@ You can then edit the content and save it as ``CMOR_.dat``. -> > *Suggestion: maybe add the reference under step 3 (additional but not strictly necessary steps)* + + diff --git a/files/recipe_test_fluxcom.yml b/files/recipe_test_fluxcom.yml index 7d983a88..5d96b7f9 100644 --- a/files/recipe_test_fluxcom.yml +++ b/files/recipe_test_fluxcom.yml @@ -9,7 +9,7 @@ documentation: - kalverla_peter datasets: - - {project: OBS, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2000, end_year: 2000, type: reanaly, version: ANN-v1} + - {project: OBS6, dataset: FLUXCOM, mip: Lmon, tier: 3, start_year: 2000, end_year: 2000, type: reanaly, version: ANN-v1} diagnostics: check_fluxcom: From a133125081629289c5d7a9b9e2386e42103b93a9 Mon Sep 17 00:00:00 2001 From: rswamina Date: Wed, 3 Mar 2021 12:20:38 +0000 Subject: [PATCH 539/647] Line numbers added to code snippet --- _episodes/10-diagnostics.md | 259 +++++++++++++++++++----------------- 1 file changed, 140 insertions(+), 119 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index bf51b481..0e4b41fb 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -13,8 +13,8 @@ objectives: - "Understanding the interface between the ESMValCore preprocessor and a diagnostic script." keypoints: -- "Take home message 1" -- "etc ..." +- "ESMValTool providees helper functions to interface a Python diagnostic script with ESMValCore preprocessor output." +- "Existing diagnostics can be used as templates and modfied to write new diagnostics." --- ## Introduction @@ -31,118 +31,115 @@ machine using the instructions from [this episode](08-development-setup/index.ht ## Understanding an existing Python diagnostic We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) and the diagnostic script called by this recipe -- [diag_scripts/examples/diagnostic.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py). For reference, we have the diagnostic file in the dropdown box below. + > ## diagnostic.py > >~~~ ->"""Python example diagnostic.""" ->import logging ->from pathlib import Path ->from pprint import pformat -> ->import iris -> ->from esmvaltool.diag_scripts.shared import ( -> group_metadata, -> run_diagnostic, -> save_data, -> save_figure, -> select_metadata, -> sorted_metadata, ->) ->from esmvaltool.diag_scripts.shared.plot import quickplot -> ->logger = logging.getLogger(Path(__file__).stem) -> -> ->def get_provenance_record(attributes, ancestor_files): -> """Create a provenance record describing the diagnostic data and plot.""" -> caption = ("Average {long_name} between {start_year} and {end_year} " -> "according to {dataset}.".format(**attributes)) -> -> record = { -> 'caption': caption, -> 'statistics': ['mean'], -> 'domains': ['global'], -> 'plot_types': ['zonal'], -> 'authors': [ -> 'andela_bouwe', -> 'righi_mattia', -> -> -> ], -> 'references': [ -> 'acknow_project', -> ], -> 'ancestors': ancestor_files, -> } -> return record -> -> ->def compute_diagnostic(filename): -> """Compute an example diagnostic.""" -> logger.debug("Loading %s", filename) -> cube = iris.load_cube(filename) -> -> logger.debug("Running example computation") -> cube = iris.util.squeeze(cube) -> return cube -> -> ->def plot_diagnostic(cube, basename, provenance_record, cfg): -> """Create diagnostic data and plot it.""" -> -> # Save the data used for the plot -> save_data(basename, provenance_record, cfg, cube) -> -> if cfg.get('quickplot'): -> # Create the plot -> quickplot(cube, **cfg['quickplot']) -> # And save the plot -> save_figure(basename, provenance_record, cfg) -> -> ->def main(cfg): -> """Compute the time average for each input dataset.""" -> # Get a description of the preprocessed data that we will use as input. -> input_data = cfg['input_data'].values() -> -> # Demonstrate use of metadata access convenience functions. -> selection = select_metadata(input_data, short_name='tas', project='CMIP5') -> logger.info("Example of how to select only CMIP5 temperature data:\n%s", -> pformat(selection)) -> -> selection = sorted_metadata(selection, sort='dataset') -> logger.info("Example of how to sort this selection by dataset:\n%s", -> pformat(selection)) -> -> grouped_input_data = group_metadata(input_data, -> 'variable_group', -> sort='dataset') -> logger.info( -> "Example of how to group and sort input data by variable groups from " -> "the recipe:\n%s", pformat(grouped_input_data)) -> -> # Example of how to loop over variables/datasets in alphabetical order -> groups = group_metadata(input_data, 'variable_group', sort='dataset') -> for group_name in groups: -> logger.info("Processing variable %s", group_name) -> for attributes in groups[group_name]: -> logger.info("Processing dataset %s", attributes['dataset']) -> input_file = attributes['filename'] -> cube = compute_diagnostic(input_file) -> -> output_basename = Path(input_file).stem -> if group_name != attributes['short_name']: -> output_basename = group_name + '_' + output_basename -> provenance_record = get_provenance_record( -> attributes, ancestor_files=[input_file]) -> plot_diagnostic(cube, output_basename, provenance_record, cfg) -> -> ->if __name__ == '__main__': -> -> with run_diagnostic() as config: -> main(config) +> 1 """Python example diagnostic.""" +> 2 import logging +> 3 import os +> 4 from pprint import pformat +> 5 +> 6 import iris +> 7 +> 8 from esmvaltool.diag_scripts.shared import (group_metadata, run_diagnostic, +> 9 select_metadata, sorted_metadata) +> 10 from esmvaltool.diag_scripts.shared._base import ( +> 11 ProvenanceLogger, get_diagnostic_filename, get_plot_filename) +> 12 from esmvaltool.diag_scripts.shared.plot import quickplot +> 13 +> 14 logger = logging.getLogger(os.path.basename(__file__)) +> 15 +> 16 +> 17 def get_provenance_record(attributes, ancestor_files): +> 18 """Create a provenance record describing the diagnostic data and plot.""" +> 19 caption = ("Average {long_name} between {start_year} and {end_year} " +> 20 "according to {dataset}.".format(**attributes)) +> 21 +> 22 record = { +> 23 'caption': caption, +> 24 'statistics': ['mean'], +> 25 'domains': ['global'], +> 26 'plot_types': ['zonal'], +> 27 'authors': [ +> 28 'andela_bouwe', +> 29 'righi_mattia', +> 30 ], +> 31 'references': [ +> 32 'acknow_project', +> 33 ], +> 34 'ancestors': ancestor_files, +> 35 } +> 36 return record +> 37 +> 38 +> 39 def compute_diagnostic(filename): +> 40 """Compute an example diagnostic.""" +> 41 logger.debug("Loading %s", filename) +> 42 cube = iris.load_cube(filename) +> 43 +> 44 logger.debug("Running example computation") +> 45 return cube.collapsed('time', iris.analysis.MEAN) +> 46 +> 47 +> 48 def plot_diagnostic(cube, basename, provenance_record, cfg): +> 49 """Create diagnostic data and plot it.""" +> 50 diagnostic_file = get_diagnostic_filename(basename, cfg) +> 51 +> 52 logger.info("Saving analysis results to %s", diagnostic_file) +> 53 iris.save(cube, target=diagnostic_file) +> 54 +> 55 if cfg['write_plots'] and cfg.get('quickplot'): +> 56 plot_file = get_plot_filename(basename, cfg) +> 57 logger.info("Plotting analysis results to %s", plot_file) +> 58 provenance_record['plot_file'] = plot_file +> 59 quickplot(cube, filename=plot_file, **cfg['quickplot']) +> 60 +> 61 logger.info("Recording provenance of %s:\n%s", diagnostic_file, +> 62 pformat(provenance_record)) +> 63 with ProvenanceLogger(cfg) as provenance_logger: +> 64 provenance_logger.log(diagnostic_file, provenance_record) +> 65 +> 66 +> 67 def main(cfg): +> 68 """Compute the time average for each input dataset.""" +> 69 # Get a description of the preprocessed data that we will use as input. +> 70 input_data = cfg['input_data'].values() +> 71 +> 72 # Demonstrate use of metadata access convenience functions. +> 73 selection = select_metadata(input_data, short_name='pr', project='CMIP5') +> 74 logger.info("Example of how to select only CMIP5 precipitation data:\n%s", +> 75 pformat(selection)) +> 76 +> 77 selection = sorted_metadata(selection, sort='dataset') +> 78 logger.info("Example of how to sort this selection by dataset:\n%s", +> 79 pformat(selection)) +> 80 +> 81 grouped_input_data = group_metadata( +> 82 input_data, 'standard_name', sort='dataset') +> 83 logger.info( +> 84 "Example of how to group and sort input data by standard_name:" +> 85 "\n%s", pformat(grouped_input_data)) +> 86 +> 87 # Example of how to loop over variables/datasets in alphabetical order +> 88 for standard_name in grouped_input_data: +> 89 logger.info("Processing variable %s", standard_name) +> 90 for attributes in grouped_input_data[standard_name]: +> 91 logger.info("Processing dataset %s", attributes['dataset']) +> 92 input_file = attributes['filename'] +> 93 cube = compute_diagnostic(input_file) +> 94 +> 95 output_basename = os.path.splitext( +> 96 os.path.basename(input_file))[0] + '_mean' +> 97 provenance_record = get_provenance_record( +> 98 attributes, ancestor_files=[input_file]) +> 99 plot_diagnostic(cube, output_basename, provenance_record, cfg) +>100 +>101 +>102 if __name__ == '__main__': +>103 +>104 with run_diagnostic() as config: +>105 main(config) > >~~~ >{: .language-python} @@ -151,13 +148,15 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ > ## What is the starting point of the diagnostic? > -> Can you spot the main function in the Python code above? How many references ->do you see to this function? +> Can you spot a function called *main* in the Python code above? How many times is this +> function mentioned? +> > > > ## Answer > > -> > The main function is defined in the middle of this script and is called near the very ->>end. The function *run_diagnostic* which you also see at the end of the file is what +> > The main function is defined in the middle of this script on line 67 and is called +>> near the very end on line 105. +>>The function *run_diagnostic* just above that is what >>is called a context manager provided with ESMValTool and is the >>main entry point for most Python diagnostics. The variable *cfg* is a Python dictionary >>loaded with all the @@ -185,12 +184,12 @@ the *run* directory. An example path would be */path_to_recipe_output/run/diag_n > Can you find one example of the settings.yml file when you run this recipe? > Take a look at the *input_files* list in your settings.yml file. Do you see a mention of > a second yml file called *metadat.yml*? -> What information do you think is saved in metadat.yml? +> What information do you think is saved in metadata.yml? > > > > ## Answer > >Congratulations on finding an example each of the *settings.yml* and *metadata.yml* ->>files! You will have noticed that metadat.yml has information on your preprocessed +>>files! You will have noticed that metadata.yml has information on your preprocessed >>data. There is one file for each variable and it has detailed information on your data >> including project (e.g., CMIP6, OBS), dataset names (e.g., MIROC-6, UKESM-0-1-LL), >>variable attributes (e.g., standard_name, units), preprocessor applied and time range @@ -216,7 +215,7 @@ of these imported right at the beginning of the file and used after input data i > > ## Answer > > > > If you look carefully, you can see that there is a statement after each use of the ->> select and group functions that starts with *logger.info*. These lines print output to +>> select and group functions that starts with *logger.info* (lines 74, 78 and 83). These lines print output to >> the log files. If you looked at the content of your log files under the run directory, you >> should see the selected and grouped output. This is how you access preprocessed >> information within your diagnostic. @@ -240,7 +239,7 @@ these cubes can be modified, combined with other cubes' data or plotted. Two other possible ways of reading netcdf files using [xarrays](http://xarray.pydata.org/en/stable/) or [SciPy's netCDF library](https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html) for your own diagnostics are given below. ->## Example with xarray +>## Example using xarray > >~~~ >import xarray as xr #import statement at the beginning of the file @@ -261,6 +260,28 @@ for your own diagnostics are given below. {: .solution} +>## Example using Scipy's netCDF library +> +>~~~ +>from scipy.io import netcdfx #import statement at the beginning of the file +> +> +>def compute_diagnostic(filename): +> """Compute an example diagnostic.""" +> logger.debug("Loading %s", filename) +> f = netcdf.netcdf_file(filename,'r') +> +> #do your analyses on the data here +> +> return f +> +>~~~ +>{: .language-python} +> +{: .solution} + +## Plotting Diagnostic Output + ## Another section From 4b1f0b546f50a42e78f57d92d8e4a9154425d4e9 Mon Sep 17 00:00:00 2001 From: rswamina Date: Wed, 3 Mar 2021 17:21:49 +0000 Subject: [PATCH 540/647] Added examples for different ways to read the netcdf file and some explanation for plotting as well as passing arguments --- _episodes/10-diagnostics.md | 63 ++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 0e4b41fb..8dc64d35 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -13,8 +13,8 @@ objectives: - "Understanding the interface between the ESMValCore preprocessor and a diagnostic script." keypoints: -- "ESMValTool providees helper functions to interface a Python diagnostic script with ESMValCore preprocessor output." -- "Existing diagnostics can be used as templates and modfied to write new diagnostics." +- "ESMValTool provides helper functions to interface a Python diagnostic script with ESMValCore preprocessor output." +- "Existing diagnostics can be used as templates and modified to write new diagnostics." --- ## Introduction @@ -156,7 +156,7 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ > > > > The main function is defined in the middle of this script on line 67 and is called >> near the very end on line 105. ->>The function *run_diagnostic* just above that is what +>>The function *run_diagnostic* function where *main* is called is what >>is called a context manager provided with ESMValTool and is the >>main entry point for most Python diagnostics. The variable *cfg* is a Python dictionary >>loaded with all the @@ -183,7 +183,7 @@ the *run* directory. An example path would be */path_to_recipe_output/run/diag_n > > Can you find one example of the settings.yml file when you run this recipe? > Take a look at the *input_files* list in your settings.yml file. Do you see a mention of -> a second yml file called *metadat.yml*? +> a second yml file called *metadata.yml*? > What information do you think is saved in metadata.yml? > > @@ -201,11 +201,13 @@ the *run* directory. An example path would be */path_to_recipe_output/run/diag_n ## Extracting information needed for analyses In the *main* function of the diagnostic, you will see that *input_data* values are read -from the *cfg* Python dictionary. Typically, users will now need to group this input data +from the *cfg* Python dictionary (line 70). +Typically, users will now need to group this input data according to some criteria such as by model or experiment and select specifics to analyse. -ESMValTool prvides a whole host of convenience functions that can do this for you. +ESMValTool provides a whole host of convenience functions that can do this for you. A list of available functions and their description is provided [here](https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html). In our example, you will see several -of these imported right at the beginning of the file and used after input data is read. +of these imported right at the beginning of the file (lines 8-12) and used after input data +is read. > ## ESMValTool Diagnostic Interface Functions > @@ -215,7 +217,8 @@ of these imported right at the beginning of the file and used after input data i > > ## Answer > > > > If you look carefully, you can see that there is a statement after each use of the ->> select and group functions that starts with *logger.info* (lines 74, 78 and 83). These lines print output to +>> select and group functions that starts with *logger.info* (lines 74, 78 and 83). +>> These lines print output to >> the log files. If you looked at the content of your log files under the run directory, you >> should see the selected and grouped output. This is how you access preprocessed >> information within your diagnostic. @@ -223,13 +226,14 @@ of these imported right at the beginning of the file and used after input data i > {: .solution} {: .challenge} -Finally, after grouping we read individual attributes such as the filename which gives us +After grouping we read individual attributes such as the filename which gives us the specific name of the preprocessed data file we want to read and analyse. -Following this, we see the call to a function called *compute_diagnostic*. +Following this, we see the call to a function called *compute_diagnostic* (line 39). In this example, this is where the analyses on the data is done. If you were writing your own diagnostic, this is the function you would write your own code in. + ## Diagnostic Computation The *compute_diagnostic* function in this example uses a software called [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data from a *netCDF* file and perform the simple computation of removing any dimension @@ -281,7 +285,44 @@ for your own diagnostics are given below. {: .solution} ## Plotting Diagnostic Output - +Often, the end product of a diagnostic script is a plot or figure. ESMValTool makes it +possible to produce a wide array of such figures as seen in the [gallery] (https://docs.esmvaltool.org/en/latest/gallery.html). In this example we use Iris cubes for processing the +netCDF data. The Iris cube returned from the *compute_diagnostic* +function (line 93) is passed to the *plot_diagnostic* function (line 99). You could return +an xarray data object for example and pass that on to the plotting function. +The *plot_diagnostic* function is where you would plug in your plotting routine in this +example. + +More specifically, the *quickplot* function (line 59) can be replaced with the +function of your choice. The lines preceding this function are to save the Iris cube object +and to save the Provenance of the file. Again, you may choose your own method of saving +your diagnostic object. More information on how to record Provenance is available [here](https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance). + +> ## Passing arguments to the diagnostic from the recipe +> +> How can you pass a user defined argument to your diagnostic ? If you +wanted to plot a colormesh plot with a particular colormap, how would you do so? +> +> > ## Answer +> > ```yaml +> > script1: +> > script: examples/diagnostic.py +> > quickplot: +> > plot_type: pcolormesh +> > cmap: Reds +>>``` +> > The lines below `script:examples/diagnostic.py` have pairs of arguments and values +>> that are passed on to the diagnostic script. In the case of the *quickplot* argument, +>>we can further pass arguments for *quickplot* such as the type of plot *pcolormesh* +>>and the colormap with keyword *cmap* as `cmap:Reds`. In line 59 of the diagnostic, +>>we access this argument. Look at other recipes and diagnostics for more examples of +>> user defined arguments. +> > +> {: .solution} +{: .challenge} + + + ## Another section From cd012b60ffe6bb699c03b100132068ff9dd66dfb Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 4 Mar 2021 15:29:35 +0100 Subject: [PATCH 541/647] remove unused sections from the lesson --- _episodes/10-diagnostics.md | 194 +++++++++++++++--------------------- 1 file changed, 78 insertions(+), 116 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 8dc64d35..3a925ae5 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -20,12 +20,12 @@ keypoints: ## Introduction The diagnostic script is an important component of ESMValTool where the -scientific analysis or performance metric is implemented. With ESMValTool, you +scientific analysis or performance metric is implemented. With ESMValTool, you can reuse an existing diagnostic, adapt and existing one for your needs or -write your own new diagnostic. Diagnostics can be written in a number of open -source languages such as Python, R, Julia and NCL but we will focus on understanding +write your own new diagnostic. Diagnostics can be written in a number of open +source languages such as Python, R, Julia and NCL but we will focus on understanding and writing Python diagnostics in this lesson. In order to access existing diagnostics or -to write your own, please install ESMValTool in the development mode on your +to write your own, please install ESMValTool in the development mode on your machine using the instructions from [this episode](08-development-setup/index.html). ## Understanding an existing Python diagnostic @@ -39,23 +39,23 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ > 2 import logging > 3 import os > 4 from pprint import pformat -> 5 +> 5 > 6 import iris -> 7 +> 7 > 8 from esmvaltool.diag_scripts.shared import (group_metadata, run_diagnostic, > 9 select_metadata, sorted_metadata) > 10 from esmvaltool.diag_scripts.shared._base import ( > 11 ProvenanceLogger, get_diagnostic_filename, get_plot_filename) > 12 from esmvaltool.diag_scripts.shared.plot import quickplot -> 13 +> 13 > 14 logger = logging.getLogger(os.path.basename(__file__)) -> 15 -> 16 +> 15 +> 16 > 17 def get_provenance_record(attributes, ancestor_files): > 18 """Create a provenance record describing the diagnostic data and plot.""" > 19 caption = ("Average {long_name} between {start_year} and {end_year} " > 20 "according to {dataset}.".format(**attributes)) -> 21 +> 21 > 22 record = { > 23 'caption': caption, > 24 'statistics': ['mean'], @@ -71,56 +71,56 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ > 34 'ancestors': ancestor_files, > 35 } > 36 return record -> 37 -> 38 +> 37 +> 38 > 39 def compute_diagnostic(filename): > 40 """Compute an example diagnostic.""" > 41 logger.debug("Loading %s", filename) > 42 cube = iris.load_cube(filename) -> 43 +> 43 > 44 logger.debug("Running example computation") > 45 return cube.collapsed('time', iris.analysis.MEAN) -> 46 -> 47 +> 46 +> 47 > 48 def plot_diagnostic(cube, basename, provenance_record, cfg): > 49 """Create diagnostic data and plot it.""" > 50 diagnostic_file = get_diagnostic_filename(basename, cfg) -> 51 +> 51 > 52 logger.info("Saving analysis results to %s", diagnostic_file) > 53 iris.save(cube, target=diagnostic_file) -> 54 +> 54 > 55 if cfg['write_plots'] and cfg.get('quickplot'): > 56 plot_file = get_plot_filename(basename, cfg) > 57 logger.info("Plotting analysis results to %s", plot_file) > 58 provenance_record['plot_file'] = plot_file > 59 quickplot(cube, filename=plot_file, **cfg['quickplot']) -> 60 +> 60 > 61 logger.info("Recording provenance of %s:\n%s", diagnostic_file, > 62 pformat(provenance_record)) > 63 with ProvenanceLogger(cfg) as provenance_logger: > 64 provenance_logger.log(diagnostic_file, provenance_record) -> 65 -> 66 +> 65 +> 66 > 67 def main(cfg): > 68 """Compute the time average for each input dataset.""" > 69 # Get a description of the preprocessed data that we will use as input. > 70 input_data = cfg['input_data'].values() -> 71 +> 71 > 72 # Demonstrate use of metadata access convenience functions. > 73 selection = select_metadata(input_data, short_name='pr', project='CMIP5') > 74 logger.info("Example of how to select only CMIP5 precipitation data:\n%s", > 75 pformat(selection)) -> 76 +> 76 > 77 selection = sorted_metadata(selection, sort='dataset') > 78 logger.info("Example of how to sort this selection by dataset:\n%s", > 79 pformat(selection)) -> 80 +> 80 > 81 grouped_input_data = group_metadata( > 82 input_data, 'standard_name', sort='dataset') > 83 logger.info( > 84 "Example of how to group and sort input data by standard_name:" > 85 "\n%s", pformat(grouped_input_data)) -> 86 +> 86 > 87 # Example of how to loop over variables/datasets in alphabetical order > 88 for standard_name in grouped_input_data: > 89 logger.info("Processing variable %s", standard_name) @@ -128,16 +128,16 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ > 91 logger.info("Processing dataset %s", attributes['dataset']) > 92 input_file = attributes['filename'] > 93 cube = compute_diagnostic(input_file) -> 94 +> 94 > 95 output_basename = os.path.splitext( > 96 os.path.basename(input_file))[0] + '_mean' > 97 provenance_record = get_provenance_record( > 98 attributes, ancestor_files=[input_file]) > 99 plot_diagnostic(cube, output_basename, provenance_record, cfg) ->100 ->101 +>100 +>101 >102 if __name__ == '__main__': ->103 +>103 >104 with run_diagnostic() as config: >105 main(config) > @@ -154,15 +154,15 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ > > > ## Answer > > -> > The main function is defined in the middle of this script on line 67 and is called ->> near the very end on line 105. +> > The main function is defined in the middle of this script on line 67 and is called +>> near the very end on line 105. >>The function *run_diagnostic* function where *main* is called is what ->>is called a context manager provided with ESMValTool and is the ->>main entry point for most Python diagnostics. The variable *cfg* is a Python dictionary +>>is called a context manager provided with ESMValTool and is the +>>main entry point for most Python diagnostics. The variable *cfg* is a Python dictionary >>loaded with all the ->>necessary information needed to run the diagnostic script including location of +>>necessary information needed to run the diagnostic script including location of >> input data and various settings. ->>In the *main* function, we will next parse this *cfg* variable and extract +>>In the *main* function, we will next parse this *cfg* variable and extract >>information as needed to do our analyses. > > > {: .solution} @@ -170,43 +170,43 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ ## What information do I need for my analyses? The very first thing passed to the diagnostic via the *cfg* dictionary is a path to a file -called *settings.yml*. It is found at the lowest level of your directory structure under -the *run* directory. An example path would be */path_to_recipe_output/run/diag_name/script_name/settings.yml*. +called *settings.yml*. It is found at the lowest level of your directory structure under +the *run* directory. An example path would be */path_to_recipe_output/run/diag_name/script_name/settings.yml*. > ## What is in the settings.yml file? -> The ESMValTool documentation page provides a generic overview of what is in the +> The ESMValTool documentation page provides a generic overview of what is in the >settings.yml file [here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html). -> +> {: .callout} > ## Challenge : digging in deeper to understand the preprocesor-diagnostic interface > > Can you find one example of the settings.yml file when you run this recipe? -> Take a look at the *input_files* list in your settings.yml file. Do you see a mention of -> a second yml file called *metadata.yml*? +> Take a look at the *input_files* list in your settings.yml file. Do you see a mention of +> a second yml file called *metadata.yml*? > What information do you think is saved in metadata.yml? > > > > ## Answer -> >Congratulations on finding an example each of the *settings.yml* and *metadata.yml* ->>files! You will have noticed that metadata.yml has information on your preprocessed +> >Congratulations on finding an example each of the *settings.yml* and *metadata.yml* +>>files! You will have noticed that metadata.yml has information on your preprocessed >>data. There is one file for each variable and it has detailed information on your data ->> including project (e.g., CMIP6, OBS), dataset names (e.g., MIROC-6, UKESM-0-1-LL), +>> including project (e.g., CMIP6, OBS), dataset names (e.g., MIROC-6, UKESM-0-1-LL), >>variable attributes (e.g., standard_name, units), preprocessor applied and time range >> of the data. You are now ready to access all of this information for your evaluation! -> > +> > > > > {: .solution} {: .challenge} ## Extracting information needed for analyses -In the *main* function of the diagnostic, you will see that *input_data* values are read -from the *cfg* Python dictionary (line 70). -Typically, users will now need to group this input data +In the *main* function of the diagnostic, you will see that *input_data* values are read +from the *cfg* Python dictionary (line 70). +Typically, users will now need to group this input data according to some criteria such as by model or experiment and select specifics to analyse. -ESMValTool provides a whole host of convenience functions that can do this for you. -A list of available functions and their description is provided [here](https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html). In our example, you will see several -of these imported right at the beginning of the file (lines 8-12) and used after input data +ESMValTool provides a whole host of convenience functions that can do this for you. +A list of available functions and their description is provided [here](https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html). In our example, you will see several +of these imported right at the beginning of the file (lines 8-12) and used after input data is read. > ## ESMValTool Diagnostic Interface Functions @@ -216,8 +216,8 @@ is read. > > > ## Answer > > -> > If you look carefully, you can see that there is a statement after each use of the ->> select and group functions that starts with *logger.info* (lines 74, 78 and 83). +> > If you look carefully, you can see that there is a statement after each use of the +>> select and group functions that starts with *logger.info* (lines 74, 78 and 83). >> These lines print output to >> the log files. If you looked at the content of your log files under the run directory, you >> should see the selected and grouped output. This is how you access preprocessed @@ -226,24 +226,24 @@ is read. > {: .solution} {: .challenge} -After grouping we read individual attributes such as the filename which gives us -the specific name of the preprocessed data file we want to read and analyse. -Following this, we see the call to a function called *compute_diagnostic* (line 39). -In this example, this is where the analyses on the data is done. -If you were writing your own diagnostic, this is the function you would write your +After grouping we read individual attributes such as the filename which gives us +the specific name of the preprocessed data file we want to read and analyse. +Following this, we see the call to a function called *compute_diagnostic* (line 39). +In this example, this is where the analyses on the data is done. +If you were writing your own diagnostic, this is the function you would write your own code in. ## Diagnostic Computation -The *compute_diagnostic* function in this example uses a software called [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read -data from a *netCDF* file and perform the simple computation of removing any dimension +The *compute_diagnostic* function in this example uses a software called [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read +data from a *netCDF* file and perform the simple computation of removing any dimension of length one. This is just an illustrative example. Iris reads data into data structures called [cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). The data in -these cubes can be modified, combined with other cubes' data or plotted. Two -other possible ways of reading netcdf files using [xarrays](http://xarray.pydata.org/en/stable/) or [SciPy's netCDF library](https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html) +these cubes can be modified, combined with other cubes' data or plotted. Two +other possible ways of reading netcdf files using [xarrays](http://xarray.pydata.org/en/stable/) or [SciPy's netCDF library](https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html) for your own diagnostics are given below. ->## Example using xarray +>## Example using xarray > >~~~ >import xarray as xr #import statement at the beginning of the file @@ -252,7 +252,7 @@ for your own diagnostics are given below. >def compute_diagnostic(filename): > """Compute an example diagnostic.""" > logger.debug("Loading %s", filename) -> ds = xr.open_dataset(filename) +> ds = xr.open_dataset(filename) > > #do your analyses on the data here > @@ -273,7 +273,7 @@ for your own diagnostics are given below. >def compute_diagnostic(filename): > """Compute an example diagnostic.""" > logger.debug("Loading %s", filename) -> f = netcdf.netcdf_file(filename,'r') +> f = netcdf.netcdf_file(filename,'r') > > #do your analyses on the data here > @@ -285,23 +285,23 @@ for your own diagnostics are given below. {: .solution} ## Plotting Diagnostic Output -Often, the end product of a diagnostic script is a plot or figure. ESMValTool makes it -possible to produce a wide array of such figures as seen in the [gallery] (https://docs.esmvaltool.org/en/latest/gallery.html). In this example we use Iris cubes for processing the -netCDF data. The Iris cube returned from the *compute_diagnostic* -function (line 93) is passed to the *plot_diagnostic* function (line 99). You could return +Often, the end product of a diagnostic script is a plot or figure. ESMValTool makes it +possible to produce a wide array of such figures as seen in the [gallery] (https://docs.esmvaltool.org/en/latest/gallery.html). In this example we use Iris cubes for processing the +netCDF data. The Iris cube returned from the *compute_diagnostic* +function (line 93) is passed to the *plot_diagnostic* function (line 99). You could return an xarray data object for example and pass that on to the plotting function. The *plot_diagnostic* function is where you would plug in your plotting routine in this -example. +example. -More specifically, the *quickplot* function (line 59) can be replaced with the -function of your choice. The lines preceding this function are to save the Iris cube object +More specifically, the *quickplot* function (line 59) can be replaced with the +function of your choice. The lines preceding this function are to save the Iris cube object and to save the Provenance of the file. Again, you may choose your own method of saving -your diagnostic object. More information on how to record Provenance is available [here](https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance). +your diagnostic object. More information on how to record Provenance is available [here](https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance). > ## Passing arguments to the diagnostic from the recipe > -> How can you pass a user defined argument to your diagnostic ? If you -wanted to plot a colormesh plot with a particular colormap, how would you do so? +> How can you pass a user defined argument to your diagnostic ? If you +wanted to plot a colormesh plot with a particular colormap, how would you do so? > > > ## Answer > > ```yaml @@ -312,51 +312,13 @@ wanted to plot a colormesh plot with a particular colormap, how would you do so? > > cmap: Reds >>``` > > The lines below `script:examples/diagnostic.py` have pairs of arguments and values ->> that are passed on to the diagnostic script. In the case of the *quickplot* argument, ->>we can further pass arguments for *quickplot* such as the type of plot *pcolormesh* ->>and the colormap with keyword *cmap* as `cmap:Reds`. In line 59 of the diagnostic, +>> that are passed on to the diagnostic script. In the case of the *quickplot* argument, +>>we can further pass arguments for *quickplot* such as the type of plot *pcolormesh* +>>and the colormap with keyword *cmap* as `cmap:Reds`. In line 59 of the diagnostic, >>we access this argument. Look at other recipes and diagnostics for more examples of >> user defined arguments. > > > {: .solution} {: .challenge} - - - -## Another section - -and some more text, etc. - -## Conclusion - - -## For development purposes - -Here are some of the elements that we can add - -> ## Example exercise -> -> This is just a reminder on how to implement exercises -> -> > ## Example answer -> > -> > And this is where to add the answer. -> > This box will be collapsed in the page is first loaded. -> > -> {: .solution} -{: .challenge} - -```bash -example command line instruction -``` - -``` -example error message -``` -{: .error} - -> ## Example callout box -> -> This is how to create a callout box -{: .callout} +{% include links.md %} From 52084f1c44df84fb404fd2a9c3c0f32d2d61bfbc Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 4 Mar 2021 15:34:42 +0100 Subject: [PATCH 542/647] remove the word esmvalcore, fix some of the markdown errors --- _episodes/10-diagnostics.md | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 3a925ae5..b5424e27 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -10,10 +10,10 @@ questions: objectives: - "Writing a new Python diagnostic" -- "Understanding the interface between the ESMValCore preprocessor and a diagnostic script." +- "Understanding the interface between the preprocessor and a diagnostic script." keypoints: -- "ESMValTool provides helper functions to interface a Python diagnostic script with ESMValCore preprocessor output." +- "ESMValTool provides helper functions to interface a Python diagnostic script with preprocessor output." - "Existing diagnostics can be used as templates and modified to write new diagnostics." --- @@ -29,12 +29,12 @@ to write your own, please install ESMValTool in the development mode on your machine using the instructions from [this episode](08-development-setup/index.html). ## Understanding an existing Python diagnostic -We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) and the diagnostic script called by this recipe -- [diag_scripts/examples/diagnostic.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py). For reference, we have the diagnostic file in the dropdown box below. +We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) and the diagnostic script called by this recipe -- [diag_scripts/examples/diagnostic.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py). For reference, we have the diagnostic file in the dropdown box below. > ## diagnostic.py > ->~~~ +>~~~python > 1 """Python example diagnostic.""" > 2 import logging > 3 import os @@ -142,6 +142,7 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ >105 main(config) > >~~~ +> >{: .language-python} > {:.solution} @@ -169,26 +170,28 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ {: .challenge} ## What information do I need for my analyses? + The very first thing passed to the diagnostic via the *cfg* dictionary is a path to a file called *settings.yml*. It is found at the lowest level of your directory structure under the *run* directory. An example path would be */path_to_recipe_output/run/diag_name/script_name/settings.yml*. > ## What is in the settings.yml file? + > The ESMValTool documentation page provides a generic overview of what is in the >settings.yml file [here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html). > {: .callout} -> ## Challenge : digging in deeper to understand the preprocesor-diagnostic interface +> ## Challenge: digging in deeper to understand the preprocesor-diagnostic interface > > Can you find one example of the settings.yml file when you run this recipe? > Take a look at the *input_files* list in your settings.yml file. Do you see a mention of > a second yml file called *metadata.yml*? > What information do you think is saved in metadata.yml? > -> -> > ## Answer -> >Congratulations on finding an example each of the *settings.yml* and *metadata.yml* +>> ## Answer +>> +>>Congratulations on finding an example each of the *settings.yml* and *metadata.yml* >>files! You will have noticed that metadata.yml has information on your preprocessed >>data. There is one file for each variable and it has detailed information on your data >> including project (e.g., CMIP6, OBS), dataset names (e.g., MIROC-6, UKESM-0-1-LL), @@ -200,6 +203,7 @@ the *run* directory. An example path would be */path_to_recipe_output/run/diag_n {: .challenge} ## Extracting information needed for analyses + In the *main* function of the diagnostic, you will see that *input_data* values are read from the *cfg* Python dictionary (line 70). Typically, users will now need to group this input data @@ -214,9 +218,9 @@ is read. > Can you spot the functions used for selecting and grouping data in the example? >After running this example, how can you tell what the functions do? > -> > ## Answer -> > -> > If you look carefully, you can see that there is a statement after each use of the +>> ## Answer +>> +>> If you look carefully, you can see that there is a statement after each use of the >> select and group functions that starts with *logger.info* (lines 74, 78 and 83). >> These lines print output to >> the log files. If you looked at the content of your log files under the run directory, you @@ -235,6 +239,7 @@ own code in. ## Diagnostic Computation + The *compute_diagnostic* function in this example uses a software called [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data from a *netCDF* file and perform the simple computation of removing any dimension of length one. This is just an illustrative example. Iris reads data into data structures called @@ -245,7 +250,7 @@ for your own diagnostics are given below. >## Example using xarray > ->~~~ +>~~~python >import xarray as xr #import statement at the beginning of the file > > @@ -266,7 +271,7 @@ for your own diagnostics are given below. >## Example using Scipy's netCDF library > ->~~~ +>~~~python >from scipy.io import netcdfx #import statement at the beginning of the file > > @@ -285,8 +290,9 @@ for your own diagnostics are given below. {: .solution} ## Plotting Diagnostic Output + Often, the end product of a diagnostic script is a plot or figure. ESMValTool makes it -possible to produce a wide array of such figures as seen in the [gallery] (https://docs.esmvaltool.org/en/latest/gallery.html). In this example we use Iris cubes for processing the +possible to produce a wide array of such figures as seen in the [gallery](https://docs.esmvaltool.org/en/latest/gallery.html). In this example we use Iris cubes for processing the netCDF data. The Iris cube returned from the *compute_diagnostic* function (line 93) is passed to the *plot_diagnostic* function (line 99). You could return an xarray data object for example and pass that on to the plotting function. From 4066916b1b52a16478e4d992d18122c77eec8f05 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 4 Mar 2021 15:38:12 +0100 Subject: [PATCH 543/647] fix line length --- _episodes/10-diagnostics.md | 193 +++++++++++++++++++----------------- 1 file changed, 104 insertions(+), 89 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index b5424e27..2ff83af4 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -21,16 +21,21 @@ keypoints: The diagnostic script is an important component of ESMValTool where the scientific analysis or performance metric is implemented. With ESMValTool, you -can reuse an existing diagnostic, adapt and existing one for your needs or -write your own new diagnostic. Diagnostics can be written in a number of open -source languages such as Python, R, Julia and NCL but we will focus on understanding -and writing Python diagnostics in this lesson. In order to access existing diagnostics or -to write your own, please install ESMValTool in the development mode on your -machine using the instructions from [this episode](08-development-setup/index.html). +can reuse an existing diagnostic, adapt and existing one for your needs or write +your own new diagnostic. Diagnostics can be written in a number of open source +languages such as Python, R, Julia and NCL but we will focus on understanding +and writing Python diagnostics in this lesson. In order to access existing +diagnostics or to write your own, please install ESMValTool in the development +mode on your machine using the instructions from [this +episode](08-development-setup/index.html). ## Understanding an existing Python diagnostic -We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) and the diagnostic script called by this recipe -- [diag_scripts/examples/diagnostic.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py). For reference, we have the diagnostic file in the dropdown box below. +We revisit a recipe we have seen before, +[recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) +and the diagnostic script called by this recipe -- +[diag_scripts/examples/diagnostic.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py). +For reference, we have the diagnostic file in the dropdown box below. > ## diagnostic.py > @@ -149,54 +154,55 @@ We revisit a recipe we have seen before, [recipe_python.yml](https://github.com/ > ## What is the starting point of the diagnostic? > -> Can you spot a function called *main* in the Python code above? How many times is this -> function mentioned? +> Can you spot a function called *main* in the Python code above? How many times +> is this function mentioned? > > -> > ## Answer -> > -> > The main function is defined in the middle of this script on line 67 and is called ->> near the very end on line 105. ->>The function *run_diagnostic* function where *main* is called is what ->>is called a context manager provided with ESMValTool and is the ->>main entry point for most Python diagnostics. The variable *cfg* is a Python dictionary ->>loaded with all the ->>necessary information needed to run the diagnostic script including location of ->> input data and various settings. ->>In the *main* function, we will next parse this *cfg* variable and extract ->>information as needed to do our analyses. +>> ## Answer +>> +>> The main function is defined in the middle of this script on line 67 and is +>> called near the very end on line 105. The function *run_diagnostic* function +>> where *main* is called is what is called a context manager provided with +>> ESMValTool and is the main entry point for most Python diagnostics. The +>> variable *cfg* is a Python dictionary loaded with all the necessary +>> information needed to run the diagnostic script including location of input +>> data and various settings. In the *main* function, we will next parse this +>> *cfg* variable and extract information as needed to do our analyses. > > > {: .solution} {: .challenge} ## What information do I need for my analyses? -The very first thing passed to the diagnostic via the *cfg* dictionary is a path to a file -called *settings.yml*. It is found at the lowest level of your directory structure under -the *run* directory. An example path would be */path_to_recipe_output/run/diag_name/script_name/settings.yml*. +The very first thing passed to the diagnostic via the *cfg* dictionary is a path +to a file called *settings.yml*. It is found at the lowest level of your +directory structure under the *run* directory. An example path would be +*/path_to_recipe_output/run/diag_name/script_name/settings.yml*. > ## What is in the settings.yml file? - -> The ESMValTool documentation page provides a generic overview of what is in the ->settings.yml file [here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html). +> +> The ESMValTool documentation page provides a generic overview of what is in +>the settings.yml file +>[here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html). > {: .callout} > ## Challenge: digging in deeper to understand the preprocesor-diagnostic interface > > Can you find one example of the settings.yml file when you run this recipe? -> Take a look at the *input_files* list in your settings.yml file. Do you see a mention of -> a second yml file called *metadata.yml*? -> What information do you think is saved in metadata.yml? +> Take a look at the *input_files* list in your settings.yml file. Do you see a +> mention of a second yml file called *metadata.yml*? What information do you +> think is saved in metadata.yml? > >> ## Answer >> ->>Congratulations on finding an example each of the *settings.yml* and *metadata.yml* ->>files! You will have noticed that metadata.yml has information on your preprocessed ->>data. There is one file for each variable and it has detailed information on your data ->> including project (e.g., CMIP6, OBS), dataset names (e.g., MIROC-6, UKESM-0-1-LL), ->>variable attributes (e.g., standard_name, units), preprocessor applied and time range ->> of the data. You are now ready to access all of this information for your evaluation! +>>Congratulations on finding an example each of the *settings.yml* and +>>*metadata.yml* files! You will have noticed that metadata.yml has information +>>on your preprocessed data. There is one file for each variable and it has +>>detailed information on your data including project (e.g., CMIP6, OBS), +>>dataset names (e.g., MIROC-6, UKESM-0-1-LL), variable attributes (e.g., +>>standard_name, units), preprocessor applied and time range of the data. You +>>are now ready to access all of this information for your evaluation! > > > > > {: .solution} @@ -204,48 +210,52 @@ the *run* directory. An example path would be */path_to_recipe_output/run/diag_n ## Extracting information needed for analyses -In the *main* function of the diagnostic, you will see that *input_data* values are read -from the *cfg* Python dictionary (line 70). -Typically, users will now need to group this input data -according to some criteria such as by model or experiment and select specifics to analyse. -ESMValTool provides a whole host of convenience functions that can do this for you. -A list of available functions and their description is provided [here](https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html). In our example, you will see several -of these imported right at the beginning of the file (lines 8-12) and used after input data -is read. +In the *main* function of the diagnostic, you will see that *input_data* values +are read from the *cfg* Python dictionary (line 70). Typically, users will now +need to group this input data according to some criteria such as by model or +experiment and select specifics to analyse. ESMValTool provides a whole host of +convenience functions that can do this for you. A list of available functions +and their description is provided +[here](https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html). +In our example, you will see several of these imported right at the beginning of +the file (lines 8-12) and used after input data is read. > ## ESMValTool Diagnostic Interface Functions > -> Can you spot the functions used for selecting and grouping data in the example? ->After running this example, how can you tell what the functions do? +> Can you spot the functions used for selecting and grouping data in the +>example? After running this example, how can you tell what the functions do? > >> ## Answer >> ->> If you look carefully, you can see that there is a statement after each use of the ->> select and group functions that starts with *logger.info* (lines 74, 78 and 83). ->> These lines print output to ->> the log files. If you looked at the content of your log files under the run directory, you ->> should see the selected and grouped output. This is how you access preprocessed ->> information within your diagnostic. +>> If you look carefully, you can see that there is a statement after each use +>> of the select and group functions that starts with *logger.info* (lines 74, +>> 78 and 83). These lines print output to the log files. If you looked at the +>> content of your log files under the run directory, you should see the +>> selected and grouped output. This is how you access preprocessed information +>> within your diagnostic. > > > {: .solution} {: .challenge} After grouping we read individual attributes such as the filename which gives us the specific name of the preprocessed data file we want to read and analyse. -Following this, we see the call to a function called *compute_diagnostic* (line 39). -In this example, this is where the analyses on the data is done. -If you were writing your own diagnostic, this is the function you would write your -own code in. - +Following this, we see the call to a function called *compute_diagnostic* (line +39). In this example, this is where the analyses on the data is done. If you +were writing your own diagnostic, this is the function you would write your own +code in. ## Diagnostic Computation -The *compute_diagnostic* function in this example uses a software called [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read -data from a *netCDF* file and perform the simple computation of removing any dimension -of length one. This is just an illustrative example. Iris reads data into data structures called -[cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). The data in -these cubes can be modified, combined with other cubes' data or plotted. Two -other possible ways of reading netcdf files using [xarrays](http://xarray.pydata.org/en/stable/) or [SciPy's netCDF library](https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html) +The *compute_diagnostic* function in this example uses a software called +[Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data +from a *netCDF* file and perform the simple computation of removing any +dimension of length one. This is just an illustrative example. Iris reads data +into data structures called +[cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). +The data in these cubes can be modified, combined with other cubes' data or +plotted. Two other possible ways of reading netcdf files using +[xarrays](http://xarray.pydata.org/en/stable/) or [SciPy's netCDF +library](https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html) for your own diagnostics are given below. >## Example using xarray @@ -291,39 +301,44 @@ for your own diagnostics are given below. ## Plotting Diagnostic Output -Often, the end product of a diagnostic script is a plot or figure. ESMValTool makes it -possible to produce a wide array of such figures as seen in the [gallery](https://docs.esmvaltool.org/en/latest/gallery.html). In this example we use Iris cubes for processing the -netCDF data. The Iris cube returned from the *compute_diagnostic* -function (line 93) is passed to the *plot_diagnostic* function (line 99). You could return -an xarray data object for example and pass that on to the plotting function. -The *plot_diagnostic* function is where you would plug in your plotting routine in this -example. +Often, the end product of a diagnostic script is a plot or figure. ESMValTool +makes it possible to produce a wide array of such figures as seen in the +[gallery](https://docs.esmvaltool.org/en/latest/gallery.html). In this example +we use Iris cubes for processing the netCDF data. The Iris cube returned from +the *compute_diagnostic* function (line 93) is passed to the *plot_diagnostic* +function (line 99). You could return an xarray data object for example and pass +that on to the plotting function. The *plot_diagnostic* function is where you +would plug in your plotting routine in this example. More specifically, the *quickplot* function (line 59) can be replaced with the -function of your choice. The lines preceding this function are to save the Iris cube object -and to save the Provenance of the file. Again, you may choose your own method of saving -your diagnostic object. More information on how to record Provenance is available [here](https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance). +function of your choice. The lines preceding this function are to save the Iris +cube object and to save the Provenance of the file. Again, you may choose your +own method of saving your diagnostic object. More information on how to record +Provenance is available +[here](https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance). > ## Passing arguments to the diagnostic from the recipe > -> How can you pass a user defined argument to your diagnostic ? If you -wanted to plot a colormesh plot with a particular colormap, how would you do so? +> How can you pass a user defined argument to your diagnostic ? If you wanted to +> plot a colormesh plot with a particular colormap, how would you do so? > -> > ## Answer -> > ```yaml -> > script1: -> > script: examples/diagnostic.py -> > quickplot: -> > plot_type: pcolormesh -> > cmap: Reds +>> ## Answer +>> +>> ```yaml +>> script1: +>> script: examples/diagnostic.py +>> quickplot: +>> plot_type: pcolormesh +>> cmap: Reds >>``` -> > The lines below `script:examples/diagnostic.py` have pairs of arguments and values ->> that are passed on to the diagnostic script. In the case of the *quickplot* argument, ->>we can further pass arguments for *quickplot* such as the type of plot *pcolormesh* ->>and the colormap with keyword *cmap* as `cmap:Reds`. In line 59 of the diagnostic, ->>we access this argument. Look at other recipes and diagnostics for more examples of ->> user defined arguments. -> > +>> +>> The lines below `script:examples/diagnostic.py` have pairs of arguments and +>> values that are passed on to the diagnostic script. In the case of the +>> *quickplot* argument, we can further pass arguments for *quickplot* such as +>> the type of plot *pcolormesh* and the colormap with keyword *cmap* as +>> `cmap:Reds`. In line 59 of the diagnostic, we access this argument. Look at +>> other recipes and diagnostics for more examples of user defined arguments. +>> > {: .solution} {: .challenge} From cde40e57a18a50fc704e9375bf44638632a1963e Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 4 Mar 2021 17:23:01 +0100 Subject: [PATCH 544/647] rephrase intro and understanding diagnostics --- _episodes/10-diagnostics.md | 83 +++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 2ff83af4..3cdecba8 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -5,12 +5,11 @@ exercises: TBD questions: - "How do I write a new diagnostic in ESMValTool?" -- "How do I read preprocessor output in a Python diagnostic?" - +- "How do I use the preprocessor output in a Python diagnostic?" objectives: -- "Writing a new Python diagnostic" -- "Understanding the interface between the preprocessor and a diagnostic script." +- "Write a new Python diagnostic script." +- "Explain how a diagnostic script reads the preprocessor output." keypoints: - "ESMValTool provides helper functions to interface a Python diagnostic script with preprocessor output." @@ -21,21 +20,43 @@ keypoints: The diagnostic script is an important component of ESMValTool where the scientific analysis or performance metric is implemented. With ESMValTool, you -can reuse an existing diagnostic, adapt and existing one for your needs or write -your own new diagnostic. Diagnostics can be written in a number of open source +can adapt an existing diagnostic or write a new script from scratch. +Diagnostics can be written in a number of open source languages such as Python, R, Julia and NCL but we will focus on understanding -and writing Python diagnostics in this lesson. In order to access existing -diagnostics or to write your own, please install ESMValTool in the development -mode on your machine using the instructions from [this -episode](08-development-setup/index.html). +and writing Python diagnostics in this lesson. +There are two approches to run your own diagnostics: + +1. using ESMValTool installed in a stable mode +2. using ESMValTool installed in a editable/development mode + +In this lesson, we will explain how to find an existing diagnostic and run it +using the second approch. For a development installation, see the instructions +in the lesson +[Development and contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}). +Also, we will work with the recipe [recipe_python.yml][recipe] and the diagnostic script +[diagnostic.py][diagnostic] called by this recipe that we have seen in the +lesson [Running your first recipe]({{ page.root }}{% link _episodes/04-recipe.md %}). + +Let's get started. ## Understanding an existing Python diagnostic -We revisit a recipe we have seen before, -[recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) -and the diagnostic script called by this recipe -- -[diag_scripts/examples/diagnostic.py](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py). -For reference, we have the diagnostic file in the dropdown box below. +After development installation, a folder called ``ESMValTool`` has been created +in your working directory. This folder contains the source code of the tool. We +can find the recipe ``recipe_python.yml`` and the python script +``diagnostic.py`` in these directories: + +- ~/ESMValTool/esmvaltool/recipes/examples/recipe_python.yml +- ~/ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py + +Let's have look into the codes of the ``diagnostic.py``. +For reference, we show the diagnostic code in the dropdown box below. +There are four main sections in the script: + +- A description i.e. the ``docstring`` (line 1). +- Import statements for different libraries (line 2-12). +- Function's defenitions implementing our analysis (line 17-99). +- A typical python top-level script i.e. ``if __name__ == '__main__'`` (line 102-105). > ## diagnostic.py > @@ -154,24 +175,29 @@ For reference, we have the diagnostic file in the dropdown box below. > ## What is the starting point of the diagnostic? > -> Can you spot a function called *main* in the Python code above? How many times -> is this function mentioned? -> +> 1. Can you spot a function called ``main`` in the code above? +> 2. What is its input arguments? +> 3. How many times is this function mentioned? > >> ## Answer >> ->> The main function is defined in the middle of this script on line 67 and is ->> called near the very end on line 105. The function *run_diagnostic* function ->> where *main* is called is what is called a context manager provided with ->> ESMValTool and is the main entry point for most Python diagnostics. The ->> variable *cfg* is a Python dictionary loaded with all the necessary ->> information needed to run the diagnostic script including location of input ->> data and various settings. In the *main* function, we will next parse this ->> *cfg* variable and extract information as needed to do our analyses. -> > +>> 1. The ``main`` function is defined in line 67 as ``main(cfg)``. +>> 2. The variable ``cfg`` is a Python dictionary holding all the necessary +>> information needed to run the diagnostic script like the location of input +>> data and various settings. In the ``main`` function, we will next parse this +>> ``cfg`` variable and extract information as needed to do our analyses (e.g. in line 70). +>> 3. The ``main`` function called near the very end on line 105. > {: .solution} {: .challenge} +> ## The function run_diagnostic +> +> The function ``run_diagnostic`` (line 104) is called a context manager +> provided with ESMValTool and is the main entry point for most Python +> diagnostics. +> +{: .callout} + ## What information do I need for my analyses? The very first thing passed to the diagnostic via the *cfg* dictionary is a path @@ -343,3 +369,6 @@ Provenance is available {: .challenge} {% include links.md %} + +[recipe]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml +[diagnostic]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py From d68893365ad9f08f0c815f7bad7b5469f5e1468f Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 5 Mar 2021 13:42:08 +0100 Subject: [PATCH 545/647] rephrase sections understanding diagnostics and what information do I need --- _episodes/10-diagnostics.md | 63 +++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 3cdecba8..6c63b9cc 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -34,8 +34,8 @@ using the second approch. For a development installation, see the instructions in the lesson [Development and contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}). Also, we will work with the recipe [recipe_python.yml][recipe] and the diagnostic script -[diagnostic.py][diagnostic] called by this recipe that we have seen in the -lesson [Running your first recipe]({{ page.root }}{% link _episodes/04-recipe.md %}). +[diagnostic.py][diagnostic] called by this recipe that we have seen in the lesson +[Running your first recipe]({{ page.root }}{% link _episodes/04-recipe.md %}). Let's get started. @@ -46,17 +46,17 @@ in your working directory. This folder contains the source code of the tool. We can find the recipe ``recipe_python.yml`` and the python script ``diagnostic.py`` in these directories: -- ~/ESMValTool/esmvaltool/recipes/examples/recipe_python.yml -- ~/ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py +- *path_to_ESMValTool/esmvaltool/recipes/examples/recipe_python.yml* +- *path_to_ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py* Let's have look into the codes of the ``diagnostic.py``. For reference, we show the diagnostic code in the dropdown box below. There are four main sections in the script: - A description i.e. the ``docstring`` (line 1). -- Import statements for different libraries (line 2-12). -- Function's defenitions implementing our analysis (line 17-99). -- A typical python top-level script i.e. ``if __name__ == '__main__'`` (line 102-105). +- Import statements (line 2-12). +- Functions that implement our analysis (line 17-99). +- A typical python top-level script (line 102-105). > ## diagnostic.py > @@ -198,37 +198,39 @@ There are four main sections in the script: > {: .callout} -## What information do I need for my analyses? +## What information do I need when writing a diagnostic script? -The very first thing passed to the diagnostic via the *cfg* dictionary is a path -to a file called *settings.yml*. It is found at the lowest level of your -directory structure under the *run* directory. An example path would be -*/path_to_recipe_output/run/diag_name/script_name/settings.yml*. +In the previous exercise, we have seen that the variable ``cfg`` is the input +argument of the ``main`` function. The first thing passed to the diagnostic +via the ``cfg`` dictionary is a path to a file called ``settings.yml``. +The ESMValTool documentation page provides an overview of what is in this file, see +[Diagnostic script interfaces][interface]. -> ## What is in the settings.yml file? +> ## Digging deeper into the preprocesor-diagnostic interface > -> The ESMValTool documentation page provides a generic overview of what is in ->the settings.yml file ->[here](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html). +> From the lesson [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}), +> we saw how to change the configurations before running a recipe. +> Let's first set the option ``remove_preproc_dir`` to ``false`` in the configuration file, +> then run the recipe ``recipe_python.yml``: > -{: .callout} - -> ## Challenge: digging in deeper to understand the preprocesor-diagnostic interface +> ~~~bash +> esmvaltool run recipe_example.yml +> ~~~ > -> Can you find one example of the settings.yml file when you run this recipe? -> Take a look at the *input_files* list in your settings.yml file. Do you see a -> mention of a second yml file called *metadata.yml*? What information do you -> think is saved in metadata.yml? +> 1. Find one example of the file ``settings.yml`` in the ``run`` directory? +> 2. Take a look at the ``input_files`` list. It contains pathes to some files +> ``metadata.yml``. What information do you think is saved in those files? > >> ## Answer >> ->>Congratulations on finding an example each of the *settings.yml* and ->>*metadata.yml* files! You will have noticed that metadata.yml has information ->>on your preprocessed data. There is one file for each variable and it has ->>detailed information on your data including project (e.g., CMIP6, OBS), ->>dataset names (e.g., MIROC-6, UKESM-0-1-LL), variable attributes (e.g., ->>standard_name, units), preprocessor applied and time range of the data. You ->>are now ready to access all of this information for your evaluation! +>> 1. One example of ``settings.yml`` can be found in the directory: +>> *path_to_recipe_output/run/map/script1/settings.yml* +>> 2. The ``metadata.yml`` files hold information +>> about the preprocessed data. There is one file for each variable having +>> detailed information on your data including project (e.g., CMIP6, OBS), +>> dataset names (e.g., MIROC-6, UKESM-0-1-LL), variable attributes (e.g., +>> standard_name, units), preprocessor applied and time range of the data. You +>> can use all of these information in your own diagnostics. > > > > > {: .solution} @@ -372,3 +374,4 @@ Provenance is available [recipe]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml [diagnostic]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py +[interface]: https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html From c1ff77203cd36dabbf2dab8be2908c440a4e4ec7 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 5 Mar 2021 14:36:33 +0100 Subject: [PATCH 546/647] rephrase section extracting information, revise its challenge --- _episodes/10-diagnostics.md | 103 ++++++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 28 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 6c63b9cc..f61e7ade 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -169,8 +169,6 @@ There are four main sections in the script: > >~~~ > ->{: .language-python} -> {:.solution} > ## What is the starting point of the diagnostic? @@ -198,7 +196,7 @@ There are four main sections in the script: > {: .callout} -## What information do I need when writing a diagnostic script? +## Preprocesor-diagnostic interface In the previous exercise, we have seen that the variable ``cfg`` is the input argument of the ``main`` function. The first thing passed to the diagnostic @@ -206,7 +204,7 @@ via the ``cfg`` dictionary is a path to a file called ``settings.yml``. The ESMValTool documentation page provides an overview of what is in this file, see [Diagnostic script interfaces][interface]. -> ## Digging deeper into the preprocesor-diagnostic interface +> ## What information do I need when writing a diagnostic script? > > From the lesson [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}), > we saw how to change the configurations before running a recipe. @@ -227,8 +225,8 @@ The ESMValTool documentation page provides an overview of what is in this file, >> *path_to_recipe_output/run/map/script1/settings.yml* >> 2. The ``metadata.yml`` files hold information >> about the preprocessed data. There is one file for each variable having ->> detailed information on your data including project (e.g., CMIP6, OBS), ->> dataset names (e.g., MIROC-6, UKESM-0-1-LL), variable attributes (e.g., +>> detailed information on your data including project (e.g., CMIP6, CMIP5), +>> dataset names (e.g., BCC-ESM1, CanESM2), variable attributes (e.g., >> standard_name, units), preprocessor applied and time range of the data. You >> can use all of these information in your own diagnostics. > > @@ -236,35 +234,85 @@ The ESMValTool documentation page provides an overview of what is in this file, > {: .solution} {: .challenge} -## Extracting information needed for analyses +## Diagnostic shared functions -In the *main* function of the diagnostic, you will see that *input_data* values -are read from the *cfg* Python dictionary (line 70). Typically, users will now -need to group this input data according to some criteria such as by model or -experiment and select specifics to analyse. ESMValTool provides a whole host of -convenience functions that can do this for you. A list of available functions -and their description is provided -[here](https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html). -In our example, you will see several of these imported right at the beginning of -the file (lines 8-12) and used after input data is read. +Looking at the codes of the ``diagnostic.py``, we see that ``input_data`` is +read from the ``cfg`` dictionary (line 70). Now we can group the ``input_data`` +according to some criteria such as the model or experiment. To do so, +ESMValTool provides many functions like ``select_metadata`` (line 73), +``sorted_metadata`` (line 77), and ``group_metadata`` (line 81). As you can see +in line 8, these functions are imported from ``esmvaltool.diag_scripts.shared`` +that means these are shared between several diagnostics scripts. A list of +available functions and their description can be found in [Shared diagnostic +script code][shared]. -> ## ESMValTool Diagnostic Interface Functions +> ## Extracting information needed for analyses > -> Can you spot the functions used for selecting and grouping data in the ->example? After running this example, how can you tell what the functions do? +> We have seen the functions used for selecting, sorting and grouping data in the +> script. What these functions do? > >> ## Answer >> ->> If you look carefully, you can see that there is a statement after each use ->> of the select and group functions that starts with *logger.info* (lines 74, ->> 78 and 83). These lines print output to the log files. If you looked at the ->> content of your log files under the run directory, you should see the ->> selected and grouped output. This is how you access preprocessed information ->> within your diagnostic. -> > +>> There is a statement after use of ``select_metadata``, ``sorted_metadata`` +>> and ``group_metadata`` that starts with ``logger.info`` (lines 74, 78 and +>> 83). These lines print output to the log files. In the previous exercise, we +>> ran the recipe ``recipe_python.yml``. If you looked at the content of the log +>> file ``path_to_recipe_output/run/map/script1/log.txt``, you can see the some +>> information on how each function works, for example: +>> +>>``` +>>2021-03-05 13:19:38,184 [34706] INFO diagnostic,83 Example of how to group and +>>sort input data by variable groups from the recipe: +>>{'tas': [{'activity': 'CMIP', +>> 'alias': 'CMIP6', +>> 'dataset': 'BCC-ESM1', +>> 'diagnostic': 'map', +>> 'end_year': 2000, +>> 'ensemble': 'r1i1p1f1', +>> 'exp': 'historical', +>> 'filename': '~/recipe_python_20210305_131929/preproc/map/tas/CMIP6_BCC-ESM1_Amon_historical_r1i1p1f1_tas_2000-2000.nc', +>> 'frequency': 'mon', +>> 'grid': 'gn', +>> 'institute': ['BCC'], +>> 'long_name': 'Near-Surface Air Temperature', +>> 'mip': 'Amon', +>> 'modeling_realm': ['atmos'], +>> 'preprocessor': 'select_january', +>> 'project': 'CMIP6', +>> 'recipe_dataset_index': 0, +>> 'short_name': 'tas', +>> 'standard_name': 'air_temperature', +>> 'start_year': 2000, +>> 'units': 'K', +>> 'variable_group': 'tas'}, +>> {'alias': 'CMIP5', +>> 'dataset': 'CanESM2', +>> 'diagnostic': 'map', +>> 'end_year': 2000, +>> 'ensemble': 'r1i1p1', +>> 'exp': 'historical', +>> 'filename': '~/recipe_python_20210305_131929/preproc/map/tas/CMIP5_CanESM2_Amon_historical_r1i1p1_tas_2000-2000.nc', +>> 'frequency': 'mon', +>> 'institute': ['CCCma'], +>> 'long_name': 'Near-Surface Air Temperature', +>> 'mip': 'Amon', +>> 'modeling_realm': ['atmos'], +>> 'preprocessor': 'select_january', +>> 'project': 'CMIP5', +>> 'recipe_dataset_index': 1, +>> 'short_name': 'tas', +>> 'standard_name': 'air_temperature', +>> 'start_year': 2000, +>> 'units': 'K', +>> 'variable_group': 'tas'}]} +>>``` +>> +>> This is how we can access preprocessed data within our diagnostic. > {: .solution} {: .challenge} +## Diagnostic Computation + After grouping we read individual attributes such as the filename which gives us the specific name of the preprocessed data file we want to read and analyse. Following this, we see the call to a function called *compute_diagnostic* (line @@ -272,8 +320,6 @@ Following this, we see the call to a function called *compute_diagnostic* (line were writing your own diagnostic, this is the function you would write your own code in. -## Diagnostic Computation - The *compute_diagnostic* function in this example uses a software called [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data from a *netCDF* file and perform the simple computation of removing any @@ -375,3 +421,4 @@ Provenance is available [recipe]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml [diagnostic]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py [interface]: https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html +[shared]: https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html From 1be031625aeefa882ba32862aaf60e2c0e6b8779 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 5 Mar 2021 15:35:10 +0100 Subject: [PATCH 547/647] rephrase section diagnostic computation, add an extra example --- _episodes/10-diagnostics.md | 132 ++++++++++++++++++++++-------------- 1 file changed, 80 insertions(+), 52 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index f61e7ade..0115eca0 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -311,67 +311,94 @@ script code][shared]. > {: .solution} {: .challenge} -## Diagnostic Computation +## Diagnostic computation -After grouping we read individual attributes such as the filename which gives us -the specific name of the preprocessed data file we want to read and analyse. -Following this, we see the call to a function called *compute_diagnostic* (line -39). In this example, this is where the analyses on the data is done. If you -were writing your own diagnostic, this is the function you would write your own -code in. +After grouping and selecting data, we can read individual attributes such as the +filename by looping over variables (line 88-92). Following this, we see the use +of the function ``compute_diagnostic`` (line 93). Let's have a look at the +defenition of this function at line 39 where the analyses on the data is done. -The *compute_diagnostic* function in this example uses a software called +Here, ``compute_diagnostic`` uses [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data -from a *netCDF* file and perform the simple computation of removing any -dimension of length one. This is just an illustrative example. Iris reads data -into data structures called -[cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). -The data in these cubes can be modified, combined with other cubes' data or -plotted. Two other possible ways of reading netcdf files using -[xarrays](http://xarray.pydata.org/en/stable/) or [SciPy's netCDF -library](https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html) -for your own diagnostics are given below. - ->## Example using xarray +from a netCDF file and performs a simple computation of averaging over time +dimension. We can adapt this function adding our own analysis. +As an example, here we want to calculate maximum of the data as: + +~~~python +def compute_diagnostic(filename): + """Compute an example diagnostic.""" + logger.debug("Loading %s", filename) + cube = iris.load_cube(filenam + + logger.debug("Running example computation") + cube.collapsed('time', iris.analysis.MEAN) + return cube.data.max() +~~~ + +> ## iris cubes > ->~~~python ->import xarray as xr #import statement at the beginning of the file -> -> ->def compute_diagnostic(filename): -> """Compute an example diagnostic.""" -> logger.debug("Loading %s", filename) -> ds = xr.open_dataset(filename) -> -> #do your analyses on the data here -> -> return ds -> ->~~~ ->{: .language-python} -> -{: .solution} - +> Iris reads data into data structures called +> [cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). +> The data in these cubes can be modified, combined with other cubes' data or +> plotted. +{: .callout} ->## Example using Scipy's netCDF library -> ->~~~python ->from scipy.io import netcdfx #import statement at the beginning of the file -> -> ->def compute_diagnostic(filename): -> """Compute an example diagnostic.""" -> logger.debug("Loading %s", filename) -> f = netcdf.netcdf_file(filename,'r') +> ## Reading data using xarray > -> #do your analyses on the data here +> Use the [xarrays](http://xarray.pydata.org/en/stable/) to read the data +> instead of iris. > -> return f +>> ## Answer +>> +>> First, import [xarray] package at the top of the script as: +>> +>>~~~python +>>import xarray as xr +>>~~~ +>> +>> Then, change the ``compute_diagnostic`` as: +>> +>>~~~python +>>def compute_diagnostic(filename): +>> """Compute an example diagnostic.""" +>> logger.debug("Loading %s", filename) +>> dataset = xr.open_dataset(filename) +>> +>> #do your analyses on the data here +>> +>> return dataset +>>~~~ +>> +> {: .solution} +{: .challenge} + +> ## Reading data using Scipy's netCDF library > ->~~~ ->{: .language-python} +> Use the [SciPy's netCDF library][netCDF] to read the data instead of iris. > -{: .solution} +>> ## Answer +>> +>> First, import [netcdfx] package at the top of the script as: +>> +>>~~~python +>>from scipy.io import netcdfx +>>~~~ +>> +>> Then, change the ``compute_diagnostic`` as: +>> +>>~~~python +>>def compute_diagnostic(filename): +>> """Compute an example diagnostic.""" +>> logger.debug("Loading %s", filename) +>> netcdf_file = netcdf.netcdf_file(filename,'r') +>> +>> #do your analyses on the data here +>> +>> return netcdf_file +>>~~~ +>> +> {: .solution} +{: .challenge} ## Plotting Diagnostic Output @@ -422,3 +449,4 @@ Provenance is available [diagnostic]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py [interface]: https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html [shared]: https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html +[netCDF]: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html From 287154d61ffa09727e4e739fdaece56d41ff5931 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 5 Mar 2021 16:35:34 +0100 Subject: [PATCH 548/647] rephrase and reorganize section plotting output --- _episodes/10-diagnostics.md | 90 ++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 0115eca0..42ddf86f 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -316,7 +316,7 @@ script code][shared]. After grouping and selecting data, we can read individual attributes such as the filename by looping over variables (line 88-92). Following this, we see the use of the function ``compute_diagnostic`` (line 93). Let's have a look at the -defenition of this function at line 39 where the analyses on the data is done. +defenition of this function in line 39 where the analyses on the data is done. Here, ``compute_diagnostic`` uses [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data @@ -400,49 +400,75 @@ def compute_diagnostic(filename): > {: .solution} {: .challenge} -## Plotting Diagnostic Output - -Often, the end product of a diagnostic script is a plot or figure. ESMValTool -makes it possible to produce a wide array of such figures as seen in the -[gallery](https://docs.esmvaltool.org/en/latest/gallery.html). In this example -we use Iris cubes for processing the netCDF data. The Iris cube returned from -the *compute_diagnostic* function (line 93) is passed to the *plot_diagnostic* -function (line 99). You could return an xarray data object for example and pass -that on to the plotting function. The *plot_diagnostic* function is where you -would plug in your plotting routine in this example. - -More specifically, the *quickplot* function (line 59) can be replaced with the -function of your choice. The lines preceding this function are to save the Iris -cube object and to save the Provenance of the file. Again, you may choose your -own method of saving your diagnostic object. More information on how to record -Provenance is available -[here](https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance). +## Diagnostic output + +### Plotting the output -> ## Passing arguments to the diagnostic from the recipe +Often, the end product of a diagnostic script is a plot or figure. The Iris cube +returned from the ``compute_diagnostic`` function (line 93) is passed to the +``plot_diagnostic`` function (line 99). Let's have a look at the defenition of +this function in line 48 where we would plug in our plotting routine in the +diagnostic script. + +More specifically, the ``quickplot`` function (line 59) can be replaced with the +function of our choice. As can be seen, this function uses +``**cfg['quickplot']`` as an input argument. If you look at the diagnostic +section in the recipe ``recipe_python.yml``, you see ``quickplot`` is a key +there: + +~~~yaml + script1: + script: examples/diagnostic.py + quickplot: + plot_type: pcolormesh + cmap: Reds +~~~ + +In this way, we can further pass arguments for ``quickplot`` such as the type of +plot ``pcolormesh`` and the colormap with keyword ``cmap`` as `Reds` from the +recipe to the diagnostic. + +> ## Passing arguments from the recipe to the diagnostic > -> How can you pass a user defined argument to your diagnostic ? If you wanted to -> plot a colormesh plot with a particular colormap, how would you do so? +> Change the type of the plot and its colormap and inspect the output figure. > >> ## Answer >> ->> ```yaml +>> In the recipe ``recipe_python.yml``, you should change ``plot_type`` and ``cmap``. +>> As an example, we choose ``plot_type: pcolor`` and ``cmap: BuGn``: +>> +>> ~~~yaml >> script1: >> script: examples/diagnostic.py >> quickplot: ->> plot_type: pcolormesh ->> cmap: Reds ->>``` ->> ->> The lines below `script:examples/diagnostic.py` have pairs of arguments and ->> values that are passed on to the diagnostic script. In the case of the ->> *quickplot* argument, we can further pass arguments for *quickplot* such as ->> the type of plot *pcolormesh* and the colormap with keyword *cmap* as ->> `cmap:Reds`. In line 59 of the diagnostic, we access this argument. Look at ->> other recipes and diagnostics for more examples of user defined arguments. +>> plot_type: pcolor +>> cmap: BuGn +>>~~~ >> +>> The plot can be found at *path_to_recipe_output/plots/map/script1/png*. +>> Look at other recipes and diagnostics for more examples of user defined +>> arguments. > {: .solution} {: .challenge} +> ## ESMValTool gallery +> +> ESMValTool makes it possible to produce a wide array of such figures as seen +> in the [gallery](https://docs.esmvaltool.org/en/latest/gallery.html). +{: .callout} + +### Saving the output + +The lines preceding this function are to save the Iris +cube object. Again, you may choose your +own method of saving your diagnostic object. + +### Recording provenance information + + and to save the Provenance of the file. More information on how to record +Provenance is available +[here](https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance). + {% include links.md %} [recipe]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml From ba1d91f2a71a2105ab71c4e6519daa7e89f24f58 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 5 Mar 2021 17:32:00 +0100 Subject: [PATCH 549/647] rephrase section provenance, add section congratulations --- _episodes/10-diagnostics.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 42ddf86f..87c068c9 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -316,7 +316,7 @@ script code][shared]. After grouping and selecting data, we can read individual attributes such as the filename by looping over variables (line 88-92). Following this, we see the use of the function ``compute_diagnostic`` (line 93). Let's have a look at the -defenition of this function in line 39 where the analyses on the data is done. +definition of this function in line 39 where the analyses on the data is done. Here, ``compute_diagnostic`` uses [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data @@ -406,7 +406,7 @@ def compute_diagnostic(filename): Often, the end product of a diagnostic script is a plot or figure. The Iris cube returned from the ``compute_diagnostic`` function (line 93) is passed to the -``plot_diagnostic`` function (line 99). Let's have a look at the defenition of +``plot_diagnostic`` function (line 99). Let's have a look at the definition of this function in line 48 where we would plug in our plotting routine in the diagnostic script. @@ -446,8 +446,6 @@ recipe to the diagnostic. >>~~~ >> >> The plot can be found at *path_to_recipe_output/plots/map/script1/png*. ->> Look at other recipes and diagnostics for more examples of user defined ->> arguments. > {: .solution} {: .challenge} @@ -457,18 +455,27 @@ recipe to the diagnostic. > in the [gallery](https://docs.esmvaltool.org/en/latest/gallery.html). {: .callout} -### Saving the output +### Saving the output (FIX ME) The lines preceding this function are to save the Iris cube object. Again, you may choose your own method of saving your diagnostic object. -### Recording provenance information +### Recording provenance - and to save the Provenance of the file. More information on how to record -Provenance is available -[here](https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance). +When developing a diagnostic script, we should make sure that it records the +provenance. To do so, we use the function ``get_provenance_record`` (line 97). +Let's have a look at the definition of this function in line 17 where we +describe the diagnostic data and plot. Using the dictionary ``record``, it is +possible to add custom provenance. Provenance is stored in the *W3C PROV XML* +format and also in an *SVG* file under the ``work`` directory. For more +information, see [recording provenance][provenance]. +## Congratulations! + +Now you know the diagnostic script structure and a few functions. There are many +more functions to be used, but these should be enough to get you started! Look +at other recipes and diagnostics for more examples. {% include links.md %} [recipe]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml @@ -476,3 +483,4 @@ Provenance is available [interface]: https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html [shared]: https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html [netCDF]: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html +[provenance]: https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance From 694e9672ca3f796aab1e7c82ef526afad930c353 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 8 Mar 2021 12:13:18 +0100 Subject: [PATCH 550/647] update diagnostic code and line numbers --- _episodes/10-diagnostics.md | 260 ++++++++++++++++++------------------ 1 file changed, 131 insertions(+), 129 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 87c068c9..db06f280 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -54,119 +54,121 @@ For reference, we show the diagnostic code in the dropdown box below. There are four main sections in the script: - A description i.e. the ``docstring`` (line 1). -- Import statements (line 2-12). -- Functions that implement our analysis (line 17-99). -- A typical python top-level script (line 102-105). +- Import statements (line 2-16). +- Functions that implement our analysis (line 21-101). +- A typical python top-level script (line 102-107). > ## diagnostic.py > >~~~python -> 1 """Python example diagnostic.""" -> 2 import logging -> 3 import os -> 4 from pprint import pformat -> 5 -> 6 import iris -> 7 -> 8 from esmvaltool.diag_scripts.shared import (group_metadata, run_diagnostic, -> 9 select_metadata, sorted_metadata) -> 10 from esmvaltool.diag_scripts.shared._base import ( -> 11 ProvenanceLogger, get_diagnostic_filename, get_plot_filename) -> 12 from esmvaltool.diag_scripts.shared.plot import quickplot -> 13 -> 14 logger = logging.getLogger(os.path.basename(__file__)) -> 15 -> 16 -> 17 def get_provenance_record(attributes, ancestor_files): -> 18 """Create a provenance record describing the diagnostic data and plot.""" -> 19 caption = ("Average {long_name} between {start_year} and {end_year} " -> 20 "according to {dataset}.".format(**attributes)) -> 21 -> 22 record = { -> 23 'caption': caption, -> 24 'statistics': ['mean'], -> 25 'domains': ['global'], -> 26 'plot_types': ['zonal'], -> 27 'authors': [ -> 28 'andela_bouwe', -> 29 'righi_mattia', -> 30 ], -> 31 'references': [ -> 32 'acknow_project', -> 33 ], -> 34 'ancestors': ancestor_files, -> 35 } -> 36 return record -> 37 -> 38 -> 39 def compute_diagnostic(filename): -> 40 """Compute an example diagnostic.""" -> 41 logger.debug("Loading %s", filename) -> 42 cube = iris.load_cube(filename) -> 43 -> 44 logger.debug("Running example computation") -> 45 return cube.collapsed('time', iris.analysis.MEAN) -> 46 -> 47 -> 48 def plot_diagnostic(cube, basename, provenance_record, cfg): -> 49 """Create diagnostic data and plot it.""" -> 50 diagnostic_file = get_diagnostic_filename(basename, cfg) -> 51 -> 52 logger.info("Saving analysis results to %s", diagnostic_file) -> 53 iris.save(cube, target=diagnostic_file) -> 54 -> 55 if cfg['write_plots'] and cfg.get('quickplot'): -> 56 plot_file = get_plot_filename(basename, cfg) -> 57 logger.info("Plotting analysis results to %s", plot_file) -> 58 provenance_record['plot_file'] = plot_file -> 59 quickplot(cube, filename=plot_file, **cfg['quickplot']) -> 60 -> 61 logger.info("Recording provenance of %s:\n%s", diagnostic_file, -> 62 pformat(provenance_record)) -> 63 with ProvenanceLogger(cfg) as provenance_logger: -> 64 provenance_logger.log(diagnostic_file, provenance_record) -> 65 -> 66 -> 67 def main(cfg): -> 68 """Compute the time average for each input dataset.""" -> 69 # Get a description of the preprocessed data that we will use as input. -> 70 input_data = cfg['input_data'].values() -> 71 -> 72 # Demonstrate use of metadata access convenience functions. -> 73 selection = select_metadata(input_data, short_name='pr', project='CMIP5') -> 74 logger.info("Example of how to select only CMIP5 precipitation data:\n%s", -> 75 pformat(selection)) -> 76 -> 77 selection = sorted_metadata(selection, sort='dataset') -> 78 logger.info("Example of how to sort this selection by dataset:\n%s", -> 79 pformat(selection)) -> 80 -> 81 grouped_input_data = group_metadata( -> 82 input_data, 'standard_name', sort='dataset') -> 83 logger.info( -> 84 "Example of how to group and sort input data by standard_name:" -> 85 "\n%s", pformat(grouped_input_data)) -> 86 -> 87 # Example of how to loop over variables/datasets in alphabetical order -> 88 for standard_name in grouped_input_data: -> 89 logger.info("Processing variable %s", standard_name) -> 90 for attributes in grouped_input_data[standard_name]: -> 91 logger.info("Processing dataset %s", attributes['dataset']) -> 92 input_file = attributes['filename'] -> 93 cube = compute_diagnostic(input_file) -> 94 -> 95 output_basename = os.path.splitext( -> 96 os.path.basename(input_file))[0] + '_mean' -> 97 provenance_record = get_provenance_record( -> 98 attributes, ancestor_files=[input_file]) -> 99 plot_diagnostic(cube, output_basename, provenance_record, cfg) ->100 ->101 ->102 if __name__ == '__main__': ->103 ->104 with run_diagnostic() as config: ->105 main(config) -> +> 1: """Python example diagnostic.""" +> 2: import logging +> 3: from pathlib import Path +> 4: from pprint import pformat +> 5: +> 6: import iris +> 7: +> 8: from esmvaltool.diag_scripts.shared import ( +> 9: group_metadata, +> 10: run_diagnostic, +> 11: save_data, +> 12: save_figure, +> 13: select_metadata, +> 14: sorted_metadata, +> 15: ) +> 16: from esmvaltool.diag_scripts.shared.plot import quickplot +> 17: +> 18: logger = logging.getLogger(Path(__file__).stem) +> 19: +> 20: +> 21: def get_provenance_record(attributes, ancestor_files): +> 22: """Create a provenance record describing the diagnostic data and plot.""" +> 23: caption = ("Average {long_name} between {start_year} and {end_year} " +> 24: "according to {dataset}.".format(**attributes)) +> 25: +> 26: record = { +> 27: 'caption': caption, +> 28: 'statistics': ['mean'], +> 29: 'domains': ['global'], +> 30: 'plot_types': ['zonal'], +> 31: 'authors': [ +> 32: 'andela_bouwe', +> 33: 'righi_mattia', +> 34: ], +> 35: 'references': [ +> 36: 'acknow_project', +> 37: ], +> 38: 'ancestors': ancestor_files, +> 39: } +> 40: return record +> 41: +> 42: +> 43: def compute_diagnostic(filename): +> 44: """Compute an example diagnostic.""" +> 45: logger.debug("Loading %s", filename) +> 46: cube = iris.load_cube(filename) +> 47: +> 48: logger.debug("Running example computation") +> 49: cube = iris.util.squeeze(cube) +> 50: return cube +> 51: +> 52: +> 53: def plot_diagnostic(cube, basename, provenance_record, cfg): +> 54: """Create diagnostic data and plot it.""" +> 55: +> 56: # Save the data used for the plot +> 57: save_data(basename, provenance_record, cfg, cube) +> 58: +> 59: if cfg.get('quickplot'): +> 60: # Create the plot +> 61: quickplot(cube, **cfg['quickplot']) +> 62: # And save the plot +> 63: save_figure(basename, provenance_record, cfg) +> 64: +> 65: +> 66: def main(cfg): +> 67: """Compute the time average for each input dataset.""" +> 68: # Get a description of the preprocessed data that we will use as input. +> 69: input_data = cfg['input_data'].values() +> 70: +> 71: # Demonstrate use of metadata access convenience functions. +> 72: selection = select_metadata(input_data, short_name='tas', project='CMIP5') +> 73: logger.info("Example of how to select only CMIP5 temperature data:\n%s", +> 74: pformat(selection)) +> 75: +> 76: selection = sorted_metadata(selection, sort='dataset') +> 77: logger.info("Example of how to sort this selection by dataset:\n%s", +> 78: pformat(selection)) +> 79: +> 80: grouped_input_data = group_metadata(input_data, +> 81: 'variable_group', +> 82: sort='dataset') +> 83: logger.info( +> 84: "Example of how to group and sort input data by variable groups from " +> 85: "the recipe:\n%s", pformat(grouped_input_data)) +> 86: +> 87: # Example of how to loop over variables/datasets in alphabetical order +> 88: groups = group_metadata(input_data, 'variable_group', sort='dataset') +> 89: for group_name in groups: +> 90: logger.info("Processing variable %s", group_name) +> 91: for attributes in groups[group_name]: +> 92: logger.info("Processing dataset %s", attributes['dataset']) +> 93: input_file = attributes['filename'] +> 94: cube = compute_diagnostic(input_file) +> 95: +> 96: output_basename = Path(input_file).stem +> 97: if group_name != attributes['short_name']: +> 98: output_basename = group_name + '_' + output_basename +> 99: provenance_record = get_provenance_record( +>100: attributes, ancestor_files=[input_file]) +>101: plot_diagnostic(cube, output_basename, provenance_record, cfg) +>102: +>103: +>104: if __name__ == '__main__': +>105: +>106: with run_diagnostic() as config: +>107: main(config) +>108: >~~~ > {:.solution} @@ -174,23 +176,23 @@ There are four main sections in the script: > ## What is the starting point of the diagnostic? > > 1. Can you spot a function called ``main`` in the code above? -> 2. What is its input arguments? +> 2. What are its input arguments? > 3. How many times is this function mentioned? > >> ## Answer >> ->> 1. The ``main`` function is defined in line 67 as ``main(cfg)``. +>> 1. The ``main`` function is defined in line 66 as ``main(cfg)``. >> 2. The variable ``cfg`` is a Python dictionary holding all the necessary >> information needed to run the diagnostic script like the location of input >> data and various settings. In the ``main`` function, we will next parse this ->> ``cfg`` variable and extract information as needed to do our analyses (e.g. in line 70). ->> 3. The ``main`` function called near the very end on line 105. +>> ``cfg`` variable and extract information as needed to do our analyses (e.g. in line 69). +>> 3. The ``main`` function called near the very end on line 107. > {: .solution} {: .challenge} > ## The function run_diagnostic > -> The function ``run_diagnostic`` (line 104) is called a context manager +> The function ``run_diagnostic`` (line 106) is called a context manager > provided with ESMValTool and is the main entry point for most Python > diagnostics. > @@ -237,10 +239,10 @@ The ESMValTool documentation page provides an overview of what is in this file, ## Diagnostic shared functions Looking at the codes of the ``diagnostic.py``, we see that ``input_data`` is -read from the ``cfg`` dictionary (line 70). Now we can group the ``input_data`` +read from the ``cfg`` dictionary (line 69). Now we can group the ``input_data`` according to some criteria such as the model or experiment. To do so, -ESMValTool provides many functions like ``select_metadata`` (line 73), -``sorted_metadata`` (line 77), and ``group_metadata`` (line 81). As you can see +ESMValTool provides many functions like ``select_metadata`` (line 72), +``sorted_metadata`` (line 76), and ``group_metadata`` (line 80). As you can see in line 8, these functions are imported from ``esmvaltool.diag_scripts.shared`` that means these are shared between several diagnostics scripts. A list of available functions and their description can be found in [Shared diagnostic @@ -254,7 +256,7 @@ script code][shared]. >> ## Answer >> >> There is a statement after use of ``select_metadata``, ``sorted_metadata`` ->> and ``group_metadata`` that starts with ``logger.info`` (lines 74, 78 and +>> and ``group_metadata`` that starts with ``logger.info`` (lines 73, 77 and >> 83). These lines print output to the log files. In the previous exercise, we >> ran the recipe ``recipe_python.yml``. If you looked at the content of the log >> file ``path_to_recipe_output/run/map/script1/log.txt``, you can see the some @@ -314,14 +316,13 @@ script code][shared]. ## Diagnostic computation After grouping and selecting data, we can read individual attributes such as the -filename by looping over variables (line 88-92). Following this, we see the use -of the function ``compute_diagnostic`` (line 93). Let's have a look at the -definition of this function in line 39 where the analyses on the data is done. +filename by looping over variables (line 89-93). Following this, we see the use +of the function ``compute_diagnostic`` (line 94). Let's have a look at the +definition of this function in line 43 where the analyses on the data is done. Here, ``compute_diagnostic`` uses [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data -from a netCDF file and performs a simple computation of averaging over time -dimension. We can adapt this function adding our own analysis. +from a netCDF file and performs an operation ``squeeze`` to removes any dimension of length one. We can adapt this function to add our own analysis. As an example, here we want to calculate maximum of the data as: ~~~python @@ -331,6 +332,7 @@ def compute_diagnostic(filename): cube = iris.load_cube(filenam logger.debug("Running example computation") + cube = iris.util.squeeze(cube) cube.collapsed('time', iris.analysis.MEAN) return cube.data.max() ~~~ @@ -405,12 +407,12 @@ def compute_diagnostic(filename): ### Plotting the output Often, the end product of a diagnostic script is a plot or figure. The Iris cube -returned from the ``compute_diagnostic`` function (line 93) is passed to the -``plot_diagnostic`` function (line 99). Let's have a look at the definition of -this function in line 48 where we would plug in our plotting routine in the +returned from the ``compute_diagnostic`` function (line 94) is passed to the +``plot_diagnostic`` function (line 101). Let's have a look at the definition of +this function in line 53 where we would plug in our plotting routine in the diagnostic script. -More specifically, the ``quickplot`` function (line 59) can be replaced with the +More specifically, the ``quickplot`` function (line 61) can be replaced with the function of our choice. As can be seen, this function uses ``**cfg['quickplot']`` as an input argument. If you look at the diagnostic section in the recipe ``recipe_python.yml``, you see ``quickplot`` is a key @@ -464,8 +466,8 @@ own method of saving your diagnostic object. ### Recording provenance When developing a diagnostic script, we should make sure that it records the -provenance. To do so, we use the function ``get_provenance_record`` (line 97). -Let's have a look at the definition of this function in line 17 where we +provenance. To do so, we use the function ``get_provenance_record`` (line 99). +Let's have a look at the definition of this function in line 21 where we describe the diagnostic data and plot. Using the dictionary ``record``, it is possible to add custom provenance. Provenance is stored in the *W3C PROV XML* format and also in an *SVG* file under the ``work`` directory. For more From 382ef46649cc6796062c65340fe2cf8d137a838d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 8 Mar 2021 15:39:49 +0100 Subject: [PATCH 551/647] fix compute_diagnostic example --- _episodes/10-diagnostics.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index db06f280..947f041e 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -322,19 +322,22 @@ definition of this function in line 43 where the analyses on the data is done. Here, ``compute_diagnostic`` uses [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data -from a netCDF file and performs an operation ``squeeze`` to removes any dimension of length one. We can adapt this function to add our own analysis. -As an example, here we want to calculate maximum of the data as: +from a netCDF file and performs an operation ``squeeze`` to remove any dimension +of length one. We can adapt this function to add our own analysis. As an +example, here we want to calculate the bias toward the averege of the data as: ~~~python def compute_diagnostic(filename): """Compute an example diagnostic.""" logger.debug("Loading %s", filename) - cube = iris.load_cube(filenam + cube = iris.load_cube(filename) logger.debug("Running example computation") cube = iris.util.squeeze(cube) - cube.collapsed('time', iris.analysis.MEAN) - return cube.data.max() + + # Calculate a bias using the average of data + cube.data = cube.core_data() - cube.data.mean() + return cube ~~~ > ## iris cubes @@ -352,7 +355,7 @@ def compute_diagnostic(filename): > >> ## Answer >> ->> First, import [xarray] package at the top of the script as: +>> First, import ``xarray`` package at the top of the script as: >> >>~~~python >>import xarray as xr @@ -380,7 +383,7 @@ def compute_diagnostic(filename): > >> ## Answer >> ->> First, import [netcdfx] package at the top of the script as: +>> First, import ``netcdfx`` package at the top of the script as: >> >>~~~python >>from scipy.io import netcdfx From fab88d551f4069e86b9e12414670ea9bdb85041e Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 8 Mar 2021 16:37:02 +0100 Subject: [PATCH 552/647] fix section saving the output --- _episodes/10-diagnostics.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 947f041e..76766abd 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -430,8 +430,8 @@ there: ~~~ In this way, we can further pass arguments for ``quickplot`` such as the type of -plot ``pcolormesh`` and the colormap with keyword ``cmap`` as `Reds` from the -recipe to the diagnostic. +plot ``pcolormesh`` and the colormap ``cmap:Reds`` from the recipe to the +diagnostic. > ## Passing arguments from the recipe to the diagnostic > @@ -460,11 +460,13 @@ recipe to the diagnostic. > in the [gallery](https://docs.esmvaltool.org/en/latest/gallery.html). {: .callout} -### Saving the output (FIX ME) +### Saving the output -The lines preceding this function are to save the Iris -cube object. Again, you may choose your -own method of saving your diagnostic object. +In our example, the function ``save_data`` in line 57 is used to save the Iris +cube. The saved files can be found under ``work`` directory in a ``.nc`` format. +There is also the function ``save_figure`` in line 63 to save the plots under +``plot`` directory in a ``.png`` format. Again, you may choose your own method +of saving the output. ### Recording provenance @@ -473,8 +475,8 @@ provenance. To do so, we use the function ``get_provenance_record`` (line 99). Let's have a look at the definition of this function in line 21 where we describe the diagnostic data and plot. Using the dictionary ``record``, it is possible to add custom provenance. Provenance is stored in the *W3C PROV XML* -format and also in an *SVG* file under the ``work`` directory. For more -information, see [recording provenance][provenance]. +format and also in an *SVG* file under the ``work`` and ``plot`` directory. For +more information, see [recording provenance][provenance]. ## Congratulations! From 46fcaa929d91fbe85599fc3ef13a47e3b638cfae Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 8 Mar 2021 16:45:03 +0100 Subject: [PATCH 553/647] add a keypoint, fix a title --- _episodes/10-diagnostics.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 76766abd..e7d2ee6c 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -12,8 +12,12 @@ objectives: - "Explain how a diagnostic script reads the preprocessor output." keypoints: -- "ESMValTool provides helper functions to interface a Python diagnostic script with preprocessor output." -- "Existing diagnostics can be used as templates and modified to write new diagnostics." +- "ESMValTool provides helper functions to interface a Python diagnostic script + with preprocessor output." +- "Existing diagnostics can be used as templates and modified to write new + diagnostics." +- "Many functions can be imported from ``esmvaltool.diag_scripts.shared`` and + used in your own diagnostic script." --- ## Introduction @@ -468,7 +472,7 @@ There is also the function ``save_figure`` in line 63 to save the plots under ``plot`` directory in a ``.png`` format. Again, you may choose your own method of saving the output. -### Recording provenance +### Recording the provenance When developing a diagnostic script, we should make sure that it records the provenance. To do so, we use the function ``get_provenance_record`` (line 99). From 2c504c098f1bc3f48a9246d687022c67c9bcba19 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 11 Mar 2021 15:48:20 +0100 Subject: [PATCH 554/647] remove stable mode --- _episodes/10-diagnostics.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index e7d2ee6c..8df7f12a 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -28,18 +28,15 @@ can adapt an existing diagnostic or write a new script from scratch. Diagnostics can be written in a number of open source languages such as Python, R, Julia and NCL but we will focus on understanding and writing Python diagnostics in this lesson. -There are two approches to run your own diagnostics: - -1. using ESMValTool installed in a stable mode -2. using ESMValTool installed in a editable/development mode In this lesson, we will explain how to find an existing diagnostic and run it -using the second approch. For a development installation, see the instructions -in the lesson -[Development and contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}). -Also, we will work with the recipe [recipe_python.yml][recipe] and the diagnostic script -[diagnostic.py][diagnostic] called by this recipe that we have seen in the lesson -[Running your first recipe]({{ page.root }}{% link _episodes/04-recipe.md %}). +using ESMValTool installed in a editable/development mode. For a development +installation, see the instructions in the lesson [Development and +contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}). +Also, we will work with the recipe [recipe_python.yml][recipe] and the +diagnostic script [diagnostic.py][diagnostic] called by this recipe that we have +seen in the lesson [Running your first recipe]({{ page.root }}{% link +_episodes/04-recipe.md %}). Let's get started. From c88326dd8800fff160457f567dd272876d88819b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 11 Mar 2021 15:57:19 +0100 Subject: [PATCH 555/647] revise the line introducing top-level script --- _episodes/10-diagnostics.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 8df7f12a..857e7d95 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -57,7 +57,8 @@ There are four main sections in the script: - A description i.e. the ``docstring`` (line 1). - Import statements (line 2-16). - Functions that implement our analysis (line 21-101). -- A typical python top-level script (line 102-107). +- A typical python top-level script i.e. ``if __name__ == '__main__'`` (line + 102-107). > ## diagnostic.py > From 0abe438a96f650c89af094822e50b150d754abd3 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 12 Mar 2021 13:23:59 +0100 Subject: [PATCH 556/647] Finalize episode resturcturing --- _episodes/09-cmorization.md | 273 +++++------------------------------- 1 file changed, 37 insertions(+), 236 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 8f64a3b5..8c951ead 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -673,34 +673,21 @@ we're updating the cubes metadata to conform to the CMOR table. Finally, the test recipe should run without errors or warnings. -## QUESTION: why is there no warning/error about the latitude direction. Should we not have to flip it? - ### 4. Finalizing the CMORizer Once everything works as expected, there's a couple of things that we can still do. -- Add header info -- Make sure the metadata are added to the config file -- Maybe go through a checklist???? -- add an entry to config-references? -- Add additional cmorizer step: - -```python -# 2d. Update the cubes metadata with all info from the config file -utils.set_global_atts(cube, attributes) -``` - - -The header contains information about where to obtain the data, when it was -accessed the last time, which ESMValTool "tier" it is associated with, and more -detailed information about the necessary downloading and processing steps. +- **Add download instructions**. The header of the CMORizer contains information about + where to obtain the data, when it was accessed the last time, which ESMValTool + "tier" it is associated with, and more detailed information about the + necessary downloading and processing steps. > ## Fill out the header for the "FLUXCOM" dataset > -> Fill out the information that is necessary in the header of a CMORizing -> script for the dataset "FLUXCOM". The different parts that need to be +> Fill out the header of the new CMORizer. The different parts that need to be > present in the header are the following: -> - caption: " """ESMValTool CMORizer for FLUXCOM GPP data." +> +> - Caption: the first line of the docstring should summarize what the script does. > - Tier > - Source > - Last access @@ -738,234 +725,48 @@ detailed information about the necessary downloading and processing steps. > > version 2.3.0 Aug 2019 > > """ > > ``` -> > -> > This is the header of the "FLUXCOM" CMORizer that is available with the -> > ESMValTool already. It is therefore entirely possible that your entries for -> > the section "Last access" and "Download and processing instructions" -> > differ from the example here since the entries for these sections are -> > somewhat subjective. -> > > {: .solution} {: .challenge} +- **Complete the metadata in the config file**. We have left a few fields empty + in the configuration file, such as 'source'. By filling out these fields we can + make sure the relevant metadata is passed on as attributes in the CMORized + data. To make this work, add the following line to the CMORizer script: +```python +# 2d. Update the cubes metadata with all info from the config file +utils.set_global_atts(cube, attributes) +``` +- **Add a reference**. Make sure that there is a reference file available for + the dataset. You can add a [BibTeX info + file](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) + here. +- **Make a pull request**. Since you have gone through all the trouble to + reformat the dataset so that the ESMValTool can work with it, it would be + great if you could provide the CMORizer, and ultimately with that the dataset, + to the rest of the community. For more information, see the previous episode + on [Contributing to ESMValTool](/08-development-setup). +- **Add documentation**. Make sure that you have added the info of your dataset + to the User Guide so that people know it is available for the ESMValTool + [Obtaining input + data](https://github.com/ESMValGroup/ESMValTool/blob/master/doc/sphinx/source/input.rst). - - - - - - - -To make sure that the CMORization has really worked as planned, we run the -CMOR checker on this newly produced NetCDF file. If the ESMValTool can read -the data without problems, you should see as one of the last lines of -ESMValTool output: - -```bash -INFO Run was successful -``` - -## Last steps - -Congratulations! You have successfully CMORized a new dataset! -Since you have gone through all the trouble to reformat the dataset so that -the ESMValTool can work with it, it would be great if you could provide the -CMORizer, and ultimately with that the dataset, to the rest of the community. -To do that there are a few more steps you have to do: -1. Check out the previous episode on [Contributing to ESMValTool](/08-development-setup) -1. Make sure that you have added the info of your dataset to the User Guide so - that people know it is available for the ESMValTool [Obtaining input - data](https://github.com/ESMValGroup/ESMValTool/blob/master/doc/sphinx/source/input.rst) -1. Make sure that there is a reference file available for the dataset [BibTeX - info - file](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) - ## Some final comments -Adding a new CMORizer to the ESMValTool is definitely already an advanced task -when working with the ESMValTool. You need to have a basic understanding of -how the ESMValTool works and how it's internal structure looks like. In -addition, you need to have a basic understanding of NetCDF files and a -programming language. In our example we used python for the CMORizing script -since we advocate for focusing the code development on only a few different -programming languages. This helps to maintain the code and to ensure the -compatibility of the code with possible fundamental changes to the structure -of the ESMValTool and ESMValCore. +Congratulations! You have just added support for a new dataset to ESMValTool! +Adding a new CMORizer is definitely already an advanced task when working with +the ESMValTool. You need to have a basic understanding of how the ESMValTool +works and how it's internal structure looks like. In addition, you need to have +a basic understanding of NetCDF files and a programming language. In our example +we used python for the CMORizing script since we advocate for focusing the code +development on only a few different programming languages. This helps to +maintain the code and to ensure the compatibility of the code with possible +fundamental changes to the structure of the ESMValTool and ESMValCore. More information about adding observations to the ESMValTool can be found in the [documentation](https://docs.esmvaltool.org/en/latest/input.html#observations). - - - - - - - - - - - - - - - - - - - From 981530319d32435b37a2fa5e86f29bfde1bec2d2 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 12 Mar 2021 13:41:46 +0100 Subject: [PATCH 557/647] final review comments addressed --- _episodes/09-cmorization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 8c951ead..9858823e 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -73,7 +73,7 @@ button on the "FLUXCOM (RS+METEO) Global Land Carbon Fluxes using CRUNCEP climate data". You'll receive an email with the FTP address to access the server. Connect to the server, follow the path in your email, and look for the file `raw/monthly/GPP.ANN.CRUNCEPv6.monthly.2000.nc`. Download that file and -save in in a folder called `/RAWOBS/Tier3/FLUXCOM`. +save it in a folder called `/RAWOBS/Tier3/FLUXCOM`. Note: you'll need a user-friendly ftp client. On Linux, `ncftp` works okay. @@ -742,7 +742,7 @@ utils.set_global_atts(cube, attributes) - **Add a reference**. Make sure that there is a reference file available for the dataset. You can add a [BibTeX info file](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) - here. + here. You - **Make a pull request**. Since you have gone through all the trouble to reformat the dataset so that the ESMValTool can work with it, it would be From 1ffb9251866eece3b2e4432c802de54161928a69 Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 14 Mar 2021 21:35:34 +0000 Subject: [PATCH 558/647] Changed the obs data path on JASMIN to the new correct one --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index b4818349..0724e599 100644 --- a/setup.md +++ b/setup.md @@ -137,7 +137,7 @@ ssh -X jasmin-sci1 Can you see the following locations: ~~~ -ls /group_workspaces/jasmin4/esmeval/obsdata/Tier2 +ls /gws/nopw/j04/esmeval/obsdata-v2/ ls /badc/cmip5/data/cmip5/output1/MOHC/HadGEM2-ES ls /badc/cmip6/data/CMIP6/CMIP/*/*/historical/r1i1p1f?/Omon/[ts]os/gn/latest/*.nc ~~~ From 659690c5aaa3d185f8851295737304bf3f62c535 Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 14 Mar 2021 21:35:57 +0000 Subject: [PATCH 559/647] Changed the obs data path on JASMIN to the new correct one --- _episodes/03-configuration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 095a2824..c69604bb 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -175,10 +175,10 @@ example configuration file. >> CMIP6: /badc/cmip6/data/CMIP6 >> CMIP5: /badc/cmip5/data/cmip5/output1 >> # CMIP3: /badc/cmip3_drs/data/cmip3/output ->> # OBS: /group_workspaces/jasmin4/esmeval/obsdata-v2 ->> # OBS6: /group_workspaces/jasmin4/esmeval/obsdata-v2 ->> # obs4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 ->> # ana4mips: /group_workspaces/jasmin4/esmeval/obsdata-v2 +>> # OBS: /gws/nopw/j04/esmeval/obsdata-v2 +>> # OBS6: /gws/nopw/j04/esmeval/obsdata-v2 +>> # obs4mips: /gws/nopw/j04/esmeval/obsdata-v2 +>> # ana4mips: /gws/nopw/j04/esmeval/obsdata-v2 >> # CORDEX: /badc/cordex/data/CORDEX/output >>``` >> From 73d8cd43ed3aaea5435f6806e9230ff281810cf1 Mon Sep 17 00:00:00 2001 From: rswamina Date: Mon, 15 Mar 2021 10:32:30 +0000 Subject: [PATCH 560/647] removed the 10-diagnostics.md file because changes to it were accidentally included in this pull request --- _episodes/10-diagnostics.md | 497 ------------------------------------ 1 file changed, 497 deletions(-) delete mode 100644 _episodes/10-diagnostics.md diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md deleted file mode 100644 index e7d2ee6c..00000000 --- a/_episodes/10-diagnostics.md +++ /dev/null @@ -1,497 +0,0 @@ ---- -title: "Writing your own diagnostic script" -teaching: TBD -exercises: TBD - -questions: -- "How do I write a new diagnostic in ESMValTool?" -- "How do I use the preprocessor output in a Python diagnostic?" - -objectives: -- "Write a new Python diagnostic script." -- "Explain how a diagnostic script reads the preprocessor output." - -keypoints: -- "ESMValTool provides helper functions to interface a Python diagnostic script - with preprocessor output." -- "Existing diagnostics can be used as templates and modified to write new - diagnostics." -- "Many functions can be imported from ``esmvaltool.diag_scripts.shared`` and - used in your own diagnostic script." ---- - -## Introduction - -The diagnostic script is an important component of ESMValTool where the -scientific analysis or performance metric is implemented. With ESMValTool, you -can adapt an existing diagnostic or write a new script from scratch. -Diagnostics can be written in a number of open source -languages such as Python, R, Julia and NCL but we will focus on understanding -and writing Python diagnostics in this lesson. -There are two approches to run your own diagnostics: - -1. using ESMValTool installed in a stable mode -2. using ESMValTool installed in a editable/development mode - -In this lesson, we will explain how to find an existing diagnostic and run it -using the second approch. For a development installation, see the instructions -in the lesson -[Development and contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}). -Also, we will work with the recipe [recipe_python.yml][recipe] and the diagnostic script -[diagnostic.py][diagnostic] called by this recipe that we have seen in the lesson -[Running your first recipe]({{ page.root }}{% link _episodes/04-recipe.md %}). - -Let's get started. - -## Understanding an existing Python diagnostic - -After development installation, a folder called ``ESMValTool`` has been created -in your working directory. This folder contains the source code of the tool. We -can find the recipe ``recipe_python.yml`` and the python script -``diagnostic.py`` in these directories: - -- *path_to_ESMValTool/esmvaltool/recipes/examples/recipe_python.yml* -- *path_to_ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py* - -Let's have look into the codes of the ``diagnostic.py``. -For reference, we show the diagnostic code in the dropdown box below. -There are four main sections in the script: - -- A description i.e. the ``docstring`` (line 1). -- Import statements (line 2-16). -- Functions that implement our analysis (line 21-101). -- A typical python top-level script (line 102-107). - -> ## diagnostic.py -> ->~~~python -> 1: """Python example diagnostic.""" -> 2: import logging -> 3: from pathlib import Path -> 4: from pprint import pformat -> 5: -> 6: import iris -> 7: -> 8: from esmvaltool.diag_scripts.shared import ( -> 9: group_metadata, -> 10: run_diagnostic, -> 11: save_data, -> 12: save_figure, -> 13: select_metadata, -> 14: sorted_metadata, -> 15: ) -> 16: from esmvaltool.diag_scripts.shared.plot import quickplot -> 17: -> 18: logger = logging.getLogger(Path(__file__).stem) -> 19: -> 20: -> 21: def get_provenance_record(attributes, ancestor_files): -> 22: """Create a provenance record describing the diagnostic data and plot.""" -> 23: caption = ("Average {long_name} between {start_year} and {end_year} " -> 24: "according to {dataset}.".format(**attributes)) -> 25: -> 26: record = { -> 27: 'caption': caption, -> 28: 'statistics': ['mean'], -> 29: 'domains': ['global'], -> 30: 'plot_types': ['zonal'], -> 31: 'authors': [ -> 32: 'andela_bouwe', -> 33: 'righi_mattia', -> 34: ], -> 35: 'references': [ -> 36: 'acknow_project', -> 37: ], -> 38: 'ancestors': ancestor_files, -> 39: } -> 40: return record -> 41: -> 42: -> 43: def compute_diagnostic(filename): -> 44: """Compute an example diagnostic.""" -> 45: logger.debug("Loading %s", filename) -> 46: cube = iris.load_cube(filename) -> 47: -> 48: logger.debug("Running example computation") -> 49: cube = iris.util.squeeze(cube) -> 50: return cube -> 51: -> 52: -> 53: def plot_diagnostic(cube, basename, provenance_record, cfg): -> 54: """Create diagnostic data and plot it.""" -> 55: -> 56: # Save the data used for the plot -> 57: save_data(basename, provenance_record, cfg, cube) -> 58: -> 59: if cfg.get('quickplot'): -> 60: # Create the plot -> 61: quickplot(cube, **cfg['quickplot']) -> 62: # And save the plot -> 63: save_figure(basename, provenance_record, cfg) -> 64: -> 65: -> 66: def main(cfg): -> 67: """Compute the time average for each input dataset.""" -> 68: # Get a description of the preprocessed data that we will use as input. -> 69: input_data = cfg['input_data'].values() -> 70: -> 71: # Demonstrate use of metadata access convenience functions. -> 72: selection = select_metadata(input_data, short_name='tas', project='CMIP5') -> 73: logger.info("Example of how to select only CMIP5 temperature data:\n%s", -> 74: pformat(selection)) -> 75: -> 76: selection = sorted_metadata(selection, sort='dataset') -> 77: logger.info("Example of how to sort this selection by dataset:\n%s", -> 78: pformat(selection)) -> 79: -> 80: grouped_input_data = group_metadata(input_data, -> 81: 'variable_group', -> 82: sort='dataset') -> 83: logger.info( -> 84: "Example of how to group and sort input data by variable groups from " -> 85: "the recipe:\n%s", pformat(grouped_input_data)) -> 86: -> 87: # Example of how to loop over variables/datasets in alphabetical order -> 88: groups = group_metadata(input_data, 'variable_group', sort='dataset') -> 89: for group_name in groups: -> 90: logger.info("Processing variable %s", group_name) -> 91: for attributes in groups[group_name]: -> 92: logger.info("Processing dataset %s", attributes['dataset']) -> 93: input_file = attributes['filename'] -> 94: cube = compute_diagnostic(input_file) -> 95: -> 96: output_basename = Path(input_file).stem -> 97: if group_name != attributes['short_name']: -> 98: output_basename = group_name + '_' + output_basename -> 99: provenance_record = get_provenance_record( ->100: attributes, ancestor_files=[input_file]) ->101: plot_diagnostic(cube, output_basename, provenance_record, cfg) ->102: ->103: ->104: if __name__ == '__main__': ->105: ->106: with run_diagnostic() as config: ->107: main(config) ->108: ->~~~ -> -{:.solution} - -> ## What is the starting point of the diagnostic? -> -> 1. Can you spot a function called ``main`` in the code above? -> 2. What are its input arguments? -> 3. How many times is this function mentioned? -> ->> ## Answer ->> ->> 1. The ``main`` function is defined in line 66 as ``main(cfg)``. ->> 2. The variable ``cfg`` is a Python dictionary holding all the necessary ->> information needed to run the diagnostic script like the location of input ->> data and various settings. In the ``main`` function, we will next parse this ->> ``cfg`` variable and extract information as needed to do our analyses (e.g. in line 69). ->> 3. The ``main`` function called near the very end on line 107. -> {: .solution} -{: .challenge} - -> ## The function run_diagnostic -> -> The function ``run_diagnostic`` (line 106) is called a context manager -> provided with ESMValTool and is the main entry point for most Python -> diagnostics. -> -{: .callout} - -## Preprocesor-diagnostic interface - -In the previous exercise, we have seen that the variable ``cfg`` is the input -argument of the ``main`` function. The first thing passed to the diagnostic -via the ``cfg`` dictionary is a path to a file called ``settings.yml``. -The ESMValTool documentation page provides an overview of what is in this file, see -[Diagnostic script interfaces][interface]. - -> ## What information do I need when writing a diagnostic script? -> -> From the lesson [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}), -> we saw how to change the configurations before running a recipe. -> Let's first set the option ``remove_preproc_dir`` to ``false`` in the configuration file, -> then run the recipe ``recipe_python.yml``: -> -> ~~~bash -> esmvaltool run recipe_example.yml -> ~~~ -> -> 1. Find one example of the file ``settings.yml`` in the ``run`` directory? -> 2. Take a look at the ``input_files`` list. It contains pathes to some files -> ``metadata.yml``. What information do you think is saved in those files? -> ->> ## Answer ->> ->> 1. One example of ``settings.yml`` can be found in the directory: ->> *path_to_recipe_output/run/map/script1/settings.yml* ->> 2. The ``metadata.yml`` files hold information ->> about the preprocessed data. There is one file for each variable having ->> detailed information on your data including project (e.g., CMIP6, CMIP5), ->> dataset names (e.g., BCC-ESM1, CanESM2), variable attributes (e.g., ->> standard_name, units), preprocessor applied and time range of the data. You ->> can use all of these information in your own diagnostics. -> > -> > -> {: .solution} -{: .challenge} - -## Diagnostic shared functions - -Looking at the codes of the ``diagnostic.py``, we see that ``input_data`` is -read from the ``cfg`` dictionary (line 69). Now we can group the ``input_data`` -according to some criteria such as the model or experiment. To do so, -ESMValTool provides many functions like ``select_metadata`` (line 72), -``sorted_metadata`` (line 76), and ``group_metadata`` (line 80). As you can see -in line 8, these functions are imported from ``esmvaltool.diag_scripts.shared`` -that means these are shared between several diagnostics scripts. A list of -available functions and their description can be found in [Shared diagnostic -script code][shared]. - -> ## Extracting information needed for analyses -> -> We have seen the functions used for selecting, sorting and grouping data in the -> script. What these functions do? -> ->> ## Answer ->> ->> There is a statement after use of ``select_metadata``, ``sorted_metadata`` ->> and ``group_metadata`` that starts with ``logger.info`` (lines 73, 77 and ->> 83). These lines print output to the log files. In the previous exercise, we ->> ran the recipe ``recipe_python.yml``. If you looked at the content of the log ->> file ``path_to_recipe_output/run/map/script1/log.txt``, you can see the some ->> information on how each function works, for example: ->> ->>``` ->>2021-03-05 13:19:38,184 [34706] INFO diagnostic,83 Example of how to group and ->>sort input data by variable groups from the recipe: ->>{'tas': [{'activity': 'CMIP', ->> 'alias': 'CMIP6', ->> 'dataset': 'BCC-ESM1', ->> 'diagnostic': 'map', ->> 'end_year': 2000, ->> 'ensemble': 'r1i1p1f1', ->> 'exp': 'historical', ->> 'filename': '~/recipe_python_20210305_131929/preproc/map/tas/CMIP6_BCC-ESM1_Amon_historical_r1i1p1f1_tas_2000-2000.nc', ->> 'frequency': 'mon', ->> 'grid': 'gn', ->> 'institute': ['BCC'], ->> 'long_name': 'Near-Surface Air Temperature', ->> 'mip': 'Amon', ->> 'modeling_realm': ['atmos'], ->> 'preprocessor': 'select_january', ->> 'project': 'CMIP6', ->> 'recipe_dataset_index': 0, ->> 'short_name': 'tas', ->> 'standard_name': 'air_temperature', ->> 'start_year': 2000, ->> 'units': 'K', ->> 'variable_group': 'tas'}, ->> {'alias': 'CMIP5', ->> 'dataset': 'CanESM2', ->> 'diagnostic': 'map', ->> 'end_year': 2000, ->> 'ensemble': 'r1i1p1', ->> 'exp': 'historical', ->> 'filename': '~/recipe_python_20210305_131929/preproc/map/tas/CMIP5_CanESM2_Amon_historical_r1i1p1_tas_2000-2000.nc', ->> 'frequency': 'mon', ->> 'institute': ['CCCma'], ->> 'long_name': 'Near-Surface Air Temperature', ->> 'mip': 'Amon', ->> 'modeling_realm': ['atmos'], ->> 'preprocessor': 'select_january', ->> 'project': 'CMIP5', ->> 'recipe_dataset_index': 1, ->> 'short_name': 'tas', ->> 'standard_name': 'air_temperature', ->> 'start_year': 2000, ->> 'units': 'K', ->> 'variable_group': 'tas'}]} ->>``` ->> ->> This is how we can access preprocessed data within our diagnostic. -> {: .solution} -{: .challenge} - -## Diagnostic computation - -After grouping and selecting data, we can read individual attributes such as the -filename by looping over variables (line 89-93). Following this, we see the use -of the function ``compute_diagnostic`` (line 94). Let's have a look at the -definition of this function in line 43 where the analyses on the data is done. - -Here, ``compute_diagnostic`` uses -[Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data -from a netCDF file and performs an operation ``squeeze`` to remove any dimension -of length one. We can adapt this function to add our own analysis. As an -example, here we want to calculate the bias toward the averege of the data as: - -~~~python -def compute_diagnostic(filename): - """Compute an example diagnostic.""" - logger.debug("Loading %s", filename) - cube = iris.load_cube(filename) - - logger.debug("Running example computation") - cube = iris.util.squeeze(cube) - - # Calculate a bias using the average of data - cube.data = cube.core_data() - cube.data.mean() - return cube -~~~ - -> ## iris cubes -> -> Iris reads data into data structures called -> [cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). -> The data in these cubes can be modified, combined with other cubes' data or -> plotted. -{: .callout} - -> ## Reading data using xarray -> -> Use the [xarrays](http://xarray.pydata.org/en/stable/) to read the data -> instead of iris. -> ->> ## Answer ->> ->> First, import ``xarray`` package at the top of the script as: ->> ->>~~~python ->>import xarray as xr ->>~~~ ->> ->> Then, change the ``compute_diagnostic`` as: ->> ->>~~~python ->>def compute_diagnostic(filename): ->> """Compute an example diagnostic.""" ->> logger.debug("Loading %s", filename) ->> dataset = xr.open_dataset(filename) ->> ->> #do your analyses on the data here ->> ->> return dataset ->>~~~ ->> -> {: .solution} -{: .challenge} - -> ## Reading data using Scipy's netCDF library -> -> Use the [SciPy's netCDF library][netCDF] to read the data instead of iris. -> ->> ## Answer ->> ->> First, import ``netcdfx`` package at the top of the script as: ->> ->>~~~python ->>from scipy.io import netcdfx ->>~~~ ->> ->> Then, change the ``compute_diagnostic`` as: ->> ->>~~~python ->>def compute_diagnostic(filename): ->> """Compute an example diagnostic.""" ->> logger.debug("Loading %s", filename) ->> netcdf_file = netcdf.netcdf_file(filename,'r') ->> ->> #do your analyses on the data here ->> ->> return netcdf_file ->>~~~ ->> -> {: .solution} -{: .challenge} - -## Diagnostic output - -### Plotting the output - -Often, the end product of a diagnostic script is a plot or figure. The Iris cube -returned from the ``compute_diagnostic`` function (line 94) is passed to the -``plot_diagnostic`` function (line 101). Let's have a look at the definition of -this function in line 53 where we would plug in our plotting routine in the -diagnostic script. - -More specifically, the ``quickplot`` function (line 61) can be replaced with the -function of our choice. As can be seen, this function uses -``**cfg['quickplot']`` as an input argument. If you look at the diagnostic -section in the recipe ``recipe_python.yml``, you see ``quickplot`` is a key -there: - -~~~yaml - script1: - script: examples/diagnostic.py - quickplot: - plot_type: pcolormesh - cmap: Reds -~~~ - -In this way, we can further pass arguments for ``quickplot`` such as the type of -plot ``pcolormesh`` and the colormap ``cmap:Reds`` from the recipe to the -diagnostic. - -> ## Passing arguments from the recipe to the diagnostic -> -> Change the type of the plot and its colormap and inspect the output figure. -> ->> ## Answer ->> ->> In the recipe ``recipe_python.yml``, you should change ``plot_type`` and ``cmap``. ->> As an example, we choose ``plot_type: pcolor`` and ``cmap: BuGn``: ->> ->> ~~~yaml ->> script1: ->> script: examples/diagnostic.py ->> quickplot: ->> plot_type: pcolor ->> cmap: BuGn ->>~~~ ->> ->> The plot can be found at *path_to_recipe_output/plots/map/script1/png*. -> {: .solution} -{: .challenge} - -> ## ESMValTool gallery -> -> ESMValTool makes it possible to produce a wide array of such figures as seen -> in the [gallery](https://docs.esmvaltool.org/en/latest/gallery.html). -{: .callout} - -### Saving the output - -In our example, the function ``save_data`` in line 57 is used to save the Iris -cube. The saved files can be found under ``work`` directory in a ``.nc`` format. -There is also the function ``save_figure`` in line 63 to save the plots under -``plot`` directory in a ``.png`` format. Again, you may choose your own method -of saving the output. - -### Recording the provenance - -When developing a diagnostic script, we should make sure that it records the -provenance. To do so, we use the function ``get_provenance_record`` (line 99). -Let's have a look at the definition of this function in line 21 where we -describe the diagnostic data and plot. Using the dictionary ``record``, it is -possible to add custom provenance. Provenance is stored in the *W3C PROV XML* -format and also in an *SVG* file under the ``work`` and ``plot`` directory. For -more information, see [recording provenance][provenance]. - -## Congratulations! - -Now you know the diagnostic script structure and a few functions. There are many -more functions to be used, but these should be enough to get you started! Look -at other recipes and diagnostics for more examples. -{% include links.md %} - -[recipe]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml -[diagnostic]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py -[interface]: https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html -[shared]: https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html -[netCDF]: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html -[provenance]: https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance From 55494bb18c6dff008b3fca8f6aebb1620791fb89 Mon Sep 17 00:00:00 2001 From: rswamina Date: Mon, 15 Mar 2021 11:03:36 +0000 Subject: [PATCH 561/647] deleting end spaces to see if the build error will be fixed --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index 0724e599..a992203e 100644 --- a/setup.md +++ b/setup.md @@ -281,4 +281,4 @@ ESMValTool development team. [cmip5-search]: https://esgf-data.dkrz.de/search/cmip5-dkrz/ [theatoga.nc]: http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc -[ds]: https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls +[ds]: https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls \ No newline at end of file From 9aeafc4757e8fbbe82c01409d9135b0c13331098 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Mon, 15 Mar 2021 16:37:27 +0100 Subject: [PATCH 562/647] Implement suggestion from code review Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/09-cmorization.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 9858823e..5bdb2075 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -740,9 +740,7 @@ utils.set_global_atts(cube, attributes) ``` - **Add a reference**. Make sure that there is a reference file available for - the dataset. You can add a [BibTeX info - file](https://github.com/ESMValGroup/ESMValTool/tree/master/esmvaltool/references) - here. You + the dataset, see the instruction [here](https://docs.esmvaltool.org/en/latest/community/diagnostic.html#adding-references). - **Make a pull request**. Since you have gone through all the trouble to reformat the dataset so that the ESMValTool can work with it, it would be From a8d73a055e8cc6a64eaf16ff51cc5dd00be4e758 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Mon, 15 Mar 2021 17:57:18 +0100 Subject: [PATCH 563/647] Birgit final suggestions --- _episodes/09-cmorization.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 5bdb2075..6e8f0a23 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -462,7 +462,7 @@ however, is beyond the scope of this tutorial. > > filename: 'GPP.ANN.CRUNCEPv6.monthly.*.nc' > > > > attributes: -> > project_id: OBS +> > project_id: OBS6 > > dataset_id: FLUXCOM > > version: 'ANN-v1' > > tier: 3 @@ -508,11 +508,11 @@ naming convention for ESMValTool datasets. Let's have a look at the NetCDF file as it was written with the very basic CMORizer from above. ```bash -ncdump -h OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012.nc +ncdump -h OBS6_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_200001-200012.nc ``` ~~~ -netcdf OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_198001-198012 { +netcdf OBS6_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_200001-200012 { dimensions: time = 12 ; lat = 360 ; From 4aa7a105b1d54090914b6f671b712ec7d6d24b0a Mon Sep 17 00:00:00 2001 From: rswamina Date: Tue, 16 Mar 2021 12:25:21 +0000 Subject: [PATCH 564/647] Minor changes and edits after proof reading --- _episodes/10-diagnostics.md | 115 +++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 857e7d95..021119c1 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -1,7 +1,7 @@ --- title: "Writing your own diagnostic script" -teaching: TBD -exercises: TBD +teaching: 20 +exercises: 30 questions: - "How do I write a new diagnostic in ESMValTool?" @@ -16,13 +16,13 @@ keypoints: with preprocessor output." - "Existing diagnostics can be used as templates and modified to write new diagnostics." -- "Many functions can be imported from ``esmvaltool.diag_scripts.shared`` and +- "Helper functions can be imported from ``esmvaltool.diag_scripts.shared`` and used in your own diagnostic script." --- ## Introduction -The diagnostic script is an important component of ESMValTool where the +The diagnostic script is an important component of ESMValTool and it is where the scientific analysis or performance metric is implemented. With ESMValTool, you can adapt an existing diagnostic or write a new script from scratch. Diagnostics can be written in a number of open source @@ -30,7 +30,7 @@ languages such as Python, R, Julia and NCL but we will focus on understanding and writing Python diagnostics in this lesson. In this lesson, we will explain how to find an existing diagnostic and run it -using ESMValTool installed in a editable/development mode. For a development +using ESMValTool installed in editable/development mode. For a development installation, see the instructions in the lesson [Development and contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}). Also, we will work with the recipe [recipe_python.yml][recipe] and the @@ -38,11 +38,11 @@ diagnostic script [diagnostic.py][diagnostic] called by this recipe that we have seen in the lesson [Running your first recipe]({{ page.root }}{% link _episodes/04-recipe.md %}). -Let's get started. +Let's get started! ## Understanding an existing Python diagnostic -After development installation, a folder called ``ESMValTool`` has been created +After a development mode installation, a folder called ``ESMValTool`` is created in your working directory. This folder contains the source code of the tool. We can find the recipe ``recipe_python.yml`` and the python script ``diagnostic.py`` in these directories: @@ -50,14 +50,14 @@ can find the recipe ``recipe_python.yml`` and the python script - *path_to_ESMValTool/esmvaltool/recipes/examples/recipe_python.yml* - *path_to_ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py* -Let's have look into the codes of the ``diagnostic.py``. +Let's have look at the code in ``diagnostic.py``. For reference, we show the diagnostic code in the dropdown box below. There are four main sections in the script: - A description i.e. the ``docstring`` (line 1). - Import statements (line 2-16). - Functions that implement our analysis (line 21-101). -- A typical python top-level script i.e. ``if __name__ == '__main__'`` (line +- A typical Python top-level script i.e. ``if __name__ == '__main__'`` (line 102-107). > ## diagnostic.py @@ -175,7 +175,7 @@ There are four main sections in the script: > {:.solution} -> ## What is the starting point of the diagnostic? +> ## What is the starting point of a diagnostic? > > 1. Can you spot a function called ``main`` in the code above? > 2. What are its input arguments? @@ -184,11 +184,15 @@ There are four main sections in the script: >> ## Answer >> >> 1. The ``main`` function is defined in line 66 as ``main(cfg)``. ->> 2. The variable ``cfg`` is a Python dictionary holding all the necessary ->> information needed to run the diagnostic script like the location of input ->> data and various settings. In the ``main`` function, we will next parse this ->> ``cfg`` variable and extract information as needed to do our analyses (e.g. in line 69). ->> 3. The ``main`` function called near the very end on line 107. +>> 2. The input argument to this function is the variable ``cfg``, a Python dictionary t +>> hat holds all the necessary +>> information needed to run the diagnostic script such as the location of input +>> data and various settings. We will next parse this ``cfg`` variable +>> in the ``main`` function and extract information as needed +>> to do our analyses (e.g. in line 69). +>> 3. The ``main`` function is called near the very end on line 107. So, it is mentioned +>> twice in our code - once where it is called by the top-level Python script and +>> second where it is defined. > {: .solution} {: .challenge} @@ -211,8 +215,8 @@ The ESMValTool documentation page provides an overview of what is in this file, > ## What information do I need when writing a diagnostic script? > > From the lesson [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}), -> we saw how to change the configurations before running a recipe. -> Let's first set the option ``remove_preproc_dir`` to ``false`` in the configuration file, +> we saw how to change the configuration settings before running a recipe. +> First we set the option ``remove_preproc_dir`` to ``false`` in the configuration file, > then run the recipe ``recipe_python.yml``: > > ~~~bash @@ -232,7 +236,7 @@ The ESMValTool documentation page provides an overview of what is in this file, >> detailed information on your data including project (e.g., CMIP6, CMIP5), >> dataset names (e.g., BCC-ESM1, CanESM2), variable attributes (e.g., >> standard_name, units), preprocessor applied and time range of the data. You ->> can use all of these information in your own diagnostics. +>> can use all of this information in your own diagnostic. > > > > > {: .solution} @@ -240,29 +244,29 @@ The ESMValTool documentation page provides an overview of what is in this file, ## Diagnostic shared functions -Looking at the codes of the ``diagnostic.py``, we see that ``input_data`` is +Looking at the code in ``diagnostic.py``, we see that ``input_data`` is read from the ``cfg`` dictionary (line 69). Now we can group the ``input_data`` according to some criteria such as the model or experiment. To do so, -ESMValTool provides many functions like ``select_metadata`` (line 72), +ESMValTool provides many functions such as ``select_metadata`` (line 72), ``sorted_metadata`` (line 76), and ``group_metadata`` (line 80). As you can see in line 8, these functions are imported from ``esmvaltool.diag_scripts.shared`` -that means these are shared between several diagnostics scripts. A list of +that means these are shared across several diagnostics scripts. A list of available functions and their description can be found in [Shared diagnostic script code][shared]. > ## Extracting information needed for analyses > > We have seen the functions used for selecting, sorting and grouping data in the -> script. What these functions do? +> script. What do these functions do? > >> ## Answer >> >> There is a statement after use of ``select_metadata``, ``sorted_metadata`` >> and ``group_metadata`` that starts with ``logger.info`` (lines 73, 77 and >> 83). These lines print output to the log files. In the previous exercise, we ->> ran the recipe ``recipe_python.yml``. If you looked at the content of the log ->> file ``path_to_recipe_output/run/map/script1/log.txt``, you can see the some ->> information on how each function works, for example: +>> ran the recipe ``recipe_python.yml``. If you look at the log +>> file ``path_to_recipe_output/run/map/script1/log.txt``, you can see the output +>> from each of these functions, for example: >> >>``` >>2021-03-05 13:19:38,184 [34706] INFO diagnostic,83 Example of how to group and @@ -317,16 +321,18 @@ script code][shared]. ## Diagnostic computation -After grouping and selecting data, we can read individual attributes such as the -filename by looping over variables (line 89-93). Following this, we see the use -of the function ``compute_diagnostic`` (line 94). Let's have a look at the -definition of this function in line 43 where the analyses on the data is done. +After grouping and selecting data, we can read individual attributes (such as filename) +of each item. Here we have grouped the input data by ``variables`` +so we loop over the variables (line 89-93). Following this, is a call to the +function ``compute_diagnostic`` (line 94). Let's have a look at the +definition of this function in line 43 where the actual analysis on the data is done. +Note that output from the ESMValCore preprocessor is in the form of NetCDF files. Here, ``compute_diagnostic`` uses [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data -from a netCDF file and performs an operation ``squeeze`` to remove any dimension +from a netCDF file and performs an operation ``squeeze`` to remove any dimensions of length one. We can adapt this function to add our own analysis. As an -example, here we want to calculate the bias toward the averege of the data as: +example, here we calculate the bias using the average of the data using Iris cubes. ~~~python def compute_diagnostic(filename): @@ -344,7 +350,7 @@ def compute_diagnostic(filename): > ## iris cubes > -> Iris reads data into data structures called +> Iris reads data from NetCDF files into data structures called > [cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). > The data in these cubes can be modified, combined with other cubes' data or > plotted. @@ -352,8 +358,8 @@ def compute_diagnostic(filename): > ## Reading data using xarray > -> Use the [xarrays](http://xarray.pydata.org/en/stable/) to read the data -> instead of iris. +> Alternately, you can use [xarrays](http://xarray.pydata.org/en/stable/) to read the data +> instead of Iris. > >> ## Answer >> @@ -381,17 +387,18 @@ def compute_diagnostic(filename): > ## Reading data using Scipy's netCDF library > -> Use the [SciPy's netCDF library][netCDF] to read the data instead of iris. +> Yet another option to read the NetCDF file data is to use +> the [SciPy's netCDF library][netCDF]. > >> ## Answer >> ->> First, import ``netcdfx`` package at the top of the script as: +>> First, import the ``netcdfx`` package at the top of the script as: >> >>~~~python >>from scipy.io import netcdfx >>~~~ >> ->> Then, change the ``compute_diagnostic`` as: +>> Then, change ``compute_diagnostic`` as: >> >>~~~python >>def compute_diagnostic(filename): @@ -414,7 +421,7 @@ def compute_diagnostic(filename): Often, the end product of a diagnostic script is a plot or figure. The Iris cube returned from the ``compute_diagnostic`` function (line 94) is passed to the ``plot_diagnostic`` function (line 101). Let's have a look at the definition of -this function in line 53 where we would plug in our plotting routine in the +this function in line 53. This is where we would plug in our plotting routine in the diagnostic script. More specifically, the ``quickplot`` function (line 61) can be replaced with the @@ -431,9 +438,9 @@ there: cmap: Reds ~~~ -In this way, we can further pass arguments for ``quickplot`` such as the type of -plot ``pcolormesh`` and the colormap ``cmap:Reds`` from the recipe to the -diagnostic. +This way, we can pass arguments such as the type of +plot ``pcolormesh`` and the colormap ``cmap:Reds`` from the recipe to the +``quickplot`` function in the diagnostic. > ## Passing arguments from the recipe to the diagnostic > @@ -441,7 +448,7 @@ diagnostic. > >> ## Answer >> ->> In the recipe ``recipe_python.yml``, you should change ``plot_type`` and ``cmap``. +>> In the recipe ``recipe_python.yml``, you could change ``plot_type`` and ``cmap``. >> As an example, we choose ``plot_type: pcolor`` and ``cmap: BuGn``: >> >> ~~~yaml @@ -458,33 +465,35 @@ diagnostic. > ## ESMValTool gallery > -> ESMValTool makes it possible to produce a wide array of such figures as seen +> ESMValTool makes it possible to produce a wide array of plots and figures as seen > in the [gallery](https://docs.esmvaltool.org/en/latest/gallery.html). {: .callout} ### Saving the output In our example, the function ``save_data`` in line 57 is used to save the Iris -cube. The saved files can be found under ``work`` directory in a ``.nc`` format. -There is also the function ``save_figure`` in line 63 to save the plots under -``plot`` directory in a ``.png`` format. Again, you may choose your own method -of saving the output. +cube. The saved files can be found under the ``work`` directory in a ``.nc`` format. +There is also the function ``save_figure`` in line 63 to save the plots under the +``plot`` directory in a ``.png`` format (or preferred format specified in your +configuration settings). Again, you may choose your own method +of saving the output. ### Recording the provenance -When developing a diagnostic script, we should make sure that it records the +When developing a diagnostic script, it is good practice to record provenance. To do so, we use the function ``get_provenance_record`` (line 99). -Let's have a look at the definition of this function in line 21 where we +Let us have a look at the definition of this function in line 21 where we describe the diagnostic data and plot. Using the dictionary ``record``, it is -possible to add custom provenance. Provenance is stored in the *W3C PROV XML* +possible to add custom provenance to our diagnostics output. +Provenance is stored in the *W3C PROV XML* format and also in an *SVG* file under the ``work`` and ``plot`` directory. For more information, see [recording provenance][provenance]. ## Congratulations! -Now you know the diagnostic script structure and a few functions. There are many -more functions to be used, but these should be enough to get you started! Look -at other recipes and diagnostics for more examples. +You now know the basic diagnostic script structure and some available tools for putting +together your own diagnostics. Have a look at existing recipes and diagnostics in the +repository for more examples of functions you can use in your diagnostics! {% include links.md %} [recipe]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml From 5488d61da85069f763581e848a65c8a05ddb46ae Mon Sep 17 00:00:00 2001 From: rswamina Date: Tue, 16 Mar 2021 13:36:16 +0000 Subject: [PATCH 565/647] Added a brief summary of possible ways to use or install and use ESMValTool including options such as module load etc. --- _episodes/02-installation.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 64dad7c6..4c53aee9 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -25,6 +25,31 @@ be found in the We will first install Conda, and then ESMValTool. We end this chapter by testing that the installation was successful. + +> ## ESMValTool Installation/Usage Options - A quick summary +> Before we begin, here are all the possible ways in which you can use ESMValTool +> depending on your level of expertise or involvement with ESMvalTool and +> associated software such as GitHub and Conda. +> +> 1) If you have access to a server where ESMValTool is already installed +> as a module, for e.g., the ``CEDA JASMIN`` server, you can simply +> load the module and start using ESMValTool with the following : +> ```bash +> module load esmvaltool +> ``` +> 2) If you would like to install ESMValTool as a conda package, then this lesson +> will tell you how! +> +> 3) If you are already familiar with ESMValTool and would like to start experimenting +> with existing diagnostics, you can dowload the source code from the ESMvalTool Github +> page, compile and run as given here (link missing). +> +> 4) If you would like to start contributing to ESMvalTool, please see the instructions for +> source installation in the lesson [Development and +> contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}) and +> in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). +{: .solution} + > ## Install ESMValTool on Windows > > ESMValTool does not directly support Windows, but successful usage has been From 26eb4500509baea47842fb0ca4e422493b34da2f Mon Sep 17 00:00:00 2001 From: rswamina Date: Tue, 16 Mar 2021 14:07:55 +0000 Subject: [PATCH 566/647] fixed broken link to example recipe --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 81971544..1438fc18 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -29,7 +29,7 @@ recipes that are shipped with ESMValTool, type esmvaltool recipes list ``` -We will start by running [examples/recipe_python.yml](https://docs.esmvaltool.org/en/latest/recipes/recipe_python.html) +We will start by running [examples/recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) ``` esmvaltool run examples/recipe_python.yml From 867317ef36b42c5c78c03efd743c610a36892564 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 11 Mar 2021 15:48:20 +0100 Subject: [PATCH 567/647] remove stable mode --- _episodes/10-diagnostics.md | 494 ++++++++++++++++++++++++++++++++++++ 1 file changed, 494 insertions(+) create mode 100644 _episodes/10-diagnostics.md diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md new file mode 100644 index 00000000..8df7f12a --- /dev/null +++ b/_episodes/10-diagnostics.md @@ -0,0 +1,494 @@ +--- +title: "Writing your own diagnostic script" +teaching: TBD +exercises: TBD + +questions: +- "How do I write a new diagnostic in ESMValTool?" +- "How do I use the preprocessor output in a Python diagnostic?" + +objectives: +- "Write a new Python diagnostic script." +- "Explain how a diagnostic script reads the preprocessor output." + +keypoints: +- "ESMValTool provides helper functions to interface a Python diagnostic script + with preprocessor output." +- "Existing diagnostics can be used as templates and modified to write new + diagnostics." +- "Many functions can be imported from ``esmvaltool.diag_scripts.shared`` and + used in your own diagnostic script." +--- + +## Introduction + +The diagnostic script is an important component of ESMValTool where the +scientific analysis or performance metric is implemented. With ESMValTool, you +can adapt an existing diagnostic or write a new script from scratch. +Diagnostics can be written in a number of open source +languages such as Python, R, Julia and NCL but we will focus on understanding +and writing Python diagnostics in this lesson. + +In this lesson, we will explain how to find an existing diagnostic and run it +using ESMValTool installed in a editable/development mode. For a development +installation, see the instructions in the lesson [Development and +contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}). +Also, we will work with the recipe [recipe_python.yml][recipe] and the +diagnostic script [diagnostic.py][diagnostic] called by this recipe that we have +seen in the lesson [Running your first recipe]({{ page.root }}{% link +_episodes/04-recipe.md %}). + +Let's get started. + +## Understanding an existing Python diagnostic + +After development installation, a folder called ``ESMValTool`` has been created +in your working directory. This folder contains the source code of the tool. We +can find the recipe ``recipe_python.yml`` and the python script +``diagnostic.py`` in these directories: + +- *path_to_ESMValTool/esmvaltool/recipes/examples/recipe_python.yml* +- *path_to_ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py* + +Let's have look into the codes of the ``diagnostic.py``. +For reference, we show the diagnostic code in the dropdown box below. +There are four main sections in the script: + +- A description i.e. the ``docstring`` (line 1). +- Import statements (line 2-16). +- Functions that implement our analysis (line 21-101). +- A typical python top-level script (line 102-107). + +> ## diagnostic.py +> +>~~~python +> 1: """Python example diagnostic.""" +> 2: import logging +> 3: from pathlib import Path +> 4: from pprint import pformat +> 5: +> 6: import iris +> 7: +> 8: from esmvaltool.diag_scripts.shared import ( +> 9: group_metadata, +> 10: run_diagnostic, +> 11: save_data, +> 12: save_figure, +> 13: select_metadata, +> 14: sorted_metadata, +> 15: ) +> 16: from esmvaltool.diag_scripts.shared.plot import quickplot +> 17: +> 18: logger = logging.getLogger(Path(__file__).stem) +> 19: +> 20: +> 21: def get_provenance_record(attributes, ancestor_files): +> 22: """Create a provenance record describing the diagnostic data and plot.""" +> 23: caption = ("Average {long_name} between {start_year} and {end_year} " +> 24: "according to {dataset}.".format(**attributes)) +> 25: +> 26: record = { +> 27: 'caption': caption, +> 28: 'statistics': ['mean'], +> 29: 'domains': ['global'], +> 30: 'plot_types': ['zonal'], +> 31: 'authors': [ +> 32: 'andela_bouwe', +> 33: 'righi_mattia', +> 34: ], +> 35: 'references': [ +> 36: 'acknow_project', +> 37: ], +> 38: 'ancestors': ancestor_files, +> 39: } +> 40: return record +> 41: +> 42: +> 43: def compute_diagnostic(filename): +> 44: """Compute an example diagnostic.""" +> 45: logger.debug("Loading %s", filename) +> 46: cube = iris.load_cube(filename) +> 47: +> 48: logger.debug("Running example computation") +> 49: cube = iris.util.squeeze(cube) +> 50: return cube +> 51: +> 52: +> 53: def plot_diagnostic(cube, basename, provenance_record, cfg): +> 54: """Create diagnostic data and plot it.""" +> 55: +> 56: # Save the data used for the plot +> 57: save_data(basename, provenance_record, cfg, cube) +> 58: +> 59: if cfg.get('quickplot'): +> 60: # Create the plot +> 61: quickplot(cube, **cfg['quickplot']) +> 62: # And save the plot +> 63: save_figure(basename, provenance_record, cfg) +> 64: +> 65: +> 66: def main(cfg): +> 67: """Compute the time average for each input dataset.""" +> 68: # Get a description of the preprocessed data that we will use as input. +> 69: input_data = cfg['input_data'].values() +> 70: +> 71: # Demonstrate use of metadata access convenience functions. +> 72: selection = select_metadata(input_data, short_name='tas', project='CMIP5') +> 73: logger.info("Example of how to select only CMIP5 temperature data:\n%s", +> 74: pformat(selection)) +> 75: +> 76: selection = sorted_metadata(selection, sort='dataset') +> 77: logger.info("Example of how to sort this selection by dataset:\n%s", +> 78: pformat(selection)) +> 79: +> 80: grouped_input_data = group_metadata(input_data, +> 81: 'variable_group', +> 82: sort='dataset') +> 83: logger.info( +> 84: "Example of how to group and sort input data by variable groups from " +> 85: "the recipe:\n%s", pformat(grouped_input_data)) +> 86: +> 87: # Example of how to loop over variables/datasets in alphabetical order +> 88: groups = group_metadata(input_data, 'variable_group', sort='dataset') +> 89: for group_name in groups: +> 90: logger.info("Processing variable %s", group_name) +> 91: for attributes in groups[group_name]: +> 92: logger.info("Processing dataset %s", attributes['dataset']) +> 93: input_file = attributes['filename'] +> 94: cube = compute_diagnostic(input_file) +> 95: +> 96: output_basename = Path(input_file).stem +> 97: if group_name != attributes['short_name']: +> 98: output_basename = group_name + '_' + output_basename +> 99: provenance_record = get_provenance_record( +>100: attributes, ancestor_files=[input_file]) +>101: plot_diagnostic(cube, output_basename, provenance_record, cfg) +>102: +>103: +>104: if __name__ == '__main__': +>105: +>106: with run_diagnostic() as config: +>107: main(config) +>108: +>~~~ +> +{:.solution} + +> ## What is the starting point of the diagnostic? +> +> 1. Can you spot a function called ``main`` in the code above? +> 2. What are its input arguments? +> 3. How many times is this function mentioned? +> +>> ## Answer +>> +>> 1. The ``main`` function is defined in line 66 as ``main(cfg)``. +>> 2. The variable ``cfg`` is a Python dictionary holding all the necessary +>> information needed to run the diagnostic script like the location of input +>> data and various settings. In the ``main`` function, we will next parse this +>> ``cfg`` variable and extract information as needed to do our analyses (e.g. in line 69). +>> 3. The ``main`` function called near the very end on line 107. +> {: .solution} +{: .challenge} + +> ## The function run_diagnostic +> +> The function ``run_diagnostic`` (line 106) is called a context manager +> provided with ESMValTool and is the main entry point for most Python +> diagnostics. +> +{: .callout} + +## Preprocesor-diagnostic interface + +In the previous exercise, we have seen that the variable ``cfg`` is the input +argument of the ``main`` function. The first thing passed to the diagnostic +via the ``cfg`` dictionary is a path to a file called ``settings.yml``. +The ESMValTool documentation page provides an overview of what is in this file, see +[Diagnostic script interfaces][interface]. + +> ## What information do I need when writing a diagnostic script? +> +> From the lesson [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}), +> we saw how to change the configurations before running a recipe. +> Let's first set the option ``remove_preproc_dir`` to ``false`` in the configuration file, +> then run the recipe ``recipe_python.yml``: +> +> ~~~bash +> esmvaltool run recipe_example.yml +> ~~~ +> +> 1. Find one example of the file ``settings.yml`` in the ``run`` directory? +> 2. Take a look at the ``input_files`` list. It contains pathes to some files +> ``metadata.yml``. What information do you think is saved in those files? +> +>> ## Answer +>> +>> 1. One example of ``settings.yml`` can be found in the directory: +>> *path_to_recipe_output/run/map/script1/settings.yml* +>> 2. The ``metadata.yml`` files hold information +>> about the preprocessed data. There is one file for each variable having +>> detailed information on your data including project (e.g., CMIP6, CMIP5), +>> dataset names (e.g., BCC-ESM1, CanESM2), variable attributes (e.g., +>> standard_name, units), preprocessor applied and time range of the data. You +>> can use all of these information in your own diagnostics. +> > +> > +> {: .solution} +{: .challenge} + +## Diagnostic shared functions + +Looking at the codes of the ``diagnostic.py``, we see that ``input_data`` is +read from the ``cfg`` dictionary (line 69). Now we can group the ``input_data`` +according to some criteria such as the model or experiment. To do so, +ESMValTool provides many functions like ``select_metadata`` (line 72), +``sorted_metadata`` (line 76), and ``group_metadata`` (line 80). As you can see +in line 8, these functions are imported from ``esmvaltool.diag_scripts.shared`` +that means these are shared between several diagnostics scripts. A list of +available functions and their description can be found in [Shared diagnostic +script code][shared]. + +> ## Extracting information needed for analyses +> +> We have seen the functions used for selecting, sorting and grouping data in the +> script. What these functions do? +> +>> ## Answer +>> +>> There is a statement after use of ``select_metadata``, ``sorted_metadata`` +>> and ``group_metadata`` that starts with ``logger.info`` (lines 73, 77 and +>> 83). These lines print output to the log files. In the previous exercise, we +>> ran the recipe ``recipe_python.yml``. If you looked at the content of the log +>> file ``path_to_recipe_output/run/map/script1/log.txt``, you can see the some +>> information on how each function works, for example: +>> +>>``` +>>2021-03-05 13:19:38,184 [34706] INFO diagnostic,83 Example of how to group and +>>sort input data by variable groups from the recipe: +>>{'tas': [{'activity': 'CMIP', +>> 'alias': 'CMIP6', +>> 'dataset': 'BCC-ESM1', +>> 'diagnostic': 'map', +>> 'end_year': 2000, +>> 'ensemble': 'r1i1p1f1', +>> 'exp': 'historical', +>> 'filename': '~/recipe_python_20210305_131929/preproc/map/tas/CMIP6_BCC-ESM1_Amon_historical_r1i1p1f1_tas_2000-2000.nc', +>> 'frequency': 'mon', +>> 'grid': 'gn', +>> 'institute': ['BCC'], +>> 'long_name': 'Near-Surface Air Temperature', +>> 'mip': 'Amon', +>> 'modeling_realm': ['atmos'], +>> 'preprocessor': 'select_january', +>> 'project': 'CMIP6', +>> 'recipe_dataset_index': 0, +>> 'short_name': 'tas', +>> 'standard_name': 'air_temperature', +>> 'start_year': 2000, +>> 'units': 'K', +>> 'variable_group': 'tas'}, +>> {'alias': 'CMIP5', +>> 'dataset': 'CanESM2', +>> 'diagnostic': 'map', +>> 'end_year': 2000, +>> 'ensemble': 'r1i1p1', +>> 'exp': 'historical', +>> 'filename': '~/recipe_python_20210305_131929/preproc/map/tas/CMIP5_CanESM2_Amon_historical_r1i1p1_tas_2000-2000.nc', +>> 'frequency': 'mon', +>> 'institute': ['CCCma'], +>> 'long_name': 'Near-Surface Air Temperature', +>> 'mip': 'Amon', +>> 'modeling_realm': ['atmos'], +>> 'preprocessor': 'select_january', +>> 'project': 'CMIP5', +>> 'recipe_dataset_index': 1, +>> 'short_name': 'tas', +>> 'standard_name': 'air_temperature', +>> 'start_year': 2000, +>> 'units': 'K', +>> 'variable_group': 'tas'}]} +>>``` +>> +>> This is how we can access preprocessed data within our diagnostic. +> {: .solution} +{: .challenge} + +## Diagnostic computation + +After grouping and selecting data, we can read individual attributes such as the +filename by looping over variables (line 89-93). Following this, we see the use +of the function ``compute_diagnostic`` (line 94). Let's have a look at the +definition of this function in line 43 where the analyses on the data is done. + +Here, ``compute_diagnostic`` uses +[Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data +from a netCDF file and performs an operation ``squeeze`` to remove any dimension +of length one. We can adapt this function to add our own analysis. As an +example, here we want to calculate the bias toward the averege of the data as: + +~~~python +def compute_diagnostic(filename): + """Compute an example diagnostic.""" + logger.debug("Loading %s", filename) + cube = iris.load_cube(filename) + + logger.debug("Running example computation") + cube = iris.util.squeeze(cube) + + # Calculate a bias using the average of data + cube.data = cube.core_data() - cube.data.mean() + return cube +~~~ + +> ## iris cubes +> +> Iris reads data into data structures called +> [cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). +> The data in these cubes can be modified, combined with other cubes' data or +> plotted. +{: .callout} + +> ## Reading data using xarray +> +> Use the [xarrays](http://xarray.pydata.org/en/stable/) to read the data +> instead of iris. +> +>> ## Answer +>> +>> First, import ``xarray`` package at the top of the script as: +>> +>>~~~python +>>import xarray as xr +>>~~~ +>> +>> Then, change the ``compute_diagnostic`` as: +>> +>>~~~python +>>def compute_diagnostic(filename): +>> """Compute an example diagnostic.""" +>> logger.debug("Loading %s", filename) +>> dataset = xr.open_dataset(filename) +>> +>> #do your analyses on the data here +>> +>> return dataset +>>~~~ +>> +> {: .solution} +{: .challenge} + +> ## Reading data using Scipy's netCDF library +> +> Use the [SciPy's netCDF library][netCDF] to read the data instead of iris. +> +>> ## Answer +>> +>> First, import ``netcdfx`` package at the top of the script as: +>> +>>~~~python +>>from scipy.io import netcdfx +>>~~~ +>> +>> Then, change the ``compute_diagnostic`` as: +>> +>>~~~python +>>def compute_diagnostic(filename): +>> """Compute an example diagnostic.""" +>> logger.debug("Loading %s", filename) +>> netcdf_file = netcdf.netcdf_file(filename,'r') +>> +>> #do your analyses on the data here +>> +>> return netcdf_file +>>~~~ +>> +> {: .solution} +{: .challenge} + +## Diagnostic output + +### Plotting the output + +Often, the end product of a diagnostic script is a plot or figure. The Iris cube +returned from the ``compute_diagnostic`` function (line 94) is passed to the +``plot_diagnostic`` function (line 101). Let's have a look at the definition of +this function in line 53 where we would plug in our plotting routine in the +diagnostic script. + +More specifically, the ``quickplot`` function (line 61) can be replaced with the +function of our choice. As can be seen, this function uses +``**cfg['quickplot']`` as an input argument. If you look at the diagnostic +section in the recipe ``recipe_python.yml``, you see ``quickplot`` is a key +there: + +~~~yaml + script1: + script: examples/diagnostic.py + quickplot: + plot_type: pcolormesh + cmap: Reds +~~~ + +In this way, we can further pass arguments for ``quickplot`` such as the type of +plot ``pcolormesh`` and the colormap ``cmap:Reds`` from the recipe to the +diagnostic. + +> ## Passing arguments from the recipe to the diagnostic +> +> Change the type of the plot and its colormap and inspect the output figure. +> +>> ## Answer +>> +>> In the recipe ``recipe_python.yml``, you should change ``plot_type`` and ``cmap``. +>> As an example, we choose ``plot_type: pcolor`` and ``cmap: BuGn``: +>> +>> ~~~yaml +>> script1: +>> script: examples/diagnostic.py +>> quickplot: +>> plot_type: pcolor +>> cmap: BuGn +>>~~~ +>> +>> The plot can be found at *path_to_recipe_output/plots/map/script1/png*. +> {: .solution} +{: .challenge} + +> ## ESMValTool gallery +> +> ESMValTool makes it possible to produce a wide array of such figures as seen +> in the [gallery](https://docs.esmvaltool.org/en/latest/gallery.html). +{: .callout} + +### Saving the output + +In our example, the function ``save_data`` in line 57 is used to save the Iris +cube. The saved files can be found under ``work`` directory in a ``.nc`` format. +There is also the function ``save_figure`` in line 63 to save the plots under +``plot`` directory in a ``.png`` format. Again, you may choose your own method +of saving the output. + +### Recording the provenance + +When developing a diagnostic script, we should make sure that it records the +provenance. To do so, we use the function ``get_provenance_record`` (line 99). +Let's have a look at the definition of this function in line 21 where we +describe the diagnostic data and plot. Using the dictionary ``record``, it is +possible to add custom provenance. Provenance is stored in the *W3C PROV XML* +format and also in an *SVG* file under the ``work`` and ``plot`` directory. For +more information, see [recording provenance][provenance]. + +## Congratulations! + +Now you know the diagnostic script structure and a few functions. There are many +more functions to be used, but these should be enough to get you started! Look +at other recipes and diagnostics for more examples. +{% include links.md %} + +[recipe]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml +[diagnostic]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py +[interface]: https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html +[shared]: https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html +[netCDF]: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html +[provenance]: https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance From 3e7dd5a66a21f082b3b5399a7b2dc0cb6f296625 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 11 Mar 2021 15:57:19 +0100 Subject: [PATCH 568/647] revise the line introducing top-level script --- _episodes/10-diagnostics.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 8df7f12a..857e7d95 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -57,7 +57,8 @@ There are four main sections in the script: - A description i.e. the ``docstring`` (line 1). - Import statements (line 2-16). - Functions that implement our analysis (line 21-101). -- A typical python top-level script (line 102-107). +- A typical python top-level script i.e. ``if __name__ == '__main__'`` (line + 102-107). > ## diagnostic.py > From 24048296f55519c7f019c2cd8ac593008e3685eb Mon Sep 17 00:00:00 2001 From: rswamina Date: Tue, 16 Mar 2021 12:25:21 +0000 Subject: [PATCH 569/647] Minor changes and edits after proof reading --- _episodes/10-diagnostics.md | 115 +++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 857e7d95..021119c1 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -1,7 +1,7 @@ --- title: "Writing your own diagnostic script" -teaching: TBD -exercises: TBD +teaching: 20 +exercises: 30 questions: - "How do I write a new diagnostic in ESMValTool?" @@ -16,13 +16,13 @@ keypoints: with preprocessor output." - "Existing diagnostics can be used as templates and modified to write new diagnostics." -- "Many functions can be imported from ``esmvaltool.diag_scripts.shared`` and +- "Helper functions can be imported from ``esmvaltool.diag_scripts.shared`` and used in your own diagnostic script." --- ## Introduction -The diagnostic script is an important component of ESMValTool where the +The diagnostic script is an important component of ESMValTool and it is where the scientific analysis or performance metric is implemented. With ESMValTool, you can adapt an existing diagnostic or write a new script from scratch. Diagnostics can be written in a number of open source @@ -30,7 +30,7 @@ languages such as Python, R, Julia and NCL but we will focus on understanding and writing Python diagnostics in this lesson. In this lesson, we will explain how to find an existing diagnostic and run it -using ESMValTool installed in a editable/development mode. For a development +using ESMValTool installed in editable/development mode. For a development installation, see the instructions in the lesson [Development and contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}). Also, we will work with the recipe [recipe_python.yml][recipe] and the @@ -38,11 +38,11 @@ diagnostic script [diagnostic.py][diagnostic] called by this recipe that we have seen in the lesson [Running your first recipe]({{ page.root }}{% link _episodes/04-recipe.md %}). -Let's get started. +Let's get started! ## Understanding an existing Python diagnostic -After development installation, a folder called ``ESMValTool`` has been created +After a development mode installation, a folder called ``ESMValTool`` is created in your working directory. This folder contains the source code of the tool. We can find the recipe ``recipe_python.yml`` and the python script ``diagnostic.py`` in these directories: @@ -50,14 +50,14 @@ can find the recipe ``recipe_python.yml`` and the python script - *path_to_ESMValTool/esmvaltool/recipes/examples/recipe_python.yml* - *path_to_ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py* -Let's have look into the codes of the ``diagnostic.py``. +Let's have look at the code in ``diagnostic.py``. For reference, we show the diagnostic code in the dropdown box below. There are four main sections in the script: - A description i.e. the ``docstring`` (line 1). - Import statements (line 2-16). - Functions that implement our analysis (line 21-101). -- A typical python top-level script i.e. ``if __name__ == '__main__'`` (line +- A typical Python top-level script i.e. ``if __name__ == '__main__'`` (line 102-107). > ## diagnostic.py @@ -175,7 +175,7 @@ There are four main sections in the script: > {:.solution} -> ## What is the starting point of the diagnostic? +> ## What is the starting point of a diagnostic? > > 1. Can you spot a function called ``main`` in the code above? > 2. What are its input arguments? @@ -184,11 +184,15 @@ There are four main sections in the script: >> ## Answer >> >> 1. The ``main`` function is defined in line 66 as ``main(cfg)``. ->> 2. The variable ``cfg`` is a Python dictionary holding all the necessary ->> information needed to run the diagnostic script like the location of input ->> data and various settings. In the ``main`` function, we will next parse this ->> ``cfg`` variable and extract information as needed to do our analyses (e.g. in line 69). ->> 3. The ``main`` function called near the very end on line 107. +>> 2. The input argument to this function is the variable ``cfg``, a Python dictionary t +>> hat holds all the necessary +>> information needed to run the diagnostic script such as the location of input +>> data and various settings. We will next parse this ``cfg`` variable +>> in the ``main`` function and extract information as needed +>> to do our analyses (e.g. in line 69). +>> 3. The ``main`` function is called near the very end on line 107. So, it is mentioned +>> twice in our code - once where it is called by the top-level Python script and +>> second where it is defined. > {: .solution} {: .challenge} @@ -211,8 +215,8 @@ The ESMValTool documentation page provides an overview of what is in this file, > ## What information do I need when writing a diagnostic script? > > From the lesson [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}), -> we saw how to change the configurations before running a recipe. -> Let's first set the option ``remove_preproc_dir`` to ``false`` in the configuration file, +> we saw how to change the configuration settings before running a recipe. +> First we set the option ``remove_preproc_dir`` to ``false`` in the configuration file, > then run the recipe ``recipe_python.yml``: > > ~~~bash @@ -232,7 +236,7 @@ The ESMValTool documentation page provides an overview of what is in this file, >> detailed information on your data including project (e.g., CMIP6, CMIP5), >> dataset names (e.g., BCC-ESM1, CanESM2), variable attributes (e.g., >> standard_name, units), preprocessor applied and time range of the data. You ->> can use all of these information in your own diagnostics. +>> can use all of this information in your own diagnostic. > > > > > {: .solution} @@ -240,29 +244,29 @@ The ESMValTool documentation page provides an overview of what is in this file, ## Diagnostic shared functions -Looking at the codes of the ``diagnostic.py``, we see that ``input_data`` is +Looking at the code in ``diagnostic.py``, we see that ``input_data`` is read from the ``cfg`` dictionary (line 69). Now we can group the ``input_data`` according to some criteria such as the model or experiment. To do so, -ESMValTool provides many functions like ``select_metadata`` (line 72), +ESMValTool provides many functions such as ``select_metadata`` (line 72), ``sorted_metadata`` (line 76), and ``group_metadata`` (line 80). As you can see in line 8, these functions are imported from ``esmvaltool.diag_scripts.shared`` -that means these are shared between several diagnostics scripts. A list of +that means these are shared across several diagnostics scripts. A list of available functions and their description can be found in [Shared diagnostic script code][shared]. > ## Extracting information needed for analyses > > We have seen the functions used for selecting, sorting and grouping data in the -> script. What these functions do? +> script. What do these functions do? > >> ## Answer >> >> There is a statement after use of ``select_metadata``, ``sorted_metadata`` >> and ``group_metadata`` that starts with ``logger.info`` (lines 73, 77 and >> 83). These lines print output to the log files. In the previous exercise, we ->> ran the recipe ``recipe_python.yml``. If you looked at the content of the log ->> file ``path_to_recipe_output/run/map/script1/log.txt``, you can see the some ->> information on how each function works, for example: +>> ran the recipe ``recipe_python.yml``. If you look at the log +>> file ``path_to_recipe_output/run/map/script1/log.txt``, you can see the output +>> from each of these functions, for example: >> >>``` >>2021-03-05 13:19:38,184 [34706] INFO diagnostic,83 Example of how to group and @@ -317,16 +321,18 @@ script code][shared]. ## Diagnostic computation -After grouping and selecting data, we can read individual attributes such as the -filename by looping over variables (line 89-93). Following this, we see the use -of the function ``compute_diagnostic`` (line 94). Let's have a look at the -definition of this function in line 43 where the analyses on the data is done. +After grouping and selecting data, we can read individual attributes (such as filename) +of each item. Here we have grouped the input data by ``variables`` +so we loop over the variables (line 89-93). Following this, is a call to the +function ``compute_diagnostic`` (line 94). Let's have a look at the +definition of this function in line 43 where the actual analysis on the data is done. +Note that output from the ESMValCore preprocessor is in the form of NetCDF files. Here, ``compute_diagnostic`` uses [Iris](https://scitools-iris.readthedocs.io/en/latest/index.html) to read data -from a netCDF file and performs an operation ``squeeze`` to remove any dimension +from a netCDF file and performs an operation ``squeeze`` to remove any dimensions of length one. We can adapt this function to add our own analysis. As an -example, here we want to calculate the bias toward the averege of the data as: +example, here we calculate the bias using the average of the data using Iris cubes. ~~~python def compute_diagnostic(filename): @@ -344,7 +350,7 @@ def compute_diagnostic(filename): > ## iris cubes > -> Iris reads data into data structures called +> Iris reads data from NetCDF files into data structures called > [cubes](https://scitools-iris.readthedocs.io/en/latest/userguide/iris_cubes.html). > The data in these cubes can be modified, combined with other cubes' data or > plotted. @@ -352,8 +358,8 @@ def compute_diagnostic(filename): > ## Reading data using xarray > -> Use the [xarrays](http://xarray.pydata.org/en/stable/) to read the data -> instead of iris. +> Alternately, you can use [xarrays](http://xarray.pydata.org/en/stable/) to read the data +> instead of Iris. > >> ## Answer >> @@ -381,17 +387,18 @@ def compute_diagnostic(filename): > ## Reading data using Scipy's netCDF library > -> Use the [SciPy's netCDF library][netCDF] to read the data instead of iris. +> Yet another option to read the NetCDF file data is to use +> the [SciPy's netCDF library][netCDF]. > >> ## Answer >> ->> First, import ``netcdfx`` package at the top of the script as: +>> First, import the ``netcdfx`` package at the top of the script as: >> >>~~~python >>from scipy.io import netcdfx >>~~~ >> ->> Then, change the ``compute_diagnostic`` as: +>> Then, change ``compute_diagnostic`` as: >> >>~~~python >>def compute_diagnostic(filename): @@ -414,7 +421,7 @@ def compute_diagnostic(filename): Often, the end product of a diagnostic script is a plot or figure. The Iris cube returned from the ``compute_diagnostic`` function (line 94) is passed to the ``plot_diagnostic`` function (line 101). Let's have a look at the definition of -this function in line 53 where we would plug in our plotting routine in the +this function in line 53. This is where we would plug in our plotting routine in the diagnostic script. More specifically, the ``quickplot`` function (line 61) can be replaced with the @@ -431,9 +438,9 @@ there: cmap: Reds ~~~ -In this way, we can further pass arguments for ``quickplot`` such as the type of -plot ``pcolormesh`` and the colormap ``cmap:Reds`` from the recipe to the -diagnostic. +This way, we can pass arguments such as the type of +plot ``pcolormesh`` and the colormap ``cmap:Reds`` from the recipe to the +``quickplot`` function in the diagnostic. > ## Passing arguments from the recipe to the diagnostic > @@ -441,7 +448,7 @@ diagnostic. > >> ## Answer >> ->> In the recipe ``recipe_python.yml``, you should change ``plot_type`` and ``cmap``. +>> In the recipe ``recipe_python.yml``, you could change ``plot_type`` and ``cmap``. >> As an example, we choose ``plot_type: pcolor`` and ``cmap: BuGn``: >> >> ~~~yaml @@ -458,33 +465,35 @@ diagnostic. > ## ESMValTool gallery > -> ESMValTool makes it possible to produce a wide array of such figures as seen +> ESMValTool makes it possible to produce a wide array of plots and figures as seen > in the [gallery](https://docs.esmvaltool.org/en/latest/gallery.html). {: .callout} ### Saving the output In our example, the function ``save_data`` in line 57 is used to save the Iris -cube. The saved files can be found under ``work`` directory in a ``.nc`` format. -There is also the function ``save_figure`` in line 63 to save the plots under -``plot`` directory in a ``.png`` format. Again, you may choose your own method -of saving the output. +cube. The saved files can be found under the ``work`` directory in a ``.nc`` format. +There is also the function ``save_figure`` in line 63 to save the plots under the +``plot`` directory in a ``.png`` format (or preferred format specified in your +configuration settings). Again, you may choose your own method +of saving the output. ### Recording the provenance -When developing a diagnostic script, we should make sure that it records the +When developing a diagnostic script, it is good practice to record provenance. To do so, we use the function ``get_provenance_record`` (line 99). -Let's have a look at the definition of this function in line 21 where we +Let us have a look at the definition of this function in line 21 where we describe the diagnostic data and plot. Using the dictionary ``record``, it is -possible to add custom provenance. Provenance is stored in the *W3C PROV XML* +possible to add custom provenance to our diagnostics output. +Provenance is stored in the *W3C PROV XML* format and also in an *SVG* file under the ``work`` and ``plot`` directory. For more information, see [recording provenance][provenance]. ## Congratulations! -Now you know the diagnostic script structure and a few functions. There are many -more functions to be used, but these should be enough to get you started! Look -at other recipes and diagnostics for more examples. +You now know the basic diagnostic script structure and some available tools for putting +together your own diagnostics. Have a look at existing recipes and diagnostics in the +repository for more examples of functions you can use in your diagnostics! {% include links.md %} [recipe]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml From 0c2dca493c9a512c689598f5c6e7efeaff2a5498 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Wed, 17 Mar 2021 14:00:38 +0000 Subject: [PATCH 570/647] Update _episodes/02-installation.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/02-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 4c53aee9..17111eb0 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -33,7 +33,7 @@ that the installation was successful. > > 1) If you have access to a server where ESMValTool is already installed > as a module, for e.g., the ``CEDA JASMIN`` server, you can simply -> load the module and start using ESMValTool with the following : +> load the module with the following: > ```bash > module load esmvaltool > ``` From bd0f5c22111b2614f05b6d09ae17ffbeb2a0bf1c Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Wed, 17 Mar 2021 14:02:51 +0000 Subject: [PATCH 571/647] Update _episodes/02-installation.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/02-installation.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 17111eb0..009d146c 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -40,10 +40,6 @@ that the installation was successful. > 2) If you would like to install ESMValTool as a conda package, then this lesson > will tell you how! > -> 3) If you are already familiar with ESMValTool and would like to start experimenting -> with existing diagnostics, you can dowload the source code from the ESMvalTool Github -> page, compile and run as given here (link missing). -> > 4) If you would like to start contributing to ESMvalTool, please see the instructions for > source installation in the lesson [Development and > contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}) and From 21406ac6612f79178fe5ee92317c553863a4cc74 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Wed, 17 Mar 2021 14:03:11 +0000 Subject: [PATCH 572/647] Update _episodes/02-installation.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/02-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 009d146c..82d7b220 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -40,7 +40,7 @@ that the installation was successful. > 2) If you would like to install ESMValTool as a conda package, then this lesson > will tell you how! > -> 4) If you would like to start contributing to ESMvalTool, please see the instructions for +> 3) If you would like to start experimenting with existing diagnostics or contributing to ESMvalTool, please see the instructions for > source installation in the lesson [Development and > contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}) and > in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). From 6d332a72bdbfa45d6f9cfe449d4f947c62d4b06a Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Wed, 17 Mar 2021 14:03:54 +0000 Subject: [PATCH 573/647] Update _episodes/02-installation.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/02-installation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 82d7b220..b9699c21 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -37,6 +37,8 @@ that the installation was successful. > ```bash > module load esmvaltool > ``` + +After loading ``esmvaltool``, we can start using ESMValTool. Please see the [next lesson]({{ page.root }}{% link _episodes/03-configuration.md %}). > 2) If you would like to install ESMValTool as a conda package, then this lesson > will tell you how! > From a21611ce9f4cd739c6f633c09d01472bedf9b64b Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 19 Mar 2021 10:45:41 +0000 Subject: [PATCH 574/647] added link to the CEDA JASMIN module load page --- _episodes/02-installation.md | 39 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index b9699c21..5371ef8a 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -26,27 +26,28 @@ We will first install Conda, and then ESMValTool. We end this chapter by testing that the installation was successful. -> ## ESMValTool Installation/Usage Options - A quick summary -> Before we begin, here are all the possible ways in which you can use ESMValTool -> depending on your level of expertise or involvement with ESMvalTool and -> associated software such as GitHub and Conda. -> -> 1) If you have access to a server where ESMValTool is already installed -> as a module, for e.g., the ``CEDA JASMIN`` server, you can simply -> load the module with the following: -> ```bash -> module load esmvaltool -> ``` +## ESMValTool Installation/Usage Options - A quick summary + Before we begin, here are all the possible ways in which you can use ESMValTool + depending on your level of expertise or involvement with ESMvalTool and + associated software such as GitHub and Conda. + + 1) If you have access to a server where ESMValTool is already installed + as a module, for e.g., the [CEDA JASMIN](https://help.jasmin.ac.uk/article/4955-community-software-esmvaltool) +server, you can simply load the module with the following: + ```bash + module load esmvaltool + ``` After loading ``esmvaltool``, we can start using ESMValTool. Please see the [next lesson]({{ page.root }}{% link _episodes/03-configuration.md %}). -> 2) If you would like to install ESMValTool as a conda package, then this lesson -> will tell you how! -> -> 3) If you would like to start experimenting with existing diagnostics or contributing to ESMvalTool, please see the instructions for -> source installation in the lesson [Development and -> contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}) and -> in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). -{: .solution} + +2) If you would like to install ESMValTool as a conda package, then this lesson + will tell you how! + + 3) If you would like to start experimenting with existing diagnostics or contributing to ESMvalTool, please see the instructions for + source installation in the lesson [Development and + contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}) and + in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). + > ## Install ESMValTool on Windows > From 12f6cc3b319dd4b4fdd3dbbe0af0ee95af5421f2 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 19 Mar 2021 10:50:56 +0000 Subject: [PATCH 575/647] Update _episodes/04-recipe.md Co-authored-by: Peter Kalverla --- _episodes/04-recipe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 1438fc18..51c04cc4 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -29,7 +29,7 @@ recipes that are shipped with ESMValTool, type esmvaltool recipes list ``` -We will start by running [examples/recipe_python.yml](https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/recipes/examples/recipe_python.yml) +We will start by running [examples/recipe_python.yml](https://docs.esmvaltool.org/en/latest/recipes/recipe_examples.html) ``` esmvaltool run examples/recipe_python.yml From 98c7a98d02c6c6cfc28accad1ff84889d6acc59f Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 19 Mar 2021 10:54:40 +0000 Subject: [PATCH 576/647] Update _episodes/10-diagnostics.md Co-authored-by: Niels Drost --- _episodes/10-diagnostics.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index 021119c1..a5c6e4a8 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -251,8 +251,7 @@ ESMValTool provides many functions such as ``select_metadata`` (line 72), ``sorted_metadata`` (line 76), and ``group_metadata`` (line 80). As you can see in line 8, these functions are imported from ``esmvaltool.diag_scripts.shared`` that means these are shared across several diagnostics scripts. A list of -available functions and their description can be found in [Shared diagnostic -script code][shared]. +available functions and their description can be found in [The ESMValTool Diagnostic API reference][shared]. > ## Extracting information needed for analyses > From a4c9810d40a69ca234f27050fd156dd60bef8047 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 19 Mar 2021 10:57:19 +0000 Subject: [PATCH 577/647] Update _episodes/10-diagnostics.md Co-authored-by: Niels Drost --- _episodes/10-diagnostics.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index a5c6e4a8..71f930b2 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -184,8 +184,8 @@ There are four main sections in the script: >> ## Answer >> >> 1. The ``main`` function is defined in line 66 as ``main(cfg)``. ->> 2. The input argument to this function is the variable ``cfg``, a Python dictionary t ->> hat holds all the necessary +>> 2. The input argument to this function is the variable ``cfg``, a Python dictionary +>> that holds all the necessary >> information needed to run the diagnostic script such as the location of input >> data and various settings. We will next parse this ``cfg`` variable >> in the ``main`` function and extract information as needed From fc8d7009e6e097dff6ba193374c71bd1c8ffc6a6 Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 19 Mar 2021 12:00:59 +0000 Subject: [PATCH 578/647] changes to reading netcdf files using the latest netCDF4 package instead of the older Scipy library --- _episodes/10-diagnostics.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index c7dd0821..d4fc5e90 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -385,17 +385,17 @@ def compute_diagnostic(filename): > {: .solution} {: .challenge} -> ## Reading data using Scipy's netCDF library +> ## Reading data using the netCDF4 package > > Yet another option to read the NetCDF file data is to use -> the [SciPy's netCDF library][netCDF]. +> the [netCDF-4 Python interface](https://unidata.github.io/netcdf4-python/) to the netCDF C library. > >> ## Answer >> ->> First, import the ``netcdfx`` package at the top of the script as: +>> First, import the ``netCDF4`` package at the top of the script as: >> >>~~~python ->>from scipy.io import netcdfx +>>import netCDF4 >>~~~ >> >> Then, change ``compute_diagnostic`` as: @@ -404,7 +404,7 @@ def compute_diagnostic(filename): >>def compute_diagnostic(filename): >> """Compute an example diagnostic.""" >> logger.debug("Loading %s", filename) ->> netcdf_file = netcdf.netcdf_file(filename,'r') +>> nc_data = netCDF4.Dataset(filename,'r') >> >> #do your analyses on the data here >> From d3bc8d47ad04d0543eb65747fd09da5aaced9779 Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 19 Mar 2021 12:07:26 +0000 Subject: [PATCH 579/647] added the link to netCDF4 documentation at the bottom of the page as is the style of the document --- _episodes/10-diagnostics.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/10-diagnostics.md b/_episodes/10-diagnostics.md index d4fc5e90..e10964ca 100644 --- a/_episodes/10-diagnostics.md +++ b/_episodes/10-diagnostics.md @@ -388,7 +388,7 @@ def compute_diagnostic(filename): > ## Reading data using the netCDF4 package > > Yet another option to read the NetCDF file data is to use -> the [netCDF-4 Python interface](https://unidata.github.io/netcdf4-python/) to the netCDF C library. +> the [netCDF-4 Python interface][netCDF] to the netCDF C library. > >> ## Answer >> @@ -500,5 +500,5 @@ repository for more examples of functions you can use in your diagnostics! [diagnostic]: https://github.com/ESMValGroup/ESMValTool/blob/master/esmvaltool/diag_scripts/examples/diagnostic.py [interface]: https://docs.esmvaltool.org/projects/esmvalcore/en/latest/interfaces.html [shared]: https://docs.esmvaltool.org/en/latest/api/esmvaltool.diag_scripts.shared.html -[netCDF]: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.io.netcdf.netcdf_file.html +[netCDF]: https://unidata.github.io/netcdf4-python/ [provenance]: https://docs.esmvaltool.org/en/latest/community/diagnostic.html?highlight=provenance#recording-provenance From f19eb46c6f85a20306579011a3ae5cc1762fa76e Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 23 Mar 2021 17:51:30 +0100 Subject: [PATCH 580/647] fix episodes links --- _episodes/08-development-setup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index aadddd50..5274e3bf 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -25,9 +25,9 @@ ESMValTool is an open-source project in ESMValGroup. We can contribute to its de - a new or updated recipe script, see lesson on [Writing your own recipe]({{ page.root }}{% link _episodes/05-preprocessor.md %}) - a new or updated diagnostics script, see lesson on -[Writing your own diagnostic script] +[Writing your own diagnostic script]({{ page.root }}{% link _episodes/10-diagnostics.md %}) - a new or updated cmorizer script, see lesson on -[CMORization: Using observational datasets] +[CMORization: Using observational datasets]({{ page.root }}{% link _episodes/09-cmorization.md %}) - helping with reviewing process of pull requests, see ESMValTool documentation on [Review of pull requests](https://docs.esmvaltool.org/en/latest/community/review.html) @@ -359,7 +359,7 @@ when you submit a pull request. >> ~~~ >> >> For details, see lesson ->> [Writing your own diagnostic script](#). +>> [Writing your own diagnostic script]({{ page.root }}{% link _episodes/10-diagnostics.md %}). >> > {: .solution} {: .challenge} From e4bdb25bf5344a87aeecc65865e2612e14dedfa7 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 23 Mar 2021 17:54:23 +0100 Subject: [PATCH 581/647] add download option to get the source code --- _episodes/08-development-setup.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 5274e3bf..1a0dce5d 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -53,7 +53,10 @@ Let’s get started. The ESMValTool source code is available on a public GitHub repository: [https://github.com/ESMValGroup/ESMValTool](https://github.com/ESMValGroup/ESMValTool). -To obtain the code, the easiest way is to clone the repository: +To obtain the code, there are two options: + +1. download the code as a ZIP file from the repository. +2. clone the repository if you want to contribute to the ESMValTool development: ~~~bash git clone https://github.com/ESMValGroup/ESMValTool.git From 49a6c58fe46946ee974faefea82842df7151bc25 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Wed, 24 Mar 2021 13:15:06 +0000 Subject: [PATCH 582/647] Update _episodes/02-installation.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/02-installation.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 5371ef8a..4399d5f7 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -25,8 +25,6 @@ be found in the We will first install Conda, and then ESMValTool. We end this chapter by testing that the installation was successful. - -## ESMValTool Installation/Usage Options - A quick summary Before we begin, here are all the possible ways in which you can use ESMValTool depending on your level of expertise or involvement with ESMvalTool and associated software such as GitHub and Conda. From 56383b44964993de2529bcbd8175be17af439af1 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Wed, 24 Mar 2021 13:15:17 +0000 Subject: [PATCH 583/647] Update _episodes/02-installation.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/02-installation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 4399d5f7..23813ec8 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -25,9 +25,9 @@ be found in the We will first install Conda, and then ESMValTool. We end this chapter by testing that the installation was successful. - Before we begin, here are all the possible ways in which you can use ESMValTool - depending on your level of expertise or involvement with ESMvalTool and - associated software such as GitHub and Conda. +Before we begin, here are all the possible ways in which you can use ESMValTool +depending on your level of expertise or involvement with ESMvalTool and +associated software such as GitHub and Conda. 1) If you have access to a server where ESMValTool is already installed as a module, for e.g., the [CEDA JASMIN](https://help.jasmin.ac.uk/article/4955-community-software-esmvaltool) From b0e8c3d0dc2794ac3f504496ce51f588e807008e Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Wed, 24 Mar 2021 13:15:24 +0000 Subject: [PATCH 584/647] Update _episodes/02-installation.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/02-installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 23813ec8..49d2a06e 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -29,8 +29,8 @@ Before we begin, here are all the possible ways in which you can use ESMValTool depending on your level of expertise or involvement with ESMvalTool and associated software such as GitHub and Conda. - 1) If you have access to a server where ESMValTool is already installed - as a module, for e.g., the [CEDA JASMIN](https://help.jasmin.ac.uk/article/4955-community-software-esmvaltool) +1. If you have access to a server where ESMValTool is already installed +as a module, for e.g., the [CEDA JASMIN](https://help.jasmin.ac.uk/article/4955-community-software-esmvaltool) server, you can simply load the module with the following: ```bash module load esmvaltool From b7e517750941311ab3bfce0b6b3cf40921e23cf3 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Wed, 24 Mar 2021 13:15:37 +0000 Subject: [PATCH 585/647] Update _episodes/02-installation.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/02-installation.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 49d2a06e..ed8d7d44 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -32,12 +32,10 @@ associated software such as GitHub and Conda. 1. If you have access to a server where ESMValTool is already installed as a module, for e.g., the [CEDA JASMIN](https://help.jasmin.ac.uk/article/4955-community-software-esmvaltool) server, you can simply load the module with the following: - ```bash - module load esmvaltool - ``` - +~~~bash +module load esmvaltool +~~~ After loading ``esmvaltool``, we can start using ESMValTool. Please see the [next lesson]({{ page.root }}{% link _episodes/03-configuration.md %}). - 2) If you would like to install ESMValTool as a conda package, then this lesson will tell you how! From e927807b0e665a6d1a9fcd4d75bbef8c744b5c91 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Wed, 24 Mar 2021 13:15:45 +0000 Subject: [PATCH 586/647] Update _episodes/02-installation.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/02-installation.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index ed8d7d44..890fe939 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -36,14 +36,12 @@ server, you can simply load the module with the following: module load esmvaltool ~~~ After loading ``esmvaltool``, we can start using ESMValTool. Please see the [next lesson]({{ page.root }}{% link _episodes/03-configuration.md %}). -2) If you would like to install ESMValTool as a conda package, then this lesson - will tell you how! - - 3) If you would like to start experimenting with existing diagnostics or contributing to ESMvalTool, please see the instructions for - source installation in the lesson [Development and - contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}) and - in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). - +2. If you would like to install ESMValTool as a conda package, then this lesson +will tell you how! +3. If you would like to start experimenting with existing diagnostics or contributing to ESMvalTool, please see the instructions for +source installation in the lesson [Development and +contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}) and +in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). > ## Install ESMValTool on Windows > From 67bc2d72d792efc02c1658d872239765c20d560b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Mar 2021 16:39:22 +0100 Subject: [PATCH 587/647] revise donwload option --- _episodes/08-development-setup.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 1a0dce5d..09f0e441 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -31,9 +31,8 @@ ESMValTool is an open-source project in ESMValGroup. We can contribute to its de - helping with reviewing process of pull requests, see ESMValTool documentation on [Review of pull requests](https://docs.esmvaltool.org/en/latest/community/review.html) -In this lesson, we first show how to set up a development installation of ESMValTool. So, you can -make modifications. Then, we explain the process of how to contribute your changes or additions -to the community. +In this lesson, we first show how to set up a development installation of ESMValTool so you can +make changes or additions. We then explain how you can contribute these changes to the community. > ## Git knowledge > @@ -55,7 +54,10 @@ The ESMValTool source code is available on a public GitHub repository: [https://github.com/ESMValGroup/ESMValTool](https://github.com/ESMValGroup/ESMValTool). To obtain the code, there are two options: -1. download the code as a ZIP file from the repository. +1. download the code from the repository. A ZIP file called + ``ESMValTool-master.zip`` is downloaded. To continue the installation, unzip + the file, move to the ``ESMValTool-master`` directory and then follow step + **2 ESMValTool dependencies**. 2. clone the repository if you want to contribute to the ESMValTool development: ~~~bash From eae8f0863bd30878dc67e79fae8a1a6fc2633a90 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 24 Mar 2021 17:48:06 +0100 Subject: [PATCH 588/647] add new section updating esmvaltool --- _episodes/08-development-setup.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 09f0e441..8fd386b9 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -176,6 +176,14 @@ If the installation is successful, ESMValTool prints a help message to the conso > {: .solution} {: .challenge} +### 4 Updating ESMValTool + +The ``master`` branch has the latest features of ESMValTool. Please make sure +that the source code on your machine is up-to-date. If you obtain the source +code using git clone as explained in step **1 Source code**, you can run ``git pull`` +to update the source code. Then ESMValTool installation will be updated +with changes from the ``master`` branch. + ## Contribution We have seen how to install ESMValTool in a ``develop`` mode. From babd1729ee309574ef222a314bf465dbcbbfeb3e Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 25 Mar 2021 15:43:46 +0100 Subject: [PATCH 589/647] re-phrase the sentence as Ranjini suggested --- _episodes/08-development-setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/08-development-setup.md b/_episodes/08-development-setup.md index 8fd386b9..ea16a946 100644 --- a/_episodes/08-development-setup.md +++ b/_episodes/08-development-setup.md @@ -56,8 +56,8 @@ To obtain the code, there are two options: 1. download the code from the repository. A ZIP file called ``ESMValTool-master.zip`` is downloaded. To continue the installation, unzip - the file, move to the ``ESMValTool-master`` directory and then follow step - **2 ESMValTool dependencies**. + the file, move to the ``ESMValTool-master`` directory and then follow the + sequence of steps starting from **2 ESMValTool dependencies**. 2. clone the repository if you want to contribute to the ESMValTool development: ~~~bash From 54fa2fe05220cc518cd951429b56d132d4f1f285 Mon Sep 17 00:00:00 2001 From: rswamina Date: Wed, 31 Mar 2021 13:55:38 +0100 Subject: [PATCH 590/647] renamed episode file names to reflect changes in order --- _episodes/{07-conclusions.md => 05-conclusions.md} | 0 _episodes/{05-preprocessor.md => 06-preprocessor.md} | 0 _episodes/{08-development-setup.md => 07-development-setup.md} | 0 _episodes/{10-diagnostics.md => 08-diagnostics.md} | 0 _episodes/{06-debugging.md => 10-debugging.md} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename _episodes/{07-conclusions.md => 05-conclusions.md} (100%) rename _episodes/{05-preprocessor.md => 06-preprocessor.md} (100%) rename _episodes/{08-development-setup.md => 07-development-setup.md} (100%) rename _episodes/{10-diagnostics.md => 08-diagnostics.md} (100%) rename _episodes/{06-debugging.md => 10-debugging.md} (100%) diff --git a/_episodes/07-conclusions.md b/_episodes/05-conclusions.md similarity index 100% rename from _episodes/07-conclusions.md rename to _episodes/05-conclusions.md diff --git a/_episodes/05-preprocessor.md b/_episodes/06-preprocessor.md similarity index 100% rename from _episodes/05-preprocessor.md rename to _episodes/06-preprocessor.md diff --git a/_episodes/08-development-setup.md b/_episodes/07-development-setup.md similarity index 100% rename from _episodes/08-development-setup.md rename to _episodes/07-development-setup.md diff --git a/_episodes/10-diagnostics.md b/_episodes/08-diagnostics.md similarity index 100% rename from _episodes/10-diagnostics.md rename to _episodes/08-diagnostics.md diff --git a/_episodes/06-debugging.md b/_episodes/10-debugging.md similarity index 100% rename from _episodes/06-debugging.md rename to _episodes/10-debugging.md From 34960fd1487dfd23195fb5d81bdcf1a528c226ee Mon Sep 17 00:00:00 2001 From: rswamina Date: Wed, 31 Mar 2021 14:19:28 +0100 Subject: [PATCH 591/647] changed references to episode files since the episode file names are now altered --- _episodes/02-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 890fe939..088353c3 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -40,7 +40,7 @@ After loading ``esmvaltool``, we can start using ESMValTool. Please see the [nex will tell you how! 3. If you would like to start experimenting with existing diagnostics or contributing to ESMvalTool, please see the instructions for source installation in the lesson [Development and -contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}) and +contribution]({{ page.root }}{% link _episodes/07-development-setup.md %}) and in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). > ## Install ESMValTool on Windows From 850f9d75e680fb26dc6bb7ede138b883c89dbc44 Mon Sep 17 00:00:00 2001 From: rswamina Date: Wed, 31 Mar 2021 14:19:43 +0100 Subject: [PATCH 592/647] changed references to episode files since the episode file names are now altered --- _episodes/07-development-setup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_episodes/07-development-setup.md b/_episodes/07-development-setup.md index ea16a946..9be8a8b7 100644 --- a/_episodes/07-development-setup.md +++ b/_episodes/07-development-setup.md @@ -23,9 +23,9 @@ We now know how ESMValTool works, but how do we develop it? ESMValTool is an open-source project in ESMValGroup. We can contribute to its development by: - a new or updated recipe script, see lesson on -[Writing your own recipe]({{ page.root }}{% link _episodes/05-preprocessor.md %}) +[Writing your own recipe]({{ page.root }}{% link _episodes/06-preprocessor.md %}) - a new or updated diagnostics script, see lesson on -[Writing your own diagnostic script]({{ page.root }}{% link _episodes/10-diagnostics.md %}) +[Writing your own diagnostic script]({{ page.root }}{% link _episodes/08-diagnostics.md %}) - a new or updated cmorizer script, see lesson on [CMORization: Using observational datasets]({{ page.root }}{% link _episodes/09-cmorization.md %}) - helping with reviewing process of pull requests, see ESMValTool documentation on @@ -214,7 +214,7 @@ Reviewing small incremental changes are more efficient. ### Background We saw 'warming stripes' in lesson -[Writing your own recipe]({{ page.root }}{% link _episodes/05-preprocessor.md %}). +[Writing your own recipe]({{ page.root }}{% link _episodes/06-preprocessor.md %}). Imagine the following task: you want to contribute warming stripes recipe and diagnostics to ESMValTool. You have to add the diagnostics [warming_stripes.py](../files/warming_stripes.py) and the recipe @@ -372,7 +372,7 @@ when you submit a pull request. >> ~~~ >> >> For details, see lesson ->> [Writing your own diagnostic script]({{ page.root }}{% link _episodes/10-diagnostics.md %}). +>> [Writing your own diagnostic script]({{ page.root }}{% link _episodes/08-diagnostics.md %}). >> > {: .solution} {: .challenge} From a5132ca521f24e6ed064d658542f82927f60d636 Mon Sep 17 00:00:00 2001 From: rswamina Date: Wed, 31 Mar 2021 14:19:55 +0100 Subject: [PATCH 593/647] changed references to episode files since the episode file names are now altered --- _episodes/08-diagnostics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/08-diagnostics.md b/_episodes/08-diagnostics.md index e10964ca..6b433cde 100644 --- a/_episodes/08-diagnostics.md +++ b/_episodes/08-diagnostics.md @@ -32,7 +32,7 @@ and writing Python diagnostics in this lesson. In this lesson, we will explain how to find an existing diagnostic and run it using ESMValTool installed in editable/development mode. For a development installation, see the instructions in the lesson [Development and -contribution]({{ page.root }}{% link _episodes/08-development-setup.md %}). +contribution]({{ page.root }}{% link _episodes/07-development-setup.md %}). Also, we will work with the recipe [recipe_python.yml][recipe] and the diagnostic script [diagnostic.py][diagnostic] called by this recipe that we have seen in the lesson [Running your first recipe]({{ page.root }}{% link From d887461d28b73d90a5e56661cafafa20de0acf99 Mon Sep 17 00:00:00 2001 From: rswamina Date: Thu, 8 Apr 2021 11:56:43 +0100 Subject: [PATCH 594/647] modifications to reflect changed chapter orders --- _episodes/06-preprocessor.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_episodes/06-preprocessor.md b/_episodes/06-preprocessor.md index 64e9c261..f5f6fef8 100644 --- a/_episodes/06-preprocessor.md +++ b/_episodes/06-preprocessor.md @@ -46,8 +46,8 @@ preprocessing, and then runs our Python script. > ## Drawing up a plan > -> In the previous episode, we have seen that ESMValTool executed a number of -> tasks. Write down which tasks we will need to do in this episode. And what does +> Previously, we have seen that ESMValTool executed a number of +> tasks. Write down which tasks we will need to do in this episode. And what do > each of these tasks do? > > > ## Answer @@ -172,7 +172,7 @@ INFO Run was successful ## Adding a dataset entry Let's add a datasets section. We will reuse the same datasets that we used in -the previous episode. The data files are stored in `~/esmvaltool_tutorial/data`. +previous episodes. The data files are stored in `~/esmvaltool_tutorial/data`. > ## Filling in the dataset keys > From 6ff51b2e8784fcc870ed9854fbd5404d2c64cf38 Mon Sep 17 00:00:00 2001 From: rswamina Date: Thu, 8 Apr 2021 11:56:58 +0100 Subject: [PATCH 595/647] modifications to reflect changed chapter orders --- _episodes/09-cmorization.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 6e8f0a23..228ba4d0 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -60,7 +60,7 @@ that contains observations of the Gross Primary Production (GPP), a variable that is important for calculating components of the global carbon cycle. We will assume that you are using a development installation of ESMValTool as -explained in the [previous episode](/08-development-setup). +explained in the [Development and Contribution episode](/07-development-setup). ## Obtaining the data @@ -224,7 +224,7 @@ CMORized, ESMValTool will give a warning or error. > > > > ``` > > -> > To learn more about writing a recipe, please refer to [Writing your own recipe](/05-preprocessor). +> > To learn more about writing a recipe, please refer to [Writing your own recipe](/06-preprocessor). > > > {: .solution} {: .challenge} @@ -745,8 +745,8 @@ utils.set_global_atts(cube, attributes) - **Make a pull request**. Since you have gone through all the trouble to reformat the dataset so that the ESMValTool can work with it, it would be great if you could provide the CMORizer, and ultimately with that the dataset, - to the rest of the community. For more information, see the previous episode - on [Contributing to ESMValTool](/08-development-setup). + to the rest of the community. For more information, see the episode + on [Development and contribution](/07-development-setup). - **Add documentation**. Make sure that you have added the info of your dataset to the User Guide so that people know it is available for the ESMValTool From 888526a1bbd7f7626acf2a325315171ae9488230 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 18 Jun 2021 17:07:05 +0200 Subject: [PATCH 596/647] add discussion to conclusion and home page --- _episodes/05-conclusions.md | 4 ++++ index.md | 1 + 2 files changed, 5 insertions(+) diff --git a/_episodes/05-conclusions.md b/_episodes/05-conclusions.md index b1f6183f..7dbaa363 100644 --- a/_episodes/05-conclusions.md +++ b/_episodes/05-conclusions.md @@ -69,6 +69,10 @@ to be suitable for use by ESMValTool. There are lots of resources available for helping you use ESMValTool. +ESMValTool [Discussions page](https://github.com/ESMValGroup/ESMValTool/discussions). +is a good place to learn about general issues, or to see if your question has been already addressed. +If you have a GitHub account, you can also post your questions on the page. + If you get stuck, a great starting point is to create a [new issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose). diff --git a/index.md b/index.md index 565112d7..0a96806f 100644 --- a/index.md +++ b/index.md @@ -63,6 +63,7 @@ independently. > > - [Documentation](https://docs.esmvaltool.org) > - [ESMValTool home page](https://www.esmvaltool.org/) +> - [Discussions page](https://github.com/ESMValGroup/ESMValTool/discussions) > - [Papers](https://www.esmvaltool.org/references.html) > - [ESMValTool Source code](https://github.com/ESMValGroup/ESMValTool) > - [ESMValCore Source code](https://github.com/ESMValGroup/ESMValCore) From 5c962d51b711502a69b23e9c31646e63242532f8 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Tue, 22 Jun 2021 19:50:30 +0200 Subject: [PATCH 597/647] Harmless change to trigger pages build (#208) Needed since the gh pages branch was renamed from master to main --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1cc8bc66..aa0d7377 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ Maintainers will do their best to help you if you have any questions, concerns, or experience any difficulties along the way. -If you work or study in climate-related domains and would be interested in -getting involved, you can reach us by email. +If you work or study in climate-related domains and would be interested +in getting involved, you can reach us by email. Please see [information][contact-info] on how to subscribe to user mailing list. ## Citation From 0a6aeea343d80cb1738a153567938c4e66593141 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 8 Jul 2021 09:18:26 +0200 Subject: [PATCH 598/647] Change link in tutorial from master to main Because master branch was recently renamed to main. See @209 --- setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.md b/setup.md index a992203e..4c5a2076 100644 --- a/setup.md +++ b/setup.md @@ -240,7 +240,7 @@ To download the data required by this tutorial, run the following command using ~~~shell wget --no-clobber --input-file \ - https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls \ + https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/main/data/dataset.urls \ --directory-prefix $HOME/esmvaltool_tutorial/data/ ~~~ @@ -281,4 +281,4 @@ ESMValTool development team. [cmip5-search]: https://esgf-data.dkrz.de/search/cmip5-dkrz/ [theatoga.nc]: http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc -[ds]: https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls \ No newline at end of file +[ds]: https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls From c0112452867ec7bf548060d8181417e98534d28c Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 8 Jul 2021 09:24:25 +0200 Subject: [PATCH 599/647] more links --- CODE_OF_CONDUCT.md | 2 +- setup.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index e160a917..37b6ff3f 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,4 +2,4 @@ As contributors and maintainers of this tutorial, we pledge to follow the ESMValTool -[Code of Conduct](https://github.com/ESMValGroup/ESMValTool/blob/master/CODE_OF_CONDUCT.md). +[Code of Conduct](https://github.com/ESMValGroup/ESMValTool/blob/main/CODE_OF_CONDUCT.md). diff --git a/setup.md b/setup.md index 4c5a2076..d7978631 100644 --- a/setup.md +++ b/setup.md @@ -281,4 +281,4 @@ ESMValTool development team. [cmip5-search]: https://esgf-data.dkrz.de/search/cmip5-dkrz/ [theatoga.nc]: http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc -[ds]: https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/master/data/dataset.urls +[ds]: https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/main/data/dataset.urls From 2123409645a0e718c9359712638f053cde5eab47 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Fri, 9 Jul 2021 09:31:14 +0200 Subject: [PATCH 600/647] raw to blob --- setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.md b/setup.md index d7978631..f054c28e 100644 --- a/setup.md +++ b/setup.md @@ -281,4 +281,4 @@ ESMValTool development team. [cmip5-search]: https://esgf-data.dkrz.de/search/cmip5-dkrz/ [theatoga.nc]: http://esgf-data1.ceda.ac.uk/thredds/fileServer/esg_dataroot/cmip5/output1/MOHC/HadGEM2-ES/historical/mon/ocean/Omon/r1i1p1/v20110916/thetaoga/thetaoga_Omon_HadGEM2-ES_historical_r1i1p1_185912-200512.nc -[ds]: https://github.com/ESMValGroup/ESMValTool_Tutorial/raw/main/data/dataset.urls +[ds]: https://github.com/ESMValGroup/ESMValTool_Tutorial/blob/main/data/dataset.urls From c163923f6c8a45600bedd2358dd6b77d3cac9612 Mon Sep 17 00:00:00 2001 From: Emma Hogan Date: Fri, 3 Sep 2021 08:32:24 +0100 Subject: [PATCH 601/647] #210: Add how to add an author to ESMValTool --- _episodes/06-preprocessor.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/_episodes/06-preprocessor.md b/_episodes/06-preprocessor.md index f5f6fef8..b514f5de 100644 --- a/_episodes/06-preprocessor.md +++ b/_episodes/06-preprocessor.md @@ -156,8 +156,14 @@ ValueError: Tag 'doe_john' does not exist in section 'authors' of /home/user/min > ## Pro tip: config-references.yml > -> The error message above points to a file named `config-references.yml`. This -> is where ESMValTool stores all its citation information. +> The error message above points to a file named +> [config-references.yml](https://github.com/ESMValGroup/ESMValTool/blob/main/esmvaltool/config-references.yml). +> This is where ESMValTool stores all its citation information. To add yourself +> as an author, add your name in the form `lastname_firstname` in alphabetical +> order following the existing entries, under the `# Development team` comment. +> See the +> [List of authors](https://docs.esmvaltool.org/en/latest/community/code_documentation.html#list-of-authors) +> section in the ESMValTool documentation for more information. {: .callout} For now, let's just use one of the existing references. Change the author field to From 7743ff9d024d119787f5247edfb6fa0f37b6c528 Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 13:39:24 +0000 Subject: [PATCH 602/647] started fixing GA tests --- .github/workflows/recipes.yml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 8cf81092..28119907 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -3,10 +3,12 @@ name: Test recipes on: push: pull_request: + schedule: + - cron: '0 4 * * *' jobs: build: - runs-on: ubuntu-20.04 + runs-on: "ubuntu-latest" steps: - uses: actions/checkout@v2 - name: Cache conda @@ -19,13 +21,19 @@ jobs: key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('files/recipe_example.yml') }} - uses: conda-incubator/setup-miniconda@v2 with: - python-version: "3.8" + python-version: "3.9" miniconda-version: "latest" - - name: Install esmvaltool - run: conda install -n test -y -c esmvalgroup -c conda-forge esmvaltool-python + channels: conda-forge + - name: Install mamba + shell: bash -l {0} + run: conda install mamba + - name: Install esmvaltool from conda + shell: bash -l {0} + run: mamba install -n test -c conda-forge esmvaltool - name: Setup config + shell: bash -l {0} run: | - $CONDA/envs/test/bin/esmvaltool config get_config_user + esmvaltool config get_config_user patch ~/.esmvaltool/config-user.yml << EOF 44c44 < #rootpath: From 76f15edde7509bebbebdf4d20a032a44f2f32f34 Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 13:46:10 +0000 Subject: [PATCH 603/647] fixed installation from conda --- .github/workflows/recipes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 28119907..9fa86d36 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -29,7 +29,7 @@ jobs: run: conda install mamba - name: Install esmvaltool from conda shell: bash -l {0} - run: mamba install -n test -c conda-forge esmvaltool + run: mamba install esmvaltool - name: Setup config shell: bash -l {0} run: | From 40eb0e866ac8dc52e5875562b98b4b9cd403e951 Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 14:36:32 +0000 Subject: [PATCH 604/647] fix the config file handling and rename data dir --- .github/workflows/recipes.yml | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 9fa86d36..8617465b 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -30,32 +30,23 @@ jobs: - name: Install esmvaltool from conda shell: bash -l {0} run: mamba install esmvaltool - - name: Setup config + - name: Get config-user file shell: bash -l {0} - run: | - esmvaltool config get_config_user - patch ~/.esmvaltool/config-user.yml << EOF - 44c44 - < #rootpath: - --- - > rootpath: - 48c48 - < # default: ~/default_inputpath - --- - > default: ~/default_inputpath - EOF + run: esmvaltool config get_config_user - name: Cache datasets uses: actions/cache@v1 env: # Increase this value to reset cache if data/dataset.urls has not changed CACHE_NUMBER: 0 with: - path: ~/default_inputpath + path: ~/climate_data key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} - name: Download dataset files for episodes 4 and 5 + shell: bash -l {0} run: | - head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --directory-prefix $HOME/default_inputpath/ + head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --directory-prefix $HOME/climate_data/ - name: Run all recipes in files/ + shell: bash -l {0} run: | mkdir ~/esmvaltool_tutorial cp files/warming_stripes.py ~/esmvaltool_tutorial/ From 4cfc2a77d6c749f5fa8fd2822d0b9385db87489c Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 14:47:09 +0000 Subject: [PATCH 605/647] added titles to recipes --- files/recipe_test_fluxcom.yml | 2 ++ files/recipe_warming_stripes.yml | 1 + files/recipe_warming_stripes_additional_datasets.yml | 1 + files/recipe_warming_stripes_local.yml | 1 + files/recipe_warming_stripes_multiple_locations.yml | 1 + files/recipe_warming_stripes_periods.yml | 1 + 6 files changed, 7 insertions(+) diff --git a/files/recipe_test_fluxcom.yml b/files/recipe_test_fluxcom.yml index 5d96b7f9..f86a8966 100644 --- a/files/recipe_test_fluxcom.yml +++ b/files/recipe_test_fluxcom.yml @@ -5,6 +5,8 @@ documentation: authors: - kalverla_peter + title: Test recipe fluxcom. + maintainer: - kalverla_peter diff --git a/files/recipe_warming_stripes.yml b/files/recipe_warming_stripes.yml index 228c867f..cfceae10 100644 --- a/files/recipe_warming_stripes.yml +++ b/files/recipe_warming_stripes.yml @@ -3,6 +3,7 @@ --- documentation: description: Reproducing Ed Hawkins' warming stripes visualization + title: Reproducing Ed Hawkins' warming stripes visualization. authors: - righi_mattia diff --git a/files/recipe_warming_stripes_additional_datasets.yml b/files/recipe_warming_stripes_additional_datasets.yml index b1b9f264..1bad5f96 100644 --- a/files/recipe_warming_stripes_additional_datasets.yml +++ b/files/recipe_warming_stripes_additional_datasets.yml @@ -3,6 +3,7 @@ --- documentation: description: Reproducing Ed Hawkins' warming stripes visualization + title: Reproducing Ed Hawkins' warming stripes visualization. authors: - righi_mattia diff --git a/files/recipe_warming_stripes_local.yml b/files/recipe_warming_stripes_local.yml index dfa112a5..cd19bcbc 100644 --- a/files/recipe_warming_stripes_local.yml +++ b/files/recipe_warming_stripes_local.yml @@ -3,6 +3,7 @@ --- documentation: description: Reproducing Ed Hawkins' warming stripes visualization + title: Reproducing Ed Hawkins' warming stripes visualization. authors: - righi_mattia diff --git a/files/recipe_warming_stripes_multiple_locations.yml b/files/recipe_warming_stripes_multiple_locations.yml index ef38b438..40a68959 100644 --- a/files/recipe_warming_stripes_multiple_locations.yml +++ b/files/recipe_warming_stripes_multiple_locations.yml @@ -3,6 +3,7 @@ --- documentation: description: Reproducing Ed Hawkins' warming stripes visualization + title: Reproducing Ed Hawkins' warming stripes visualization. authors: - righi_mattia diff --git a/files/recipe_warming_stripes_periods.yml b/files/recipe_warming_stripes_periods.yml index 3215bcb1..4754489f 100644 --- a/files/recipe_warming_stripes_periods.yml +++ b/files/recipe_warming_stripes_periods.yml @@ -3,6 +3,7 @@ --- documentation: description: Reproducing Ed Hawkins' warming stripes visualization + title: Reproducing Ed Hawkins' warming stripes visualization. authors: - righi_mattia From 3a5a7bbaea2fa5f64c68a31c011d7bb673165261 Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 15:12:38 +0000 Subject: [PATCH 606/647] run only stripes recipes --- .github/workflows/recipes.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 8617465b..0151cb62 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -44,10 +44,10 @@ jobs: - name: Download dataset files for episodes 4 and 5 shell: bash -l {0} run: | - head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --directory-prefix $HOME/climate_data/ + head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --no-verbose --directory-prefix $HOME/climate_data/ - name: Run all recipes in files/ shell: bash -l {0} run: | mkdir ~/esmvaltool_tutorial cp files/warming_stripes.py ~/esmvaltool_tutorial/ - for file in files/recipe*.yml; do $CONDA/envs/test/bin/esmvaltool run $PWD/$file; done + for file in files/recipe_warming_stripes*.yml; do $CONDA/envs/test/bin/esmvaltool run $PWD/$file; done From 215299f3cc306af36607303735f0bd59d59f801e Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 15:26:01 +0000 Subject: [PATCH 607/647] turn off data caching and turn on auto download --- .github/workflows/recipes.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 0151cb62..0b6950bb 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -33,21 +33,21 @@ jobs: - name: Get config-user file shell: bash -l {0} run: esmvaltool config get_config_user - - name: Cache datasets - uses: actions/cache@v1 - env: - # Increase this value to reset cache if data/dataset.urls has not changed - CACHE_NUMBER: 0 - with: - path: ~/climate_data - key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} - - name: Download dataset files for episodes 4 and 5 - shell: bash -l {0} - run: | - head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --no-verbose --directory-prefix $HOME/climate_data/ - - name: Run all recipes in files/ + #- name: Cache datasets + # uses: actions/cache@v1 + # env: + # # Increase this value to reset cache if data/dataset.urls has not changed + # CACHE_NUMBER: 0 + # with: + # path: ~/climate_data + # key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} + #- name: Download dataset files for episodes 4 and 5 + # shell: bash -l {0} + # run: | + # head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --no-verbose --directory-prefix $HOME/climate_data/ + - name: Run all warming stripes recipes in files/ shell: bash -l {0} run: | mkdir ~/esmvaltool_tutorial cp files/warming_stripes.py ~/esmvaltool_tutorial/ - for file in files/recipe_warming_stripes*.yml; do $CONDA/envs/test/bin/esmvaltool run $PWD/$file; done + for file in files/recipe_warming_stripes*.yml; do $CONDA/envs/test/bin/esmvaltool run $PWD/$file --offline=False; done From 9d497817d1af809fff25c7c26550f2e84f8296be Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 15:34:36 +0000 Subject: [PATCH 608/647] added comments and changed job name for better readability --- .github/workflows/recipes.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml index 0b6950bb..ad5b30eb 100644 --- a/.github/workflows/recipes.yml +++ b/.github/workflows/recipes.yml @@ -7,7 +7,7 @@ on: - cron: '0 4 * * *' jobs: - build: + install-esmvaltool-and-run-recipes: runs-on: "ubuntu-latest" steps: - uses: actions/checkout@v2 @@ -30,9 +30,13 @@ jobs: - name: Install esmvaltool from conda shell: bash -l {0} run: mamba install esmvaltool + # this step is currently unnecessary; might be useful depending on config customizations - name: Get config-user file shell: bash -l {0} run: esmvaltool config get_config_user + ################################# + # turning off local data caching since we turned on auto ESGF data download + ################################# #- name: Cache datasets # uses: actions/cache@v1 # env: @@ -45,6 +49,9 @@ jobs: # shell: bash -l {0} # run: | # head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --no-verbose --directory-prefix $HOME/climate_data/ + ###################################### + # recipe fluxcom is not running since it needs OBS6 data, unavailable for download + ###################################### - name: Run all warming stripes recipes in files/ shell: bash -l {0} run: | From 3da6fe4edc37d26f57c0ec0f8a464f193c53f558 Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 16:07:03 +0000 Subject: [PATCH 609/647] renamed workflows --- .../workflows/build-check-tutorial-site.yml | 38 ++++++++++++ .../install-esmvaltool-run-recipes.yml | 60 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 .github/workflows/build-check-tutorial-site.yml create mode 100644 .github/workflows/install-esmvaltool-run-recipes.yml diff --git a/.github/workflows/build-check-tutorial-site.yml b/.github/workflows/build-check-tutorial-site.yml new file mode 100644 index 00000000..e870c419 --- /dev/null +++ b/.github/workflows/build-check-tutorial-site.yml @@ -0,0 +1,38 @@ +name: Jekyll site CI + +on: + push: + pull_request: + +jobs: + build: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Setup Ruby + uses: ruby/setup-ruby@v1.64.1 + with: + ruby-version: 2.7 + - name: Cache Ruby deps + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ruby-deps-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ruby-deps- + - name: Ruby deps + run: gem install json kramdown jekyll bundler + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Python deps + run: pip install pyyaml + - name: Nokogiri deps + run: sudo apt install -y pkg-config libxml2-dev libxslt-dev + - name: Site deps + run: bundle install + - name: Build site + run: bundle exec jekyll build + - name: Check all lessons + run: make lesson-check-all diff --git a/.github/workflows/install-esmvaltool-run-recipes.yml b/.github/workflows/install-esmvaltool-run-recipes.yml new file mode 100644 index 00000000..ad5b30eb --- /dev/null +++ b/.github/workflows/install-esmvaltool-run-recipes.yml @@ -0,0 +1,60 @@ +name: Test recipes + +on: + push: + pull_request: + schedule: + - cron: '0 4 * * *' + +jobs: + install-esmvaltool-and-run-recipes: + runs-on: "ubuntu-latest" + steps: + - uses: actions/checkout@v2 + - name: Cache conda + uses: actions/cache@v1 + env: + # Increase this value to reset cache if files/recipe_example.yml has not changed + CACHE_NUMBER: 1 + with: + path: ~/conda_pkgs_dir + key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('files/recipe_example.yml') }} + - uses: conda-incubator/setup-miniconda@v2 + with: + python-version: "3.9" + miniconda-version: "latest" + channels: conda-forge + - name: Install mamba + shell: bash -l {0} + run: conda install mamba + - name: Install esmvaltool from conda + shell: bash -l {0} + run: mamba install esmvaltool + # this step is currently unnecessary; might be useful depending on config customizations + - name: Get config-user file + shell: bash -l {0} + run: esmvaltool config get_config_user + ################################# + # turning off local data caching since we turned on auto ESGF data download + ################################# + #- name: Cache datasets + # uses: actions/cache@v1 + # env: + # # Increase this value to reset cache if data/dataset.urls has not changed + # CACHE_NUMBER: 0 + # with: + # path: ~/climate_data + # key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} + #- name: Download dataset files for episodes 4 and 5 + # shell: bash -l {0} + # run: | + # head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --no-verbose --directory-prefix $HOME/climate_data/ + ###################################### + # recipe fluxcom is not running since it needs OBS6 data, unavailable for download + ###################################### + - name: Run all warming stripes recipes in files/ + shell: bash -l {0} + run: | + mkdir ~/esmvaltool_tutorial + cp files/warming_stripes.py ~/esmvaltool_tutorial/ + for file in files/recipe_warming_stripes*.yml; do $CONDA/envs/test/bin/esmvaltool run $PWD/$file --offline=False; done From cdd21fc6756e239a79a05ef1d04084aef60489c4 Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 16:07:26 +0000 Subject: [PATCH 610/647] old file --- .github/workflows/ci.yml | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index e870c419..00000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Jekyll site CI - -on: - push: - pull_request: - -jobs: - build: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - name: Setup Ruby - uses: ruby/setup-ruby@v1.64.1 - with: - ruby-version: 2.7 - - name: Cache Ruby deps - uses: actions/cache@v2 - with: - path: vendor/bundle - key: ruby-deps-${{ hashFiles('**/Gemfile.lock') }} - restore-keys: | - ruby-deps- - - name: Ruby deps - run: gem install json kramdown jekyll bundler - - name: Setup Python - uses: actions/setup-python@v2 - with: - python-version: '3.x' - - name: Python deps - run: pip install pyyaml - - name: Nokogiri deps - run: sudo apt install -y pkg-config libxml2-dev libxslt-dev - - name: Site deps - run: bundle install - - name: Build site - run: bundle exec jekyll build - - name: Check all lessons - run: make lesson-check-all From b2119e6ae54ade0d13081cb269bd2b2fcc29c53b Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Fri, 26 Nov 2021 16:07:30 +0000 Subject: [PATCH 611/647] old file --- .github/workflows/recipes.yml | 60 ----------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 .github/workflows/recipes.yml diff --git a/.github/workflows/recipes.yml b/.github/workflows/recipes.yml deleted file mode 100644 index ad5b30eb..00000000 --- a/.github/workflows/recipes.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Test recipes - -on: - push: - pull_request: - schedule: - - cron: '0 4 * * *' - -jobs: - install-esmvaltool-and-run-recipes: - runs-on: "ubuntu-latest" - steps: - - uses: actions/checkout@v2 - - name: Cache conda - uses: actions/cache@v1 - env: - # Increase this value to reset cache if files/recipe_example.yml has not changed - CACHE_NUMBER: 1 - with: - path: ~/conda_pkgs_dir - key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('files/recipe_example.yml') }} - - uses: conda-incubator/setup-miniconda@v2 - with: - python-version: "3.9" - miniconda-version: "latest" - channels: conda-forge - - name: Install mamba - shell: bash -l {0} - run: conda install mamba - - name: Install esmvaltool from conda - shell: bash -l {0} - run: mamba install esmvaltool - # this step is currently unnecessary; might be useful depending on config customizations - - name: Get config-user file - shell: bash -l {0} - run: esmvaltool config get_config_user - ################################# - # turning off local data caching since we turned on auto ESGF data download - ################################# - #- name: Cache datasets - # uses: actions/cache@v1 - # env: - # # Increase this value to reset cache if data/dataset.urls has not changed - # CACHE_NUMBER: 0 - # with: - # path: ~/climate_data - # key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} - #- name: Download dataset files for episodes 4 and 5 - # shell: bash -l {0} - # run: | - # head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --no-verbose --directory-prefix $HOME/climate_data/ - ###################################### - # recipe fluxcom is not running since it needs OBS6 data, unavailable for download - ###################################### - - name: Run all warming stripes recipes in files/ - shell: bash -l {0} - run: | - mkdir ~/esmvaltool_tutorial - cp files/warming_stripes.py ~/esmvaltool_tutorial/ - for file in files/recipe_warming_stripes*.yml; do $CONDA/envs/test/bin/esmvaltool run $PWD/$file --offline=False; done From 79c15bfcac990eccc67817c8fc0f95d09136d61d Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Mon, 29 Nov 2021 17:06:55 +0000 Subject: [PATCH 612/647] turned off run on PRs and deleted commented out syntax --- .../install-esmvaltool-run-recipes.yml | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/.github/workflows/install-esmvaltool-run-recipes.yml b/.github/workflows/install-esmvaltool-run-recipes.yml index ad5b30eb..16627392 100644 --- a/.github/workflows/install-esmvaltool-run-recipes.yml +++ b/.github/workflows/install-esmvaltool-run-recipes.yml @@ -1,8 +1,8 @@ -name: Test recipes +name: Test Tutorial Recipes on: push: - pull_request: + # pull_request: # turn on for tests to run on PRs schedule: - cron: '0 4 * * *' @@ -34,24 +34,6 @@ jobs: - name: Get config-user file shell: bash -l {0} run: esmvaltool config get_config_user - ################################# - # turning off local data caching since we turned on auto ESGF data download - ################################# - #- name: Cache datasets - # uses: actions/cache@v1 - # env: - # # Increase this value to reset cache if data/dataset.urls has not changed - # CACHE_NUMBER: 0 - # with: - # path: ~/climate_data - # key: ${{ runner.os }}-datasets-${{ env.CACHE_NUMBER }}-${{ hashFiles('data/dataset.urls') }} - #- name: Download dataset files for episodes 4 and 5 - # shell: bash -l {0} - # run: | - # head -4 data/dataset.urls | grep -v '#' | wget --input-file - --no-clobber --no-verbose --directory-prefix $HOME/climate_data/ - ###################################### - # recipe fluxcom is not running since it needs OBS6 data, unavailable for download - ###################################### - name: Run all warming stripes recipes in files/ shell: bash -l {0} run: | From 287e5d124e97ef3126dcc16df4a69a820a10dad3 Mon Sep 17 00:00:00 2001 From: Valeriu Predoi Date: Mon, 29 Nov 2021 17:08:42 +0000 Subject: [PATCH 613/647] turn off run on PRs --- .github/workflows/build-check-tutorial-site.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-check-tutorial-site.yml b/.github/workflows/build-check-tutorial-site.yml index e870c419..32172838 100644 --- a/.github/workflows/build-check-tutorial-site.yml +++ b/.github/workflows/build-check-tutorial-site.yml @@ -2,7 +2,7 @@ name: Jekyll site CI on: push: - pull_request: + # pull_request: # turn on when GA tests need to run on PRs too jobs: build: From 136d2ea374cc5a566621399379c97844a3133dbf Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Wed, 29 Dec 2021 15:38:55 +0100 Subject: [PATCH 614/647] Update link --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index 0a96806f..94b834b3 100644 --- a/index.md +++ b/index.md @@ -52,7 +52,7 @@ independently. developers via the [github issues page](https://github.com/ESMValGroup/ESMValTool/issues) or via the ESMValTool email list. Please see - [information](https://docs.esmvaltool.org/en/latest/community/contact.html#user-mailing-list) + [information](https://docs.esmvaltool.org/en/latest/introduction.html#user-mailing-list) on how to subscribe to user mailing list. 4. This tutorial includes several advanced lessons after the conclusion. These From 6573f295a6b39745b96edda5450ea38f8ec07807 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Wed, 29 Dec 2021 17:46:13 +0100 Subject: [PATCH 615/647] update installation to mamba --- _episodes/02-installation.md | 92 ++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 088353c3..65d63ba5 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -17,17 +17,17 @@ keypoints: The instructions help with the installation of ESMValTool on operating systems like Linux/MacOSX/Windows. -We use the [Conda](https://conda.io/projects/conda/en/latest/index.html) +We use the [Mamba](https://mamba.readthedocs.io/en/latest/index.html) package manager to install the ESMValTool. Other installation methods are also available; they can be found in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html). -We will first install Conda, and then ESMValTool. We end this chapter by testing +We will first install Mamba, and then ESMValTool. We end this chapter by testing that the installation was successful. Before we begin, here are all the possible ways in which you can use ESMValTool -depending on your level of expertise or involvement with ESMvalTool and -associated software such as GitHub and Conda. +depending on your level of expertise or involvement with ESMValTool and +associated software such as GitHub and Mamba. 1. If you have access to a server where ESMValTool is already installed as a module, for e.g., the [CEDA JASMIN](https://help.jasmin.ac.uk/article/4955-community-software-esmvaltool) @@ -57,45 +57,25 @@ in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installa ## Install ESMValTool on Linux/MacOSX -### Install Conda +### Install Mamba -ESMValTool is distributed using [Conda](https://conda.io/). -Let's check if we already have Conda installed by running: +ESMValTool is distributed using [Mamba](https://mamba.readthedocs.io/en/latest/index.html) +To install mamba on ``Linux`` or ``MacOSX``, follow the instructions below: -```bash -conda list -``` - -If conda is installed, we will see a list of packages. -We recommend updating conda before esmvaltool installation. To do so, run: - -```bash -conda update -n base conda -``` - -If conda is **not** installed, we can use Miniconda minimal installer for conda. -We recommend a Python 3 based installer. For more information about installing conda, -see [the conda installation documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). - -To install conda on ``Linux`` or ``MacOSX``, follow the instructions below: - -1. Please download Miniconda3 at [the miniconda - page](https://docs.conda.io/en/latest/miniconda.html). - If you have problems with the 64 bit version in the next step(s) - you can alternatively try a 32 bit version. +1. Please download the installation file for the latest Mamba version [here](https://github.com/conda-forge/miniforge#mambaforge). 2. Next, run the installer from the place where you downloaded it: On ``Linux``: ```bash - bash Miniconda3-latest-Linux-x86_64.sh + bash Mambaforge-Linux-x86_64.sh ``` On ``MacOSX``: ```bash - bash Miniconda3-latest-MacOSX-x86_64.sh + bash Mambaforge-MacOSX-x86_64.sh ``` 3. Follow the instructions in the installer. The defaults should normally @@ -103,13 +83,21 @@ To install conda on ``Linux`` or ``MacOSX``, follow the instructions below: 4. You will need to restart your terminal for the changes to have effect. -5. Verify you have a working conda installation by listing all installed - packages +5. We recommend updating mamba before the esmvaltool installation. To do so, run: + + ```bash + mamba update --name base mamba + ``` + +6. Verify you have a working mamba installation by: ```bash - conda list + which mamba ``` +For more information about installing mamba, +see [the mamba installation documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#mamba-installation). + ### Install Julia Some ESMValTool diagnostics are written in the Julia programming language. @@ -196,19 +184,32 @@ available: - `esmvaltool-python` - `esmvaltool-ncl` - `esmvaltool-r` -- `esmvaltool-julia` - `esmvaltool` --> the complete package, i.e. the combination of the above. -For the tutorial, we will use only Python diagnostics. Thus, to install the -ESMValTool-python package, run +For the tutorial, we will install the complete package. Thus, to install the +ESMValTool package, run + +```bash +mamba create --name esmvaltool 'python=3.9' +``` + +Next, we install many of the required dependencies, including the ESMValCore package +and Python, R, and NCL interpreters, into this environment by running: + +```bash +mamba env update --name esmvaltool --file environment.yml +``` + +On MacOSX ESMValTool functionalities in Julia, NCL, and R are not supported. To install +a Mamba environment on MacOSX, use the dedicated environment file: ```bash -conda create -n esmvaltool -c conda-forge -c esmvalgroup esmvaltool-python +mamba env create --name esmvaltool --file environment_osx.yml ``` -This will create a new [Conda +This will create a new [Mamba environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) -called `esmvaltool`, with the ESMValTool-Python package and all of its dependencies +called `esmvaltool`, with the ESMValTool package and all of its dependencies installed in it. @@ -221,19 +222,16 @@ installed in it. > the moment, please try again later or [raise an > issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose) > - If `Solving environment` takes more than 10 minutes, you may need to update -> conda: `conda update -n base conda` -> - You can help conda solve the environment by specifying +> mamba: `mamba update -n base mamba` +> - You can help mamba solve the environment by specifying > the python version: > ```bash -> conda create -n esmvaltool -c conda-forge -c esmvalgroup esmvaltool-python python=3.8 +> mamba create -n esmvaltool esmvaltool python=3.8 > ``` > - Note that on ``MacOSX``, ``esmvaltool-python`` and > ``esmvaltool-ncl`` only work with Python 3.7. Use `python=3.7` instead of `python=3.8`. -> - If you have an old conda installation you could get a `UnsatisfiableError` -> message. Please install a newer version of conda and try again -> - Downloads fail due to company proxy, see [conda -> docs](https://docs.anaconda.com/anaconda/user-guide/tasks/proxy/) how to -> resolve. +> - If you have an old mamba installation you could get a `UnsatisfiableError` +> message. Please install a newer version of mamba and try again > {: .callout} From afedbf465a7c9def67727915f8d9197c3db6bec4 Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Wed, 29 Dec 2021 17:58:38 +0100 Subject: [PATCH 616/647] small fix --- _episodes/02-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 65d63ba5..82613660 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -59,7 +59,7 @@ in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installa ### Install Mamba -ESMValTool is distributed using [Mamba](https://mamba.readthedocs.io/en/latest/index.html) +ESMValTool is distributed using [Mamba](https://mamba.readthedocs.io/en/latest/index.html). To install mamba on ``Linux`` or ``MacOSX``, follow the instructions below: 1. Please download the installation file for the latest Mamba version [here](https://github.com/conda-forge/miniforge#mambaforge). From 93a9ea18a80264191fbf99908fe4679050ef48eb Mon Sep 17 00:00:00 2001 From: Lisa Bock Date: Mon, 10 Jan 2022 11:24:34 +0100 Subject: [PATCH 617/647] changes regarding the review --- _episodes/02-installation.md | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 82613660..f87a0594 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -95,6 +95,8 @@ To install mamba on ``Linux`` or ``MacOSX``, follow the instructions below: which mamba ``` + This should show the path to your mamba executeable, e.g. `~/mambaforge/bin/mamba`. + For more information about installing mamba, see [the mamba installation documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#mamba-installation). @@ -215,23 +217,8 @@ installed in it. > ## Common issues > -> - Installation takes a long time -> - Downloads and compilations can take several minutes to complete, -> please be patient. -> - You might have bad luck and the dependencies can not be resolved at -> the moment, please try again later or [raise an -> issue](https://github.com/ESMValGroup/ESMValTool/issues/new/choose) -> - If `Solving environment` takes more than 10 minutes, you may need to update -> mamba: `mamba update -n base mamba` -> - You can help mamba solve the environment by specifying -> the python version: -> ```bash -> mamba create -n esmvaltool esmvaltool python=3.8 -> ``` -> - Note that on ``MacOSX``, ``esmvaltool-python`` and -> ``esmvaltool-ncl`` only work with Python 3.7. Use `python=3.7` instead of `python=3.8`. -> - If you have an old mamba installation you could get a `UnsatisfiableError` -> message. Please install a newer version of mamba and try again +> You find a list of common installation problems and their solutions in the +> [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#common-installation-problems-and-their-solutions). > {: .callout} @@ -264,15 +251,15 @@ to display the command line help. > > The `esmvaltool --help` command lists `version` as a > > command to get the version > > -> > In my case when I run +> > When you run > > ~~~ > > esmvaltool version > > ~~~ > > {: .bash} -> > I get that my installed ESMValTool version is +> > The version of ESMValTool installed should be displayed on the screen as: > > ~~~ -> > ESMValCore: 2.0.0 -> > ESMValTool: 2.0.0 +> > ESMValCore: 2.4.0 +> > ESMValTool: 2.4.0 > > ~~~ > > {: .output} > {: .solution} From 52cb8500e1e082e3dfd1094bce240ab74f9d2d87 Mon Sep 17 00:00:00 2001 From: rswamina Date: Mon, 17 Jan 2022 23:10:36 +0000 Subject: [PATCH 618/647] Added title to recipe in Introduction --- _episodes/01-introduction.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index aa91494c..1e441f20 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -58,6 +58,7 @@ An example recipe could look like this: ```yaml documentation: + title: This is an example recipe. description: Example recipe authors: - lastname_firstname From 95cd4c7037cc377f1fa2546eab7afa0492192f3d Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 23 Jan 2022 17:26:17 +0000 Subject: [PATCH 619/647] made a few changes to text for better readability --- _episodes/01-introduction.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/_episodes/01-introduction.md b/_episodes/01-introduction.md index 1e441f20..986b5fcc 100644 --- a/_episodes/01-introduction.md +++ b/_episodes/01-introduction.md @@ -24,7 +24,7 @@ technical steps, let's talk about what ESMValTool is all about. > ## What is ESMValTool? > -> What do you already know about, or expect from ESMValTool? +> What do you already know about or expect from ESMValTool? > > > ## ESMValTool is... > > @@ -87,8 +87,8 @@ diagnostics: > be found in the documentation of ESMValTool. > > > ## Solution -> > The keys are explained in the ESMValTool documentation, in the section `The -> recipe format`, under +> > The keys are explained in the ESMValTool documentation, in the `Recipe +>> section `, under > [datasets](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-datasets) > {: .solution} {: .challenge} @@ -101,8 +101,8 @@ results. > ## Explore the available recipes > -> Go to the [documentation of esmvaltool](https://docs.esmvaltool.org/) and -> explore the `available recipes` section. Which recipe(s) would you like to +> Go to the [ESMValTool Documentation webpage](https://docs.esmvaltool.org/) and +> explore the `Available recipes` section. Which recipe(s) would you like to > try? {: .challenge} @@ -113,10 +113,10 @@ software engineers. It is an open source project to which anyone can contribute. Many of the interactions take place on GitHub. Here, we briefly introduce you to some of the most important pages. -> ## Meet ESMValGroup +> ## Meet the ESMValGroup > -> Browse to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is -> our 'organization' GitHub page. Have a look around. How many collaborators are +> Go to [github.com/ESMValGroup](https://github.com/ESMValGroup). This is +> the GitHub page of our 'organization'. Have a look around. How many collaborators are > there? Do you know any of them? > > Near the top of the page there are 2 pinned repositories: ESMValTool and From 58190a885e258133b5b23bb73af8f00ccfbaddef Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 23 Jan 2022 17:52:10 +0000 Subject: [PATCH 620/647] made a few changes to text for better readability --- _episodes/02-installation.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index f87a0594..961b4305 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -9,7 +9,7 @@ objectives: - "Install ESMValTool" - "Demonstrate that the installation was successful" keypoints: -- "All the required packages can be installed using conda." +- "All the required packages can be installed using mamba." - "You can find more information about installation in the [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html)." --- @@ -31,12 +31,12 @@ associated software such as GitHub and Mamba. 1. If you have access to a server where ESMValTool is already installed as a module, for e.g., the [CEDA JASMIN](https://help.jasmin.ac.uk/article/4955-community-software-esmvaltool) -server, you can simply load the module with the following: +server, you can simply load the module with the following command: ~~~bash module load esmvaltool ~~~ -After loading ``esmvaltool``, we can start using ESMValTool. Please see the [next lesson]({{ page.root }}{% link _episodes/03-configuration.md %}). -2. If you would like to install ESMValTool as a conda package, then this lesson +After loading ``esmvaltool``, we can start using ESMValTool right away. Please see the [next lesson]({{ page.root }}{% link _episodes/03-configuration.md %}). +2. If you would like to install ESMValTool as a mamba package, then this lesson will tell you how! 3. If you would like to start experimenting with existing diagnostics or contributing to ESMvalTool, please see the instructions for source installation in the lesson [Development and @@ -95,7 +95,7 @@ To install mamba on ``Linux`` or ``MacOSX``, follow the instructions below: which mamba ``` - This should show the path to your mamba executeable, e.g. `~/mambaforge/bin/mamba`. + This should show the path to your mamba executable, e.g. `~/mambaforge/bin/mamba`. For more information about installing mamba, see [the mamba installation documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#mamba-installation). From a69ad977614879846890f6212d7099d5eb7afc81 Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 23 Jan 2022 23:04:32 +0000 Subject: [PATCH 621/647] changes made to include options to download data from ESGF nodes and to remove defunct options such as write_plots --- _episodes/03-configuration.md | 118 +++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 44 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index c69604bb..5a02ce2a 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -27,10 +27,11 @@ This is a [YAML file](https://yaml.org/spec/1.2/spec.html). You can get the default configuration file by running: ~~~bash - esmvaltool config get_config_user + esmvaltool config get_config_user --path= ~~~ - -It will save the file to: `~/.esmvaltool/config-user.yml`, where `~` is the +The default configuration file will be downloaded to the directory specified with +the `--path` variable. If this option is not used, the file will be saved to the default +location: `~/.esmvaltool/config-user.yml`, where `~` is the path to your home directory. Note that files and directories starting with a period are "hidden", to see the `.esmvaltool` directory in the terminal use `ls -la ~`. @@ -67,7 +68,7 @@ The configuration file starts with output settings that inform ESMValTool about your preference for output. You can turn on or off the setting by ``true`` or ``false`` values. Most of these settings are fairly self-explanatory. -For example, `write_plots: true` means that diagnostics create plots. + > ## Saving preprocessed data > @@ -101,8 +102,9 @@ using the format: YYYYMMDD_HHMMSS. > ## Set the destination directory > > Let's name our destination directory ``esmvaltool_output`` in the working directory. -> ESMValTool should write the output to this path. -> How to modify the `config-user.yml`? +> ESMValTool should write the output to this path, so make sure you have the disk space +> to write output to this directory. +> How do we set this in the `config-user.yml`? > >> ## Solution >> @@ -120,35 +122,46 @@ using the format: YYYYMMDD_HHMMSS. ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from -the climate model intercomparison project whereas OBS is used for an observational dataset. -We can find more information about the projects in the ESMValTool +the Climate Model Intercomparison Project whereas OBS is used for an observational +dataset. +More information about the projects used in ESMValTool is available in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html). +When using ESMValTool on your own machine, you can create a directory to download +climate model data or observation data sets and let the tool use data from there. +It is also possible to ask +ESMValTool to download climate model data as needed. This can be done by specifying a +download directory and by setting the option to download data as shown below. + +```yaml +# Directory for storing downloaded climate data +download_dir: ~/climate_data +offline: false +``` +If you are working offline or do not want to download the data then set the +option above to `true`. + The ``rootpath`` specifies the directories where ESMValTool will look for input data. -For each category, you can define either one path or several paths as a list. -For example: +For each category, you can define either one path or several paths as a list. For example: ```yaml rootpath: CMIP5: [~/cmip5_inputpath1, ~/cmip5_inputpath2] OBS: ~/obs_inputpath RAWOBS: ~/rawobs_inputpath - default: ~/default_inputpath - CORDEX: ~/default_inputpath + default: ~/climate_data ``` - -Site-specific entries for Jasmin and DKRZ are listed at the end of the -example configuration file. +These are typically available in the default configuration file you downloaded, so simply +removing the machine specific lines should be sufficient to access input data. > ## Set the correct rootpath > > In this tutorial, we will work with data from > [CMIP5](https://esgf-node.llnl.gov/projects/cmip5/) > and [CMIP6](https://esgf-node.llnl.gov/projects/cmip6). -> How can we moodify the `rootpath` to make sure the data path is set correctly -> for both CMIP5 and CMIP6? -> +> How can we modify the `rootpath` to make sure the data path is set correctly +> for both CMIP5 and CMIP6? > Note: -> to get the data, check instruction in +> to get the data, check the instructions in > [Setup]({{ page.root }}{% link setup.md %}). > >> ## Solution @@ -156,6 +169,7 @@ example configuration file. >> - Are you working on your own local machine? >> You need to add the root path of the folder where the data is available >> to the `config-user.yml` file as: +>> >>```yaml >> rootpath: >> ... @@ -163,23 +177,33 @@ example configuration file. >> CMIP6: ~/esmvaltool_tutorial/data >>``` >> ->> - Are you working with on a computer cluster like Jasmin or DKRZ? ->> Site-specific path to the data are already listed at the end of the +>> - Are you working on your local machine and have downloaded data using ESMValTool? +>> You need to add the root path of the folder where the data has been downloaded to as +>> specified in the `download_dir`. +>> +>> ```yaml +>> rootpath: +>> ... +>> CMIP5: ~/climate_data +>> CMIP6: ~/climate_data +>>``` +>> +>> - Are you working on a computer cluster like Jasmin or DKRZ? +>> Site-specific path to the data for JASMIN/DKRZ/ETH/IPSL +>> are already listed at the end of the >> `config-user.yml` file. You need to uncomment the related lines. ->> For example, on Jasmin: +>> For example, on JASMIN: >> >>```yaml ->> # Site-specific entries: Jasmin ->> # Uncomment the lines below to locate data on JASMIN ->> rootpath: ->> CMIP6: /badc/cmip6/data/CMIP6 ->> CMIP5: /badc/cmip5/data/cmip5/output1 ->> # CMIP3: /badc/cmip3_drs/data/cmip3/output ->> # OBS: /gws/nopw/j04/esmeval/obsdata-v2 ->> # OBS6: /gws/nopw/j04/esmeval/obsdata-v2 ->> # obs4mips: /gws/nopw/j04/esmeval/obsdata-v2 ->> # ana4mips: /gws/nopw/j04/esmeval/obsdata-v2 ->> # CORDEX: /badc/cordex/data/CORDEX/output +>>auxiliary_data_dir: /gws/nopw/j04/esmeval/aux_data/AUX +>>rootpath: +>> CMIP6: /badc/cmip6/data/CMIP6 +>> CMIP5: /badc/cmip5/data/cmip5/output1 +>> OBS: /gws/nopw/j04/esmeval/obsdata-v2 +>> OBS6: /gws/nopw/j04/esmeval/obsdata-v2 +>> obs4MIPs: /gws/nopw/j04/esmeval/obsdata-v2 +>> ana4mips: /gws/nopw/j04/esmeval/obsdata-v2 +>> default: /gws/nopw/j04/esmeval/obsdata-v2 >>``` >> >> - For more information about setting the rootpath, see also the ESMValTool @@ -216,8 +240,16 @@ information about ``drs``, you can visit the ESMValTool documentation on >> CMIP5: default >> CMIP6: default >>``` ->> ->> - Are you working with on a computer cluster like Jasmin or DKRZ? +>> - Are you asking ESMValTool to download the data for use with your diagnostics? +>> You need to set the `drs` of the data in the `config-user.yml` file as: +>> ```yaml +>> drs: +>> CMIP5: ESGF +>> CMIP6: ESGF +>> CORDEX: ESGF +>> obs4MIPs: ESGF +>>``` +>> - Are you working on a computer cluster like Jasmin or DKRZ? >> Site-specific `drs` of the data are already listed at the end of the >> `config-user.yml` file. You need to uncomment the related lines. >> For example, on Jasmin: @@ -227,12 +259,10 @@ information about ``drs``, you can visit the ESMValTool documentation on >> drs: >> CMIP6: BADC >> CMIP5: BADC ->> # CMIP3: BADC ->> # CORDEX: BADC ->> # OBS: BADC ->> # OBS6: BADC ->> # obs4mips: BADC ->> # ana4mips: BADC +>> OBS: default +>> OBS6: default +>> obs4mips: default +>> ana4mips: default >>``` >> > {: .solution} @@ -242,8 +272,8 @@ information about ``drs``, you can visit the ESMValTool documentation on > > 1. In the previous exercise, we set the `drs` of CMIP5 data to `default`. > Can you explain why? -> 2. Have a look at the directory structure of the data. -> There is the folder `Tier1`. What does it mean? +> 2. Have a look at the directory structure of the `OBS` data. +> There is a folder called `Tier1`. What does it mean? > >> ## Solution >> @@ -254,7 +284,7 @@ information about ``drs``, you can visit the ESMValTool documentation on >> 2. Observational data are organized in Tiers depending on their level of >> public availability. Therefore the default directory must be structured >> accordingly with sub-directories `TierX` e.g. Tier1, Tier2 or Tier3, even ->> when `drs: default`. +>> when `drs: default`. More details can be found in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html#observational-data). >> > {: .solution} {: .challenge} From 9fc67d8a9d6b37fe0e271d55e73457ce5624f247 Mon Sep 17 00:00:00 2001 From: rswamina Date: Mon, 24 Jan 2022 21:55:22 +0000 Subject: [PATCH 622/647] title added to recipe, output from running a recipe changed to reflect new v2.4 message, some options added to distinguish between module loaded version of esmvaltool or installed esmvaltool --- _episodes/04-recipe.md | 269 +++++++++++++++++++++-------------------- 1 file changed, 141 insertions(+), 128 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 51c04cc4..09d927f8 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -22,7 +22,7 @@ run your first recipe, look at the recipe output, and make small modifications. ## Running an existing recipe -The recipe format has briefly been introduced in episode 1. To see all the +The recipe format has briefly been introduced in the [Introduction]({{ page.root }}{% link _episodes/01-introduction.md %}) episode. To see all the recipes that are shipped with ESMValTool, type ```bash @@ -35,6 +35,13 @@ We will start by running [examples/recipe_python.yml](https://docs.esmvaltool.or esmvaltool run examples/recipe_python.yml ``` + +or if you have the user configuration file in your current directory then + +``` +esmvaltool run --config_file ./config-user.yml examples/recipe_python.yml +``` + If everything is okay, you should see that ESMValTool is printing a lot of output to the command line. The final message should be "Run was successful". The exact output varies depending on your machine, but it should look something @@ -43,126 +50,127 @@ like the example output below. > ## Example output > > ``` -> INFO [29586] -> ______________________________________________________________________ -> _____ ____ __ ____ __ _ _____ _ -> | ____/ ___|| \/ \ \ / /_ _| |_ _|__ ___ | | -> | _| \___ \| |\/| |\ \ / / _` | | | |/ _ \ / _ \| | -> | |___ ___) | | | | \ V / (_| | | | | (_) | (_) | | -> |_____|____/|_| |_| \_/ \__,_|_| |_|\___/ \___/|_| -> ______________________________________________________________________ -> -> ESMValTool - Earth System Model Evaluation Tool. -> -> http://www.esmvaltool.org -> -> CORE DEVELOPMENT TEAM AND CONTACTS: -> Veronika Eyring (PI; DLR, Germany - veronika.eyring@dlr.de) -> Bouwe Andela (NLESC, Netherlands - b.andela@esciencecenter.nl) -> Bjoern Broetz (DLR, Germany - bjoern.broetz@dlr.de) -> Lee de Mora (PML, UK - ledm@pml.ac.uk) -> Niels Drost (NLESC, Netherlands - n.drost@esciencecenter.nl) -> Nikolay Koldunov (AWI, Germany - nikolay.koldunov@awi.de) -> Axel Lauer (DLR, Germany - axel.lauer@dlr.de) -> Benjamin Mueller (LMU, Germany - b.mueller@iggf.geo.uni-muenchen.de) -> Valeriu Predoi (URead, UK - valeriu.predoi@ncas.ac.uk) -> Mattia Righi (DLR, Germany - mattia.righi@dlr.de) -> Manuel Schlund (DLR, Germany - manuel.schlund@dlr.de) -> Javier Vegas-Regidor (BSC, Spain - javier.vegas@bsc.es) -> Klaus Zimmermann (SMHI, Sweden - klaus.zimmermann@smhi.se) -> -> For further help, please read the documentation at -> http://docs.esmvaltool.org. Have fun! -> -> INFO [29586] Using config file esmvaltool_config.yml -> INFO [29586] Writing program log files to: -> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/main_log.txt -> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/main_log_debug.txt -> INFO [29586] Starting the Earth System Model Evaluation Tool v2.0.0 at time: 2020-10-07 14:17:34 UTC -> INFO [29586] ---------------------------------------------------------------------- -> INFO [29586] RECIPE = /home/user/gh/esmvalgroup/ESMValTool/esmvaltool/recipes/examples/recipe_python.yml -> INFO [29586] RUNDIR = /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run -> INFO [29586] WORKDIR = /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/work -> INFO [29586] PREPROCDIR = /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc -> INFO [29586] PLOTDIR = /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/plots -> INFO [29586] ---------------------------------------------------------------------- -> INFO [29586] Running tasks using at most 1 processes -> INFO [29586] If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. -> INFO [29586] If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. -> INFO [29586] Creating tasks from recipe -> INFO [29586] Creating tasks for diagnostic map -> INFO [29586] Creating preprocessor task map/tas -> INFO [29586] Creating preprocessor 'select_january' task for variable 'tas' -> INFO [29586] Using input files for variable tas of dataset BCC-ESM1: -> /home/user/esmvaltool_tutorial/data/cmip6/tas_Amon_BCC-ESM1_historical_r1i1p1f1_gn_185001-201412.nc -> INFO [29586] Using input files for variable tas of dataset CanESM2: -> /home/user/esmvaltool_tutorial/data/cmip5/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc -> INFO [29586] PreprocessingTask map/tas created. It will create the files: -> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/map/tas/CMIP5_CanESM2_Amon_historical_r1i1p1_tas_2000-2000.nc -> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/map/tas/CMIP6_BCC-ESM1_Amon_historical_r1i1p1f1_tas_2000-2000.nc -> INFO [29586] Creating diagnostic task map/script1 -> INFO [29586] Creating tasks for diagnostic timeseries -> INFO [29586] Creating preprocessor task timeseries/tas_amsterdam -> INFO [29586] Creating preprocessor 'annual_mean_amsterdam' task for variable 'tas' -> INFO [29586] Using input files for variable tas of dataset BCC-ESM1: -> /home/user/esmvaltool_tutorial/data/cmip6/tas_Amon_BCC-ESM1_historical_r1i1p1f1_gn_185001-201412.nc -> INFO [29586] Using input files for variable tas of dataset CanESM2: -> /home/user/esmvaltool_tutorial/data/cmip5/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc -> INFO [29586] PreprocessingTask timeseries/tas_amsterdam created. It will create the files: -> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_amsterdam/CMIP5_CanESM2_Amon_historical_r1i1p1_tas_1850-2000.> nc -> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_amsterdam/> CMIP6_BCC-ESM1_Amon_historical_r1i1p1f1_tas_1850-2000.nc -> INFO [29586] Creating preprocessor task timeseries/tas_global -> INFO [29586] Creating preprocessor 'annual_mean_global' task for variable 'tas' -> INFO [29586] Using input files for variable tas of dataset BCC-ESM1: -> /home/user/esmvaltool_tutorial/data/cmip6/tas_Amon_BCC-ESM1_historical_r1i1p1f1_gn_185001-201412.nc -> INFO [29586] Using input files for variable tas of dataset CanESM2: -> /home/user/esmvaltool_tutorial/data/cmip5/tas_Amon_CanESM2_historical_r1i1p1_185001-200512.nc -> INFO [29586] PreprocessingTask timeseries/tas_global created. It will create the files: -> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_global/CMIP6_BCC-ESM1_Amon_historical_r1i1p1f1_tas_1850-2000.> nc -> /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_global/CMIP5_CanESM2_Amon_historical_r1i1p1_tas_1850-2000.nc -> INFO [29586] Creating diagnostic task timeseries/script1 -> INFO [29586] These tasks will be executed: timeseries/tas_global, timeseries/tas_amsterdam, map/tas, map/script1, timeseries/script1 -> INFO [29586] Running 5 tasks sequentially -> INFO [29586] Starting task map/tas in process [29586] -> INFO [29586] Successfully completed task map/tas (priority 0) in 0:00:04.291697 -> INFO [29586] Starting task map/script1 in process [29586] -> INFO [29586] Running command ['/home/user/miniconda3/envs/esmvaltool_tutorial/bin/python3.8', '/home/user/gh/esmvalgroup/ESMValTool/esmvaltool/diag_scripts/> examples/diagnostic.py', '/home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/map/script1/settings.yml'] -> INFO [29586] Writing output to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/work/map/script1 -> INFO [29586] Writing plots to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/plots/map/script1 -> INFO [29586] Writing log to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/map/script1/log.txt -> INFO [29586] To re-run this diagnostic script, run: -> cd /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/map/script1; MPLBACKEND="Agg" /home/user/miniconda3/envs/esmvaltool_tutorial/bin/> python3.8 /home/user/gh/esmvalgroup/ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py /home/user/esmvaltool_tutorial/output/> recipe_python_20201007_141734/run/map/script1/settings.yml -> INFO [29586] Maximum memory used (estimate): 0.3 GB -> INFO [29586] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. -> INFO [29586] Successfully completed task map/script1 (priority 1) in 0:00:03.574651 -> INFO [29586] Starting task timeseries/tas_amsterdam in process [29586] -> INFO [29586] Generated PreprocessorFile: /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/preproc/timeseries/tas_amsterdam/> MultiModelMean_Amon_tas_1850-2000.nc -> INFO [29586] Successfully completed task timeseries/tas_amsterdam (priority 2) in 0:00:09.730443 -> INFO [29586] Starting task timeseries/tas_global in process [29586] -> WARNING [29586] /home/user/miniconda3/envs/esmvaltool_tutorial/lib/python3.8/site-packages/iris/analysis/cartography.py:394: UserWarning: Using > DEFAULT_SPHERICAL_EARTH_RADIUS. -> warnings.warn("Using DEFAULT_SPHERICAL_EARTH_RADIUS.") -> -> INFO [29586] Calculated grid area shape: (1812, 64, 128) -> WARNING [29586] /home/user/miniconda3/envs/esmvaltool_tutorial/lib/python3.8/site-packages/iris/analysis/cartography.py:394: UserWarning: Using > DEFAULT_SPHERICAL_EARTH_RADIUS. -> warnings.warn("Using DEFAULT_SPHERICAL_EARTH_RADIUS.") -> -> INFO [29586] Calculated grid area shape: (1812, 64, 128) -> INFO [29586] Successfully completed task timeseries/tas_global (priority 3) in 0:00:06.073527 -> INFO [29586] Starting task timeseries/script1 in process [29586] -> INFO [29586] Running command ['/home/user/miniconda3/envs/esmvaltool_tutorial/bin/python3.8', '/home/user/gh/esmvalgroup/ESMValTool/esmvaltool/diag_scripts/> examples/diagnostic.py', '/home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/timeseries/script1/settings.yml'] -> INFO [29586] Writing output to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/work/timeseries/script1 -> INFO [29586] Writing plots to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/plots/timeseries/script1 -> INFO [29586] Writing log to /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/timeseries/script1/log.txt -> INFO [29586] To re-run this diagnostic script, run: -> cd /home/user/esmvaltool_tutorial/output/recipe_python_20201007_141734/run/timeseries/script1; MPLBACKEND="Agg" /home/user/miniconda3/envs/esmvaltool_tutorial/> bin/python3.8 /home/user/gh/esmvalgroup/ESMValTool/esmvaltool/diag_scripts/examples/diagnostic.py /home/user/esmvaltool_tutorial/output/> recipe_python_20201007_141734/run/timeseries/script1/settings.yml -> INFO [29586] Maximum memory used (estimate): 0.3 GB -> INFO [29586] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. -> INFO [29586] Successfully completed task timeseries/script1 (priority 4) in 0:00:03.712112 -> INFO [29586] Ending the Earth System Model Evaluation Tool v2.0.0 at time: 2020-10-07 14:18:02 UTC -> INFO [29586] Time for running the recipe was: 0:00:27.483308 -> INFO [29586] Maximum memory used (estimate): 0.7 GB -> INFO [29586] Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. -> INFO [29586] Run was successful +>2022-01-24 17:31:48,745 UTC [190720] INFO +>______________________________________________________________________ +> _____ ____ __ ____ __ _ _____ _ +> | ____/ ___|| \/ \ \ / /_ _| |_ _|__ ___ | | +> | _| \___ \| |\/| |\ \ / / _` | | | |/ _ \ / _ \| | +> | |___ ___) | | | | \ V / (_| | | | | (_) | (_) | | +> |_____|____/|_| |_| \_/ \__,_|_| |_|\___/ \___/|_| +>______________________________________________________________________ +> +>ESMValTool - Earth System Model Evaluation Tool. +> +>http://www.esmvaltool.org +> +> CORE DEVELOPMENT TEAM AND CONTACTS: +> Birgit Hassler (Co-PI; DLR, Germany - birgit.hassler@dlr.de) +> Alistair Sellar (Co-PI; Met Office, UK - alistair.sellar@metoffice.gov.uk) +> Bouwe Andela (Netherlands eScience Center, The Netherlands - b.andela@esciencecenter.nl) +> Lee de Mora (PML, UK - ledm@pml.ac.uk) +> Niels Drost (Netherlands eScience Center, The Netherlands - n.drost@esciencecenter.nl) +> Veronika Eyring (DLR, Germany - veronika.eyring@dlr.de) +> Bettina Gier (UBremen, Germany - gier@uni-bremen.de) +> Remi Kazeroni (DLR, Germany - remi.kazeroni@dlr.de) +> Nikolay Koldunov (AWI, Germany - nikolay.koldunov@awi.de) +> Axel Lauer (DLR, Germany - axel.lauer@dlr.de) +> Saskia Loosveldt-Tomas (BSC, Spain - saskia.loosveldt@bsc.es) +> Ruth Lorenz (ETH Zurich, Switzerland - ruth.lorenz@env.ethz.ch) +> Benjamin Mueller (LMU, Germany - b.mueller@iggf.geo.uni-muenchen.de) +> Valeriu Predoi (URead, UK - valeriu.predoi@ncas.ac.uk) +> Mattia Righi (DLR, Germany - mattia.righi@dlr.de) +> Manuel Schlund (DLR, Germany - manuel.schlund@dlr.de) +> Breixo Solino Fernandez (DLR, Germany - breixo.solinofernandez@dlr.de) +> Javier Vegas-Regidor (BSC, Spain - javier.vegas@bsc.es) +> Klaus Zimmermann (SMHI, Sweden - klaus.zimmermann@smhi.se) +> +>For further help, please read the documentation at +>http://docs.esmvaltool.org. Have fun! +> +>2022-01-24 17:31:48,745 UTC [190720] INFO Package versions +>2022-01-24 17:31:48,746 UTC [190720] INFO ---------------- +>2022-01-24 17:31:48,746 UTC [190720] INFO ESMValCore: 2.4.0 +>2022-01-24 17:31:48,746 UTC [190720] INFO ESMValTool: 2.4.0 +>2022-01-24 17:31:48,746 UTC [190720] INFO ---------------- +>2022-01-24 17:31:48,746 UTC [190720] INFO Using config file /home/users/username/esmvaltool-tutorial/config-user.yml +>2022-01-24 17:31:48,746 UTC [190720] INFO Writing program log files to: +>/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/main_log.txt +>/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/main_log_debug.txt +>2022-01-24 17:31:48,747 UTC [190720] INFO Starting the Earth System Model Evaluation Tool at time: 2022-01-24 17:31:48 UTC +>2022-01-24 17:31:48,747 UTC [190720] INFO ---------------------------------------------------------------------- +>2022-01-24 17:31:48,747 UTC [190720] INFO RECIPE = /apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/recipes/examples/recipe_python.yml +>2022-01-24 17:31:48,747 UTC [190720] INFO RUNDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run +>2022-01-24 17:31:48,747 UTC [190720] INFO WORKDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/work +>2022-01-24 17:31:48,747 UTC [190720] INFO PREPROCDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/preproc +>2022-01-24 17:31:48,747 UTC [190720] INFO PLOTDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/plots +>2022-01-24 17:31:48,747 UTC [190720] INFO ---------------------------------------------------------------------- +>2022-01-24 17:31:48,747 UTC [190720] INFO Running tasks using at most 24 processes +>2022-01-24 17:31:48,747 UTC [190720] INFO If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. +>2022-01-24 17:31:48,747 UTC [190720] INFO If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. +>2022-01-24 17:31:48,805 UTC [190720] INFO Creating tasks from recipe +>2022-01-24 17:31:48,805 UTC [190720] INFO Creating tasks for diagnostic map +>2022-01-24 17:31:48,805 UTC [190720] INFO Creating preprocessor task map/tas +>2022-01-24 17:31:48,805 UTC [190720] INFO Creating preprocessor 'select_january' task for variable 'tas' +>2022-01-24 17:31:48,835 UTC [190720] INFO Found input files for CMIP6 +>2022-01-24 17:31:48,900 UTC [190720] INFO Found input files for CMIP5 +>2022-01-24 17:31:48,961 UTC [190720] INFO PreprocessingTask map/tas created. +>2022-01-24 17:31:48,961 UTC [190720] INFO Creating diagnostic task map/script1 +>2022-01-24 17:31:48,962 UTC [190720] INFO Creating tasks for diagnostic timeseries +>2022-01-24 17:31:48,962 UTC [190720] INFO Creating preprocessor task timeseries/tas_amsterdam +>2022-01-24 17:31:48,963 UTC [190720] INFO Creating preprocessor 'annual_mean_amsterdam' task for variable 'tas' +>2022-01-24 17:31:48,969 UTC [190720] INFO Found input files for CMIP6 +>2022-01-24 17:31:49,019 UTC [190720] INFO Found input files for CMIP5 +>2022-01-24 17:31:49,063 UTC [190720] INFO PreprocessingTask timeseries/tas_amsterdam created. +>2022-01-24 17:31:49,064 UTC [190720] INFO Creating preprocessor task timeseries/tas_global +>2022-01-24 17:31:49,064 UTC [190720] INFO Creating preprocessor 'annual_mean_global' task for variable 'tas' +>2022-01-24 17:31:49,065 UTC [190720] WARNING Missing data for fx variable 'areacella' of dataset CMIP6 +>2022-01-24 17:31:49,071 UTC [190720] INFO Found input files for CMIP6 +>2022-01-24 17:31:49,138 UTC [190720] INFO Found input files for CMIP5 +>2022-01-24 17:31:49,183 UTC [190720] INFO PreprocessingTask timeseries/tas_global created. +>2022-01-24 17:31:49,183 UTC [190720] INFO Creating diagnostic task timeseries/script1 +>2022-01-24 17:31:49,184 UTC [190720] INFO These tasks will be executed: map/script1, map/tas, timeseries/tas_amsterdam, timeseries/script1, timeseries/tas_global +>2022-01-24 17:31:49,195 UTC [190720] INFO Running 5 tasks using 5 processes +>2022-01-24 17:31:49,239 UTC [190776] INFO Starting task map/tas in process [190776] +>2022-01-24 17:31:49,240 UTC [190777] INFO Starting task timeseries/tas_amsterdam in process [190777] +>2022-01-24 17:31:49,240 UTC [190778] INFO Starting task timeseries/tas_global in process [190778] +>2022-01-24 17:31:49,335 UTC [190720] INFO Progress: 3 tasks running, 2 tasks waiting for ancestors, 0/5 done +>2022-01-24 17:31:55,735 UTC [190776] INFO Successfully completed task map/tas (priority 0) in 0:00:06.494906 +>2022-01-24 17:31:55,847 UTC [190720] INFO Progress: 2 tasks running, 2 tasks waiting for ancestors, 1/5 done +>2022-01-24 17:31:55,852 UTC [190779] INFO Starting task map/script1 in process [190779] +>2022-01-24 17:31:55,861 UTC [190779] INFO Running command ['/apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python', '/apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/diag_scripts/examples/diagnostic.py', '/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/map/script1/settings.yml'] +>2022-01-24 17:31:55,862 UTC [190779] INFO Writing output to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/work/map/script1 +>2022-01-24 17:31:55,862 UTC [190779] INFO Writing plots to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/plots/map/script1 +>2022-01-24 17:31:55,862 UTC [190779] INFO Writing log to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/map/script1/log.txt +>2022-01-24 17:31:55,862 UTC [190779] INFO To re-run this diagnostic script, run: +>cd /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/map/script1; MPLBACKEND="Agg" /apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python /apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/diag_scripts/examples/diagnostic.py /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/map/script1/settings.yml +>2022-01-24 17:31:55,947 UTC [190720] INFO Progress: 3 tasks running, 1 tasks waiting for ancestors, 1/5 done +>2022-01-24 17:31:58,538 UTC [190777] INFO Generated PreprocessorFile: /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/preproc/timeseries/tas_amsterdam/MultiModelMean_Amon_tas_1850-2000.nc +>2022-01-24 17:31:58,762 UTC [190777] INFO Successfully completed task timeseries/tas_amsterdam (priority 2) in 0:00:09.521837 +>2022-01-24 17:31:58,953 UTC [190720] INFO Progress: 2 tasks running, 1 tasks waiting for ancestors, 2/5 done +>2022-01-24 17:31:59,700 UTC [190778] INFO Successfully completed task timeseries/tas_global (priority 3) in 0:00:10.459256 +>2022-01-24 17:31:59,855 UTC [190720] INFO Progress: 1 tasks running, 1 tasks waiting for ancestors, 3/5 done +>2022-01-24 17:31:59,863 UTC [190780] INFO Starting task timeseries/script1 in process [190780] +>2022-01-24 17:31:59,871 UTC [190780] INFO Running command ['/apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python', '/apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/diag_scripts/examples/diagnostic.py', '/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/timeseries/script1/settings.yml'] +>2022-01-24 17:31:59,872 UTC [190780] INFO Writing output to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/work/timeseries/script1 +>2022-01-24 17:31:59,872 UTC [190780] INFO Writing plots to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/plots/timeseries/script1 +>2022-01-24 17:31:59,872 UTC [190780] INFO Writing log to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/timeseries/script1/log.txt +>2022-01-24 17:31:59,872 UTC [190780] INFO To re-run this diagnostic script, run: +>cd /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/timeseries/script1; MPLBACKEND="Agg" /apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python /apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/diag_scripts/examples/diagnostic.py /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/timeseries/script1/settings.yml +>2022-01-24 17:31:59,956 UTC [190720] INFO Progress: 2 tasks running, 0 tasks waiting for ancestors, 3/5 done +>2022-01-24 17:32:01,586 UTC [190779] INFO Successfully completed task map/script1 (priority 1) in 0:00:05.733018 +>2022-01-24 17:32:01,760 UTC [190720] INFO Progress: 1 tasks running, 0 tasks waiting for ancestors, 4/5 done +>2022-01-24 17:32:06,079 UTC [190780] INFO Maximum memory used (estimate): 0.2 GB +>2022-01-24 17:32:06,081 UTC [190780] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +>2022-01-24 17:32:06,760 UTC [190780] INFO Successfully completed task timeseries/script1 (priority 4) in 0:00:06.896972 +>2022-01-24 17:32:06,771 UTC [190720] INFO Progress: 0 tasks running, 0 tasks waiting for ancestors, 5/5 done +>2022-01-24 17:32:06,771 UTC [190720] INFO Successfully completed all tasks. +>2022-01-24 17:32:07,764 UTC [190720] INFO Wrote recipe output to: +>file:///home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/index.html +>2022-01-24 17:32:07,764 UTC [190720] INFO Ending the Earth System Model Evaluation Tool at time: 2022-01-24 17:32:07 UTC +>2022-01-24 17:32:07,764 UTC [190720] INFO Time for running the recipe was: 0:00:19.017514 +>2022-01-24 17:32:08,702 UTC [190720] INFO Maximum memory used (estimate): 1.3 GB +>2022-01-24 17:32:08,703 UTC [190720] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +>2022-01-24 17:32:08,704 UTC [190720] INFO Run was successful > ``` > {: .solution} @@ -194,13 +202,14 @@ Let's dissect what's happening here. > > ## Answers > > > > 1. The config file should be the one we edited in the previous episode, -> > something like `/home//.esmvaltool/config-user.yml`. +> > something like `/home//.esmvaltool/config-user.yml` or `./config-user.yml`. > > 1. ESMValTool found the recipe in its installation directory, something like -> > `/home/user/miniconda3/envs/esmvaltool_tutorial/bin/esmvaltool/recipes/examples/`. +> > `/home/user/username/miniconda3/envs/esmvaltool_tutorial/bin/esmvaltool/recipes/examples/` +>> or if you are using a pre-installed module on a server, something like `/apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/recipes/examples/recipe_python.yml` > > 1. ESMValTool creates a time-stamped output directory for every run. In this > > case, it should be something like `recipe_python_YYYYMMDD_HHMMSS`. This > > folder is made inside the output directory specified in the previous -> > episode: `~/home//esmvaltool_tutorial/output`. +> > episode: `~/home//esmvaltool_tutorial/esmvaltool_output`. > > 1. There should be four output folders: > > - `plots/`: this is where output figures are stored. > > - `preproc/`: this is where pre-processed data are stored. @@ -240,7 +249,7 @@ distinguished in the log messages: > > following line in the output: > > > > ``` -> > INFO [29586] These tasks will be executed: timeseries/tas_global, timeseries/tas_amsterdam, map/tas, map/script1, timeseries/script1 +> >[190720] INFO These tasks will be executed: map/script1, map/tas, timeseries/tas_amsterdam, timeseries/script1, timeseries/tas_global > > ``` > > > > So there are three tasks related to timeseries: global temperature, @@ -279,6 +288,8 @@ For reference, you can also view the recipe by unfolding the box below. > description: | > Example recipe that plots a map and timeseries of temperature. > +> title: Recipe that runs an example diagnostic written in Python. +> > authors: > - andela_bouwe > - righi_mattia @@ -318,6 +329,8 @@ For reference, you can also view the recipe by unfolding the box below. > annual_mean_global: > area_statistics: > operator: mean +> fx_variables: +> areacella: > annual_statistics: > operator: mean > @@ -497,7 +510,7 @@ ESMValTool. > > You are free to modify the names of preprocessors or diagnostics. > > > > In the `diff` file below you will see the changes we have made to the file. -> > The top 2 lines are the filenames and the lines like `@@ -29,10 +29,10 @@` +> > The top 2 lines are the filenames and the lines like `@@ -31,10 +31,10 @@` > > represent the line numbers in the original and modified file, respectively. > > For more info on this format, see > > [here](https://en.wikipedia.org/wiki/Diff#Unified_format). @@ -505,7 +518,7 @@ ESMValTool. > > ```diff > > --- recipe_python.yml > > +++ recipe_python_london.yml -> > @@ -29,10 +29,10 @@ +> > @@ -31,10 +31,10 @@ > > extract_month: > > month: 1 > > @@ -519,7 +532,7 @@ ESMValTool. > > scheme: linear > > annual_statistics: > > operator: mean -> > @@ -71,16 +71,16 @@ +> > @@ -73,16 +73,16 @@ > > cmap: Reds > > > > timeseries: From 2339015255f53fded5c8424763e3d1a9ed4153aa Mon Sep 17 00:00:00 2001 From: rswamina Date: Mon, 24 Jan 2022 22:21:43 +0000 Subject: [PATCH 623/647] adding a mention of a current working directory to run through all our lessons --- _episodes/03-configuration.md | 16 ++++++++++++++-- _episodes/04-recipe.md | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 5a02ce2a..d5e2f75a 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -20,6 +20,15 @@ keypoints: ## The configuration file +For the purposes of this tutorial, we will create a directory in our home directory +called `esmvaltool_tutorial` and use that as our working directory. The following steps +should do that: + +~~~bash + mkdir esmvaltool_tutorial + cd esmvaltool_tutorial +~~~ + The ``config-user.yml`` configuration file contains all the global level information needed by ESMValTool to run. This is a [YAML file](https://yaml.org/spec/1.2/spec.html). @@ -30,11 +39,14 @@ You can get the default configuration file by running: esmvaltool config get_config_user --path= ~~~ The default configuration file will be downloaded to the directory specified with -the `--path` variable. If this option is not used, the file will be saved to the default +the `--path` variable. For instance, you can provide the path to your working directory +as the `target_dir`. If this option is not used, the file will be saved to the default location: `~/.esmvaltool/config-user.yml`, where `~` is the path to your home directory. Note that files and directories starting with a period are "hidden", to see the `.esmvaltool` directory in the terminal use -`ls -la ~`. +`ls -la ~`. + + We run a text editor called ``nano`` to have a look inside the configuration file and then modify it if needed: diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 09d927f8..b7b1028f 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -204,12 +204,12 @@ Let's dissect what's happening here. > > 1. The config file should be the one we edited in the previous episode, > > something like `/home//.esmvaltool/config-user.yml` or `./config-user.yml`. > > 1. ESMValTool found the recipe in its installation directory, something like -> > `/home/user/username/miniconda3/envs/esmvaltool_tutorial/bin/esmvaltool/recipes/examples/` +> > `/home/user/username/miniconda3/envs/esmvaltool/bin/esmvaltool/recipes/examples/` >> or if you are using a pre-installed module on a server, something like `/apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/recipes/examples/recipe_python.yml` > > 1. ESMValTool creates a time-stamped output directory for every run. In this > > case, it should be something like `recipe_python_YYYYMMDD_HHMMSS`. This > > folder is made inside the output directory specified in the previous -> > episode: `~/home//esmvaltool_tutorial/esmvaltool_output`. +> > episode: `~/home//esmvaltool_tutorial/esmvaltool_output`. > > 1. There should be four output folders: > > - `plots/`: this is where output figures are stored. > > - `preproc/`: this is where pre-processed data are stored. From 916355470fb164cedfee217424dc586eb041d4f4 Mon Sep 17 00:00:00 2001 From: rswamina Date: Mon, 24 Jan 2022 23:37:08 +0000 Subject: [PATCH 624/647] minor edits for readability --- _episodes/05-conclusions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/05-conclusions.md b/_episodes/05-conclusions.md index 7dbaa363..55becc14 100644 --- a/_episodes/05-conclusions.md +++ b/_episodes/05-conclusions.md @@ -10,7 +10,7 @@ questions: - "How can I cite ESMValtool?" objectives: -- "breathe - you're finished now!" +- "Breathe - you're finished now!" - "Congratulations & Thanks!" - "Find out about the mini-tutorials, and what to do next." @@ -69,7 +69,7 @@ to be suitable for use by ESMValTool. There are lots of resources available for helping you use ESMValTool. -ESMValTool [Discussions page](https://github.com/ESMValGroup/ESMValTool/discussions). +The ESMValTool [Discussions page](https://github.com/ESMValGroup/ESMValTool/discussions). is a good place to learn about general issues, or to see if your question has been already addressed. If you have a GitHub account, you can also post your questions on the page. From 29ea6a1487f516d2572ed3ef262d528a2fa2df9a Mon Sep 17 00:00:00 2001 From: rswamina Date: Mon, 24 Jan 2022 23:37:32 +0000 Subject: [PATCH 625/647] edits to yml code bloack type --- _episodes/07-development-setup.md | 2 +- _episodes/08-diagnostics.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/07-development-setup.md b/_episodes/07-development-setup.md index 9be8a8b7..43678a8f 100644 --- a/_episodes/07-development-setup.md +++ b/_episodes/07-development-setup.md @@ -365,7 +365,7 @@ when you submit a pull request. >> To fix the recipe, we need to edit the path of the diagnostic script >> as ``warming_stripes.py``: >> ->> ~~~yml +>> ~~~yaml >> scripts: >> warming_stripes_script: >> script: warming_stripes.py diff --git a/_episodes/08-diagnostics.md b/_episodes/08-diagnostics.md index 6b433cde..c6c6d2a9 100644 --- a/_episodes/08-diagnostics.md +++ b/_episodes/08-diagnostics.md @@ -430,13 +430,13 @@ function of our choice. As can be seen, this function uses section in the recipe ``recipe_python.yml``, you see ``quickplot`` is a key there: -~~~yaml +```yaml script1: script: examples/diagnostic.py quickplot: plot_type: pcolormesh cmap: Reds -~~~ +``` This way, we can pass arguments such as the type of plot ``pcolormesh`` and the colormap ``cmap:Reds`` from the recipe to the @@ -451,13 +451,13 @@ plot ``pcolormesh`` and the colormap ``cmap:Reds`` from the recipe to the >> In the recipe ``recipe_python.yml``, you could change ``plot_type`` and ``cmap``. >> As an example, we choose ``plot_type: pcolor`` and ``cmap: BuGn``: >> ->> ~~~yaml +>> ```yaml >> script1: >> script: examples/diagnostic.py >> quickplot: >> plot_type: pcolor >> cmap: BuGn ->>~~~ +>>``` >> >> The plot can be found at *path_to_recipe_output/plots/map/script1/png*. > {: .solution} From 5ceca57eed6eff307b6bd856f680ef12e0de76a3 Mon Sep 17 00:00:00 2001 From: rswamina Date: Mon, 24 Jan 2022 23:44:14 +0000 Subject: [PATCH 626/647] edits to yml code block type --- _episodes/07-development-setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/07-development-setup.md b/_episodes/07-development-setup.md index 43678a8f..a9940281 100644 --- a/_episodes/07-development-setup.md +++ b/_episodes/07-development-setup.md @@ -365,11 +365,11 @@ when you submit a pull request. >> To fix the recipe, we need to edit the path of the diagnostic script >> as ``warming_stripes.py``: >> ->> ~~~yaml +>> ```yaml >> scripts: >> warming_stripes_script: >> script: warming_stripes.py ->> ~~~ +>> ``` >> >> For details, see lesson >> [Writing your own diagnostic script]({{ page.root }}{% link _episodes/08-diagnostics.md %}). From a2503055aabe54929aec6c8a2849c3e556b372ba Mon Sep 17 00:00:00 2001 From: rswamina Date: Tue, 25 Jan 2022 00:02:25 +0000 Subject: [PATCH 627/647] added title to recipe --- _episodes/09-cmorization.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 228ba4d0..3ccfc877 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -205,6 +205,7 @@ CMORized, ESMValTool will give a warning or error. > > documentation: > > > > description: Test recipe for FLUXCOM data +>> title: This is a test recipe for the FLUXCOM data. > > > > authors: > > - kalverla_peter From 774dd352259cfc1bba55fbf88be4b8be8e19590e Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 30 Jan 2022 22:02:13 +0000 Subject: [PATCH 628/647] added text to clarify that the user config file will not be overwritten --- _episodes/03-configuration.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index d5e2f75a..3eeb8cfe 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -44,7 +44,10 @@ as the `target_dir`. If this option is not used, the file will be saved to the d location: `~/.esmvaltool/config-user.yml`, where `~` is the path to your home directory. Note that files and directories starting with a period are "hidden", to see the `.esmvaltool` directory in the terminal use -`ls -la ~`. +`ls -la ~`. Note that if a configuration file by that name already exists in the default +location, the `get_config_user` command will not update the file as ESMValTool will not +overwrite the file. You will have to move the file first if you want an updated copy of the +user configuration file. From 4ca1e04e599abcdd3c2236049881b9fc84e2ad34 Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 30 Jan 2022 22:07:30 +0000 Subject: [PATCH 629/647] added text to clarify OBS may be a name for obs data --- _episodes/03-configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/03-configuration.md b/_episodes/03-configuration.md index 3eeb8cfe..551645e0 100644 --- a/_episodes/03-configuration.md +++ b/_episodes/03-configuration.md @@ -137,8 +137,8 @@ using the format: YYYYMMDD_HHMMSS. ESMValTool uses several categories (in ESMValTool, this is referred to as projects) for input data based on their source. The current categories in the configuration file are mentioned below. For example, CMIP is used for a dataset from -the Climate Model Intercomparison Project whereas OBS is used for an observational -dataset. +the Climate Model Intercomparison Project whereas OBS may be +used for an observational dataset. More information about the projects used in ESMValTool is available in the [documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html). When using ESMValTool on your own machine, you can create a directory to download From ba19835f41f5f23f384d497ed6105e3414914501 Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 30 Jan 2022 22:17:00 +0000 Subject: [PATCH 630/647] fixed config file path in a couple of places --- _episodes/04-recipe.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index b7b1028f..507b4947 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -202,14 +202,14 @@ Let's dissect what's happening here. > > ## Answers > > > > 1. The config file should be the one we edited in the previous episode, -> > something like `/home//.esmvaltool/config-user.yml` or `./config-user.yml`. +> > something like `/home//.esmvaltool/config-user.yml` or `~/esmvaltool_tutorial/config-user.yml`. > > 1. ESMValTool found the recipe in its installation directory, something like -> > `/home/user/username/miniconda3/envs/esmvaltool/bin/esmvaltool/recipes/examples/` +> > `/home/users/username/miniconda3/envs/esmvaltool/bin/esmvaltool/recipes/examples/` >> or if you are using a pre-installed module on a server, something like `/apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/recipes/examples/recipe_python.yml` > > 1. ESMValTool creates a time-stamped output directory for every run. In this > > case, it should be something like `recipe_python_YYYYMMDD_HHMMSS`. This > > folder is made inside the output directory specified in the previous -> > episode: `~/home//esmvaltool_tutorial/esmvaltool_output`. +> > episode: `~/esmvaltool_tutorial/esmvaltool_output`. > > 1. There should be four output folders: > > - `plots/`: this is where output figures are stored. > > - `preproc/`: this is where pre-processed data are stored. From 1b0f4bc4ba8d623a75103ff8617ed6a7cdf0f907 Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 30 Jan 2022 22:19:44 +0000 Subject: [PATCH 631/647] removed full stop to correct grammar. --- _episodes/05-conclusions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/05-conclusions.md b/_episodes/05-conclusions.md index 55becc14..cbe78cd9 100644 --- a/_episodes/05-conclusions.md +++ b/_episodes/05-conclusions.md @@ -69,7 +69,7 @@ to be suitable for use by ESMValTool. There are lots of resources available for helping you use ESMValTool. -The ESMValTool [Discussions page](https://github.com/ESMValGroup/ESMValTool/discussions). +The ESMValTool [Discussions page](https://github.com/ESMValGroup/ESMValTool/discussions) is a good place to learn about general issues, or to see if your question has been already addressed. If you have a GitHub account, you can also post your questions on the page. From e03daae8658b3c092f1eab0c674e60642167a7e0 Mon Sep 17 00:00:00 2001 From: rswamina Date: Sun, 30 Jan 2022 22:30:01 +0000 Subject: [PATCH 632/647] added title to recipe in example --- _episodes/06-preprocessor.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_episodes/06-preprocessor.md b/_episodes/06-preprocessor.md index b514f5de..5ecde474 100644 --- a/_episodes/06-preprocessor.md +++ b/_episodes/06-preprocessor.md @@ -95,6 +95,7 @@ description. --- documentation: description: Reproducing Ed Hawkins' warming stripes visualization + title: This recipe produces warming stripes. ``` Notice that `yaml` always requires 2 spaces indentation between the different From 4b099d459cf0aae019f2dca8f503f8113663e710 Mon Sep 17 00:00:00 2001 From: rswamina Date: Fri, 4 Feb 2022 23:23:30 +0000 Subject: [PATCH 633/647] Added title to recipe and some other minor edits for better readability --- _episodes/06-preprocessor.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/_episodes/06-preprocessor.md b/_episodes/06-preprocessor.md index 5ecde474..cf55de44 100644 --- a/_episodes/06-preprocessor.md +++ b/_episodes/06-preprocessor.md @@ -22,7 +22,7 @@ keypoints: One of the key strenghts of ESMValTool is in making complex analyses reusable and reproducible. But that doesn't mean everything in ESMValTool needs to be -complex. Sometimes, the biggest challenge is in making things simpler. You +complex. Sometimes, the biggest challenge is in keeping things simple. You probably know the 'warming stripes' visualization by Professor Ed Hawkins. On the site you can find the same visualization for many regions in the world. @@ -46,9 +46,9 @@ preprocessing, and then runs our Python script. > ## Drawing up a plan > -> Previously, we have seen that ESMValTool executed a number of -> tasks. Write down which tasks we will need to do in this episode. And what do -> each of these tasks do? +> Previously, we saw that running ESMValTool executes a number of +> tasks. Write down what tasks we will need to execute in this episode and what +> each of these tasks does? > > > ## Answer > > @@ -95,7 +95,8 @@ description. --- documentation: description: Reproducing Ed Hawkins' warming stripes visualization - title: This recipe produces warming stripes. + title: Reproducing Ed Hawkins' warming stripes visualization. + ``` Notice that `yaml` always requires 2 spaces indentation between the different @@ -118,9 +119,8 @@ Error validating data /home/user/esmvaltool_tutorial/recipe_barcodes.yml with sc {: .error} Here, ESMValTool is telling us that it is missing a required field, namely the -authors. It is good to know that ESMValTool always tries to validate the recipe -in an early stage. This initial check doesn't catch everything though, so we -should always stay alert. +authors. We see that ESMValTool always tries to validate the recipe +at an early stage. Let's add some additional information to the recipe. Open the recipe file again, and add an authors section below the description. ESMValTool expects the authors @@ -140,6 +140,8 @@ below the documentation. The file should now look like: --- documentation: description: Reproducing Ed Hawkins' warming stripes visualization + title: Reproducing Ed Hawkins' warming stripes visualization. + authors: - doe_john diagnostics: @@ -354,7 +356,7 @@ for each of the modifications we'll make below. > > You could have used `extract_point` or `extract_region`. We used > > `extract_point`. Here's a copy of the [recipe at this > > point](../files/recipe_warming_stripes_local.yml) and this is the difference -> > with the previous recipe: +> > from the previous recipe: > > > > ```diff > > --- recipe_warming_stripes.yml From a6d2b53a1942ac3313b40d1737795c845344c924 Mon Sep 17 00:00:00 2001 From: rswamina Date: Thu, 10 Feb 2022 22:12:09 +0000 Subject: [PATCH 634/647] changes made to clarify that recipes produce an error message when run without a variable to process --- _episodes/06-preprocessor.md | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/_episodes/06-preprocessor.md b/_episodes/06-preprocessor.md index cf55de44..e4689560 100644 --- a/_episodes/06-preprocessor.md +++ b/_episodes/06-preprocessor.md @@ -174,18 +174,21 @@ For now, let's just use one of the existing references. Change the author field ESMValTool. If you now run the recipe again, you should see the final message ``` -INFO Run was successful +ERROR No tasks to run! ``` {: .output} +Although there is no actual error in the recipe, ESMValTool assumes you mistakenly +left out a variable name to process and alerts you with this error message. ## Adding a dataset entry Let's add a datasets section. We will reuse the same datasets that we used in -previous episodes. The data files are stored in `~/esmvaltool_tutorial/data`. +previous episodes. > ## Filling in the dataset keys > -> Explore the data directory, and look at the explanation of the dataset entry +> Use the paths specified in the configuration file to explore the data directory, +> and look at the explanation of the dataset entry > in the [ESMValTool > documentation](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/recipe/overview.html#recipe-section-documentation). > For both the datasets, write down the following properties: @@ -219,18 +222,23 @@ previous episodes. The data files are stored in `~/esmvaltool_tutorial/data`. > {: .solution} {: .challenge} -We will start with the BCC-ESM1 dataset. Add a datasets section to the recipe, -listing a single dataset, like so: +We start with the BCC-ESM1 dataset and add a datasets section to the recipe, +listing a single dataset, as shown below. Note that key fields such +as `mip` or `start_year` are included in the `datasets` section here but are part +of the `diagnostic` section in the recipe example seen in [Running your first recipe]({{ page.root }}{% link _episodes/04-recipe.md %}). ```yaml datasets: - - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn, start_year: 1850, end_year: 2014} + - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, +ensemble: r1i1p1f1, grid: gn, start_year: 1850, end_year: 2014} ``` -Verify that the recipe still runs. Note that we have not included the short name -of the variable in this dataset section. This allows us to reuse this dataset -entry with different variable names later on. This is not really necessary for -our simple use case, but it is common practice in ESMValTool. +The recipe should run but produce the same message as in the previous case since we +still have not included a variable to actually process. We have not included the +short name of the variable in this dataset section because this allows +us to reuse this dataset entry with different variable names later on. +This is not really necessary for our simple use case, but it is common practice +in ESMValTool. ## Adding the preprocessor section From 5c7d02ef4f715518ee24075ad3e2701562920000 Mon Sep 17 00:00:00 2001 From: rswamina <42945525+rswamina@users.noreply.github.com> Date: Fri, 11 Feb 2022 10:35:16 +0000 Subject: [PATCH 635/647] Update _episodes/06-preprocessor.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/06-preprocessor.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_episodes/06-preprocessor.md b/_episodes/06-preprocessor.md index e4689560..45863dd5 100644 --- a/_episodes/06-preprocessor.md +++ b/_episodes/06-preprocessor.md @@ -229,8 +229,7 @@ of the `diagnostic` section in the recipe example seen in [Running your first re ```yaml datasets: - - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, -ensemble: r1i1p1f1, grid: gn, start_year: 1850, end_year: 2014} + - {dataset: BCC-ESM1, project: CMIP6, mip: Amon, exp: historical, ensemble: r1i1p1f1, grid: gn, start_year: 1850, end_year: 2014} ``` The recipe should run but produce the same message as in the previous case since we From f83b91737c28d620601a8e43bf52888f88a6cafe Mon Sep 17 00:00:00 2001 From: Remi Kazeroni Date: Mon, 30 May 2022 13:40:13 +0200 Subject: [PATCH 636/647] review suggestions added --- _episodes/09-cmorization.md | 64 +++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 3ccfc877..a6294840 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -40,8 +40,9 @@ the data. This process is called "CMORization". > Concretely, the CMOR standards dictate e.g. the variable names and units, coordinate information, how the data should be structured (e.g. 1 variable per file), additional metadata requirements, but also file naming conventions a.k.a. -the data reference syntax (DRS). All this information is stored in so-called -CMOR tables. As an example, the CMOR tables for the CMIP6 project can be found +the data reference syntax ([DRS](https://docs.esmvaltool.org/projects/esmvalcore/en/latest/quickstart/find_data.html)). +> All this information is stored in so-called CMOR tables. +> As an example, the CMOR tables for the CMIP6 project can be found [here](https://github.com/PCMDI/cmip6-cmor-tables). {: .callout} @@ -58,6 +59,7 @@ ESMValTool offers two ways to CMORize data: In this lesson, we will re-implement a CMORizer script for the FLUXCOM dataset that contains observations of the Gross Primary Production (GPP), a variable that is important for calculating components of the global carbon cycle. +See the next section on how to obtain data. We will assume that you are using a development installation of ESMValTool as explained in the [Development and Contribution episode](/07-development-setup). @@ -73,7 +75,7 @@ button on the "FLUXCOM (RS+METEO) Global Land Carbon Fluxes using CRUNCEP climate data". You'll receive an email with the FTP address to access the server. Connect to the server, follow the path in your email, and look for the file `raw/monthly/GPP.ANN.CRUNCEPv6.monthly.2000.nc`. Download that file and -save it in a folder called `/RAWOBS/Tier3/FLUXCOM`. +save it in a folder called `~/data/RAWOBS/Tier3/FLUXCOM`. Note: you'll need a user-friendly ftp client. On Linux, `ncftp` works okay. @@ -116,10 +118,20 @@ run the CMORizer scripts: cmorize_obs -c -o ``` -The ``config-user-yml`` is the file in which we define the different data -paths, e.g. where the ESMValTool would find the "RAWOBS" folder. The -``dataset-name`` needs to be identical to the folder name that was created -to store the raw observation data files, in our case this would be "FLUXCOM". +The ``config-user.yml`` is the file in which we define the different data +paths, see the episode on [Configuration](03-configuration). +In the ``rootpath`` of your ``config-user.yml`, make sure to add the right +directory for "RAWOBS" data in which you downloaded the FLUXCOM dataset: + +```yaml +rootpath: + RAWOBS: ~/data/RAWOBS +``` + +This enables ESMValTool to find the raw observational datasets stored in the +"RAWOBS" folder. The ``dataset-name`` needs to be identical to the folder +name that was created to store the raw observation data files, i.e. +``RAWOBS/TierX/dataset-name``. In our case this would be "FLUXCOM". If everything is okay, the output should look something like this: @@ -157,15 +169,21 @@ If everything is okay, the output should look something like this: {: .output} So you can see that several fixes are applied, and the CMORized file is written -to the ESMValTool output directory. In order to use it, we'll have to copy it -from the output directory to a folder called -`/OBS/Tier3/FLUXCOM` and make sure the path to ``OBS`` is set -correctly in our config-user file. +to the ESMValTool output directory, i.e. +`~/esmvaltool_output/cmorize_obs_YYYYMMDD_HHMMSS/TierX/dataset-name/filename.nc` +In order to use it, we'll have to copy it from the output directory to a folder +called `~/data/OBS/Tier3/FLUXCOM` and make sure the path to ``OBS`` is set +correctly in our config-user file: + +```yaml +rootpath: + OBS: ~/data/OBS +``` You can also see the path where ESMValTool stores the reformatting script: -`/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py`. You may +`~/ESMValTool/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py`. You may have a look at this file if you want. The script also uses a configuration file: -`/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml`. +`~/ESMValTool/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml`. ## Make a test recipe @@ -247,9 +265,9 @@ going on. We'll also remove the CMORized data that we've just created, so our test recipe will not be able to use it anymore. ```bash -rm /OBS/Tier3/FLUXCOM/OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_200001-200012.nc -rm /esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.nc -rm /esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml +rm ~/data/OBS/Tier3/FLUXCOM/OBS_FLUXCOM_reanaly_ANN-v1_Lmon_gpp_200001-200012.nc +rm ~/ESMValTool/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py +rm ~/ESMValTool/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml ``` If you now run the test recipe again it should fail, and somewhere in the output @@ -301,7 +319,7 @@ shortly. When you type the command ``cmorize_obs`` in the terminal, ESMValTool will call this function with the settings found in your configuration files. The ESMValTool CMORizer also needs a dataset configuration file. Create a file -called `/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml` +called `~/ESMValTool/esmvaltool/cmorizers/obs/cmor_config/FLUXCOM.yml` and fill it with the following boilerplate: ```yaml @@ -323,7 +341,7 @@ attributes: # mip: ??? ``` - **Note**: the name of this file *must* be identical to dataset name. + **Note**: the name of this file *must* be identical to ``dataset-name``. As you can see, the configuration file contains information about the original filename of the dataset, and some additional metadata that you might recognize @@ -556,9 +574,15 @@ address in the next section. ### 3. Implementing additional fixes -Copy the output of the CMORizer to your folder `/OBS6/Tier3/` +Copy the output of the CMORizer to your folder `~/data/OBS6/Tier3/` and change the test recipe to look for OBS6 data instead of OBS (note: we're -upgrading the CMORizer to newer standards here!). +upgrading the CMORizer to newer standards here!). Make sure the path to ``OBS6`` +is set correctly in our config-user file: + +```yaml +rootpath: + OBS6: ~/data/OBS6 +``` If we now run the test recipe on our newly 'CMORized' data, From 92f4f996ddf6bc28610f3923af8242c415a24d63 Mon Sep 17 00:00:00 2001 From: Remi Kazeroni Date: Mon, 30 May 2022 13:47:14 +0200 Subject: [PATCH 637/647] broken links fixed --- _episodes/09-cmorization.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index a6294840..3f58626c 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -62,7 +62,7 @@ that is important for calculating components of the global carbon cycle. See the next section on how to obtain data. We will assume that you are using a development installation of ESMValTool as -explained in the [Development and Contribution episode](/07-development-setup). +explained in the [Development and Contribution episode]({{ page.root }}{% link _episodes/07-development-setup.md %}). ## Obtaining the data @@ -119,7 +119,7 @@ cmorize_obs -c -o ``` The ``config-user.yml`` is the file in which we define the different data -paths, see the episode on [Configuration](03-configuration). +paths, see the episode on [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}). In the ``rootpath`` of your ``config-user.yml`, make sure to add the right directory for "RAWOBS" data in which you downloaded the FLUXCOM dataset: @@ -243,7 +243,7 @@ CMORized, ESMValTool will give a warning or error. > > > > ``` > > -> > To learn more about writing a recipe, please refer to [Writing your own recipe](/06-preprocessor). +> > To learn more about writing a recipe, please refer to [Writing your own recipe]({{ page.root }}{% link _episodes/06-preprocessor.md %}). > > > {: .solution} {: .challenge} @@ -771,7 +771,7 @@ utils.set_global_atts(cube, attributes) reformat the dataset so that the ESMValTool can work with it, it would be great if you could provide the CMORizer, and ultimately with that the dataset, to the rest of the community. For more information, see the episode - on [Development and contribution](/07-development-setup). + on [Development and contribution]({{ page.root }}{% link _episodes/07-development-setup.md %}). - **Add documentation**. Make sure that you have added the info of your dataset to the User Guide so that people know it is available for the ESMValTool From 91244231486d94377e1ef38e55afa38c9646b560 Mon Sep 17 00:00:00 2001 From: Remi Kazeroni Date: Mon, 30 May 2022 13:52:59 +0200 Subject: [PATCH 638/647] path fixed --- _episodes/09-cmorization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 3f58626c..bec2ec72 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -288,7 +288,7 @@ The first step now is to create a new file in the right folder that will contain our new CMORizer instructions. Create a file called ``cmorize_obs_fluxcom.py`` ```bash -nano /esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py +nano ~/ESMValTool/esmvaltool/cmorizers/obs/cmorize_obs_fluxcom.py ``` and fill it with the following boilerplate code: From f5e3e579428b8650e98db45c038da1ab34ded95e Mon Sep 17 00:00:00 2001 From: Remi Kazeroni Date: Mon, 30 May 2022 14:05:57 +0200 Subject: [PATCH 639/647] episode updated --- _episodes/09-cmorization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index bec2ec72..320d93aa 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -61,8 +61,8 @@ that contains observations of the Gross Primary Production (GPP), a variable that is important for calculating components of the global carbon cycle. See the next section on how to obtain data. -We will assume that you are using a development installation of ESMValTool as -explained in the [Development and Contribution episode]({{ page.root }}{% link _episodes/07-development-setup.md %}). +As in the previous episode ([Development and Contribution episode]({{ page.root }}{% link _episodes/07-development-setup.md %})), +we will be using the development installation of ESMValTool. ## Obtaining the data From 3f3e60c919a3913dae67ec6f863e9bc6cd5b3a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Kazeroni?= <70641264+remi-kazeroni@users.noreply.github.com> Date: Tue, 7 Jun 2022 17:05:24 +0200 Subject: [PATCH 640/647] Switch to Levante and update documentation links --- setup.md | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/setup.md b/setup.md index f054c28e..047f8615 100644 --- a/setup.md +++ b/setup.md @@ -172,10 +172,10 @@ Please skip this section if you are not going to use DKRZ and go [here](#github- If you do not already have an account at the DKRZ, then [register](https://luv.dkrz.de/projects/newuser/) as soon as possible. You could find a short introduction on how to get started at DKRZ -[here](https://www.dkrz.de/up/my-dkrz/getting-started/getting-started-at-dkrz). +[here](https://docs.dkrz.de/doc/getting_started/index.html). -There is also a [user manual](https://www.dkrz.de/up/systems/mistral) for -Mistral which is DKRZ's current supercomputer. +There is also a [user manual](https://docs.dkrz.de/doc/levante/index.html) for +Levante which is DKRZ's current supercomputer. #### Join a project @@ -191,37 +191,34 @@ resources](https://www.dkrz.de/services/bereitstellung-von-rechenleistung?set_la #### Access to data on DKRZ CMIP5 and CMIP6 data are available in these directories: -- CMIP5: /mnt/lustre01/work/kd0956/CMIP5/data/cmip5/output1/ -- CMIP6: /mnt/lustre02/work/ik1017/CMIP6/data/CMIP6/CMIP/ +- CMIP5: /work/kd0956/CMIP5/data/cmip5/output1/ +- CMIP6: /work/ik1017/CMIP6/data/CMIP6/CMIP/ #### Test your Setup -Log into Mistral (DKRZ) +Log into Levante (DKRZ) ~~~ -ssh -X user-account@mistral.dkrz.de +ssh -X user-account@levante.dkrz.de ~~~ {: .language-bash} #### Additional information -Login nodes are for compiling and job submission only! For all other tasks, use -one of the pre- and post-processing nodes -~~~ -ssh -X @mistralpp.dkrz.de -~~~ -(see also [this](https://www.dkrz.de/up/systems/mistral/hpc-concepts)) +Login nodes are for compiling and job submission only! For all other tasks, you +can use the [interactive](https://docs.dkrz.de/doc/levante/running-jobs/partitions-and-limits.html#interactive) +partition or start an [interactive session](https://docs.dkrz.de/doc/levante/data-processing-on-levante.html#). Data storage: -- Personal data: home directory (24GiB) -- Project data: /work// -- Temporary data: scratch directory on /scratch/\*/ is +- Personal data: home directory (30GiB) +- Project data: /work/project_id/username +- Temporary data: scratch directory on /scratch/\*/username is automatically deleted after 14 days (15TiB) (Please use this directory for all your testing! Do not use the work directory for tests.) (see also - [this](https://www.dkrz.de/up/systems/mistral/hpc-concepts)) + [this](https://docs.dkrz.de/doc/levante/file-systems.html)) Running batch jobs: Info and examples on SLURM job scheduling system at DKRZ can -be found [here](https://www.dkrz.de/up/systems/mistral/running-job). +be found [here](https://docs.dkrz.de/doc/levante/running-jobs/index.html). Congratulations! Please go here [here](#github-account-advanced) next. From 0dd5cb0ae6a69580d852f8c9de86390914212074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Kazeroni?= <70641264+remi-kazeroni@users.noreply.github.com> Date: Tue, 7 Jun 2022 17:40:29 +0200 Subject: [PATCH 641/647] Update 02-installation.md --- _episodes/02-installation.md | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index 961b4305..f14414e4 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -192,14 +192,7 @@ For the tutorial, we will install the complete package. Thus, to install the ESMValTool package, run ```bash -mamba create --name esmvaltool 'python=3.9' -``` - -Next, we install many of the required dependencies, including the ESMValCore package -and Python, R, and NCL interpreters, into this environment by running: - -```bash -mamba env update --name esmvaltool --file environment.yml +mamba create --name esmvaltool esmvaltool 'python=3.10' ``` On MacOSX ESMValTool functionalities in Julia, NCL, and R are not supported. To install @@ -258,8 +251,8 @@ to display the command line help. > > {: .bash} > > The version of ESMValTool installed should be displayed on the screen as: > > ~~~ -> > ESMValCore: 2.4.0 -> > ESMValTool: 2.4.0 +> > ESMValCore: 2.5.0 +> > ESMValTool: 2.5.0 > > ~~~ > > {: .output} > {: .solution} From d16984584d9c46e963aa8f171c30fedc1fc5e164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Kazeroni?= <70641264+remi-kazeroni@users.noreply.github.com> Date: Tue, 7 Jun 2022 17:43:19 +0200 Subject: [PATCH 642/647] Update macos instructions --- _episodes/02-installation.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index f14414e4..c1f7b352 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -196,11 +196,7 @@ mamba create --name esmvaltool esmvaltool 'python=3.10' ``` On MacOSX ESMValTool functionalities in Julia, NCL, and R are not supported. To install -a Mamba environment on MacOSX, use the dedicated environment file: - -```bash -mamba env create --name esmvaltool --file environment_osx.yml -``` +a Mamba environment on MacOSX, please refer to specific [information](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#installation-on-macosx). This will create a new [Mamba environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) From eef7358c898f53dda020380cd9e2386f6bc6a058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Kazeroni?= <70641264+remi-kazeroni@users.noreply.github.com> Date: Tue, 7 Jun 2022 17:53:58 +0200 Subject: [PATCH 643/647] Update Julia installation --- _episodes/02-installation.md | 112 +++++++++++++---------------------- 1 file changed, 42 insertions(+), 70 deletions(-) diff --git a/_episodes/02-installation.md b/_episodes/02-installation.md index c1f7b352..57baf637 100644 --- a/_episodes/02-installation.md +++ b/_episodes/02-installation.md @@ -100,6 +100,42 @@ To install mamba on ``Linux`` or ``MacOSX``, follow the instructions below: For more information about installing mamba, see [the mamba installation documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#mamba-installation). +### Install the ESMValTool package + +The ESMValTool package contains diagnostics scripts in four languages: R, +Python, Julia and NCL. This introduces a lot of dependencies, and therefore the +installation can take quite long. It is, however, possible to install +'subpackages' for each of the languages. The following (sub)packages are +available: + +- `esmvaltool-python` +- `esmvaltool-ncl` +- `esmvaltool-r` +- `esmvaltool` --> the complete package, i.e. the combination of the above. + +For the tutorial, we will install the complete package. Thus, to install the +ESMValTool package, run + +```bash +mamba create --name esmvaltool esmvaltool 'python=3.10' +``` + +On MacOSX ESMValTool functionalities in Julia, NCL, and R are not supported. To install +a Mamba environment on MacOSX, please refer to specific [information](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#installation-on-macosx). + +This will create a new [Mamba +environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) +called `esmvaltool`, with the ESMValTool package and all of its dependencies +installed in it. + + +> ## Common issues +> +> You find a list of common installation problems and their solutions in the +> [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#common-installation-problems-and-their-solutions). +> +{: .callout} + ### Install Julia Some ESMValTool diagnostics are written in the Julia programming language. @@ -113,46 +149,18 @@ installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). > ## Julia installation instructions > -> First, open a bash terminal and create a directory to install Julia in and cd -> into it -> -> ```bash -> mkdir ~/julia -> cd ~/julia -> ``` -> -> Next, to download and extract the file `julia-1.0.5-linux-x86_64.tar.gz`, you can use the following commands:: -> -> ```bash -> wget https://julialang-s3.julialang.org/bin/linux/x64/1.0/julia-1.0.5-linux-x86_64.tar.gz -> tar -xvzf julia-1.0.5-linux-x86\_64.tar.gz -> ``` -> -> This will extract the files to a directory named `~/julia/julia-1.0.5`. To run -> Julia, you need to add the full path of Julia's `bin` folder to PATH environment -> variable. To do this, you can edit the `~/.bashrc` (or `~/.bash_profile`) file. -> Open the file in a text editor called ``nano``: -> -> ```bash -> nano ~/.bashrc -> ``` -> -> and add a new line as follows at the -> bottom of the file: +> First, open a bash terminal and activate the newly created `esmvaltool` environment. > > ```bash -> export PATH="$PATH:$HOME/julia/julia-1.0.5/bin" +> conda activate esmvaltool > ``` > -> Finally, for the settings to take effect, either reload your bash profile +> Next, to install Julia via `mamba`, you can use the following command: > > ```bash -> source ~/.bashrc +> mamba install julia > ``` -> -> (or `source ~/.bash_profile`), or close the bash terminal window and open a new -> one. -> +> > To check that the Julia executable can be found, run > > ```bash @@ -162,7 +170,7 @@ installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). > to display the path to the Julia executable, it should be > > ``` -> ~/julia/julia-1.0.5/bin/julia +> ~/mambaforge/envs/esmvaltool/bin/julia > ``` > {: .output} > @@ -175,42 +183,6 @@ installation page](https://julialang.org/downloads/platform/#linux_and_freebsd). > to start the interactive Julia interpreter. Press `Ctrl+D` to exit. {: .solution} -### Install the ESMValTool package - -The ESMValTool package contains diagnostics scripts in four languages: R, -Python, Julia and NCL. This introduces a lot of dependencies, and therefore the -installation can take quite long. It is, however, possible to install -'subpackages' for each of the languages. The following (sub)packages are -available: - -- `esmvaltool-python` -- `esmvaltool-ncl` -- `esmvaltool-r` -- `esmvaltool` --> the complete package, i.e. the combination of the above. - -For the tutorial, we will install the complete package. Thus, to install the -ESMValTool package, run - -```bash -mamba create --name esmvaltool esmvaltool 'python=3.10' -``` - -On MacOSX ESMValTool functionalities in Julia, NCL, and R are not supported. To install -a Mamba environment on MacOSX, please refer to specific [information](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#installation-on-macosx). - -This will create a new [Mamba -environment](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) -called `esmvaltool`, with the ESMValTool package and all of its dependencies -installed in it. - - -> ## Common issues -> -> You find a list of common installation problems and their solutions in the -> [documentation](https://docs.esmvaltool.org/en/latest/quickstart/installation.html#common-installation-problems-and-their-solutions). -> -{: .callout} - ### Test that the installation was successful To test that the installation was successful, run From 3babeeda5ef28fb833f09731233acdf386bf53a8 Mon Sep 17 00:00:00 2001 From: Remi Kazeroni Date: Wed, 8 Jun 2022 12:20:08 +0200 Subject: [PATCH 644/647] version and date changed --- _episodes/04-recipe.md | 170 ++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 507b4947..243e7105 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -87,90 +87,90 @@ like the example output below. >For further help, please read the documentation at >http://docs.esmvaltool.org. Have fun! > ->2022-01-24 17:31:48,745 UTC [190720] INFO Package versions ->2022-01-24 17:31:48,746 UTC [190720] INFO ---------------- ->2022-01-24 17:31:48,746 UTC [190720] INFO ESMValCore: 2.4.0 ->2022-01-24 17:31:48,746 UTC [190720] INFO ESMValTool: 2.4.0 ->2022-01-24 17:31:48,746 UTC [190720] INFO ---------------- ->2022-01-24 17:31:48,746 UTC [190720] INFO Using config file /home/users/username/esmvaltool-tutorial/config-user.yml ->2022-01-24 17:31:48,746 UTC [190720] INFO Writing program log files to: ->/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/main_log.txt ->/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/main_log_debug.txt ->2022-01-24 17:31:48,747 UTC [190720] INFO Starting the Earth System Model Evaluation Tool at time: 2022-01-24 17:31:48 UTC ->2022-01-24 17:31:48,747 UTC [190720] INFO ---------------------------------------------------------------------- ->2022-01-24 17:31:48,747 UTC [190720] INFO RECIPE = /apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/recipes/examples/recipe_python.yml ->2022-01-24 17:31:48,747 UTC [190720] INFO RUNDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run ->2022-01-24 17:31:48,747 UTC [190720] INFO WORKDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/work ->2022-01-24 17:31:48,747 UTC [190720] INFO PREPROCDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/preproc ->2022-01-24 17:31:48,747 UTC [190720] INFO PLOTDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/plots ->2022-01-24 17:31:48,747 UTC [190720] INFO ---------------------------------------------------------------------- ->2022-01-24 17:31:48,747 UTC [190720] INFO Running tasks using at most 24 processes ->2022-01-24 17:31:48,747 UTC [190720] INFO If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. ->2022-01-24 17:31:48,747 UTC [190720] INFO If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. ->2022-01-24 17:31:48,805 UTC [190720] INFO Creating tasks from recipe ->2022-01-24 17:31:48,805 UTC [190720] INFO Creating tasks for diagnostic map ->2022-01-24 17:31:48,805 UTC [190720] INFO Creating preprocessor task map/tas ->2022-01-24 17:31:48,805 UTC [190720] INFO Creating preprocessor 'select_january' task for variable 'tas' ->2022-01-24 17:31:48,835 UTC [190720] INFO Found input files for CMIP6 ->2022-01-24 17:31:48,900 UTC [190720] INFO Found input files for CMIP5 ->2022-01-24 17:31:48,961 UTC [190720] INFO PreprocessingTask map/tas created. ->2022-01-24 17:31:48,961 UTC [190720] INFO Creating diagnostic task map/script1 ->2022-01-24 17:31:48,962 UTC [190720] INFO Creating tasks for diagnostic timeseries ->2022-01-24 17:31:48,962 UTC [190720] INFO Creating preprocessor task timeseries/tas_amsterdam ->2022-01-24 17:31:48,963 UTC [190720] INFO Creating preprocessor 'annual_mean_amsterdam' task for variable 'tas' ->2022-01-24 17:31:48,969 UTC [190720] INFO Found input files for CMIP6 ->2022-01-24 17:31:49,019 UTC [190720] INFO Found input files for CMIP5 ->2022-01-24 17:31:49,063 UTC [190720] INFO PreprocessingTask timeseries/tas_amsterdam created. ->2022-01-24 17:31:49,064 UTC [190720] INFO Creating preprocessor task timeseries/tas_global ->2022-01-24 17:31:49,064 UTC [190720] INFO Creating preprocessor 'annual_mean_global' task for variable 'tas' ->2022-01-24 17:31:49,065 UTC [190720] WARNING Missing data for fx variable 'areacella' of dataset CMIP6 ->2022-01-24 17:31:49,071 UTC [190720] INFO Found input files for CMIP6 ->2022-01-24 17:31:49,138 UTC [190720] INFO Found input files for CMIP5 ->2022-01-24 17:31:49,183 UTC [190720] INFO PreprocessingTask timeseries/tas_global created. ->2022-01-24 17:31:49,183 UTC [190720] INFO Creating diagnostic task timeseries/script1 ->2022-01-24 17:31:49,184 UTC [190720] INFO These tasks will be executed: map/script1, map/tas, timeseries/tas_amsterdam, timeseries/script1, timeseries/tas_global ->2022-01-24 17:31:49,195 UTC [190720] INFO Running 5 tasks using 5 processes ->2022-01-24 17:31:49,239 UTC [190776] INFO Starting task map/tas in process [190776] ->2022-01-24 17:31:49,240 UTC [190777] INFO Starting task timeseries/tas_amsterdam in process [190777] ->2022-01-24 17:31:49,240 UTC [190778] INFO Starting task timeseries/tas_global in process [190778] ->2022-01-24 17:31:49,335 UTC [190720] INFO Progress: 3 tasks running, 2 tasks waiting for ancestors, 0/5 done ->2022-01-24 17:31:55,735 UTC [190776] INFO Successfully completed task map/tas (priority 0) in 0:00:06.494906 ->2022-01-24 17:31:55,847 UTC [190720] INFO Progress: 2 tasks running, 2 tasks waiting for ancestors, 1/5 done ->2022-01-24 17:31:55,852 UTC [190779] INFO Starting task map/script1 in process [190779] ->2022-01-24 17:31:55,861 UTC [190779] INFO Running command ['/apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python', '/apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/diag_scripts/examples/diagnostic.py', '/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/map/script1/settings.yml'] ->2022-01-24 17:31:55,862 UTC [190779] INFO Writing output to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/work/map/script1 ->2022-01-24 17:31:55,862 UTC [190779] INFO Writing plots to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/plots/map/script1 ->2022-01-24 17:31:55,862 UTC [190779] INFO Writing log to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/map/script1/log.txt ->2022-01-24 17:31:55,862 UTC [190779] INFO To re-run this diagnostic script, run: ->cd /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/map/script1; MPLBACKEND="Agg" /apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python /apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/diag_scripts/examples/diagnostic.py /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/map/script1/settings.yml ->2022-01-24 17:31:55,947 UTC [190720] INFO Progress: 3 tasks running, 1 tasks waiting for ancestors, 1/5 done ->2022-01-24 17:31:58,538 UTC [190777] INFO Generated PreprocessorFile: /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/preproc/timeseries/tas_amsterdam/MultiModelMean_Amon_tas_1850-2000.nc ->2022-01-24 17:31:58,762 UTC [190777] INFO Successfully completed task timeseries/tas_amsterdam (priority 2) in 0:00:09.521837 ->2022-01-24 17:31:58,953 UTC [190720] INFO Progress: 2 tasks running, 1 tasks waiting for ancestors, 2/5 done ->2022-01-24 17:31:59,700 UTC [190778] INFO Successfully completed task timeseries/tas_global (priority 3) in 0:00:10.459256 ->2022-01-24 17:31:59,855 UTC [190720] INFO Progress: 1 tasks running, 1 tasks waiting for ancestors, 3/5 done ->2022-01-24 17:31:59,863 UTC [190780] INFO Starting task timeseries/script1 in process [190780] ->2022-01-24 17:31:59,871 UTC [190780] INFO Running command ['/apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python', '/apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/diag_scripts/examples/diagnostic.py', '/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/timeseries/script1/settings.yml'] ->2022-01-24 17:31:59,872 UTC [190780] INFO Writing output to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/work/timeseries/script1 ->2022-01-24 17:31:59,872 UTC [190780] INFO Writing plots to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/plots/timeseries/script1 ->2022-01-24 17:31:59,872 UTC [190780] INFO Writing log to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/timeseries/script1/log.txt ->2022-01-24 17:31:59,872 UTC [190780] INFO To re-run this diagnostic script, run: ->cd /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/timeseries/script1; MPLBACKEND="Agg" /apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python /apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/diag_scripts/examples/diagnostic.py /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/run/timeseries/script1/settings.yml ->2022-01-24 17:31:59,956 UTC [190720] INFO Progress: 2 tasks running, 0 tasks waiting for ancestors, 3/5 done ->2022-01-24 17:32:01,586 UTC [190779] INFO Successfully completed task map/script1 (priority 1) in 0:00:05.733018 ->2022-01-24 17:32:01,760 UTC [190720] INFO Progress: 1 tasks running, 0 tasks waiting for ancestors, 4/5 done ->2022-01-24 17:32:06,079 UTC [190780] INFO Maximum memory used (estimate): 0.2 GB ->2022-01-24 17:32:06,081 UTC [190780] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. ->2022-01-24 17:32:06,760 UTC [190780] INFO Successfully completed task timeseries/script1 (priority 4) in 0:00:06.896972 ->2022-01-24 17:32:06,771 UTC [190720] INFO Progress: 0 tasks running, 0 tasks waiting for ancestors, 5/5 done ->2022-01-24 17:32:06,771 UTC [190720] INFO Successfully completed all tasks. ->2022-01-24 17:32:07,764 UTC [190720] INFO Wrote recipe output to: ->file:///home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220124_173145/index.html ->2022-01-24 17:32:07,764 UTC [190720] INFO Ending the Earth System Model Evaluation Tool at time: 2022-01-24 17:32:07 UTC ->2022-01-24 17:32:07,764 UTC [190720] INFO Time for running the recipe was: 0:00:19.017514 ->2022-01-24 17:32:08,702 UTC [190720] INFO Maximum memory used (estimate): 1.3 GB ->2022-01-24 17:32:08,703 UTC [190720] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. ->2022-01-24 17:32:08,704 UTC [190720] INFO Run was successful +>2022-04-24 17:31:48,745 UTC [190720] INFO Package versions +>2022-04-24 17:31:48,746 UTC [190720] INFO ---------------- +>2022-04-24 17:31:48,746 UTC [190720] INFO ESMValCore: 2.5.0 +>2022-04-24 17:31:48,746 UTC [190720] INFO ESMValTool: 2.5.0 +>2022-04-24 17:31:48,746 UTC [190720] INFO ---------------- +>2022-04-24 17:31:48,746 UTC [190720] INFO Using config file /home/users/username/esmvaltool-tutorial/config-user.yml +>2022-04-24 17:31:48,746 UTC [190720] INFO Writing program log files to: +>/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/main_log.txt +>/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/main_log_debug.txt +>2022-04-24 17:31:48,747 UTC [190720] INFO Starting the Earth System Model Evaluation Tool at time: 2022-04-24 17:31:48 UTC +>2022-04-24 17:31:48,747 UTC [190720] INFO ---------------------------------------------------------------------- +>2022-04-24 17:31:48,747 UTC [190720] INFO RECIPE = /apps/jasmin/community/esmvaltool/ESMValTool_2.5.0/esmvaltool/recipes/examples/recipe_python.yml +>2022-04-24 17:31:48,747 UTC [190720] INFO RUNDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run +>2022-04-24 17:31:48,747 UTC [190720] INFO WORKDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/work +>2022-04-24 17:31:48,747 UTC [190720] INFO PREPROCDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/preproc +>2022-04-24 17:31:48,747 UTC [190720] INFO PLOTDIR = /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/plots +>2022-04-24 17:31:48,747 UTC [190720] INFO ---------------------------------------------------------------------- +>2022-04-24 17:31:48,747 UTC [190720] INFO Running tasks using at most 24 processes +>2022-04-24 17:31:48,747 UTC [190720] INFO If your system hangs during execution, it may not have enough memory for keeping this number of tasks in memory. +>2022-04-24 17:31:48,747 UTC [190720] INFO If you experience memory problems, try reducing 'max_parallel_tasks' in your user configuration file. +>2022-04-24 17:31:48,805 UTC [190720] INFO Creating tasks from recipe +>2022-04-24 17:31:48,805 UTC [190720] INFO Creating tasks for diagnostic map +>2022-04-24 17:31:48,805 UTC [190720] INFO Creating preprocessor task map/tas +>2022-04-24 17:31:48,805 UTC [190720] INFO Creating preprocessor 'select_january' task for variable 'tas' +>2022-04-24 17:31:48,835 UTC [190720] INFO Found input files for CMIP6 +>2022-04-24 17:31:48,900 UTC [190720] INFO Found input files for CMIP5 +>2022-04-24 17:31:48,961 UTC [190720] INFO PreprocessingTask map/tas created. +>2022-04-24 17:31:48,961 UTC [190720] INFO Creating diagnostic task map/script1 +>2022-04-24 17:31:48,962 UTC [190720] INFO Creating tasks for diagnostic timeseries +>2022-04-24 17:31:48,962 UTC [190720] INFO Creating preprocessor task timeseries/tas_amsterdam +>2022-04-24 17:31:48,963 UTC [190720] INFO Creating preprocessor 'annual_mean_amsterdam' task for variable 'tas' +>2022-04-24 17:31:48,969 UTC [190720] INFO Found input files for CMIP6 +>2022-04-24 17:31:49,019 UTC [190720] INFO Found input files for CMIP5 +>2022-04-24 17:31:49,063 UTC [190720] INFO PreprocessingTask timeseries/tas_amsterdam created. +>2022-04-24 17:31:49,064 UTC [190720] INFO Creating preprocessor task timeseries/tas_global +>2022-04-24 17:31:49,064 UTC [190720] INFO Creating preprocessor 'annual_mean_global' task for variable 'tas' +>2022-04-24 17:31:49,065 UTC [190720] WARNING Missing data for fx variable 'areacella' of dataset CMIP6 +>2022-04-24 17:31:49,071 UTC [190720] INFO Found input files for CMIP6 +>2022-04-24 17:31:49,138 UTC [190720] INFO Found input files for CMIP5 +>2022-04-24 17:31:49,183 UTC [190720] INFO PreprocessingTask timeseries/tas_global created. +>2022-04-24 17:31:49,183 UTC [190720] INFO Creating diagnostic task timeseries/script1 +>2022-04-24 17:31:49,184 UTC [190720] INFO These tasks will be executed: map/script1, map/tas, timeseries/tas_amsterdam, timeseries/script1, timeseries/tas_global +>2022-04-24 17:31:49,195 UTC [190720] INFO Running 5 tasks using 5 processes +>2022-04-24 17:31:49,239 UTC [190776] INFO Starting task map/tas in process [190776] +>2022-04-24 17:31:49,240 UTC [190777] INFO Starting task timeseries/tas_amsterdam in process [190777] +>2022-04-24 17:31:49,240 UTC [190778] INFO Starting task timeseries/tas_global in process [190778] +>2022-04-24 17:31:49,335 UTC [190720] INFO Progress: 3 tasks running, 2 tasks waiting for ancestors, 0/5 done +>2022-04-24 17:31:55,735 UTC [190776] INFO Successfully completed task map/tas (priority 0) in 0:00:06.494906 +>2022-04-24 17:31:55,847 UTC [190720] INFO Progress: 2 tasks running, 2 tasks waiting for ancestors, 1/5 done +>2022-04-24 17:31:55,852 UTC [190779] INFO Starting task map/script1 in process [190779] +>2022-04-24 17:31:55,861 UTC [190779] INFO Running command ['/apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python', '/apps/jasmin/community/esmvaltool/ESMValTool_2.5.0/esmvaltool/diag_scripts/examples/diagnostic.py', '/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/map/script1/settings.yml'] +>2022-04-24 17:31:55,862 UTC [190779] INFO Writing output to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/work/map/script1 +>2022-04-24 17:31:55,862 UTC [190779] INFO Writing plots to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/plots/map/script1 +>2022-04-24 17:31:55,862 UTC [190779] INFO Writing log to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/map/script1/log.txt +>2022-04-24 17:31:55,862 UTC [190779] INFO To re-run this diagnostic script, run: +>cd /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/map/script1; MPLBACKEND="Agg" /apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python /apps/jasmin/community/esmvaltool/ESMValTool_2.5.0/esmvaltool/diag_scripts/examples/diagnostic.py /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/map/script1/settings.yml +>2022-04-24 17:31:55,947 UTC [190720] INFO Progress: 3 tasks running, 1 tasks waiting for ancestors, 1/5 done +>2022-04-24 17:31:58,538 UTC [190777] INFO Generated PreprocessorFile: /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/preproc/timeseries/tas_amsterdam/MultiModelMean_Amon_tas_1850-2000.nc +>2022-04-24 17:31:58,762 UTC [190777] INFO Successfully completed task timeseries/tas_amsterdam (priority 2) in 0:00:09.521837 +>2022-04-24 17:31:58,953 UTC [190720] INFO Progress: 2 tasks running, 1 tasks waiting for ancestors, 2/5 done +>2022-04-24 17:31:59,700 UTC [190778] INFO Successfully completed task timeseries/tas_global (priority 3) in 0:00:10.459256 +>2022-04-24 17:31:59,855 UTC [190720] INFO Progress: 1 tasks running, 1 tasks waiting for ancestors, 3/5 done +>2022-04-24 17:31:59,863 UTC [190780] INFO Starting task timeseries/script1 in process [190780] +>2022-04-24 17:31:59,871 UTC [190780] INFO Running command ['/apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python', '/apps/jasmin/community/esmvaltool/ESMValTool_2.5.0/esmvaltool/diag_scripts/examples/diagnostic.py', '/home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/timeseries/script1/settings.yml'] +>2022-04-24 17:31:59,872 UTC [190780] INFO Writing output to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/work/timeseries/script1 +>2022-04-24 17:31:59,872 UTC [190780] INFO Writing plots to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/plots/timeseries/script1 +>2022-04-24 17:31:59,872 UTC [190780] INFO Writing log to /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/timeseries/script1/log.txt +>2022-04-24 17:31:59,872 UTC [190780] INFO To re-run this diagnostic script, run: +>cd /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/timeseries/script1; MPLBACKEND="Agg" /apps/jasmin/community/esmvaltool/miniconda3/envs/esmvaltool/bin/python /apps/jasmin/community/esmvaltool/ESMValTool_2.5.0/esmvaltool/diag_scripts/examples/diagnostic.py /home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/run/timeseries/script1/settings.yml +>2022-04-24 17:31:59,956 UTC [190720] INFO Progress: 2 tasks running, 0 tasks waiting for ancestors, 3/5 done +>2022-04-24 17:32:01,586 UTC [190779] INFO Successfully completed task map/script1 (priority 1) in 0:00:05.733018 +>2022-04-24 17:32:01,760 UTC [190720] INFO Progress: 1 tasks running, 0 tasks waiting for ancestors, 4/5 done +>2022-04-24 17:32:06,079 UTC [190780] INFO Maximum memory used (estimate): 0.2 GB +>2022-04-24 17:32:06,081 UTC [190780] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +>2022-04-24 17:32:06,760 UTC [190780] INFO Successfully completed task timeseries/script1 (priority 4) in 0:00:06.896972 +>2022-04-24 17:32:06,771 UTC [190720] INFO Progress: 0 tasks running, 0 tasks waiting for ancestors, 5/5 done +>2022-04-24 17:32:06,771 UTC [190720] INFO Successfully completed all tasks. +>2022-04-24 17:32:07,764 UTC [190720] INFO Wrote recipe output to: +>file:///home/users/username/esmvaltool-tutorial/esmvaltool_output/recipe_python_20220424_173145/index.html +>2022-04-24 17:32:07,764 UTC [190720] INFO Ending the Earth System Model Evaluation Tool at time: 2022-04-24 17:32:07 UTC +>2022-04-24 17:32:07,764 UTC [190720] INFO Time for running the recipe was: 0:00:19.017514 +>2022-04-24 17:32:08,702 UTC [190720] INFO Maximum memory used (estimate): 1.3 GB +>2022-04-24 17:32:08,703 UTC [190720] INFO Sampled every second. It may be inaccurate if short but high spikes in memory consumption occur. +>2022-04-24 17:32:08,704 UTC [190720] INFO Run was successful > ``` > {: .solution} @@ -205,7 +205,7 @@ Let's dissect what's happening here. > > something like `/home//.esmvaltool/config-user.yml` or `~/esmvaltool_tutorial/config-user.yml`. > > 1. ESMValTool found the recipe in its installation directory, something like > > `/home/users/username/miniconda3/envs/esmvaltool/bin/esmvaltool/recipes/examples/` ->> or if you are using a pre-installed module on a server, something like `/apps/jasmin/community/esmvaltool/ESMValTool_2.4.0/esmvaltool/recipes/examples/recipe_python.yml` +>> or if you are using a pre-installed module on a server, something like `/apps/jasmin/community/esmvaltool/ESMValTool_2.5.0/esmvaltool/recipes/examples/recipe_python.yml` > > 1. ESMValTool creates a time-stamped output directory for every run. In this > > case, it should be something like `recipe_python_YYYYMMDD_HHMMSS`. This > > folder is made inside the output directory specified in the previous From f409eee23c245226dba09d5a8fcd2f4f6f79f91c Mon Sep 17 00:00:00 2001 From: Remi Kazeroni Date: Wed, 8 Jun 2022 12:21:59 +0200 Subject: [PATCH 645/647] svg files removed --- _episodes/04-recipe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_episodes/04-recipe.md b/_episodes/04-recipe.md index 243e7105..957d1ecb 100644 --- a/_episodes/04-recipe.md +++ b/_episodes/04-recipe.md @@ -465,12 +465,12 @@ Do you recognize the basic recipe structure that was introduced in episode 1? > > log of the diagnostic script run. It also creates `/plots/map/script1` and > > `/work/map/script1`, which contain output figures and output datasets, > > respectively. For each output file, there is also corresponding provenance -> > information in the form of `.svg`, `.xml`, `.bibtex` and `.txt` files. +> > information in the form of `.xml`, `.bibtex` and `.txt` files. > > - **timeseries/script1**: creates `/run/timeseries/script1` with general > > information and a log of the diagnostic script run. It also creates > > `/plots/timeseries/script1` and `/work/timeseries/script1`, which contain > > output figures and output datasets, respectively. For each output file, -> > there is also corresponding provenance information in the form of `.svg`, +> > there is also corresponding provenance information in the form of > > `.xml`, `.bibtex` and `.txt` files. > > > {: .solution} From 34033bdfaf9cd51c3c6b787fa3b738a464332145 Mon Sep 17 00:00:00 2001 From: Remi Kazeroni Date: Wed, 8 Jun 2022 16:38:12 +0200 Subject: [PATCH 646/647] episode updated --- _episodes/06-preprocessor.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_episodes/06-preprocessor.md b/_episodes/06-preprocessor.md index 45863dd5..0f69eab6 100644 --- a/_episodes/06-preprocessor.md +++ b/_episodes/06-preprocessor.md @@ -112,9 +112,11 @@ esmvaltool run recipe_warming_stripes.yml In this case, it gives an error. Below you see the last few lines of the error message. ``` ... -Error validating data /home/user/esmvaltool_tutorial/recipe_barcodes.yml with schema /home/user/miniconda3/envs/esmvaltool_tutorial/lib/python3.8/site-packages/esmvalcore/recipe_schema.yml +Error validating data /home/user/esmvaltool_tutorial/recipe_warming_stripes.yml with schema /home/user/mambaforge/envs/esmvaltool_tutorial/lib/python3.10/site-packages/esmvalcore/recipe_schema.yml documentation.authors: Required field missing -2020-10-08 15:23:11,162 UTC [19451] INFO If you suspect this is a bug or need help, please open an issue on https://github.com/ESMValGroup/ESMValTool/issues and attach the run/recipe_*.yml and run/main_log_debug.txt files from the output directory. +2020-10-08 15:23:11,162 UTC [19451] INFO If you have a question or need help, please start a new discussion on https://github.com/ESMValGroup/ESMValTool/discussions +If you suspect this is a bug, please open an issue on https://github.com/ESMValGroup/ESMValTool/issues +To make it easier to find out what the problem is, please consider attaching the files run/recipe_*.yml and run/main_log_debug.txt from the output directory. ``` {: .error} @@ -153,7 +155,7 @@ This is the minimal recipe layout that is required by ESMValTool. If we now run the recipe again, you will probably see the following error: ``` -ValueError: Tag 'doe_john' does not exist in section 'authors' of /home/user/miniconda3/envs/esmvaltool_tutorial/python3.8/site-packages/esmvaltool/config-references.yml +ValueError: Tag 'doe_john' does not exist in section 'authors' of /home/user/mambaforge/envs/esmvaltool_tutorial/python3.10/site-packages/esmvaltool/config-references.yml ``` {: .error} @@ -291,8 +293,6 @@ preprocessors: standardize: false ``` -and verify that the recipe still runs. - ## Completing the diagnostics section Now we are ready to finish our diagnostics section. Remember that we want to From 90908a54ebcf09b9b889affb850e78d98209ef2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Kazeroni?= <70641264+remi-kazeroni@users.noreply.github.com> Date: Fri, 10 Jun 2022 18:31:28 +0200 Subject: [PATCH 647/647] Update _episodes/09-cmorization.md Co-authored-by: SarahAlidoost <55081872+SarahAlidoost@users.noreply.github.com> --- _episodes/09-cmorization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_episodes/09-cmorization.md b/_episodes/09-cmorization.md index 320d93aa..902fd06a 100644 --- a/_episodes/09-cmorization.md +++ b/_episodes/09-cmorization.md @@ -120,7 +120,7 @@ cmorize_obs -c -o The ``config-user.yml`` is the file in which we define the different data paths, see the episode on [Configuration]({{ page.root }}{% link _episodes/03-configuration.md %}). -In the ``rootpath`` of your ``config-user.yml`, make sure to add the right +In the ``rootpath`` of your ``config-user.yml``, make sure to add the right directory for "RAWOBS" data in which you downloaded the FLUXCOM dataset: ```yaml