diff --git a/data/fieldlist_NCAR.jsonc b/data/fieldlist_NCAR.jsonc index 709fdbc06..8358c3a58 100644 --- a/data/fieldlist_NCAR.jsonc +++ b/data/fieldlist_NCAR.jsonc @@ -13,6 +13,8 @@ "lat": {"axis": "Y", "standard_name": "latitude", "units": "degrees_north"}, "TLONG": {"axis": "X", "standard_name": "array of t-grid longitudes", "units": "degrees_east"}, "TLAT": {"axis": "Y", "standard_name": "array of t-grid latitudes", "units": "degrees_north"}, + //"nlon": {"axis": "X", "standard_name": "xindex", "units": "degrees_east"}, + //"nlat": {"axis": "Y", "standard_name": "yindex", "units": "degrees_north"}, "plev": { "standard_name": "air_pressure", "units": "hPa", @@ -198,7 +200,13 @@ "units": "m2", "ndim": 2 }, - // Variables for AMOC_3D_Structure module: + "TAREA": { + "standard_name": "area of T cells", + "modifier": "ocean_realm", + "units": "centimeters^2", + "ndim": 2 + }, + // Variables for AMOC_3D_Structure module: // "uo": { // "standard_name": "sea_water_x_velocity", // "units": "m s-1" @@ -228,6 +236,21 @@ "standard_name": "Potential Temperature", "units": "degC", "ndim": 4 + }, + "SALT": { + "standard_name": "Salinity", + "units": "psu", + "ndim": 4 + }, + "SHF": { + "standard_name": "Surface Heat Flux", + "units": "watts m^-2", + "ndim": 3 + }, + "SFWF": { + "standard_name": "Surface Freshwater Flux", + "units": "kg/m2/s", + "ndim": 3 }, // Variables for Convective Transition Diagnostics module: // ta: 3D temperature, units = K: @@ -260,3 +283,5 @@ "date_int_offset" : 1 } } + + diff --git a/diagnostics/natl_ocean/doc/gaussians.jpg b/diagnostics/natl_ocean/doc/gaussians.jpg new file mode 100644 index 000000000..0236250eb Binary files /dev/null and b/diagnostics/natl_ocean/doc/gaussians.jpg differ diff --git a/diagnostics/natl_ocean/doc/wmt_dummy.rst b/diagnostics/natl_ocean/doc/wmt_dummy.rst new file mode 100644 index 000000000..3744d1561 --- /dev/null +++ b/diagnostics/natl_ocean/doc/wmt_dummy.rst @@ -0,0 +1,260 @@ +.. This is a comment in RestructuredText format (two periods and a space). + +.. Note that all "statements" and "paragraphs" need to be separated by a blank + line. This means the source code can be hard-wrapped to 80 columns for ease + of reading. Multi-line comments or commands like this need to be indented by + exactly three spaces. + +.. Underline with '='s to set top-level heading: + https://docutils.sourceforge.io/docs/user/rst/quickref.html#section-structure + +Example Diagnostic Documentation +================================ + +Last update: 5/06/2020 + +This is an example document that you can use as a template for your diagnostics' +own documentation: it describes what information you should provide in each +section. For example, if this were a real POD, you'd place a one-paragraph +synopsis of your diagnostic here (like an abstract). + +It also serves as an example of the RestructuredText (ReST, .rst) format used to +generate this page: compare this output with the input `source file +`__. +The easiest way to get started is to copy the source file into the online editor +at `https://livesphinx.herokuapp.com/ `__ and +experiment. + +.. Underline with '-'s to make a second-level heading. + +Version & Contact info +---------------------- + +.. '-' starts items in a bulleted list: + https://docutils.sourceforge.io/docs/user/rst/quickref.html#bullet-lists + +Here you should describe who contributed to the diagnostic, and who should be +contacted for further information: + +- Version/revision information: version 1 (5/06/2020) +- PI (name, affiliation, email) +- Developer/point of contact (name, affiliation, email) +- Other contributors + +.. Underline with '^'s to make a third-level heading. + +Open source copyright agreement +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The MDTF framework is distributed under the LGPLv3 license (see LICENSE.txt). +Unless you've distributed your script elsewhere, you don't need to change this. + +Functionality +------------- + +In this section you should summarize the stages of the calculations your +diagnostic performs, and how they translate to the individual source code files +provided in your submission. This will, e.g., let maintainers fixing a bug or +people with questions about how your code works know where to look. + +Required programming language and libraries +------------------------------------------- + +In this section you should summarize the programming languages and third-party +libraries used by your diagnostic. You also provide this information in the +``settings.jsonc`` file, but here you can give helpful comments to human +maintainers (eg, "We need at least version 1.5 of this library because we call +this function.") + +Required model output variables +------------------------------- + +In this section you should describe each variable in the input data your +diagnostic uses. You also need to provide this in the ``settings.jsonc`` file, +but here you should go into detail on the assumptions your diagnostic makes +about the structure of the data. + +References +---------- + +Here you should cite the journal articles providing the scientific basis for +your diagnostic. To keep the documentation format used in version 2.0 of +the framework, we list references "manually" with the following command: + +.. Note this syntax, which sets the "anchor" for the hyperlink: two periods, one + space, one underscore, the reference tag, and a colon, then a blank line. + +.. code-block:: restructuredtext + + .. _ref-Maloney: + + 1. E. D. Maloney et al. (2019): Process-Oriented Evaluation of Climate + and Weather Forecasting Models. *BAMS*, **100** (9), 1665–1686, + `doi:10.1175/BAMS-D-18-0042.1 `__. + +which produces + +.. _ref-Maloney: + +1. E. D. Maloney et al. (2019): Process-Oriented Evaluation of Climate and +Weather Forecasting Models. *BAMS*, **100** (9), 1665–1686, +`doi:10.1175/BAMS-D-18-0042.1 `__. + +which can be cited in text as ``:ref:`a hyperlink ```, which +gives :ref:`a hyperlink ` to the location of the reference on the +page. Because references are split between this section and the following "More +about this diagnostic" section, unfortunately you'll have to number references +manually. + +We don't enforce any particular bibliographic style, but please provide a +hyperlink to the article's DOI for ease of online access. Hyperlinks are written +as ```link text `__`` (text and url enclosed in backticks, followed by two +underscores). + +More about this diagnostic +-------------------------- + +In this section, you can go into more detail on the science behind your +diagnostic, for example, by copying in relevant text articles you've written +using th It's especially helpful if you're able to teach users how to use +your diagnostic's output, by showing how to interpret example plots. + +Instead of doing that here, we provide more examples of RestructuredText +syntax that you can customize as needed. + +As mentioned above, we recommend the online editor at `https://livesphinx.herokuapp.com/ +`__, which gives immediate feedback and has +support for sphinx-specific commands. + +Here's an +`introduction `__ +to the RestructuredText format, a +`quick reference `__, +and a `syntax comparison `__ to +other text formats you may be familiar with. + +Links to external sites +^^^^^^^^^^^^^^^^^^^^^^^ + +URLs written out in the text are linked automatically: https://ncar.ucar.edu/. + +To use custom text for the link, use the syntax +```link text `__`` (text and url enclosed in backticks, +followed by two underscores). This produces `link text `__. + +More references and citations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Here's another reference: + +.. code-block:: restructuredtext + + .. _ref-Charney: + + 2. Charney, Jule; Fjørtoft, Ragnar; von Neumann, John (1950). Numerical + Integration of the Barotropic Vorticity Equation. *Tellus* **2** (4) 237–254, + `doi:10.3402/tellusa.v2i4.8607 `__. + +.. _ref-Charney: + +2. Charney, Jule; Fjørtoft, Ragnar; von Neumann, John (1950). Numerical +Integration of the Barotropic Vorticity Equation. *Tellus* **2** (4) 237–254, +`doi:10.3402/tellusa.v2i4.8607 `__. + +Here's an example of citing these references: + +.. code-block:: restructuredtext + + :ref:`Maloney et. al., 2019 `, + :ref:`Charney, Fjørtoft and von Neumann, 1950 ` + +produces :ref:`Maloney et. al., 2019 `, +:ref:`Charney, Fjørtoft and von Neumann, 1950 `. + +Figures +^^^^^^^ + +Images **must** be provided in either .png or .jpeg formats in order to be +displayed properly in both the html and pdf output. + +Here's the syntax for including a figure in the document: + +.. code-block:: restructuredtext + + .. _my-figure-tag: [only needed for linking to figures] + + .. figure:: [path to image file, relative to the source.rst file] + :align: left + :width: 75 % [these both need to be indented by three spaces] + + Paragraphs or other text following the figure that are indented by three + spaces are treated as a caption/legend, eg: + + - red line: a Gaussian + - blue line: another Gaussian + +which produces + +.. _my-figure-tag: + +.. figure:: gaussians.jpg + :align: left + :width: 75 % + + Paragraphs or other text following the figure that are indented by three + spaces are treated as a caption/legend, eg: + + - blue line: a Gaussian + - orange line: another Gaussian + +The tag lets you refer to figures in the text, e.g. +``:ref:`Figure 1 ``` → :ref:`Figure 1 `. + +Equations +^^^^^^^^^ + +Accented and Greek letters can be written directly using Unicode: é, Ω. +(Make sure your text editor is saving the file in UTF-8 encoding). + +Use the following syntax for superscripts and subscripts in in-line text: + +.. code-block:: restructuredtext + + W m\ :sup:`-2`\ ; CO\ :sub:`2`\ . + +which produces: W m\ :sup:`-2`\ ; CO\ :sub:`2`\ . +Note one space is needed after both forward slashes in the input; these spaces +are not included in the output. + +Equations can be written using standard +`latex `__ +(PDF link) syntax. Short equations in-line with the text can be written as +``:math:`f = 2 \Omega \sin \phi``` → :math:`f = 2 \Omega \sin \phi`. + +Longer display equations can be written as follows. Note that a blank line is +needed after the ``.. math::`` heading and after each equation, with the +exception of aligned equations. + +.. code-block:: restructuredtext + + .. math:: + + \frac{D \mathbf{u}_g}{Dt} + f_0 \hat{\mathbf{k}} \times \mathbf{u}_a &= 0; \\ + \frac{Dh}{Dt} + f \nabla_z \cdot \mathbf{u}_a &= 0, + + \text{where } \mathbf{u}_g = \frac{g}{f_0} \hat{\mathbf{k}} \times \nabla_z h. + +which produces: + +.. math:: + + \frac{D \mathbf{u}_g}{Dt} + f_0 \hat{\mathbf{k}} \times \mathbf{u}_a &= 0; \\ + \frac{Dh}{Dt} + f \nabla_z \cdot \mathbf{u}_a &= 0, + + \text{where } \mathbf{u}_g = \frac{g}{f_0} \hat{\mathbf{k}} \times \nabla_z h. + +The editor at `https://livesphinx.herokuapp.com/ +`__ can have issues formatting complicated +equations, so you may want to check its output with a latex-specific editor, +such as `overleaf `__ or other `equation editors +`__. diff --git a/diagnostics/natl_ocean/my_tests.jsonc b/diagnostics/natl_ocean/my_tests.jsonc new file mode 100644 index 000000000..42e4c4be7 --- /dev/null +++ b/diagnostics/natl_ocean/my_tests.jsonc @@ -0,0 +1,140 @@ +// Configuration for MDTF-diagnostics driver script self-test. +// +// Copy this file and customize the settings as needed to run the framework on +// your own model output without repeating command-line options. Pass it to the +// framework at the end of the command line (positionally) or with the +// -f/--input-file flag. Any other explicit command line options will override +// what's listed here. +// +// All text to the right of an unquoted "//" is a comment and ignored, as well +// as blank lines (JSONC quasi-standard.) +{ + "case_list" : [ + // The cases below correspond to the different sample model data sets. Note + // that the MDTF package does not currently support analyzing multiple + // models in a single invocation. Comment out or delete the first entry and + // uncomment the second to run NOAA-GFDL-AM4 only for the MJO_prop_amp POD, + // and likewise for the SM_ET_coupling POD. + { + // "CASENAME" : "QBOi.EXP1.AMIP.001", + // "CASENAME" : "DUMMY", + "CASENAME" : "b.e21.BHIST.f09_g17.CMIP6-historical.001", + "model" : "CESM", + "convention" : "CESM", + "FIRSTYR" : 1850, + "LASTYR" : 1851, + "pod_list": [ + // Optional: PODs to run for this model only (defaults to all) + "natl_ocean" + //"Wheeler_Kiladis", + //"EOF_500hPa", + //"MJO_suite", + //"MJO_teleconnection" + // "convective_transition_diag", + // "precip_diurnal_cycle", + // "ocn_surf_flux_diag", + // "mixed_layer_depth", + // "tropical_pacific_sea_level", + // "temp_extremes_distshape", + // "precip_buoy_diag" + ] + } + // { + // "CASENAME" : "GFDL.CM4.c96L32.am4g10r8", + // "model" : "AM4", + // "convention" : "GFDL", + // "FIRSTYR" : 1, + // "LASTYR" : 10, + // "pod_list" : ["MJO_prop_amp"] + // } + // { + // "CASENAME" : "Lmon_GISS-E2-H_historical_r1i1p1", + // "model" : "CMIP", + // "convention" : "CMIP", + // "FIRSTYR" : 1951, + // "LASTYR" : 2005, + // "pod_list" : ["SM_ET_coupling"] + // } + // { + // "CASENAME" : "NCAR-CAM5.timeslice", + // "model" : "CESM", + // "convention" : "CMIP", + // "FIRSTYR" : 2000, + // "LASTYR" : 2004, + // "pod_list": ["example"] + // } + ], + // PATHS --------------------------------------------------------------------- + // Location of supporting data downloaded when the framework was installed. + + // If a relative path is given, it's resolved relative to the MDTF-diagnostics + // code directory. Environment variables (eg, $HOME) can be referenced with a + // "$" and will be expended to their current values when the framework runs. + + // Parent directory containing observational data used by individual PODs. + "OBS_DATA_ROOT": "../inputdata/obs_data/", + + // Parent directory containing results from different models. + "MODEL_DATA_ROOT": "../inputdata/model/", + + // Working directory. Defaults to OUTPUT_DIR if blank. + //"WORKING_DIR": "../wkdir", + "WORKING_DIR": "/glade/scratch/taydral/MDTFwkdir", + + // Directory to write output. The results of each run of the framework will be + // put in a subdirectory of this directory. +// "OUTPUT_DIR": "../wkdir", + "OUTPUT_DIR": "/glade/scratch/taydral/MDTFwkdir", + + // Location of the Anaconda/miniconda installation to use for managing + // dependencies (path returned by running `conda info --base`.) If empty, + // framework will attempt to determine location of system's conda installation. + "conda_root": "/glade/u/home/taydral/miniconda3", + + // Directory containing the framework-specific conda environments. This should + // be equal to the "--env_dir" flag passed to conda_env_setup.sh. If left + // blank, the framework will look for its environments in the system default + // location. + "conda_env_root": "/glade/u/home/taydral/miniconda3/envs", + + // SETTINGS ------------------------------------------------------------------ + // Any command-line option recognized by the mdtf script (type `mdtf --help`) + // can be set here, in the form "flag name": "desired setting". + + // Method used to fetch model data. + "data_manager": "Local_File", + + // Type of data that POD(s) will analyze + // "single_run" (default) or "multi_run" + "data_type": "single_run", + + // Method used to manage dependencies. + "environment_manager": "Conda", + + // Settings affecting what output is generated: + + // Set to true to have PODs save postscript figures in addition to bitmaps. + "save_ps": false, + + // Set to true to have PODs save netCDF files of processed data. + "save_nc": false, + + // Set to true to save HTML and bitmap plots in a .tar file. + "make_variab_tar": true, + + // Set to true to overwrite results in OUTPUT_DIR; otherwise results saved + // under a unique name. + "overwrite": false, + + // Settings used in debugging: + + // Log verbosity level. + "verbose": 1, + + // Set to true for framework test. Data is fetched but PODs are not run. + "test_mode": false, + + // Set to true for framework test. No external commands are run and no remote + // data is copied. Implies test_mode. + "dry_run": false +} diff --git a/diagnostics/natl_ocean/natl_ocean.html b/diagnostics/natl_ocean/natl_ocean.html new file mode 100644 index 000000000..6b21ed150 --- /dev/null +++ b/diagnostics/natl_ocean/natl_ocean.html @@ -0,0 +1,88 @@ + +MDTF example diagnostic + +

