diff --git a/README.md b/README.md index c26e9d11e..332a1e8fe 100644 --- a/README.md +++ b/README.md @@ -19,37 +19,40 @@ PODs. PODs generate diagnostic figures that can be viewed as an html file using The links in the table below show sample output, a brief description, and a link to the full documentation for each currently-supported POD. -| Diagnostic | Contributor | -|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------| -| [Blocking Neale](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/blocking_neale/doc/blocking_neale.rst) | Rich Neale (NCAR), Dani Coleman (NCAR) | -| [Convective Transition Diagnostics](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/convective_transition_diag/convective_transition_diag.html) | J. David Neelin (UCLA) | -| [Diurnal Cycle of Precipitation](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/precip_diurnal_cycle/precip_diurnal_cycle.html) | Rich Neale (NCAR) | -| [Eulerian Storm Track](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/eulerian_storm_track/doc/eulerian_storm_track.rst) | James Booth (CUNY), Jeyavinoth Jeyaratnam | -| [Extratropical Variance (EOF 500hPa Height)](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/EOF_500hPa/EOF_500hPa.html) | CESM/AMWG (NCAR) | -| [Forcing Feedback Diagnostic](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/forcing_feedback/doc/forcing_feedback.rst) | Brian Soden (U. Miami), Ryan Kramer| -| [Mixed Layer Depth](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/mixed_layer_depth/doc/mixed_layer_depth.rst) | Cecilia Bitz (U. Washington), Lettie Roach | -| [MJO Propagation and Amplitude ](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_GFDL.CM4.c96L32.am4g10r8/MJO_prop_amp/MJO_prop_amp.html)| Xianan Jiang (UCLA) | -| [MJO Spectra and Phasing](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/MJO_suite/MJO_suite.html) | CESM/AMWG (NCAR) | -| [MJO Teleconnections](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/MJO_teleconnection/MJO_teleconnection.html) | Eric Maloney (CSU) | -| [Moist Static Energy Diagnostic Package](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/ENSO_MSE/doc/ENSO_MSE.rst) | H. Annamalai (U. Hawaii), Jan Hafner (U. Hawaii) | -| [Ocean Surface Flux Diagnostic](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/ocn_surf_flux_diag/doc/ocn_surf_flux_diag.rst) | Charlotte A. DeMott (Colorado State University), Chia-Weh Hsu (GFDL) | -| [Precipitation Buoyancy Diagnostic](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/precip_buoy_diag/doc/precip_buoy_diag.rst) | J. David Neelin (UCLA), Fiaz Ahmed | -| [Rossby Wave Sources Diagnostic Package](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/ENSO_RWS/doc/ENSO_RWS.rst) | H. Annamalai (U. Hawaii), Jan Hafner (U. Hawaii) | -| [Sea Ice Suite](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/seaice_suite/doc/seaice_suite.rst) | Cecilia Bitz (U. Washington), Lettie Roach | -| [Soil Moisture-Evapotranspiration coupling](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/SM_ET_coupling/doc/SM_ET_coupling.rst) | Eric Wood (Princeton) | -| [Stratosphere-Troposphere Coupling: Annular Modes](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_annular_modes/doc/stc_annular_modes.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | -| [Stratosphere-Troposphere Coupling: Eddy Heat Fluxes](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_eddy_heat_fluxes/doc/stc_eddy_heat_fluxes.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | -| [Stratosphere-Troposphere Coupling: QBO and ENSO stratospheric teleconnections](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_qbo_enso/doc/stc_qbo_enso.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL), Dillon Elsbury (NOAA) | -| [Stratosphere-Troposphere Coupling: Stratospheric Ozone and Circulation](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_eddy_heat_fluxes/doc/stc_ozone.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | -| [Stratosphere-Troposphere Coupling: Stratospheric Polar Vortex Extremes](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_spv_extremes/doc/stc_spv_extremes.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | -| [Stratosphere-Troposphere Coupling: Vertical Wave Coupling](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_vert_wave_coupling/doc/stc_vert_wave_coupling.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | -| [Surface Albedo Feedback](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/albedofb/doc/surface_albedo_feedback.rst) | Cecilia Bitz (U. Washington), Aaron Donahoe (U. Washington), Ed Blanchard, Wei Cheng, Lettie Roach | -| [Surface Temperature Extremes and Distribution Shape](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/temp_extremes_distshape/doc/temp_extremes_distshape.rst) | J. David Neelin (UCLA), Paul C Loikith (PSU), Arielle Catalano (PSU) | -| [TC MSE Variance Budget Analysis](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/TC_MSE/doc/TC_MSE.rst) | Allison Wing (Florida State University), Jarrett Starr (Florida State University)| -| [Top Heaviness Metric](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/top_heaviness_metric/doc/top_heaviness_metric.rst) | Zhuo Wang (U.Illinois Urbana-Champaign), Jiacheng Ye (U.Illinois Urbana-Champaign)| -| [Tropical Cyclone Rain Rate Azimuthal Average](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/TC_Rain/doc/TC_Rain.rst) | Daehyun Kim (U. Washington), Nelly Emlaw (U.Washington) | -| [Tropical Pacific Sea Level](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/tropical_pacific_sea_level/doc/tropical_pacific_sea_level.rst) | Jianjun Yin (U. Arizona), Chia-Weh Hsu (GFDL)| -| [Wavenumber-Frequency Spectra](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/Wheeler_Kiladis/Wheeler_Kiladis.html) | CESM/AMWG (NCAR) | +| Diagnostic | Contributor | +|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------| +| [AMOC 3D structure ](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_GFDL-CM2p1/transport_onto_TS/transport_onto_TS.html) (implementation in progress) | Xiaobiao Xu (FSU/COAPS) | +| [Blocking Neale](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/blocking_neale/doc/blocking_neale.rst) | Rich Neale (NCAR), Dani Coleman (NCAR) | +| [Convective Transition Diagnostics](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/convective_transition_diag/convective_transition_diag.html) | J. David Neelin (UCLA) | +| [Diurnal Cycle of Precipitation](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/precip_diurnal_cycle/precip_diurnal_cycle.html) | Rich Neale (NCAR) | +| [Eulerian Storm Track](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/eulerian_storm_track/doc/eulerian_storm_track.rst) | James Booth (CUNY), Jeyavinoth Jeyaratnam | +| [Extratropical Variance (EOF 500hPa Height)](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/EOF_500hPa/EOF_500hPa.html) | CESM/AMWG (NCAR) | +| [Forcing Feedback Diagnostic](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/forcing_feedback/doc/forcing_feedback.rst) | Brian Soden (U. Miami), Ryan Kramer | +| [Finite-amplitude Rossby Wave Diagnostics](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/forcing_feedback/doc/forcing_feedback.rst) | Clare S. Y. Huang (U. Chicago), Christopher Polster (JGU Mainz), Noboru Nakamura (U. Chicago)| +| [Mixed Layer Depth](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/mixed_layer_depth/doc/mixed_layer_depth.rst) | Cecilia Bitz (U. Washington), Lettie Roach | +| [MJO Propagation and Amplitude ](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_GFDL.CM4.c96L32.am4g10r8/MJO_prop_amp/MJO_prop_amp.html) | Xianan Jiang (UCLA) | +| [MJO Spectra and Phasing](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/MJO_suite/MJO_suite.html) | CESM/AMWG (NCAR) | +| [MJO Teleconnections](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/MJO_teleconnection/MJO_teleconnection.html) | Eric Maloney (CSU) | +| [Moist Static Energy Diagnostic Package](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/ENSO_MSE/doc/ENSO_MSE.rst) | H. Annamalai (U. Hawaii), Jan Hafner (U. Hawaii) | +| [Ocean Surface Flux Diagnostic](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/ocn_surf_flux_diag/doc/ocn_surf_flux_diag.rst) | Charlotte A. DeMott (Colorado State University), Chia-Weh Hsu (GFDL) | +| [Precipitation Buoyancy Diagnostic](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/precip_buoy_diag/doc/precip_buoy_diag.rst) | J. David Neelin (UCLA), Fiaz Ahmed | +| [Rossby Wave Sources Diagnostic Package](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/ENSO_RWS/doc/ENSO_RWS.rst) | H. Annamalai (U. Hawaii), Jan Hafner (U. Hawaii) | +| [Sea Ice Suite](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/seaice_suite/doc/seaice_suite.rst) | Cecilia Bitz (U. Washington), Lettie Roach | +| [Soil Moisture-Evapotranspiration coupling](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/SM_ET_coupling/doc/SM_ET_coupling.rst) | Eric Wood (Princeton) | +| [Stratosphere-Troposphere Coupling: Annular Modes](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_annular_modes/doc/stc_annular_modes.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | +| [Stratosphere-Troposphere Coupling: Eddy Heat Fluxes](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_eddy_heat_fluxes/doc/stc_eddy_heat_fluxes.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | +| [Stratosphere-Troposphere Coupling: QBO and ENSO stratospheric teleconnections](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_qbo_enso/doc/stc_qbo_enso.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL), Dillon Elsbury (NOAA) | +| [Stratosphere-Troposphere Coupling: Stratospheric Ozone and Circulation](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_eddy_heat_fluxes/doc/stc_ozone.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | +| [Stratosphere-Troposphere Coupling: Stratospheric Polar Vortex Extremes](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_spv_extremes/doc/stc_spv_extremes.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | +| [Stratosphere-Troposphere Coupling: Vertical Wave Coupling](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/stc_vert_wave_coupling/doc/stc_vert_wave_coupling.rst) | Amy H. Butler (NOAA CSL), Zachary D. Lawrence (CIRES/NOAA PSL) | +| [Surface Albedo Feedback](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/albedofb/doc/surface_albedo_feedback.rst) | Cecilia Bitz (U. Washington), Aaron Donahoe (U. Washington), Ed Blanchard, Wei Cheng, Lettie Roach | +| [Surface Temperature Extremes and Distribution Shape](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/temp_extremes_distshape/doc/temp_extremes_distshape.rst) | J. David Neelin (UCLA), Paul C Loikith (PSU), Arielle Catalano (PSU) | +| [TC MSE Variance Budget Analysis](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/TC_MSE/doc/TC_MSE.rst) | Allison Wing (Florida State University), Jarrett Starr (Florida State University) | +| [Top Heaviness Metric](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/top_heaviness_metric/doc/top_heaviness_metric.rst) | Zhuo Wang (U.Illinois Urbana-Champaign), Jiacheng Ye (U.Illinois Urbana-Champaign) | +| [Tropical Cyclone Rain Rate Azimuthal Average](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/TC_Rain/doc/TC_Rain.rst) | Daehyun Kim (U. Washington), Nelly Emlaw (U.Washington) | +| [Tropical Pacific Sea Level](https://github.com/NOAA-GFDL/MDTF-diagnostics/blob/main/diagnostics/tropical_pacific_sea_level/doc/tropical_pacific_sea_level.rst) | Jianjun Yin (U. Arizona), Chia-Weh Hsu (GFDL) | +| [Warm Rain Microphysics](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/warm_rain_microphysics/documentation) (implementation in progress) | Kentaroh Suzuki (AORI, U. Tokyo) | +| [Wavenumber-Frequency Spectra](https://www.cgd.ucar.edu/cms/bundy/Projects/diagnostics/mdtf/mdtf_figures/MDTF_QBOi.EXP1.AMIP.001.save/Wheeler_Kiladis/Wheeler_Kiladis.html) | CESM/AMWG (NCAR) | ## Example POD Analysis Results diff --git a/diagnostics/finite_amplitude_wave_diag/default_finite_amplitude_wave_diag.jsonc b/diagnostics/finite_amplitude_wave_diag/default_finite_amplitude_wave_diag.jsonc new file mode 100644 index 000000000..3512eb229 --- /dev/null +++ b/diagnostics/finite_amplitude_wave_diag/default_finite_amplitude_wave_diag.jsonc @@ -0,0 +1,128 @@ +// 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" : "GFDL-CM3_historical_r1i1p1", + "model" : "CMIP", + "convention" : "CMIP", + "FIRSTYR" : 2005, + "LASTYR" : 2005, + "pod_list": [ + // Optional: PODs to run for this model only (defaults to all) + "finite_amplitude_wave_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", + + // Directory to write output. The results of each run of the framework will be + // put in a subdirectory of this directory. + "OUTPUT_DIR": "../wkdir", + + // Location of the Anaconda/miniconda or micromamba installation to use for managing + // dependencies (path returned by running `[conda | micromamba] info`.) If empty, + // framework will attempt to determine location of system's conda installation. + "conda_root": "$HOME/miniconda3", + + // Location of micromamba executable if using micromamba + "micromamba_exe":"", + + // 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": "$HOME/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": true, + + // Set to true to have PODs save netCDF files of processed data. + "save_nc": true, + + // 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": 2, + + // 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/finite_amplitude_wave_diag/doc/finite_amplitude_wave_diag_zonal_mean.rst b/diagnostics/finite_amplitude_wave_diag/doc/finite_amplitude_wave_diag_zonal_mean.rst new file mode 100644 index 000000000..c6fda4731 --- /dev/null +++ b/diagnostics/finite_amplitude_wave_diag/doc/finite_amplitude_wave_diag_zonal_mean.rst @@ -0,0 +1,127 @@ +.. 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 + +Finite Amplitude Rossby Wave Diagnostics Documentation +====================================================== + +.. rst-class:: center + +Clare S. Y. Huang\ |^1|, Christopher Polster |^2| and Noboru Nakamura\ |^1| + +.. rst-class:: center + +|^1|\ The University of Chicago, Chicago, Illinois + +|^2|\ Johannes Gutenberg-Universität Mainz, Germany + +.. rst-class:: center + +Last update: 03/12/2024 + +Description +----------- +(to be filled in ) + +.. Underline with '-'s to make a second-level heading. + +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 (03/12/2024) +- PI (name, affiliation, email): Clare S. Y. Huang (The University of Chicago, csyhuang@uchicago.edu) +- Developer/point of contact: Clare S. Y. Huang (The University of Chicago, csyhuang@uchicago.edu) +- Other contributors: Christopher Polster, Noboru Nakamura + +.. 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 +------------- + +(to be filled in) + +Required programming language and libraries +------------------------------------------- + +(to be filled in) + + +Required model output variables +------------------------------- + +(to be filled in) + +References +---------- + +References +---------- + +.. _ref-Nakamura-annual-review: + +10241. Nakamura, N. (2024). Large-Scale Eddy-Mean Flow Interaction in the Earth's Extratropical Atmosphere. *Annual Review of Fluid Mechanics*, **56**, 349-377, +`doi:10.1146/annurev-fluid-121021-035602 `__. + +.. _ref-Neal-et-al-GRL: + +10242. Neal, E., Huang, C. S., & Nakamura, N. (2022). The 2021 Pacific Northwest heat wave and associated blocking: meteorology and the role of an upstream cyclone as a diabatic source of wave activity. *Geophysical Research Letters*, **49(8)**, e2021GL097699. `doi:10.1029/2021GL097699 `__. + +.. _ref-Nakamura-Science: + +10243. Nakamura, N., & Huang, C. S. (2018). Atmospheric blocking as a traffic jam in the jet stream. *Science*, **361(6397)**, 42-47, `doi:10.1126/science.aat0721 `__. + +.. _ref-Nakamura-Solomon-JAS-2010: + +10244. Nakamura, N., & Solomon, A. (2010). Finite-amplitude wave activity and mean flow adjustments in the atmospheric general circulation. Part I: Quasigeostrophic theory and analysis. *Journal of the atmospheric sciences*, **67(12)**, 3967-3983, `doi:10.1175/2010JAS3503.1 `__. + +.. _ref-Nakamura-Solomon-JAS-2011: + +10245. Nakamura, N., & Solomon, A. (2011). Finite-amplitude wave activity and mean flow adjustments in the atmospheric general circulation. Part II: Analysis in the isentropic coordinate. Journal of the atmospheric sciences, 68(11), 2783-2799, `doi:10.1175/2011JAS3685.1 `__. + +.. _ref-Huang-Nakamura-JAS-2016: + +10246. Huang, C. S., & Nakamura, N. (2016). Local finite-amplitude wave activity as a diagnostic of anomalous weather events. Journal of the Atmospheric Sciences, 73(1), 211-229, `doi:10.1175/JAS-D-15-0194.1 `__. + +.. _ref-Huang-Nakamura-GRL-2017: + +10247. Huang, C. S., & Nakamura, N. (2017). Local wave activity budgets of the wintertime Northern Hemisphere: Implication for the Pacific and Atlantic storm tracks. Geophysical Research Letters, 44(11), 5673-5682, `doi:10.1002/2017GL073760 `__. + +More about this diagnostic +-------------------------- + +(to be filled in) + +Links to external sites +^^^^^^^^^^^^^^^^^^^^^^^ + +(to be filled in) + +More references and citations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +(to be filled in) + +Figures +^^^^^^^ + +(to be filled in) + +Equations +^^^^^^^^^ + +(to be filled in) diff --git a/diagnostics/finite_amplitude_wave_diag/env_finite_amplitude_wave_diag.yml b/diagnostics/finite_amplitude_wave_diag/env_finite_amplitude_wave_diag.yml new file mode 100644 index 000000000..96abe0bed --- /dev/null +++ b/diagnostics/finite_amplitude_wave_diag/env_finite_amplitude_wave_diag.yml @@ -0,0 +1,18 @@ +name: _MDTF_finite_amplitude_wave_diag +channels: +- conda-forge +dependencies: +- python=3.12 +- numpy=1.26.4 +- scipy=1.14.0 +- netCDF4=1.6.5 +- xarray=2024.1.1 +- cartopy=0.22.0 +- matplotlib=3.8.2 +- pytest==7.4.0 +- dask +- gridfill +- bottleneck +- pip=23.3.1 +- pip: + - falwa==2.0.0 diff --git a/diagnostics/finite_amplitude_wave_diag/finite_amplitude_wave_diag.html b/diagnostics/finite_amplitude_wave_diag/finite_amplitude_wave_diag.html new file mode 100644 index 000000000..866d6fdb8 --- /dev/null +++ b/diagnostics/finite_amplitude_wave_diag/finite_amplitude_wave_diag.html @@ -0,0 +1,120 @@ + + + Finite-amplitude Rossby wave diagnostics + +

Finite-amplitude Rossby wave diagnostics

+ + +

The goal to incorporate Finite-amplitude wave activity (FAWA) formalism into MDTF repo is to provide diagnostic tools for model comparison. Each diagnostic shall associate with an interpretation related to the physical process.

+

Below are some proposed candidates and associated physical interpretations:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
DiagnosticInterpretation
Seasonal climatology of zonal mean FAWAIt quantifies the strength of vertically propagating planetary waves, and also relative strength of synoptic eddies in troposphere
Seasonal climatology of UrefTo quantify strength of mean-flow interaction, i.e., adiabatic adjustment of flow from an eddy-free reference state is given by Uref-Ubar(zonal mean wind)
Seasonal climatology of <LWA> (<...> = vertically averaged)To quantify geographical distribution (and amplitude) of eddies
Seasonal climatology of temporal Covariance of <LWA> and <U> (as in NH18 Fig. 2A)A measure of strength of nonlinear wave-mean flow interaction (via nonlinear zonal wave activity flux)
+ + +Full Documentation and Contact Information + +

Zonal-mean finite-amplitude wave diagnostics for {{CASENAME}} (Climatologies)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name of DiagnosticDJFMAMJJASON
zonal mean zonal windplotplotplotplot
zonal mean wave activity (FAWA)plotplotplotplot
zonal mean reference states (Uref)plotplotplotplot
zonal mean wind adjustment (\Delta U)plotplotplotplot
+ + +

Vertically-averaged finite-amplitude wave diagnostics for {{CASENAME}} (Climatologies)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name of DiagnosticDJFMAMJJASON
Barotropic zonal mean zonal windplotplotplotplot
Barotropic local wave activityplotplotplotplot
Covariance between barotropic zonal wind and LWAplotplotplotplot
diff --git a/diagnostics/finite_amplitude_wave_diag/finite_amplitude_wave_diag_utils.py b/diagnostics/finite_amplitude_wave_diag/finite_amplitude_wave_diag_utils.py new file mode 100644 index 000000000..5bbc253c5 --- /dev/null +++ b/diagnostics/finite_amplitude_wave_diag/finite_amplitude_wave_diag_utils.py @@ -0,0 +1,223 @@ +from typing import Optional + +import gridfill +import matplotlib.pyplot as plt # python library we use to make plots +import numpy as np +import xarray as xr +from falwa.constant import P_GROUND, SCALE_HEIGHT +from matplotlib import gridspec +from cartopy import crs as ccrs + +# from diagnostics.finite_amplitude_wave_diag.finite_amplitude_wave_diag_zonal_mean import plev_name, lat_name, lon_name, \ +# sampled_dataset + + +def gridfill_each_level(lat_lon_field, itermax=1000, verbose=False): + """ + Fill missing values in lat-lon grids with values derived by solving Poisson's equation + using a relaxation scheme. + + Args: + lat_lon_field(np.ndarray): 2D array to apply gridfill on + itermax(int): maximum iteration for poisson solver + verbose(bool): verbose level of poisson solver + + Returns: + A 2D array of the same dimension with all nan filled. + """ + if np.isnan(lat_lon_field).sum() == 0: + return lat_lon_field + + lat_lon_filled, converged = gridfill.fill( + grids=np.ma.masked_invalid(lat_lon_field), xdim=1, ydim=0, eps=0.01, + cyclic=True, itermax=itermax, verbose=verbose) + + return lat_lon_filled + + +class LatLonMapPlotter(object): + def __init__(self, figsize, title_str, xgrid, ygrid, cmap, xland, yland, lon_range, lat_range): + self._figsize = figsize + self._title_str = title_str + self._xgrid = xgrid + self._ygrid = ygrid + self._cmap = cmap + self._xland = xland + self._yland = yland + self._lon_range = lon_range + self._lat_range = lat_range + + def plot_and_save_variable(self, variable, cmap, var_title_str, save_path, num_level=30): + fig = plt.figure(figsize=self._figsize) + spec = gridspec.GridSpec( + ncols=1, nrows=1, wspace=0.3, hspace=0.3) + ax = fig.add_subplot(spec[0], projection=ccrs.PlateCarree()) + ax.coastlines(color='black', alpha=0.7) + ax.set_aspect('auto', adjustable=None) + main_fig = ax.contourf( + self._xgrid, self._ygrid, + variable, + num_level, + cmap=cmap) + ax.scatter(self._xgrid[self._xland], self._ygrid[self._yland], s=1, c='gray') + ax.set_xticks(self._lon_range, crs=ccrs.PlateCarree()) + ax.set_yticks(self._lat_range, crs=ccrs.PlateCarree()) + fig.colorbar(main_fig, ax=ax) + ax.set_title(f"{self._title_str}\n{var_title_str}") + plt.savefig(save_path, bbox_inches='tight') + # plt.savefig(save_path.replace("/PS/", "/").replace(".eps", ".png"), bbox_inches='tight') # Do I need this? + plt.show() + + +class HeightLatPlotter(object): + def __init__(self, figsize, title_str, xgrid, ygrid, cmap, xlim): + self._figsize = figsize + self._title_str = title_str + self._xgrid = xgrid + self._ygrid = ygrid + self._cmap = cmap + self._xlim = xlim # [-80, 80] + + def plot_and_save_variable(self, variable, cmap, var_title_str, save_path, num_level=30): + fig = plt.figure(figsize=self._figsize) + spec = gridspec.GridSpec(ncols=1, nrows=1) + ax = fig.add_subplot(spec[0]) + # *** Zonal mean U *** + main_fig = ax.contourf( + self._xgrid, + self._ygrid, + variable, + num_level, + cmap=cmap if cmap else self._cmap) + fig.colorbar(main_fig, ax=ax) + ax.set_title(f"{self._title_str}\n{var_title_str}") + ax.set_xlim(self._xlim) + plt.tight_layout() + plt.savefig(save_path, bbox_inches='tight') + # plt.savefig(save_path.replace("/PS/", "/").replace(".eps", ".png"), bbox_inches='tight') # Do I need this? + plt.show() + + +def convert_pseudoheight_to_hPa(height_array): + """ + Args: + height_array(np.array): pseudoheight in [m] + + Returns: + np.array which contains pressure levels in [hPa] + """ + p_array = P_GROUND * np.exp(- height_array / SCALE_HEIGHT) + return p_array + + +def convert_hPa_to_pseudoheight(p_array): + """ + Args: + height_array(np.array): pseudoheight in [m] + + Returns: + np.array which contains pressure levels in [hPa] + """ + height_array = - SCALE_HEIGHT * np.log(p_array / P_GROUND) + return height_array + + +class DataPreprocessor: + def __init__( + self, wk_dir, xlon, ylat, u_var_name, v_var_name, t_var_name, plev_name, lat_name, lon_name, time_coord_name): + + self._wk_dir = wk_dir + self._xlon: np.array = xlon # user input + self._ylat: np.array = ylat # user input + self._u_var_name: str = u_var_name + self._v_var_name: str = v_var_name + self._t_var_name: str = t_var_name + self._plev_name: str = plev_name + self._lat_name: str = lat_name + self._lon_name: str = lon_name + self._original_plev = None + self._original_lat = None + self._original_lon = None + self._original_time_coord = None + self._time_coord_name: str = time_coord_name + self._new_time_coord_name: str = "day" + self._sampled_dataset = None # Shall be xarray. Set type later + self._gridfill_needed: Optional[bool] = None + self._yz_mask = None + self._xy_mask = None + + @property + def xy_mask(self): + return self._xy_mask + + @property + def yz_mask(self): + return self._yz_mask + + def _save_original_coordinates(self, dataset): + self._original_plev = dataset.coords[self._plev_name] + self._original_lat = dataset.coords[self._lat_name] + self._original_lon = dataset.coords[self._lon_name] + + def _check_if_gridfill_is_needed(self, sampled_dataset): + num_of_nan = sampled_dataset[self._u_var_name].isnull().sum().values + if num_of_nan > 0: + self._gridfill_needed = True + self._do_save_mask(sampled_dataset) + else: + self._gridfill_needed = False + + def _do_save_mask(self, dataset): + self._yz_mask = dataset[self._u_var_name]\ + .to_masked_array().mask.sum(axis=0).sum(axis=-1).astype(bool) + self._xy_mask = dataset[self._u_var_name]\ + .to_masked_array().mask[:, 1:, :, :].sum(axis=0).sum(axis=0).astype(bool) + + def _save_preprocessed_data(self, dataset, output_path): + dataset.to_netcdf(output_path) + dataset.close() + print(f"Finished outputing preprocessed dataset: {output_path}") + + def _interpolate_onto_regular_grid(self, dataset): + dataset = dataset.interp( + coords={self._lat_name: self._ylat, self._lon_name: self._xlon}, + method="linear", + kwargs={"fill_value": "extrapolate"}) + return dataset + + def _implement_gridfill(self, dataset: xr.Dataset): + if not self._gridfill_needed: + print("No NaN values detected. Gridfill not needed. Bypass DataPreprocessor._implement_gridfill.") + return dataset + # *** Implement gridfill procedure *** + print(f"self._gridfill_needed = True. Do gridfill with poisson solver.") + args_tuple = [self._u_var_name, self._v_var_name, self._t_var_name] + gridfill_file_path = self._wk_dir + "/model/netCDF/gridfill_{var}.nc" + for var_name in args_tuple: + field_at_all_level = xr.apply_ufunc( + gridfill_each_level, + *[dataset[var_name]], + input_core_dims=((self._lat_name, self._lon_name),), + output_core_dims=((self._lat_name, self._lon_name),), + vectorize=True, dask="allowed") + field_at_all_level.to_netcdf(gridfill_file_path.format(var=var_name)) + field_at_all_level.close() + print(f"Finished outputing {var_name} to {gridfill_file_path.format(var=var_name)}") + load_gridfill_path = gridfill_file_path.format(var="*") + return load_gridfill_path + + def output_preprocess_data(self, sampled_dataset, output_path): + """ + Main procedure executed by this class + """ + self._save_original_coordinates(sampled_dataset) + self._check_if_gridfill_is_needed(sampled_dataset) + gridfill_path = self._implement_gridfill(sampled_dataset) + gridfilled_dataset = xr.open_mfdataset(gridfill_path) + dataset = self._interpolate_onto_regular_grid(gridfilled_dataset) # Interpolate onto regular grid + gridfilled_dataset.close() + self._save_preprocessed_data(dataset, output_path) # Save preprocessed data + dataset.close() + + + diff --git a/diagnostics/finite_amplitude_wave_diag/finite_amplitude_wave_diag_zonal_mean.py b/diagnostics/finite_amplitude_wave_diag/finite_amplitude_wave_diag_zonal_mean.py new file mode 100644 index 000000000..7c51f7e0e --- /dev/null +++ b/diagnostics/finite_amplitude_wave_diag/finite_amplitude_wave_diag_zonal_mean.py @@ -0,0 +1,314 @@ +# Finite-amplitude Rossby wave POD +# ================================================================================ +# Calculate finite-amplitude wave diagnostics that quantifies wave-mean flow +# interactions. +# +# Last update: 05/19/2024 +# ================================================================================ +# Version & Contact info +# +# - Version/revision information: version 1 (09/07/2023) +# - PI: Clare S. Y. Huang. The University of Chicago. csyhuang@uchicago.edu. +# - Developer/point of contact (name, affiliation, email): (same as PI) +# - Other contributors: Christopher Polster (JGU Mainz), Noboru Nakamura (UChicago) +# ================================================================================ +# Open source copyright agreement +# +# The MDTF framework is distributed under the LGPLv3 license (see LICENSE.txt). +# ================================================================================ +# Functionality (not written yet) +# ================================================================================ +# Required programming language and libraries (not written yet) +# ================================================================================ +# Required model output variables (not written yet) +# ================================================================================ +# References (not written yet) +# ================================================================================ +import os +import gc +import socket +from collections import namedtuple +import matplotlib +from finite_amplitude_wave_diag_utils import convert_hPa_to_pseudoheight, DataPreprocessor, LatLonMapPlotter, \ + HeightLatPlotter + +# 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. +from typing import Dict +import numpy as np +import xarray as xr # python library we use to read netcdf files +from falwa.xarrayinterface import QGDataset +from falwa.oopinterface import QGFieldNH18 +from falwa.constant import P_GROUND, SCALE_HEIGHT + +if socket.gethostname() == 'otc': + matplotlib.use('Agg') # non-X windows backend + +# 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. +already_done_gridfill: bool = True +# load_environ: bool = (socket.gethostname() == 'otc') +frequency = "day" # TODO: change later + +print( + f""" + Start running on OTC. Print out all environment variables: + {os.environ} + """) +wk_dir = os.environ["WK_DIR"] +uvt_path = f"{os.environ['DATADIR']}/{frequency}/{os.environ['CASENAME']}.[uvt]a.{frequency}.nc" +casename = os.environ["CASENAME"] + +print( + f""" + wk_dir = {wk_dir} + uvt_path = {uvt_path} + casename = {casename} + """) + +# *** Coordinates of input dataset *** +u_var_name = "ua" +v_var_name = "va" +t_var_name = "ta" +time_coord_name = "time" +plev_name = "plev" +lat_name = "lat" +lon_name = "lon" + +# *** Regular analysis grid defined by developer *** +xlon = np.arange(0, 360, 1.0) +ylat = np.arange(-90, 91, 1.0) + +# 2) Doing computations: +model_dataset = xr.open_mfdataset(uvt_path) # command to load the netcdf file +firstyr = model_dataset.coords['time'].values[0].year +lastyr = model_dataset.coords['time'].values[-1].year +if model_dataset[plev_name].units == 'Pa': # Pa shall be divided by 100 to become hPa + print("model_dataset[plev_name].units == 'Pa'. Convert it to hPa.") + model_dataset = model_dataset.assign_coords({plev_name: model_dataset[plev_name] // 100}) + model_dataset[plev_name].attrs["units"] = 'hPa' +print(f""" + Use xlon: {xlon} + Use ylat: {ylat} + firstyr, lastyr = {firstyr}, {lastyr} + """) + +# === 2.0) Save original grid === +original_grid = { + time_coord_name: model_dataset.coords[time_coord_name], + plev_name: model_dataset.coords[plev_name], + lat_name: model_dataset.coords[lat_name], + lon_name: model_dataset.coords[lon_name]} + + +def compute_from_sampled_data(gridfilled_dataset: xr.Dataset): + + # === 2.3) VERTICAL RESOLUTION: determine the maximum pseudo-height this calculation can handle === + dz = 1000 # TODO Variable to set earlier? + hmax = -SCALE_HEIGHT * np.log(gridfilled_dataset[plev_name].min() / P_GROUND) + kmax = int(hmax // dz) + 1 + original_pseudoheight = convert_hPa_to_pseudoheight(original_grid[plev_name]).rename("height") + + # === 2.4) WAVE ACTIVITY COMPUTATION: Compute Uref, FAWA, barotropic components of u and LWA === + qgds = QGDataset( + gridfilled_dataset, + var_names={"u": u_var_name, "v": v_var_name, "t": t_var_name}, + qgfield=QGFieldNH18, + qgfield_kwargs={"dz": dz, "kmax": kmax}) + gridfilled_dataset.close() + # Compute reference states and LWA + qgds.interpolate_fields(return_dataset=False) + qgds.compute_reference_states(return_dataset=False) + qgds.compute_lwa_and_barotropic_fluxes(return_dataset=False) + output_dataset = xr.Dataset(data_vars={ + 'uref': qgds.uref, + 'zonal_mean_u': qgds.interpolated_u.mean(axis=-1), + 'zonal_mean_lwa': qgds.lwa.mean(axis=-1), + 'lwa_baro': qgds.lwa_baro, + 'u_baro': qgds.u_baro}).interp(coords={ + "xlon": (lon_name, original_grid[lon_name].data), + "ylat": (lat_name, original_grid[lat_name].data)}) + return output_dataset + + +def calculate_covariance(lwa_baro, u_baro): + """ + Calculate covariance. + Args: + lwa_baro: dataset.lwa_baro + u_baro: dataset.u_baro + Returns: + cov_map in dimension of (lat, lon) + """ + baro_matrix_shape = lwa_baro.data.shape + flatten_lwa_baro = lwa_baro.data.reshape(baro_matrix_shape[0], baro_matrix_shape[1] * baro_matrix_shape[2]) + flatten_u_baro = u_baro.data.reshape(baro_matrix_shape[0], baro_matrix_shape[1] * baro_matrix_shape[2]) + covv = np.cov(m=flatten_lwa_baro, y=flatten_u_baro, rowvar=False) + row_cov = np.diagonal(covv, offset=baro_matrix_shape[1] * baro_matrix_shape[2]) + cov_map = row_cov.reshape(baro_matrix_shape[1], baro_matrix_shape[2]) + return cov_map + + +def time_average_processing(dataset: xr.Dataset): + SeasonalAverage = namedtuple( + "SeasonalAverage", [ + "zonal_mean_u", + "uref", + "zonal_mean_lwa", + "lwa_baro", + "u_baro", + "covariance_lwa_u_baro"]) + + seasonal_avg_zonal_mean_u = dataset.zonal_mean_u.mean(axis=0) + seasonal_avg_zonal_mean_lwa = dataset.zonal_mean_lwa.mean(axis=0) + seasonal_avg_uref = dataset.uref.mean(axis=0) + seasonal_avg_lwa_baro = dataset.lwa_baro.mean(axis=0) + seasonal_avg_u_baro = dataset.u_baro.mean(axis=0) + seasonal_covariance_lwa_u_baro = calculate_covariance(lwa_baro=dataset.lwa_baro, u_baro=dataset.u_baro) + seasonal_avg_data = SeasonalAverage( + seasonal_avg_zonal_mean_u, seasonal_avg_uref, seasonal_avg_zonal_mean_lwa, + seasonal_avg_lwa_baro, seasonal_avg_u_baro, seasonal_covariance_lwa_u_baro) + return seasonal_avg_data + + +def plot_and_save_figure(seasonal_average_data, analysis_height_array, plot_dir, title_str, season, + xy_mask=None, yz_mask=None): + if xy_mask is None: + xy_mask = np.zeros_like(seasonal_average_data.u_baro) + yland, xland = [], [] + else: + yland, xland = np.where(xy_mask) + if yz_mask is None: + yz_mask = np.zeros_like(seasonal_average_data.zonal_mean_u) + lon_range = np.arange(-180, 181, 60) + lat_range = np.arange(-90, 91, 30) + + cmap = "jet" + + height_lat_plotter = HeightLatPlotter(figsize=(4, 4), title_str=title_str, xgrid=original_grid['lat'], + ygrid=analysis_height_array, cmap=cmap, xlim=[-80, 80]) + height_lat_plotter.plot_and_save_variable(variable=seasonal_average_data.zonal_mean_u, cmap=cmap, + var_title_str='zonal mean U', + save_path=f"{plot_dir}{season}_zonal_mean_u.eps", num_level=30) + height_lat_plotter.plot_and_save_variable(variable=seasonal_average_data.zonal_mean_lwa, cmap=cmap, + var_title_str='zonal mean LWA', + save_path=f"{plot_dir}{season}_zonal_mean_lwa.eps", num_level=30) + height_lat_plotter.plot_and_save_variable(variable=seasonal_average_data.uref, cmap=cmap, + var_title_str='zonal mean Uref', + save_path=f"{plot_dir}{season}_zonal_mean_uref.eps", num_level=30) + height_lat_plotter.plot_and_save_variable(variable=seasonal_average_data.zonal_mean_u - seasonal_average_data.uref, + cmap=cmap, var_title_str='zonal mean $\Delta$ U', + save_path=f"{plot_dir}{season}_zonal_mean_delta_u.eps", num_level=30) + + # Use encapsulated class to plot + lat_lon_plotter = LatLonMapPlotter(figsize=(6, 3), title_str=title_str, xgrid=original_grid['lon'], + ygrid=original_grid['lat'], cmap=cmap, xland=xland, yland=yland, + lon_range=lon_range, lat_range=lat_range) + lat_lon_plotter.plot_and_save_variable(variable=seasonal_average_data.u_baro, cmap=cmap, var_title_str='U baro', + save_path=f"{plot_dir}{season}_u_baro.eps", num_level=30) + lat_lon_plotter.plot_and_save_variable(variable=seasonal_average_data.lwa_baro, cmap=cmap, var_title_str='LWA baro', + save_path=f"{plot_dir}{season}_lwa_baro.eps", num_level=30) + lat_lon_plotter.plot_and_save_variable(variable=seasonal_average_data.covariance_lwa_u_baro, cmap="Purples_r", + var_title_str='Covariance between LWA and U(baro)', + save_path=f"{plot_dir}{season}_u_lwa_covariance.eps", num_level=30) + + +# === 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). + +# *** MAIN PROCESS: Produce data by season, daily *** +model_or_obs: str = "model" # It can be "model" or "obs" +season_to_months = [ + ("DJF", [1, 2, 12]), ("MAM", [3, 4, 5]), ("JJA", [6, 7, 8]), ("SON", [9, 10, 11])] +intermediate_output_paths: Dict[str, str] = { + item[0]: f"{wk_dir}/{model_or_obs}/intermediate_{item[0]}.nc" for item in season_to_months} + +for season, selected_months in season_to_months: + print(f"season: {season}") + # Construct data preprocessor + data_preprocessor = DataPreprocessor( + wk_dir=wk_dir, xlon=xlon, ylat=ylat, u_var_name=u_var_name, v_var_name=v_var_name, t_var_name=t_var_name, + plev_name=plev_name, lat_name=lat_name, lon_name=lon_name, time_coord_name=time_coord_name) + + plot_dir = f"{wk_dir}/{model_or_obs}/PS/" + + # Do temporal sampling to reduce the data size + print("Start samping data in frequency 'day'.") + sampled_dataset = model_dataset.where( + model_dataset.time.dt.month.isin(selected_months), drop=True) \ + .groupby("time.day").first(skipna=False) + preprocessed_output_path = intermediate_output_paths[season] # TODO set it + print(f"Start preparing intermediate data in the directory: {preprocessed_output_path}") + data_preprocessor.output_preprocess_data( + sampled_dataset=sampled_dataset, output_path=preprocessed_output_path) + print(f"Finished preparing intermediate data in the directory: {preprocessed_output_path}") + intermediate_dataset = xr.open_mfdataset(preprocessed_output_path) + print(f"Start computing FAWA diagnostics from sampled data.") + fawa_diagnostics_dataset = compute_from_sampled_data(intermediate_dataset) + analysis_height_array = fawa_diagnostics_dataset.coords['height'].data + seasonal_avg_data = time_average_processing(fawa_diagnostics_dataset) + print( + f""" + Finished computing FAWA diagnostics from sampled data. + fawa_diagnostics_dataset: {fawa_diagnostics_dataset} + seasonal_avg_data: {seasonal_avg_data} + """) + + # === 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. + + # set an informative title using info about the analysis set in env vars + title_string = f"{casename} ({firstyr}-{lastyr}) {season}" + # Plot the model data: + plot_and_save_figure( + seasonal_average_data=seasonal_avg_data, + analysis_height_array=analysis_height_array, + plot_dir=plot_dir, + title_str=title_string, + season=season, + xy_mask=data_preprocessor.xy_mask, + yz_mask=data_preprocessor.yz_mask) + print(f"Finishing outputting figures to {plot_dir}.") + + # Close xarray datasets + sampled_dataset.close() + intermediate_dataset.close() + fawa_diagnostics_dataset.close() + gc.collect() +print("Finish the whole process") +model_dataset.close() + +# 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). +# os.system(f"rm -f {wk_dir}/model/gridfill_*.nc") +# os.system(f"rm -f {wk_dir}/model/intermediate_*.nc") + +### 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("POD Finite-amplitude wave diagnostic (zonal mean) finished successfully!") + diff --git a/diagnostics/finite_amplitude_wave_diag/settings.jsonc b/diagnostics/finite_amplitude_wave_diag/settings.jsonc new file mode 100644 index 000000000..cf20be21a --- /dev/null +++ b/diagnostics/finite_amplitude_wave_diag/settings.jsonc @@ -0,0 +1,42 @@ +{ + "settings":{ + "driver":"finite_amplitude_wave_diag_zonal_mean.py", + "long_name":"Finite-amplitude Rossby Wave Diagnostics (zonal-mean version)", + "realm" : "atmos", + "description":"Finite-amplitude Rossby Wave Diagnostics (zonal-mean version)", + "runtime_requirements":{ + "python3":[ + "matplotlib", + "xarray", + "netCDF4", + "numpy", + "cartopy", + "falwa" + ] + } + }, + "data":{"frequency":"day"}, + "dimensions":{ + "lat": {"standard_name": "latitude"}, + "lon": {"standard_name": "longitude"}, + "plev":{"standard_name":"air_pressure", "units":"Pa", "positive":"down", "axis":"Z"}, + "time": {"standard_name": "time"} + }, + "varlist":{ + "ua":{ + "standard_name":"eastward_wind", + "units":"m s-1", + "dimensions":["time", "plev", "lat", "lon"], + "freq":"day"}, + "va":{ + "standard_name":"northward_wind", + "units":"m s-1", + "dimensions":["time", "plev", "lat", "lon"], + "freq":"day"}, + "ta":{ + "standard_name":"air_temperature", + "units":"K", + "dimensions":["time", "plev", "lat", "lon"], + "freq":"day"} + } +} \ No newline at end of file