Example diagnostic: time-averaged near-surface temperature

+

+If this were a real diagnostic, this would be where you'd give a brief summary +of what your diagnostic computes and how to interpret the output plots it +generated, which will be linked below. You can include hyperlinks to journal +articles, etc. for more detailed documentation on your methods or sources of +observational data. +

+

+The names of any environment variables set for the diagnostic (enclosed in +curly braces) will be replaced by the same values they had when the diagnostic +was run. For example, this diagnostic's favorite color is "{{EXAMPLE_FAV_COLOR}}." +

+ + + + + + + + + + + + + + + + +
Time averages, {{FIRSTYR}}-{{LASTYR}} +{{CASENAME}} +MODEL +
SST (degC) +plot +
Top layer salt (psu) +plot + +
Bias plots, {{FIRSTYR}}-{{LASTYR}} +{{CASENAME}} +MODEL +
SST (degC) +plot +
Top layer salt (psu) +plot + +
WMT plots, {{FIRSTYR}}-{{LASTYR}} +{{CASENAME}} +MODEL +
SST (degC) +plot +
Top layer salt (psu) +plot + +
MOC plots, {{FIRSTYR}}-{{LASTYR}} +{{CASENAME}} +MODEL +
SST (degC) +plot +
Top layer salt (psu) +plot + +
Synthesis plots, {{FIRSTYR}}-{{LASTYR}} +{{CASENAME}} +MODEL +
SST (degC) +plot +
Top layer salt (psu) +plot + + + +
+ diff --git a/diagnostics/natl_ocean/natl_ocean.py b/diagnostics/natl_ocean/natl_ocean.py new file mode 100644 index 000000000..24e6db59d --- /dev/null +++ b/diagnostics/natl_ocean/natl_ocean.py @@ -0,0 +1,302 @@ +# MDTF North Atlantic Ocean POD +# ================================================================================ +# This script does a simple diagnostic calculation to illustrate how to adapt code +# for use in the MDTF diagnostic framework. The main change is to set input/output +# paths, variable names etc. from shell environment variables the framework +# provides, instead of hard-coding them. +# +# Below, this script consists of 2 parts: (1) a template of comprehensive header POD +# developers must include in their POD's main driver script, (2) actual code, and +# (3) extensive in-line comments. +# ================================================================================ +# +# This file is part of the Example Diagnostic POD of the MDTF code package (see mdtf/MDTF-diagnostics/LICENSE.txt) +# +# Example Diagnostic POD +# +# Last update: 8/1/2020 +# +# This is a example POD that you can use as a template for your diagnostics. +# If this were a real POD, you'd place a one-paragraph synopsis of your +# diagnostic here (like an abstract). +# +# Version & Contact info +# +# Here you should describe who contributed to the diagnostic, and who should be +# contacted for further information: +# +# - Version/revision information: version 1 (5/06/2020) +# - PI (name, affiliation, email) +# - Developer/point of contact (name, affiliation, email) +# - Other contributors +# +# Open source copyright agreement +# +# The MDTF framework is distributed under the LGPLv3 license (see LICENSE.txt). +# Unless you've distirbuted your script elsewhere, you don't need to change this. +# +# Functionality +# +# In this section you should summarize the stages of the calculations your +# diagnostic performs, and how they translate to the individual source code files +# provided in your submission. This will, e.g., let maintainers fixing a bug or +# people with questions about how your code works know where to look. +# +# Required programming language and libraries +# +# In this section you should summarize the programming languages and third-party +# libraries used by your diagnostic. You also provide this information in the +# ``settings.jsonc`` file, but here you can give helpful comments to human +# maintainers (eg, "We need at least version 1.5 of this library because we call +# this function.") +# +# Required model output variables +# +# In this section you should describe each variable in the input data your +# diagnostic uses. You also need to provide this in the ``settings.jsonc`` file, +# but here you should go into detail on the assumptions your diagnostic makes +# about the structure of the data. +# +# References +# +# Here you should cite the journal articles providing the scientific basis for +# your diagnostic. +# +# Maloney, E. D, and Co-authors, 2019: Process-oriented evaluation of climate +# and wether forcasting models. BAMS, 100(9), 1665-1686, +# doi:10.1175/BAMS-D-18-0042.1. +# +import os +import matplotlib +matplotlib.use('Agg') # non-X windows backend +# Commands to load third-party libraries. Any code you don't include that's +# not part of your language's standard library should be listed in the +# settings.jsonc file. +import xarray as xr # python library we use to read netcdf files +import matplotlib.pyplot as plt # python library we use to make plots +import xwmt +import numpy as np +from natl_wmt import wmt_calc + + +### 1) Loading model data files: ############################################### +# +# The framework copies model data to a regular directory structure of the form +# //...nc +# Here and frequency are requested in the "varlist" part of +# settings.json. + +# The following command sets input_path to the value of the shell environment +# variable called TAS_FILE. This variable is set by the framework to let the +# script know where the locally downloaded copy of the data for this variable +# (which we called "tas") is. +sst_path = os.environ["SST_FILE"] +salt_path = os.environ["SALT_FILE"] +shf_path = os.environ["SHF_FILE"] +sfwf_path = os.environ["SFWF_FILE"] +tarea_path = os.environ["TAREA_FILE"] + +wk_dir = "{WK_DIR}".format(**os.environ) +obs_dir = "{OBS_DATA}/".format(**os.environ) +output_dir = wk_dir+'/model/' +figures_dir = wk_dir+'/model/' +modelname = "{CASENAME}".format(**os.environ) + + + +# command to load the netcdf file +sst_dataset = xr.open_dataset(sst_path) +salt_dataset = xr.open_dataset(salt_path) +shf_dataset = xr.open_dataset(shf_path) +sfwf_dataset = xr.open_dataset(sfwf_path) +tarea_dataset = xr.open_dataset(tarea_path) + +### 2) Doing computations: ##################################################### +# +# Diagnostics in the framework are intended to work with native output from a +# variety of models. For this reason, variable names should not be hard-coded +# but instead set from environment variables. +# +sst_var_name = os.environ["SST_var"] +salt_var_name = os.environ["SALT_var"] +shf_var_name = os.environ["SHF_var"] +sfwf_var_name = os.environ["SFWF_var"] +tarea_var_name = os.environ["TAREA_var"] +#wmt_var_name = "WMT" + +# For safety, don't even assume that the time dimension of the input file is +# named "time": +time_coord_name = os.environ["time_coord"] +depth_coord_name = os.environ["z_t_coord"] +lat_coord_name = os.environ["TLAT_coord"] +lon_coord_name = os.environ["TLONG_coord"] + +# Set variable arrays +sst_data = sst_dataset[sst_var_name] +sss_data = salt_dataset[salt_var_name].isel({depth_coord_name:0}) +shf_data = shf_dataset[shf_var_name] +sfwf_data = sfwf_dataset[sfwf_var_name] +tarea_data = sfwf_dataset[tarea_var_name] + +# The only computation done here: compute the time average of input data +model_mean_sst = sst_data.mean(time_coord_name) +model_mean_sss = sss_data.mean(time_coord_name) +model_mean_shf = shf_data.mean(time_coord_name) +model_mean_sfwf = sfwf_data.mean(time_coord_name) + +##bias script goes here + +## WMT calculation ## +#1)Create dataset for xwmt +wmt_ds=sst_data.to_dataset(name='tos') +wmt_ds['sos'] = sss_data +wmt_ds['hfds'] = shf_data +wmt_ds['wfo'] = sfwf_data +wmt_ds['wet'] = xr.where(~np.isnan(wmt_ds.tos),1,0) +wmt_ds['sfdsi'] = xr.zeros_like(wmt_ds['hfds']).rename('sfdsi') +wmt_ds['areacello'] = tarea_data/100e2 +#wmt_ds = wmt_ds.drop({'ULAT','ULONG'}) +wmt_ds = wmt_ds.rename({'nlat': 'y', 'nlon':'x', lat_coord_name:'lat', lon_coord_name:'lon'}) +#wmt_ds = wmt_ds.rename({lat_coord_name:'lat', lon_coord_name:'lon'}) +#2)Calculate WMT +model_mean_wmt = wmt_calc(wmt_ds) + +##MOC script goes here + +##Synthesis script goes here + + +# Note that we supplied the observational data as time averages, to save space +# and avoid having to repeat that calculation each time the diagnostic is run. + +# Logging relevant debugging or progress information is a good idea. Anything +# your diagnostic prints to STDOUT will be saved to its own log file. +print("Computed time average of {SST_var} for {CASENAME}.".format(**os.environ)) + +### 3) Saving output data: ##################################################### +# +# Diagnostics should write output data to disk to a) make relevant results +# available to the user for further use or b) to pass large amounts of data +# between stages of a calculation run as different sub-scripts. Data can be in +# any format (as long as it's documented) and should be written to the +# directory /model/netCDF (created by the framework). +# +sst_out_path = output_dir+"/netCDF/sst_means.nc".format(**os.environ) +sss_out_path = output_dir+"/netCDF/sss_means.nc".format(**os.environ) +shf_out_path = output_dir+"/netCDF/shf_means.nc".format(**os.environ) +sfwf_out_path = output_dir+"/netCDF/sfwf_means.nc".format(**os.environ) +tarea_out_path = output_dir+"/netCDF/tarea.nc".format(**os.environ) +wmt_out_path = output_dir+"/netCDF/wmt_mean.nc".format(**os.environ) +print('pathsmade') + +# write out time averages as a netcdf file +model_mean_sst.to_netcdf(sst_out_path) +model_mean_sss.to_netcdf(sss_out_path) +model_mean_shf.to_netcdf(shf_out_path) +model_mean_sfwf.to_netcdf(sfwf_out_path) +tarea_data.to_netcdf(tarea_out_path) +model_mean_wmt.to_netcdf(wmt_out_path) +print('filessaved') + + +### 4) Saving output plots: #################################################### +# +# Plots should be saved in EPS or PS format at //PS +# (created by the framework). Plots can be given any filename, but should have +# the extension ".eps" or ".ps". To make the webpage output, the framework will +# convert these to bitmaps with the same name but extension ".png". + +# Define a python function to make the plot, since we'll be doing it twice and +# we don't want to repeat ourselves. +def plot_and_save_figure(model_or_obs, title_string, fieldname, dataset): + # initialize the plot + plt.figure(figsize=(12,6)) + plot_axes = plt.subplot(1,1,1) + # actually plot the data (makes a lat-lon colormap) + dataset.plot(ax = plot_axes) + plot_axes.set_title(title_string) + # save the plot in the right location + plot_path = "{WK_DIR}/{model_or_obs}/example_{model_or_obs}_{fieldname}_plot.png".format( + model_or_obs=model_or_obs, fieldname=fieldname, **os.environ + ) + plt.savefig(plot_path, bbox_inches='tight') +# end of function + +# set an informative title using info about the analysis set in env vars +title_string = "{CASENAME}: mean {SST_var} ({FIRSTYR}-{LASTYR})".format(**os.environ) +# Plot the model data: +plot_and_save_figure("model", title_string, sst_var_name, model_mean_sst) + +title_string = "{CASENAME}: mean {SALT_var} ({FIRSTYR}-{LASTYR})".format(**os.environ) +plot_and_save_figure("model", title_string, salt_var_name, model_mean_sss) + +title_string = "{CASENAME}: mean {SHF_var} ({FIRSTYR}-{LASTYR})".format(**os.environ) +plot_and_save_figure("model", title_string, shf_var_name, model_mean_shf) + +title_string = "{CASENAME}: mean {SFWF_var} ({FIRSTYR}-{LASTYR})".format(**os.environ) +plot_and_save_figure("model", title_string, sfwf_var_name, model_mean_sfwf) + +title_string = "{CASENAME}: {TAREA_var} ".format(**os.environ) +plot_and_save_figure("model", title_string, tarea_var_name, tarea_data) + +#title_string = "{CASENAME}: WMT ".format(**os.environ) +#plot_and_save_figure("model", title_string, wmt_var_name, model_mean_wmt.wmt) +print('plots saved') + +plt.figure(figsize=(12,6)) +plot_axes = plt.subplot(1,1,1) +# actually plot the data (makes a lat-lon colormap) +model_mean_wmt.wmt.plot(ax = plot_axes) +title_string = "{CASENAME}: WMT ".format(**os.environ) +plot_axes.set_title(title_string) +plot_axes.set_xlabel(r'$\sigma_{2}$ (kg/m$^{3}$)') +plot_axes.set_ylabel('WMT (Sv)') +# save the plot in the right location +plot_path = "{WK_DIR}/model/example_model_WMT_plot.png".format(**os.environ) +plt.savefig(plot_path, bbox_inches='tight') + + +### 5) Loading obs data files & plotting obs figures: ########################## +# +# If your diagnostic uses any model-independent supporting data (eg. reference +# or observational data) larger than a few kB of text, it should be provided via +# the observational data distribution instead of being included with the source +# code. This data can be in any format: the framework doesn't process it. The +# environment variable OBS_DATA will be set to a path where the framework has +# copied a directory containing your supplied data. +# +# The following command replaces the substring "{OBS_DATA}" with the value of +# the OBS_DATA environment variable. +obs_path = "{OBS_DATA}/SST/sst.mnmean.nc".format(**os.environ) + +# command to load the netcdf file +obs_dataset = xr.open_dataset(obs_path) + + +obs_mean_sst = obs_dataset['sst'].mean('time') + +# Plot the observational data: +title_string = "Observations: mean {SST_var}".format(**os.environ) +plot_and_save_figure("obs", title_string, sst_var_name, obs_mean_sst) + + +### 6) Cleaning up: ############################################################ +# +# In addition to your language's normal housekeeping, don't forget to delete any +# temporary/scratch files you created in step 4). +# +model_dataset.close() +obs_dataset.close() + + +### 7) Error/Exception-Handling Example ######################################## +nonexistent_file_path = "{DATADIR}/mon/nonexistent_file.nc".format(**os.environ) +try: + nonexistent_dataset = xr.open_dataset(nonexistent_file_path) +except IOError as error: + print(error) + print("This message is printed by the example POD because exception-handling is working!") + + +### 8) Confirm POD executed sucessfully ######################################## +print("Last log message by Example POD: finished successfully!") diff --git a/diagnostics/natl_ocean/natl_wmt.py b/diagnostics/natl_ocean/natl_wmt.py new file mode 100644 index 000000000..59c26ec5d --- /dev/null +++ b/diagnostics/natl_ocean/natl_wmt.py @@ -0,0 +1,28 @@ +import os +# non-X windows backend +# Commands to load third-party libraries. Any code you don't include that's +# not part of your language's standard library should be listed in the +# settings.jsonc file. +import xarray as xr # python library we use to read netcdf files +import xwmt +import numpy as np + +## insert function description ## + +def wmt_calc(ds): + lon = ds['lon'] + lon = lon.where(lon<180.,other=lon-360.) + lat = ds['lat'] + SPNA = ds.where((lat>=40) & (lat<=80) & (lon>=-65.) & (lon<=15.)) + + #2)Calculate WMT using xwmt + wmt_init = xwmt.swmt(SPNA) + wmt_spna = wmt_init.G('sigma2', bins=np.linspace(33.1,38)) + + #time average of WMT + time_coord_name = os.environ["time_coord"] + wmt_spna_mean = wmt_spna.mean(time_coord_name)/1e6 + + #wmt to dataset + wmt_spna_mean_ds = wmt_spna_mean.to_dataset(name='wmt') + return wmt_spna_mean_ds diff --git a/diagnostics/natl_ocean/settings.jsonc b/diagnostics/natl_ocean/settings.jsonc new file mode 100644 index 000000000..ca6a3f8b2 --- /dev/null +++ b/diagnostics/natl_ocean/settings.jsonc @@ -0,0 +1,90 @@ +// Example MDTF diagnostic settings file +// +// This should be an ascii text file in JSON format +// (https://en.wikipedia.org/wiki/JSON#Data_types_and_syntax), with the addition +// that all text to the right of a "//" is a comment and ignored (sometimes +// called "JSONC" format). +// +{ + "settings" : { + "driver" : "natl_ocean.py", + "long_name" : "Subtropical to Subpolar North Atlantic Ocean Diagnostics", + "realm" : "ocean", + "description" : "Subtropical to Subpolar North Atlantic Ocean Diagnostics", + + // (optional) Any diagnostic-specific environment variables, given as + // key:value pairs. The user can't change these at runtime, but they can be + // used to set site-specific installation settings for your diagnostic. + "pod_env_vars" : { + "EXAMPLE_FAV_COLOR": "blue" + }, + + // Programs and third-party libraries your diagnostic needs to run. This is + // a set of key:value pairs, where "key" is the name of a language's + // executable and "value" is a list of all the libraries that language needs. + // The framework will ensure everything listed here is on your diagnostic's + // $PATH when it runs. + "runtime_requirements": { + "python3": ["matplotlib", "xarray", "netCDF4"] + } + }, + + // In this section, you define the names and units for the coordinates used by + // the variables defined below in the "varlist" section. Names in the + // "dimensions" attribute for each variable must correspond to a coordinate + // named here. + "dimensions": { + "time": {"standard_name": "time"}, + "TLONG": { + "standard_name": "array of t-grid longitudes", + "axis": "X" + }, + "TLAT": { + "standard_name": "array of t-grid latitudes", + "axis": "Y" + }, + "z_t": { + "standard_name": "depth from surface to midpoint of layer", + "axis": "Z", + "units": "centimeters", + "positive": "down" + } + }, + + // In this section, you describe what model data your diagnostic uses. Add one + // list entry (the section in curly braces) for each variable, separated by + // commas. + "varlist" : { + "SST": { + "standard_name" : "Potential Temperature", + "units": "degC", + "frequency" : "mon", + "dimensions": ["time", "z_t", "TLAT", "TLONG"] + }, + "SALT": { + "standard_name" : "Salinity", + "units": "psu", + "frequency" : "mon", + "dimensions": ["time", "z_t", "TLAT", "TLONG"] + }, + "SHF": { + "standard_name" : "Surface Heat Flux", + "units": "W/m2", + "frequency" : "mon", + "dimensions": ["time", "TLAT", "TLONG"] + }, + "SFWF": { + "standard_name" : "Surface Freshwater Flux", + "units": "kg/m2/s", + "frequency" : "mon", + "dimensions": ["time", "TLAT", "TLONG"] + }, + "TAREA": { + "standard_name" : "area of T cells", + "units": "centimeters^2", + "dimensions": ["TLAT", "TLONG"] + } + + // If we needed a second variable, we'd list it here. + } +}