diff --git a/.github/workflows/ADF_linting.yaml b/.github/workflows/ADF_linting.yaml index 950def006..a8685fc41 100644 --- a/.github/workflows/ADF_linting.yaml +++ b/.github/workflows/ADF_linting.yaml @@ -34,5 +34,6 @@ jobs: env: PR_NUMBER: ${{ github.event.number }} ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + #ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} run: .github/scripts/pr_mod_file_tests.py --access_token $ACCESS_TOKEN --pr_num $PR_NUMBER --rcfile lib/test/pylintrc --pylint_level 9.5 diff --git a/.gitignore b/.gitignore index 0e4df2b8c..bfe7abc69 100644 --- a/.gitignore +++ b/.gitignore @@ -109,4 +109,7 @@ GitHub.sublime-settings !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json -.history \ No newline at end of file +.history + + + diff --git a/README.md b/README.md index 4060749ad..16d156064 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ If you are using conda on a non-CISL machine, then you can create and activate t ``` conda env create -f env/conda_environment.yaml -conda activate adf_v0.11 +conda activate adf_v1.0.0 ``` Also, along with these python requirements, the `ncrcat` NetCDF Operator (NCO) is also needed. On the CISL machines this can be loaded by simply running: diff --git a/config_cam_baseline_example.yaml b/config_cam_baseline_example.yaml index d9f3ad4c2..89aa4ec5a 100644 --- a/config_cam_baseline_example.yaml +++ b/config_cam_baseline_example.yaml @@ -481,6 +481,7 @@ plotting_scripts: - cam_taylor_diagram - qbo - ozone_diagnostics + - MOPITT #- tape_recorder #- tem #- regional_map_multicase #To use this please un-comment and fill-out @@ -506,6 +507,7 @@ diag_var_list: - FLNT - LANDFRAC - O3 + - CO # # MDTF recommended variables diff --git a/config_cam_baseline_example_testENSO.yaml b/config_cam_baseline_example_testENSO.yaml new file mode 100644 index 000000000..8113000ec --- /dev/null +++ b/config_cam_baseline_example_testENSO.yaml @@ -0,0 +1,537 @@ +#============================== +#config_cam_baseline_example.yaml + +#This is the main CAM diagnostics config file +#for doing comparisons of a CAM run against +#another CAM run, or a CAM baseline simulation. + +#Currently, if one is on NCAR's Casper or +#Cheyenne machine, then only the diagnostic output +#paths are needed, at least to perform a quick test +#run (these are indicated with "MUST EDIT" comments). +#Running these diagnostics on a different machine, +#or with a different, non-example simulation, will +#require additional modifications. +# +#Config file Keywords: +#-------------------- +# +#1. Using ${xxx} will substitute that text with the +# variable referenced by xxx. For example: +# +# cam_case_name: cool_run +# cam_climo_loc: /some/where/${cam_case_name} +# +# will set "cam_climo_loc" in the diagnostics package to: +# /some/where/cool_run +# +# Please note that currently this will only work if the +# variable only exists in one location in the file. +# +#2. Using ${.xxx} will do the same as +# keyword 1 above, but specifies which sub-section the +# variable is coming from, which is necessary for variables +# that are repeated in different subsections. For example: +# +# diag_basic_info: +# cam_climo_loc: /some/where/${diag_cam_climo.start_year} +# +# diag_cam_climo: +# start_year: 1850 +# +# will set "cam_climo_loc" in the diagnostics package to: +# /some/where/1850 +# +#Finally, please note that for both 1 and 2 the keywords must be lowercase. +#This is because future developments will hopefully use other keywords +#that are uppercase. Also please avoid using periods (".") in variable +#names, as this will likely cause issues with the current file parsing +#system. +#-------------------- +# +##============================== +# +# This file doesn't (yet) read environment variables, so the user must +# set this themselves. It is also a good idea to search the doc for 'user' +# to see what default paths are being set for output/working files. +# +# Note that the string 'USER-NAME-NOT-SET' is used in the jupyter script +# to check for a failure to customize +# +user: 'mdfowler' + + +#This first set of variables specify basic info used by all diagnostic runs: +diag_basic_info: + + #Is this a model vs observations comparison? + #If "false" or missing, then a model-model comparison is assumed: + compare_obs: false + + #Generate HTML website (assumed false if missing): + #Note: The website files themselves will be located in the path + #specified by "cam_diag_plot_loc", under the "/website" subdirectory, + #where "" is the subdirectory created for this particular diagnostics run + #(usually "case_vs_obs_XXX" or "case_vs_baseline_XXX"). + create_html: true + + #Location of observational datasets: + #Note: this only matters if "compare_obs" is true and the path + #isn't specified in the variable defaults file. + obs_data_loc: /glade/campaign/cgd/amp/amwg/ADF_obs + + #Location where re-gridded and interpolated CAM climatology files are stored: + cam_regrid_loc: /glade/derecho/scratch/${user}/ADF/regrid + + #Overwrite CAM re-gridded files? + #If false, or missing, then regridding will be skipped for regridded variables + #that already exist in "cam_regrid_loc": + cam_overwrite_regrid: false + + #Location where diagnostic plots are stored: + cam_diag_plot_loc: /glade/derecho/scratch/${user}/ADF/plots + + #Location of ADF variable plotting defaults YAML file: + #If left blank or missing, ADF/lib/adf_variable_defaults.yaml will be used + #Uncomment and change path for custom variable defaults file + #defaults_file: /some/path/to/defaults/file.yaml + + #Vertical pressure levels (in hPa) on which to plot 3-D variables + #when using horizontal (e.g. lat/lon) map projections. + #If this config option is missing, then no 3-D variables will be plotted on + #horizontal maps. Please note too that pressure levels must currently match + #what is available in the observations file in order to be plotted in a + #model vs obs run: + plot_press_levels: [200,850] + + #Longitude line on which to center all lat/lon maps. + #If this config option is missing then the central + #longitude will default to 180 degrees E. + central_longitude: 180 + + #Number of processors on which to run the ADF. + #If this config variable isn't present then + #the ADF defaults to one processor. Also, if + #you set it to "*" then it will default + #to all of the processors available on a + #single node/machine: + num_procs: 8 + + #If set to true, then redo all plots even if they already exist. + #If set to false, then if a plot is found it will be skipped: + redo_plot: true + +#This second set of variables provides info for the CAM simulation(s) being diagnosed: +diag_cam_climo: + + # History file list of strings to match + # eg. cam.h0 or ocn.pop.h.ecosys.nday1 or hist_str: [cam.h2,cam.h0] + # Only affects timeseries as everything else uses the created timeseries + # Default: + hist_str: cam.h0a + + #Calculate climatologies? + #If false, the climatology files will not be created: + calc_cam_climo: true + + #Overwrite CAM climatology files? + #If false, or not prsent, then already existing climatology files will be skipped: + cam_overwrite_climo: false + + #Name of CAM case (or CAM run name): + cam_case_name: b.e30_alpha06b.B1850C_LTso.ne30_t232_wgx3.132 + + #Case nickname + #NOTE: if nickname starts with '0' - nickname must be in quotes! + # ie '026a' as opposed to 026a + #If missing or left blank, will default to cam_case_name + case_nickname: '132' + + #Location of CAM history (h0) files: + #Example test files + # cam_hist_loc: /glade/campaign/cgd/amp/amwg/ADF_test_cases/${diag_cam_climo.cam_case_name} + cam_hist_loc: /glade/derecho/scratch/hannay/archive//b.e30_alpha06b.B1850C_LTso.ne30_t232_wgx3.132/atm/hist + + #Location of CAM climatologies (to be created and then used by this script) + cam_climo_loc: /glade/derecho/scratch/${user}/ADF/${diag_cam_climo.cam_case_name}/climo + + #model year when time series files should start: + #Note: Leaving this entry blank will make time series + # start at earliest available year. + start_year: 2 + + #model year when time series files should end: + #Note: Leaving this entry blank will make time series + # end at latest available year. + end_year: 44 + + #Do time series files exist? + #If True, then diagnostics assumes that model files are already time series. + #If False, or if simply not present, then diagnostics will attempt to create + #time series files from history (time-slice) files: + cam_ts_done: false + + #Save interim time series files? + #WARNING: This can take up a significant amount of space, + # but will save processing time the next time + cam_ts_save: true + + #Overwrite time series files, if found? + #If set to false, then time series creation will be skipped if files are found: + cam_overwrite_ts: false + + #Location where time series files are (or will be) stored: + cam_ts_loc: /glade/derecho/scratch/${user}/ADF/${diag_cam_climo.cam_case_name}/ts + + #TEM diagnostics + #--------------- + #TEM history file number + #If missing or blank, ADF will default to h4 + tem_hist_str: cam.h4 + + #Location where TEM files are stored: + #NOTE: If path not specified or commented out, TEM calculation/plots will be skipped! + cam_tem_loc: /glade/derecho/scratch/${user}/${diag_cam_climo.cam_case_name}/tem/ + + #Overwrite TEM files, if found? + #If set to false, then TEM creation will be skipped if files are found: + overwrite_tem: false + + #---------------------- + + #You can alternatively provide a list of cases, which will make the ADF + #apply the same diagnostics to each case separately in a single ADF session. + #All of the config variables below show how it is done, and are the only ones + #that need to be lists. This also automatically enables the generation of + #a "main_website" in "cam_diag_plot_loc" that brings all of the different cases + #together under a single website. + + #Also please note that config keywords cannot currently be used in list mode. + + #cam_case_name: + # - b.e23_alpha17f.BLT1850.ne30_t232.098 + # - b.e23_alpha17f.BLT1850.ne30_t232.095 + + #Case nickname + #NOTE: if nickname starts with '0' - nickname must be in quotes! + # ie '026a' as opposed to 026a + #If missing or left blank, will default to cam_case_name + #case_nickname: + # - cool nickname + # - cool nickname 2 + + #calc_cam_climo: + # - true + # - true + + #cam_overwrite_climo: + # - false + # - false + + #cam_hist_loc: + # - /glade/campaign/cgd/amp/amwg/ADF_test_cases/b.e23_alpha17f.BLT1850.ne30_t232.098 + # - /glade/campaign/cgd/amp/amwg/ADF_test_cases/b.e23_alpha17f.BLT1850.ne30_t232.095 + + #cam_climo_loc: + # - /some/where/you/want/to/have/climo_files/ #MUST EDIT! + # - /the/same/or/some/other/climo/files/location + + #start_year: + # - 10 + # - 10 + + #end_year: + # - 14 + # - 14 + + #cam_ts_done: + # - false + # - false + + #cam_ts_save: + # - true + # - true + + #cam_overwrite_ts: + # - false + # - false + + #cam_ts_loc: + # - /some/where/you/want/to/have/time_series_files + # - /same/or/different/place/you/want/files + + #TEM diagnostics + #--------------- + #TEM history file number + #If missing or blank, ADF will default to h4 + #tem_hist_str: + # - cam.h4 + # - cam.h# + + #Location where TEM files are stored: + #NOTE: If path not specified or commented out, TEM calculation/plots will be skipped! + #cam_tem_loc: + # - /some/where/you/want/to/have/TEM_files/ + # - /same/or/different/place/you/want/TEM_files/ + + #Overwrite TEM files, if found? + #If set to false, then TEM creation will be skipped if files are found: + #overwrite_tem: + # - false + # - true + + #---------------------- + + +#This third set of variables provide info for the CAM baseline climatologies. +#This only matters if "compare_obs" is false: +diag_cam_baseline_climo: + + # History file list of strings to match + # eg. cam.h0 or ocn.pop.h.ecosys.nday1 or hist_str: [cam.h2,cam.h0] + # Only affects timeseries as everything else uses the created timeseries + # Default: + hist_str: cam.h0a + + #Calculate cam baseline climatologies? + #If false, the climatology files will not be created: + calc_cam_climo: true + + #Overwrite CAM climatology files? + #If false, or not present, then already existing climatology files will be skipped: + cam_overwrite_climo: false + + #Name of CAM baseline case: + cam_case_name: b.e23_alpha17f.BLT1850.ne30_t232.093 + + #Baseline case nickname + #NOTE: if nickname starts with '0' - nickname must be in quotes! + # ie '026a' as opposed to 026a + #If missing or left blank, will default to cam_case_name + case_nickname: #cool nickname + + #Location of CAM baseline history (h0) files: + #Example test files + cam_hist_loc: /glade/campaign/cgd/amp/amwg/ADF_test_cases/${diag_cam_baseline_climo.cam_case_name} + + #Location of baseline CAM climatologies: + cam_climo_loc: /glade/derecho/scratch/${user}/ADF/${diag_cam_baseline_climo.cam_case_name}/climo + + #model year when time series files should start: + #Note: Leaving this entry blank will make time series + # start at earliest available year. + start_year: 10 + + #model year when time series files should end: + #Note: Leaving this entry blank will make time series + # end at latest available year. + end_year: 14 + + #Do time series files need to be generated? + #If True, then diagnostics assumes that model files are already time series. + #If False, or if simply not present, then diagnostics will attempt to create + #time series files from history (time-slice) files: + cam_ts_done: false + + #Save interim time series files for baseline run? + #WARNING: This can take up a significant amount of space: + cam_ts_save: true + + #Overwrite baseline time series files, if found? + #If set to false, then time series creation will be skipped if files are found: + cam_overwrite_ts: false + + #Location where time series files are (or will be) stored: + cam_ts_loc: /glade/derecho/scratch/${user}/ADF/${diag_cam_baseline_climo.cam_case_name}/ts + + #TEM diagnostics + #--------------- + #TEM history file number + #If missing or blank, ADF will default to h4 + tem_hist_str: cam.h4 + + #Location where TEM files are stored: + #NOTE: If path not specified or commented out, TEM calculation/plots will be skipped! + cam_tem_loc: /glade/derecho/scratch/${user}/${diag_cam_baseline_climo.cam_case_name}/tem/ + + #Overwrite TEM files, if found? + #If set to false, then TEM creation will be skipped if files are found: + overwrite_tem: false + + +#This fourth set of variables provides settings for calling the Climate Variability +# Diagnostics Package (CVDP). If cvdp_run is set to true the CVDP will be set up and +# run in background mode, likely completing after the ADF has completed. +# If CVDP is to be run PSL, TREFHT, TS and PRECT (or PRECC and PRECL) should be listed +# in the diag_var_list variable listing. +# For more CVDP information: https://www.cesm.ucar.edu/working_groups/CVC/cvdp/ +diag_cvdp_info: + + # Run the CVDP on the listed run(s)? + cvdp_run: false + + # CVDP code path, sets the location of the CVDP codebase + # CGD systems path = /home/asphilli/CESM-diagnostics/CVDP/Release/v5.2.0/ + # CISL systems path = /glade/u/home/asphilli/CESM-diagnostics/CVDP/Release/v5.2.0/ + # github location = https://github.com/NCAR/CVDP-ncl + cvdp_codebase_loc: /glade/u/home/asphilli/CESM-diagnostics/CVDP/Release/v5.2.0/ + + # Location where cvdp codebase will be copied to and diagnostic plots will be stored + cvdp_loc: /glade/derecho/scratch/${user}/ADF/cvdp/ + + # tar up CVDP results? + cvdp_tar: false + +# This set of variables provides settings for calling NOAA's +# Model Diagnostic Task Force (MDTF) diagnostic package. +# https://github.com/NOAA-GFDL/MDTF-diagnostics +# +# If mdtf_run: true, the MDTF will be set up and +# run in background mode, likely completing after the ADF has completed. +# +# WARNING: This currently only runs on CASPER (not derecho) +# +# The variables required depend on the diagnostics (PODs) selected. +# AMWG-developed PODS and their required variables: +# (Note that PRECT can be computed from PRECC & PRECL) +# - MJO_suite: daily PRECT, FLUT, U850, U200, V200 (all required) +# - Wheeler-Kiladis Wavenumber Frequency Spectra: daily PRECT, FLUT, U200, U850, OMEGA500 +# (will use what is available) +# - Blocking (Rich Neale): daily OMEGA500 +# - Precip Diurnal Cycle (Rich Neale): 3-hrly PRECT +# +# Many other diagnostics are available; see +# https://mdtf-diagnostics.readthedocs.io/en/main/sphinx/start_overview.html + +# +diag_mdtf_info: + # Run the MDTF on the model cases + mdtf_run: false + + # The file that will be written by ADF to input to MDTF. Call this whatever you want. + mdtf_input_settings_filename : mdtf_input.json + + ## MDTF code path, sets the location of the MDTF codebase and pre-compiled conda envs + # CHANGE if you have any: your own MDTF code, installed conda envs and/or obs_data + + mdtf_codebase_path : /glade/campaign/cgd/amp/amwg/mdtf + mdtf_codebase_loc : ${mdtf_codebase_path}/MDTF-diagnostics.v3.1.20230817.ADF + conda_root : /glade/u/apps/opt/conda + conda_env_root : ${mdtf_codebase_path}/miniconda2/envs.MDTFv3.1.20230412/ + OBS_DATA_ROOT : ${mdtf_codebase_path}/obs_data + + # SET this to a writable dir. The ADF will place ts files here for the MDTF to read (adds the casename) + MODEL_DATA_ROOT : ${diag_cam_climo.cam_ts_loc}/mdtf/inputdata/model + + # Choose diagnostics (PODs). Full list of available PODs: https://github.com/NOAA-GFDL/MDTF-diagnostics + pod_list : [ "MJO_suite" ] + + # Intermediate/output file settings + make_variab_tar: false # tar up MDTF results + save_ps : false # save postscript figures in addition to bitmaps + save_nc : false # save netCDF files of processed data (recommend true when starting with new model data) + overwrite: true # overwrite results in OUTPUT_DIR; otherwise results will be saved under a unique name + + # Settings used in debugging: + verbose : 3 # Log verbosity level. + test_mode: false # Set to true for framework test. Data is fetched but PODs are not run. + dry_run : false # Framework test. No external commands are run and no remote data is copied. Implies test_mode. + + # Settings that shouldn't change in ADF implementation for now + data_type : single_run # single_run or multi_run (only works with single right now) + data_manager : Local_File # Fetch data or it is local? + environment_manager : Conda # Manage dependencies + + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++ +#These variables below only matter if you are using +#a non-standard method, or are adding your own +#diagnostic scripts. +#+++++++++++++++++++++++++++++++++++++++++++++++++++ + +#Note: If you want to pass arguments to a particular script, you can +#do it like so (using the "averaging_example" script in this case): +# - {create_climo_files: {kwargs: {clobber: true}}} + +#Name of time-averaging scripts being used to generate climatologies. +#These scripts must be located in "scripts/averaging": +time_averaging_scripts: + - create_climo_files + #- create_TEM_files #To generate TEM files, please un-comment + +#Name of regridding scripts being used. +#These scripts must be located in "scripts/regridding": +regridding_scripts: + - regrid_and_vert_interp + +#List of analysis scripts being used. +#These scripts must be located in "scripts/analysis": +analysis_scripts: + - amwg_table + - ENSO_acrossRuns + #- aerosol_gas_tables + +#List of plotting scripts being used. +#These scripts must be located in "scripts/plotting": +plotting_scripts: + - global_latlon_map + # - global_latlon_vect_map + # - zonal_mean + # - meridional_mean + # - polar_map + # - cam_taylor_diagram + # - qbo + # - ozone_diagnostics + - enso_comparison_plots + #- tape_recorder + #- tem + #- regional_map_multicase #To use this please un-comment and fill-out + #the "region_multicase" section below + +#List of CAM variables that will be processesd: +#If CVDP is to be run PSL, TREFHT, TS and PRECT (or PRECC and PRECL) should be listed +diag_var_list: + - SWCF + - LWCF + - PRECC + - PRECL + - PSL + - Q + - U + - T + - RELHUM + - TREFHT + - TS + - TAUX + - TAUY + - FSNT + - FLNT + - LANDFRAC + - O3 + +# +# MDTF recommended variables +# - FLUT +# - OMEGA500 +# - PRECT +# - PS +# - PSL +# - U200 +# - U850 +# - V200 +# - V850 + +# Options for multi-case regional contour plots (./plotting/regional_map_multicase.py) +# region_multicase: +# region_spec: [slat, nlat, wlon, elon] +# region_time_option: # If calendar, will look for specified years. If zeroanchor will use a nyears starting from year_offset from the beginning of timeseries +# region_start_year: +# region_end_year: +# region_nyear: +# region_year_offset: +# region_month: +# region_season: +# region_variables: + +#END OF FILE diff --git a/config_noresm_default.yaml b/config_noresm_default.yaml new file mode 100644 index 000000000..dbd805b86 --- /dev/null +++ b/config_noresm_default.yaml @@ -0,0 +1,523 @@ +#============================== +#config_noresm_default.yaml +# modified from config_amwg_default_plots.yaml + +# This config file contains the standard set of variables and plots used for +# evaluating CAM simulations in the AMWG working group. + +#Currently, if one is on NCAR's Casper or +#Cheyenne machine, then only the diagnostic output +#paths are needed, at least to perform a quick test +#run (these are indicated with "MUST EDIT" comments). +#Running these diagnostics on a different machine, +#or with a different, non-example simulation, will +#require additional modifications. +# +# On sigma2 NIRD, please see the discussion on github +# https://github.com/NorESMhub/noresm3_dev_simulations/discussions/17 +# for details +# +#Config file Keywords: +#-------------------- +# +#1. Using ${xxx} will substitute that text with the +# variable referenced by xxx. For example: +# +# cam_case_name: cool_run +# cam_climo_loc: /some/where/${cam_case_name} +# +# will set "cam_climo_loc" in the diagnostics package to: +# /some/where/cool_run +# +# Please note that currently this will only work if the +# variable only exists in one location in the file. +# +#2. Using ${.xxx} will do the same as +# keyword 1 above, but specifies which sub-section the +# variable is coming from, which is necessary for variables +# that are repeated in different subsections. For example: +# +# diag_basic_info: +# cam_climo_loc: /some/where/${diag_cam_climo.start_year} +# +# diag_cam_climo: +# start_year: 1850 +# +# will set "cam_climo_loc" in the diagnostics package to: +# /some/where/1850 +# +#Finally, please note that for both 1 and 2 the keywords must be lowercase. +#This is because future developments will hopefully use other keywords +#that are uppercase. Also please avoid using periods (".") in variable +#names, as this will likely cause issues with the current file parsing +#system. +#-------------------- +user: 'USER-NAME-NOT-SET' +# +##============================== +# +# This file doesn't (yet) read environment variables, so the user must +# set this themselves. It is also a good idea to search the doc for 'user' +# to see what default paths are being set for output/working files. +# +# Note that the string 'USER-NAME-NOT-SET' is used in the jupyter script +# to check for a failure to customize +# + +#------------------------------------------------------------------------------------- +#This first set of variables specify basic info used by all diagnostic runs: +#------------------------------------------------------------------------------------- +diag_basic_info: + + #History file string to match (eg. cam.h0 or ocn.pop.h.ecosys.nday1) + # Only affects timeseries as everything else uses timeseries + # Leave off trailing '.' + #Default: cam.h0a + hist_str: cam.h0a + + #Is this a model vs observations comparison? + #If "false" or missing, then a model-model comparison is assumed: + compare_obs: false + + #Generate HTML website (assumed false if missing): + #Note: The website files themselves will be located in the path + #specified by "cam_diag_plot_loc", under the "/website" subdirectory, + #where "" is the subdirectory created for this particular diagnostics run + #(usually "case_vs_obs_XXX" or "case_vs_baseline_XXX"). + create_html: true + + #Location of observational datasets: + #Note: this only matters if "compare_obs" is true and the path + #isn't specified in the variable defaults file. + obs_data_loc: /nird/datalake/NS16000B/ADF-obs + + #Location where re-gridded and interpolated CAM climatology files are stored: + cam_regrid_loc: /scratch/${user}/noresm3/${diag_cam_climo.cam_case_name}/atm/proc/tseries/regrid + + #Overwrite CAM re-gridded files? + #If false, or missing, then regridding will be skipped for regridded variables + #that already exist in "cam_regrid_loc": + cam_overwrite_regrid: false + + #Location where diagnostic plots are stored: + cam_diag_plot_loc: /nird/datalake/NS2345K/www/diagnostics/ADF/${user} + + #Location of ADF variable plotting defaults YAML file: + #If left blank or missing, ADF/lib/adf_variable_defaults.yaml will be used + #Uncomment and change path for custom variable defaults file + #defaults_file: /some/path/to/defaults/file.yaml + + #Vertical pressure levels (in hPa) on which to plot 3-D variables + #when using horizontal (e.g. lat/lon) map projections. + #If this config option is missing, then no 3-D variables will be plotted on + #horizontal maps. Please note too that pressure levels must currently match + #what is available in the observations file in order to be plotted in a + #model vs obs run: + plot_press_levels: [200,500,850] + + #Longitude line on which to center all lat/lon maps. + #If this config option is missing then the central + #longitude will default to 180 degrees E. + central_longitude: 180 + + #Number of processors on which to run the ADF. + #If this config variable isn't present then + #the ADF defaults to one processor. Also, if + #you set it to "*" then it will default + #to all of the processors available on a + #single node/machine: + num_procs: 8 + + #If set to true, then redo all plots even if they already exist. + #If set to false, then if a plot is found it will be skipped: + redo_plot: true + +#------------------------------------------------------------------------------------- +#This second set of variables provides info for the CAM simulation(s) being diagnosed: +#------------------------------------------------------------------------------------- +diag_cam_climo: + + # History file list of strings to match + # eg. cam.h0 or ocn.pop.h.ecosys.nday1 or hist_str: [cam.h2,cam.h0] + # Only affects timeseries as everything else uses the created timeseries + # Default: + hist_str: cam.h0a + + #Calculate climatologies? + #If false, the climatology files will not be created: + calc_cam_climo: true + + #Overwrite CAM climatology files? + #If false, or not prsent, then already existing climatology files will be skipped: + cam_overwrite_climo: false + + #Name of CAM case (or CAM run name): + cam_case_name: n1850.ne30_tn14.hybrid_fatessp.20241219 + + #Case nickname + #NOTE: if nickname starts with '0' - nickname must be in quotes! + # ie '026a' as opposed to 026a + #If missing or left blank, will default to cam_case_name + case_nickname: #cool nickname + + #Location of CAM history (h0a) files: + #Example test files + cam_hist_loc: /nird/datalake/NS9560K/noresm3/cases/${diag_cam_climo.cam_case_name}/atm/hist + + #Location of CAM climatologies (to be created and then used by this script) + cam_climo_loc: /scratch/${user}/noresm3/${diag_cam_climo.cam_case_name}/atm/proc/climo + + #model year when time series files should start: + #Note: Leaving this entry blank will make time series + # start at earliest available year. + start_year: 100 + + #model year when time series files should end: + #Note: Leaving this entry blank will make time series + # end at latest available year. + end_year: 110 + + #Do time series files exist? + #If True, then diagnostics assumes that model files are already time series. + #If False, or if simply not present, then diagnostics will attempt to create + #time series files from history (time-slice) files: + cam_ts_done: false + + #Save interim time series files? + #WARNING: This can take up a significant amount of space, + # but will save processing time the next time + cam_ts_save: true + + #Overwrite time series files, if found? + #If set to false, then time series creation will be skipped if files are found: + cam_overwrite_ts: false + + #Location where time series files are (or will be) stored: + cam_ts_loc: /scratch/${user}/noresm3/${diag_cam_climo.cam_case_name}/atm/proc/tseries + +#------------------------------------------------------------------------------------- + #TEM diagnostics + #--------------- + #TEM history file number + #If missing or blank, ADF will default to h4 + tem_hist_str: cam.h4 + + #Location where TEM files are stored: + #NOTE: If path not specified or commented out, TEM calculation/plots will be skipped! + cam_tem_loc: /scratch/${user}/noresm3/ADF/${diag_cam_climo.cam_case_name}/tem/ + + #Overwrite TEM files, if found? + #If set to false, then TEM creation will be skipped if files are found: + overwrite_tem: false + + #---------------------- + +#This third set of variables provide info for the CAM baseline climatologies. +#------------------------------------------------------------------------------------- +#This only matters if "compare_obs" is false: +diag_cam_baseline_climo: + + # History file list of strings to match + # eg. cam.h0 or ocn.pop.h.ecosys.nday1 or hist_str: [cam.h2,cam.h0] + # Only affects timeseries as everything else uses the created timeseries + # Default: + hist_str: cam.h0a + + #Calculate cam baseline climatologies? + #If false, the climatology files will not be created: + calc_cam_climo: true + + #Overwrite CAM climatology files? + #If false, or not present, then already existing climatology files will be skipped: + cam_overwrite_climo: false + + #Name of CAM baseline case: + cam_case_name: n1850.ne30_tn14.hybrid_fatessp.20241204 + + #Baseline case nickname + #NOTE: if nickname starts with '0' - nickname must be in quotes! + # ie '026a' as opposed to 026a + #If missing or left blank, will default to cam_case_name + case_nickname: + + #Location of CAM baseline history (h0a) files: + #Example test files + cam_hist_loc: /nird/datalake/NS9560K/noresm3/cases/${diag_cam_baseline_climo.cam_case_name}/atm/hist + + #Location of baseline CAM climatologies: + cam_climo_loc: /scratch/${user}/noresm3/${diag_cam_baseline_climo.cam_case_name}/atm/proc/climo + + #model year when time series files should start: + #Note: Leaving this entry blank will make time series + # start at earliest available year. + start_year: 52 + + #model year when time series files should end: + #Note: Leaving this entry blank will make time series + # end at latest available year. + end_year: 71 + + #Do time series files need to be generated? + #If True, then diagnostics assumes that model files are already time series. + #If False, or if simply not present, then diagnostics will attempt to create + #time series files from history (time-slice) files: + cam_ts_done: false + + #Save interim time series files for baseline run? + #WARNING: This can take up a significant amount of space: + cam_ts_save: true + + #Overwrite baseline time series files, if found? + #If set to false, then time series creation will be skipped if files are found: + cam_overwrite_ts: false + + #Location where time series files are (or will be) stored: + cam_ts_loc: /scratch/${user}/diagnostics/ADF/${diag_cam_baseline_climo.cam_case_name}/atm/tseries + + #TEM diagnostics + #--------------- + #TEM history file number + #If missing or blank, ADF will default to h4 + tem_hist_str: cam.h4 + + #Location where TEM files are stored: + #NOTE: If path not specified or commented out, TEM calculation/plots will be skipped! + cam_tem_loc: /scratch/${user}/${diag_cam_baseline_climo.cam_case_name}/tem/ + + #Overwrite TEM files, if found? + #If set to false, then TEM creation will be skipped if files are found: + overwrite_tem: false + +#------------------------------------------------------------------------------------- +#This fourth set of variables provides settings for calling the Climate Variability +#------------------------------------------------------------------------------------- +# Diagnostics Package (CVDP). If cvdp_run is set to true the CVDP will be set up and +# run in background mode, likely completing after the ADF has completed. +# If CVDP is to be run PSL, TREFHT, TS and PRECT (or PRECC and PRECL) should be listed +# in the diag_var_list variable listing. +# For more CVDP information: https://www.cesm.ucar.edu/working_groups/CVC/cvdp/ +diag_cvdp_info: + + # Run the CVDP on the listed run(s)? + cvdp_run: false + + # CVDP code path, sets the location of the CVDP codebase + # CGD systems path = /home/asphilli/CESM-diagnostics/CVDP/Release/v5.2.0/ + # CISL systems path = /glade/u/home/asphilli/CESM-diagnostics/CVDP/Release/v5.2.0/ + # github location = https://github.com/NCAR/CVDP-ncl + cvdp_codebase_loc: /glade/u/home/asphilli/CESM-diagnostics/CVDP/Release/v5.2.0/ + + # Location where cvdp codebase will be copied to and diagnostic plots will be stored + cvdp_loc: /glade/scratch/asphilli/ADF-Sandbox/cvdp/ #MUST EDIT! + + # tar up CVDP results? + cvdp_tar: false + +# This set of variables provides settings for calling NOAA's +# Model Diagnostic Task Force (MDTF) diagnostic package. +# https://github.com/NOAA-GFDL/MDTF-diagnostics +# +# If mdtf_run: true, the MDTF will be set up and +# run in background mode, likely completing after the ADF has completed. +# +# WARNING: This currently only runs on CASPER (not derecho) +# +# The variables required depend on the diagnostics (PODs) selected. +# AMWG-developed PODS and their required variables: +# (Note that PRECT can be computed from PRECC & PRECL) +# - MJO_suite: daily PRECT, FLUT, U850, U200, V200 (all required) +# - Wheeler-Kiladis Wavenumber Frequency Spectra: daily PRECT, FLUT, U200, U850, OMEGA500 +# (will use what is available) +# - Blocking (Rich Neale): daily OMEGA500 +# - Precip Diurnal Cycle (Rich Neale): 3-hrly PRECT +# +# Many other diagnostics are available; see +# https://mdtf-diagnostics.readthedocs.io/en/main/sphinx/start_overview.html + +# +diag_mdtf_info: + # Run the MDTF on the model cases + mdtf_run: false + + # The file that will be written by ADF to input to MDTF. Call this whatever you want. + mdtf_input_settings_filename : mdtf_input.json + + ## MDTF code path, sets the location of the MDTF codebase and pre-compiled conda envs + # CHANGE if you have any: your own MDTF code, installed conda envs and/or obs_data + + mdtf_codebase_path : /glade/campaign/cgd/amp/amwg/mdtf + mdtf_codebase_loc : ${mdtf_codebase_path}/MDTF-diagnostics.v3.1.20230817.ADF + conda_root : /glade/u/apps/opt/conda + conda_env_root : ${mdtf_codebase_path}/miniconda2/envs.MDTFv3.1.20230412/ + OBS_DATA_ROOT : ${mdtf_codebase_path}/obs_data + + # SET this to a writable dir. The ADF will place ts files here for the MDTF to read (adds the casename) + MODEL_DATA_ROOT : ${diag_cam_climo.cam_ts_loc}/mdtf/inputdata/model + + # Choose diagnostics (PODs). Full list of available PODs: https://github.com/NOAA-GFDL/MDTF-diagnostics + pod_list : [ "MJO_suite" ] + + # Intermediate/output file settings + make_variab_tar: false # tar up MDTF results + save_ps : false # save postscript figures in addition to bitmaps + save_nc : false # save netCDF files of processed data (recommend true when starting with new model data) + overwrite: true # overwrite results in OUTPUT_DIR; otherwise results will be saved under a unique name + + # Settings used in debugging: + verbose : 3 # Log verbosity level. + test_mode: false # Set to true for framework test. Data is fetched but PODs are not run. + dry_run : false # Framework test. No external commands are run and no remote data is copied. Implies test_mode. + + # Settings that shouldn't change in ADF implementation for now + data_type : single_run # single_run or multi_run (only works with single right now) + data_manager : Local_File # Fetch data or it is local? + environment_manager : Conda # Manage dependencies + + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++ +#These variables below only matter if you are using +#a non-standard method, or are adding your own +#diagnostic scripts. +#+++++++++++++++++++++++++++++++++++++++++++++++++++ + +#Note: If you want to pass arguments to a particular script, you can +#do it like so (using the "averaging_example" script in this case): +# - {create_climo_files: {kwargs: {clobber: true}}} + +#Name of time-averaging scripts being used to generate climatologies. +#These scripts must be located in "scripts/averaging": +time_averaging_scripts: + - {create_climo_files: {kwargs: {clobber: false}}} + #- create_TEM_files #To generate TEM files, please un-comment + +#Name of regridding scripts being used. +#These scripts must be located in "scripts/regridding": +regridding_scripts: + - regrid_and_vert_interp + +#List of analysis scripts being used. +#These scripts must be located in "scripts/analysis": +analysis_scripts: + - amwg_table + +#List of plotting scripts being used. +#These scripts must be located in "scripts/plotting": +plotting_scripts: + - global_mean_timeseries + - global_latlon_map + - global_latlon_vect_map + - zonal_mean + - meridional_mean + - polar_map + - cam_taylor_diagram + - ozone_diagnostics + - qbo + #- tape_recorder + #- tem #To plot TEM, please un-comment fill-out the "tem_info" section below + +#List of CAM variables that will be processesd: +#If CVDP is to be run PSL, TREFHT, TS and PRECT (or PRECC and PRECL) should be listed +diag_var_list: + - AODDUST + - AODVIS + - cb_SULFATE + - cb_isoprene + - cb_monoterp + - cb_DUST + - cb_DMS + - cb_BC + - cb_OM + - cb_H2O2 + - cb_H2SO4 + - cb_SALT + - SFmonoterp + - SFisoprene + - SFSS + - SFDUST + - SFSOA + - SFSO4 + - SFSO2_net + - SFOM + - SFBC + - SFDMS + - SFH2O2 + - SFH2SO4 + - cb_SO2 + - D550_BC + - D550_DU + - D550_POM + - D550_SO4 + - D550_SS + - CLDHGH + - CLDICE + - CLDLIQ + - CLDLOW + - CLDMED + - CLDTOT + - CLOUD + - RESTOM + - FLNS + - FLNT + - FLNTC + - FSNS + - FSNT + - FSNTC + - LHFLX + - LWCF + - OMEGA500 + - PBLH + - PRECT + - PS + - PSL + - QFLX + - RELHUM + - SHFLX + - SST + - SWCF + - T + - TAUX + - TAUY + - TGCLDIWP + - TGCLDLWP + - TMQ + - TREFHT + - TS + - U + - U10 + - ICEFRAC + - OCNFRAC + - LANDFRAC + - O3 + # 2d fields + # - SFSO2 0 => 1.4e-10 kg/m2/s (SO2 surface flux) + # - WD_DMS -4.5e-15 => 1.7e-22 kg/m2/s (vertical integrated wet deposition flux) + # - WD_SO2 -1.5e-10 => 3.8e-16 kg/m2/s (vertical integrated wet deposition flux) + # - DF_DMS -4.5e-21 => 5.1e-13 kg/m2/s (vertical integrated dry deposition flux) + # - DF_H2O2 6.6e-26 => 2.7e-11 kg/m2/s (vertical integrated dry deposition flux) + # - DF_SO2 1.5e-27 => 7.0e-10 kg/m2/s (vertical integrated dry deposition flux) + # 3d fields + # - sum_BC 1.8e-14 => 1.2e-8 kg/kg (sum of BC concentrations) + # - sum_DST 6.3e-20 => 7.9e-6 kg/kg + # - sum_OM 6.3e-15 => 7.2e-8 kt/kg + +# + +# Options for TEM diagnostics (./averaging/create_TEM_files.py and ./plotting/temp.py) +#tem_info: + #Location where TEM files are stored: + #If path not specified or commented out, TEM calculation/plots will be skipped + #tem_loc: /glade/scratch/richling/adf-output/ADF-data/TEM/ + + #TEM history file number + #If missing or blank, ADF will default to h4 + #hist_num: h4 + + #Overwrite TEM files, if found? + #If set to false, then TEM creation will be skipped if files are found: + #overwrite_tem_case: false + + #overwrite_tem_case: + #overwrite_tem_base: false + +#END OF FILE diff --git a/env/conda_environment.yaml b/env/conda_environment.yaml index 4729a9a1d..0326ecedb 100644 --- a/env/conda_environment.yaml +++ b/env/conda_environment.yaml @@ -1,17 +1,20 @@ -name: adf_v0.11 +name: adf_v1.0.0 channels: - conda-forge - defaults dependencies: - - pyyaml=6.0 - - scipy=1.10.0 - - cartopy=0.21.1 - - netcdf4=1.6.2 - - xarray=2023.1.0 - - matplotlib=3.6.3 - - pandas=1.5.3 - - pint=0.16 #GeoCAT doesn't work with newer versions - - xskillscore=0.0.5 - - geocat-comp=2022.08.0 - - python=3.11 -prefix: /glade/work/$USER/conda-envs/adf_v0.11 + - pyyaml=6.0.2 + - scipy=1.12.0 + - cartopy=0.23.0 + - netcdf4=1.6.5 + - xarray=2024.1.1 + - uxarray=2025.03.0 + - matplotlib=3.9.4 + - pandas=2.2.0 + - pint=0.23 + - xskillscore=0.0.24 + - geocat-comp=2024.04.0 + - python=3.12 + - xesmf>=0.8.8 +prefix: /diagnostics/conda-envs/adf_v1.0.0 + diff --git a/jupyter_sample.ipynb b/jupyter_sample.ipynb index 44754a17e..ac6130a1c 100644 --- a/jupyter_sample.ipynb +++ b/jupyter_sample.ipynb @@ -471,9 +471,9 @@ ], "metadata": { "kernelspec": { - "display_name": "NPL (conda)", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "npl-conda" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -485,7 +485,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.12" + "version": "3.11.10" } }, "nbformat": 4, diff --git a/lib/adf_base.py b/lib/adf_base.py index 64618f2c0..ab128ea02 100644 --- a/lib/adf_base.py +++ b/lib/adf_base.py @@ -48,23 +48,17 @@ def __init__(self, debug = False): if not isinstance(debug, bool): raise TypeError("'debug' must be a boolean type (True or False)") - self.__debug_fname = '' + # Format the datetime object to a string without microseconds + self.__debug_fname = f"ADF_debug_{datetime.now().strftime('%Y-%m-%d-%H:%M:%S')}.log" # Create debug log, if requested: if debug: - # Get the current date and time - current_timestamp = datetime.now() - # Format the datetime object to a string without microseconds - dt_str = current_timestamp.strftime('%Y-%m-%d %H:%M:%S') - ext = f'{str(dt_str).replace(" ","-")}' - debug_fname = f"ADF_debug_{ext}.log" - self.__debug_fname = debug_fname - logging.basicConfig(filename=debug_fname, level=logging.DEBUG) + logging.basicConfig(filename=self.__debug_fname, level=logging.DEBUG) self.__debug_log = logging.getLogger("ADF") else: self.__debug_log = None - + ######### @@ -102,4 +96,4 @@ def end_diag_fail(self, msg: str): #++++++++++++++++++++ #End Class definition -#++++++++++++++++++++ +#++++++++++++++++++++ \ No newline at end of file diff --git a/lib/adf_config.py b/lib/adf_config.py index 61a8ba112..b26c55485 100644 --- a/lib/adf_config.py +++ b/lib/adf_config.py @@ -19,6 +19,8 @@ import os.path import re import copy +import os +import subprocess #+++++++++++++++++++++++++++++++++++++++++++++++++ #import non-standard python modules, including ADF @@ -308,6 +310,100 @@ def read_config_var(self, varname, conf_dict=None, required=False): #config variables dictionary: return copy.deepcopy(var) + def config_dict(self): + + """ + Return a copy of the entire config dictionary. + """ + + config_dict = self.__config_dict + return copy.copy(config_dict) + + def get_git_info(self): + + """ + Gather currnet Git info during ADF run. + + Returns: + -------- + info : dict + Dictionary with the following keys: + - branch: Current Git branch name. + - commit: Current commit hash. + - remote_url: URL of the remote repository. + - repo_name: Name of the repository. + - is_dirty: Boolean indicating if there are uncommitted changes. + """ + + #Initialize empty dictionary: + info = {} + + try: + # Current branch + info['branch'] = subprocess.run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], + stdout=subprocess.PIPE, text=True, check=True).stdout.strip() + + # Commit hash + info['commit'] = subprocess.run(['git', 'rev-parse', 'HEAD'], + stdout=subprocess.PIPE, text=True, check=True).stdout.strip() + + # Remote URL + remote_url = subprocess.run(['git', 'remote', 'get-url', 'origin'], + stdout=subprocess.PIPE, text=True, check=True).stdout.strip() + info['remote_url'] = remote_url + + # Repo name + info['repo_name'] = os.path.splitext(os.path.basename(remote_url))[0] + + # Check if any modified files in ADF directory + info['is_dirty'] = bool(subprocess.run(['git', 'status', '--short'], + stdout=subprocess.PIPE, text=True, check=True).stdout.strip()) + + except subprocess.CalledProcessError as e: + print("Git command failed:", e) + info = None + + return info + + def get_active_conda_environment(self): + """ + Utility function to get the name of the active conda environment. + + Returns: + -------- + env_name (str or None): Name of the active conda environment, or None if not found. + """ + """env_name = None + try: + # Execute 'conda env list' and capture output + result = subprocess.run(['conda', 'env', 'list'], + capture_output=True, text=True, check=True) + output_lines = result.stdout.splitlines() + for line in output_lines: + # The active environment is marked with an asterisk (*) + if '*' in line.strip(): + # Extract the environment name (first part of the line) + env_name = line.strip().split()[0] + except subprocess.CalledProcessError as e: + print(f"Error executing conda command: {e}") + return env_name""" + # 'CONDA_DEFAULT_ENV' is the most reliable and direct way to get the env name. + env_name = os.environ.get('CONDA_DEFAULT_ENV') + if env_name: + return env_name + + # As a fallback, we can derive the name from the 'CONDA_PREFIX' path. + # The environment name is the last part of the path. + env_path = os.environ.get('CONDA_PREFIX') + if env_path: + return os.path.basename(env_path) + + # If neither are set, we are likely not in a conda environment. + return None + + + ######### + #++++++++++++++++++++ #End Class definition -#++++++++++++++++++++ +#++++++++++++++++++++ \ No newline at end of file diff --git a/lib/adf_dataset.py b/lib/adf_dataset.py index eb89dfaf2..0fd8432a4 100644 --- a/lib/adf_dataset.py +++ b/lib/adf_dataset.py @@ -1,12 +1,9 @@ from pathlib import Path import xarray as xr +import adf_utils as utils import warnings # use to warn user about missing files - -def my_formatwarning(msg, *args, **kwargs): - # ignore everything except the message - return str(msg) + '\n' -warnings.formatwarning = my_formatwarning +warnings.formatwarning = utils.my_formatwarning # "reference data" # It is often just a "baseline case", @@ -173,7 +170,6 @@ def load_reference_timeseries_da(self, field): return self.load_da(fils, field, add_offset=add_offset, scale_factor=scale_factor) - #------------------ @@ -366,4 +362,4 @@ def get_value_converters(self, case, variablename): - \ No newline at end of file + diff --git a/lib/adf_diag.py b/lib/adf_diag.py index cb611376f..0d0b1a385 100644 --- a/lib/adf_diag.py +++ b/lib/adf_diag.py @@ -1007,9 +1007,11 @@ def setup_run_cvdp(self): else: cvdp_dir = self.get_cvdp_info("cvdp_loc", required=True) + case_names[0] # end if + + cvdp_dir = os.path.abspath(cvdp_dir) if not os.path.isdir(cvdp_dir): shutil.copytree( - self.get_cvdp_info("cvdp_codebase_loc", required=True), cvdp_dir + self.get_cvdp_info("cvdp_codebase_loc"), cvdp_dir ) # End if @@ -1157,11 +1159,25 @@ def derive_variables(self, res=None, hist_str=None, vars_to_derive=None, ts_dir= whether to overwrite the file (true) or exit with a warning message. """ - + start_years = self.climo_yrs["syears"] + start_years = str(start_years[0]).zfill(4) + end_years = self.climo_yrs["eyears"] + end_years = str(end_years[0]).zfill(4) + date_range_string_case = f"{start_years}01-{end_years}12" # Loop through derived variables for var in vars_to_derive: print(f"\t - deriving time series for {var}") - + filename = f'{self.get_cam_info("cam_case_name")[0]}.{hist_str}*.{var}.{date_range_string_case}.nc' + if glob.glob(os.path.join(ts_dir, filename)): + expname = f'{self.get_baseline_info("cam_case_name")}' + start_years = self.climo_yrs["syear_baseline"] + start_years = str(start_years).zfill(4) + end_years = self.climo_yrs["eyear_baseline"] + end_years = str(end_years).zfill(4) + date_range_string = f"{start_years}01-{end_years}12" + else: + expname = f'{self.get_cam_info("cam_case_name")[0]}' + date_range_string = date_range_string_case # Grab list of constituents for this variable constit_list = constit_dict[var] @@ -1170,13 +1186,12 @@ def derive_variables(self, res=None, hist_str=None, vars_to_derive=None, ts_dir= for constit in constit_list: # Check if the constituent file is present, if so add it to list if hist_str: - const_glob_str = f"*{hist_str}*.{constit}.*.nc" + const_glob_str = f"{expname}.{hist_str}*.{constit}.{date_range_string}.nc" else: - const_glob_str = f"*.{constit}.*.nc" + const_glob_str = f"{expname}.*.{constit}.{date_range_string}.nc" # end if if glob.glob(os.path.join(ts_dir, const_glob_str)): constit_files.append(glob.glob(os.path.join(ts_dir, const_glob_str ))[0]) - # Check if all the necessary constituent files were found if len(constit_files) != len(constit_list): ermsg = f"\t WARNING: Not all constituent files present; {var} cannot be calculated." @@ -1273,6 +1288,8 @@ def derive_variables(self, res=None, hist_str=None, vars_to_derive=None, ts_dir= # Drop all constituents from final saved dataset # These are not necessary because they have their own time series files ds_final = ds.drop_vars(constit_list) + if "time_bnds" in list(ds_final.keys()): + ds_final = ds_final.drop_vars("time_bnds") # Copy attributes from constituent file to derived variable ds_final[var].attrs = attrs ds_final.to_netcdf(derived_file, unlimited_dims='time', mode='w') @@ -1525,13 +1542,10 @@ def _load_dataset(fils): ----- When just one entry is provided, use `open_dataset`, otherwise `open_mfdatset` """ - import warnings # use to warn user about missing files. - #Format warning messages: - def my_formatwarning(msg, *args, **kwargs): - """Issue `msg` as warning.""" - return str(msg) + '\n' - warnings.formatwarning = my_formatwarning + import adf_utils as utils + import warnings # use to warn user about missing files + warnings.formatwarning = utils.my_formatwarning if len(fils) == 0: warnings.warn("\t WARNING: Input file list is empty.") @@ -1542,4 +1556,4 @@ def my_formatwarning(msg, *args, **kwargs): return xr.open_dataset(fils[0]) #End if # End def -######## \ No newline at end of file +######## diff --git a/lib/adf_info.py b/lib/adf_info.py index 41ebde606..683b395c8 100644 --- a/lib/adf_info.py +++ b/lib/adf_info.py @@ -32,6 +32,7 @@ import copy import os import getpass +import subprocess #+++++++++++++++++++++++++++++++++++++++++++++++++ #import non-standard python modules, including ADF @@ -49,7 +50,6 @@ #+++++++++++++++++++ #Define Obs class #+++++++++++++++++++ - class AdfInfo(AdfConfig): """ @@ -82,10 +82,11 @@ def __init__(self, config_file, debug=False): # Add CVDP info to object: self.__cvdp_info = self.read_config_var("diag_cvdp_info") - # Expand CVDP climo info variable strings: if self.__cvdp_info is not None: self.expand_references(self.__cvdp_info) + cvdp_default_loc = Path("externals/CVDP/") + self.__cvdp_info.get("cvdp_codebase_loc",cvdp_default_loc) # End if # Add MDTF info to object: @@ -128,7 +129,6 @@ def __init__(self, config_file, debug=False): self.__cam_climo_info[conf_var] = [conf_val] #End if #End for - #------------------------------------------- #Initialize ADF variable list: self.__diag_var_list = self.read_config_var('diag_var_list', required=True) @@ -223,8 +223,8 @@ def __init__(self, config_file, debug=False): print(msg) syear_baseline = found_syear_baseline if syear_baseline not in found_yr_range: - msg = f"\t WARNING: Given start year '{syear_baseline}' is not in current dataset " - msg += f"{data_name}, using first found year: {found_syear_baseline}" + msg = f"\t WARNING: Given start year '{syear_baseline}' is not in current " + msg += f"dataset {data_name}, using first found year: {found_syear_baseline}" print(msg) syear_baseline = found_syear_baseline @@ -234,8 +234,8 @@ def __init__(self, config_file, debug=False): print(msg) eyear_baseline = found_eyear_baseline if eyear_baseline not in found_yr_range: - msg = f"\t WARNING: Given end year '{eyear_baseline}' is not in current dataset " - msg += f"{data_name}, using first found year: {found_eyear_baseline}" + msg = f"\t WARNING: Given end year '{eyear_baseline}' is not in current " + msg += f"dataset {data_name}, using first found year: {found_eyear_baseline}" print(msg) eyear_baseline = found_eyear_baseline # End if @@ -254,6 +254,7 @@ def __init__(self, config_file, debug=False): #Grab first possible hist string, just looking for years of run base_hist_str = baseline_hist_str[0] + print(f"AVAILABLE BASE_HIST_STR: {base_hist_str}") starting_location = Path(baseline_hist_locs) print(f"\tChecking history files in '{starting_location}'") file_list = sorted(starting_location.glob("*" + base_hist_str + ".*.nc")) @@ -294,7 +295,7 @@ def __init__(self, config_file, debug=False): raise AdfError(msg) base_climo_yrs = sorted(np.unique(base_climo_yrs)) - + print(f"AVAILABLE YEARS IN BASE RUN: {base_climo_yrs}") base_found_syr = int(base_climo_yrs[0]) base_found_eyr = int(base_climo_yrs[-1]) @@ -306,8 +307,8 @@ def __init__(self, config_file, debug=False): print(msg) syear_baseline = base_found_syr if syear_baseline not in base_climo_yrs: - msg = f"\t WARNING: Given start year '{syear_baseline}' is not in current dataset " - msg += f"{data_name}, using first found year: {base_climo_yrs[0]}" + msg = f"\t WARNING: Given start year '{syear_baseline}' is not in current " + msg += f"dataset {data_name}, using first found year: {base_climo_yrs[0]}" print(msg) syear_baseline = base_found_syr @@ -317,8 +318,8 @@ def __init__(self, config_file, debug=False): print(msg) eyear_baseline = base_found_eyr if eyear_baseline not in base_climo_yrs: - msg = f"\t WARNING: Given end year '{eyear_baseline}' is not in current dataset " - msg += f"{data_name}, using last found year: {base_climo_yrs[-1]}" + msg = f"\t WARNING: Given end year '{eyear_baseline}' is not in current " + msg += f"dataset {data_name}, using last found year: {base_climo_yrs[-1]}" print(msg) eyear_baseline = base_found_eyr @@ -462,7 +463,7 @@ def __init__(self, config_file, debug=False): emsg += "\tTry checking the path 'cam_hist_loc' in 'diag_cam_climo' " emsg += "section in your config file is correct..." self.end_diag_fail(emsg) - + #Check if there are any history files file_list = sorted(starting_location.glob('*'+hist_str+'.*.nc')) if len(file_list) == 0: @@ -488,7 +489,7 @@ def __init__(self, config_file, debug=False): msg = f"\t ERROR: No climo years found in {cam_hist_locs[case_idx]}, " raise AdfError(msg) case_climo_yrs = sorted(np.unique(case_climo_yrs)) - + print(f'Case climo years: {case_climo_yrs}') case_found_syr = int(case_climo_yrs[0]) case_found_eyr = int(case_climo_yrs[-1]) @@ -542,7 +543,7 @@ def __init__(self, config_file, debug=False): diag_location = Path(plot_loc) print(f"\n\tDiagnostic Plot Location: {diag_location}") if not diag_location.is_dir(): - print(f"\tINFO: Directory not found, making new diagnostic plot location") + print("\tINFO: Directory not found, making new diagnostic plot location") diag_location.mkdir(parents=True) #End for @@ -555,7 +556,6 @@ def __init__(self, config_file, debug=False): if not self.compare_obs: self.__plot_location.append(os.path.join(plot_dir, first_case_dir)) #End if - #------------------------------------------------------------------------- #Initialize "num_procs" variable: @@ -593,7 +593,6 @@ def __init__(self, config_file, debug=False): self.__num_procs = 1 #End if #End except - else: #If anything else, then try to convert to integer: try: @@ -614,9 +613,9 @@ def __init__(self, config_file, debug=False): #End if #Print number of processors being used to debug log (if requested): self.debug_log(f"ADF is running with {self.__num_procs} processors.") - # ----------------------------------------- ######### + def hist_str_to_list(self, conf_var, conf_val): """ Make hist_str a nested list [ncases,nfiles] of the given value(s) @@ -628,8 +627,6 @@ def hist_str_to_list(self, conf_var, conf_val): conf_val ] self.__cam_climo_info[conf_var] = [hist_str] - # ----------------------------------------- - ######### # Create property needed to return "user" name to user: @@ -705,7 +702,6 @@ def climo_yrs(self): return {"syears":syears,"eyears":eyears, "syear_baseline":self.__syear_baseline, "eyear_baseline":self.__eyear_baseline} - # Create property needed to return the case nicknames to user: @property def case_nicknames(self): @@ -729,6 +725,7 @@ def hist_string(self): hist_strs = {"test_hist_str":cam_hist_strs, "base_hist_str":base_hist_strs} return hist_strs + ######### #Utility function to access expanded 'diag_basic_info' variables: @@ -825,7 +822,6 @@ def get_mdtf_info(self, var_str, required=False): var_str, conf_dict=self.__mdtf_info, required=required ) - ######### # Utility function to grab climo years from pre-made time series files: @@ -860,7 +856,7 @@ def get_climo_yrs_from_ts(self, input_ts_loc, case_name): break else: logmsg = "get years for time series:" - logmsg = f"\n\tVar '{var}' not in dataset, skip to next to try and find climo years..." + logmsg += f"\n\tVar '{var}' not in dataset, skip to next to try and find climo years..." self.debug_log(logmsg) #Read in file(s) @@ -879,9 +875,7 @@ def get_climo_yrs_from_ts(self, input_ts_loc, case_name): if time_bounds_name: time = cam_ts_data['time'] - #NOTE: force `load` here b/c if dask & time is cftime, - #throws a NotImplementedError: - + #NOTE: force `load` here b/c if dask & time is cftime, throws a NotImplementedError: time = xr.DataArray(cam_ts_data[time_bounds_name].load().mean(dim='nbnd').values, dims=time.dims, attrs=time.attrs) cam_ts_data['time'] = time @@ -899,6 +893,7 @@ def get_climo_yrs_from_ts(self, input_ts_loc, case_name): return syr, eyr + #++++++++++++++++++++ #End Class definition -#++++++++++++++++++++ \ No newline at end of file +#++++++++++++++++++++ diff --git a/lib/adf_utils.py b/lib/adf_utils.py new file mode 100644 index 000000000..179051011 --- /dev/null +++ b/lib/adf_utils.py @@ -0,0 +1,706 @@ +""" . +Generic computation helper functions + +Functions +--------- +load_dataset() + generalized load dataset method used for plotting/analysis functions +mask_land_or_ocean(arr, msk, use_nan=False) + Apply a land or ocean mask to provided variable. +global_average(fld, wgt, verbose=False) + pure numpy global average. +spatial_average(indata, weights=None, spatial_dims=None) + Compute spatial average +wgt_rmse(fld1, fld2, wgt): + Calculate the area-weighted RMSE. +annual_mean(data, whole_years=False, time_name='time'): + Calculate annual averages from time series data. +seasonal_mean(data, season=None, is_climo=None): + Calculates the time-weighted seasonal average (or average over all time). +domain_stats(data, domain): + Provides statistics in specified region. +pres_from_hybrid(psfc, hya, hyb, p0=100000.): + Converts a hybrid level to a pressure +vert_remap(x_mdl, p_mdl, plev) + Interpolates to specified pressure levels. +lev_to_plev(data, ps, hyam, hybm, P0=100000., new_levels=None, convert_to_mb=False) + Interpolate model hybrid levels to specified pressure levels. +pmid_to_plev(data, pmid, new_levels=None, convert_to_mb=False) + Interpolate `data` from hybrid-sigma levels to isobaric levels using provided mid-level pressures. +zonal_mean_xr(fld) + Average over all dimensions except `lev` and `lat`. +validate_dims(fld, list_of_dims) + Checks if specified dimensions are in a DataArray +lat_lon_validate_dims(fld) + Check if input field has lat and lon. +zm_validate_dims(fld) + Check for dimensions for zonal average. + +Notes +----- + +""" + +#import statements: +import numpy as np +import xarray as xr +import pandas as pd +import geocat.comp as gcomp + +from adf_base import AdfError + +import warnings # use to warn user about missing files. + +#Format warning messages: +def my_formatwarning(msg, *args, **kwargs): + """Issue `msg` as warning.""" + return str(msg) + '\n' +warnings.formatwarning = my_formatwarning + +#Set seasonal ranges: +seasons = {"ANN": np.arange(1,13,1), + "DJF": [12, 1, 2], + "JJA": [6, 7, 8], + "MAM": [3, 4, 5], + "SON": [9, 10, 11] + } + + +################# +#HELPER FUNCTIONS +################# + +def load_dataset(fils): + """ + This method exists to get an xarray Dataset from input file information that can be passed into the plotting methods. + + Parameters + ---------- + fils : list + strings or paths to input file(s) + + Returns + ------- + xr.Dataset + + Notes + ----- + When just one entry is provided, use `open_dataset`, otherwise `open_mfdatset` + """ + if len(fils) == 0: + warnings.warn(f"\t WARNING: Input file list is empty.") + return None + elif len(fils) > 1: + return xr.open_mfdataset(fils, combine='by_coords') + else: + return xr.open_dataset(fils[0]) + #End if +#End def + + +def mask_land_or_ocean(arr, msk, use_nan=False): + """Apply a land or ocean mask to provided variable. + + Parameters + ---------- + arr : xarray.DataArray + the xarray variable to apply the mask to. + msk : xarray.DataArray + the xarray variable that contains the land or ocean mask, + assumed to be the same shape as "arr". + use_nan : bool, optional + argument for whether to set the missing values + to np.nan values instead of the defaul "-999." values. + + Returns + ------- + arr : xarray.DataArray + Same as input `arr` but masked as specified. + """ + + if use_nan: + missing_value = np.nan + else: + missing_value = -999. + #End if + + arr = xr.where(msk>=0.9,arr,missing_value) + arr.attrs["missing_value"] = missing_value + return(arr) + + + +####### + +def global_average(fld, wgt, verbose=False): + """A simple, pure numpy global average. + + Parameters + ---------- + fld : np.ndarray + an input ndarray + wgt : np.ndarray + a 1-dimensional array of weights, should be same size as one dimension of `fld` + verbose : bool, optional + prints information when `True` + + Returns + ------- + weighted average of `fld` + """ + + s = fld.shape + for i in range(len(s)): + if np.size(fld, i) == len(wgt): + a = i + break + fld2 = np.ma.masked_invalid(fld) + if verbose: + print("(global_average)-- fraction of mask that is True: {}".format(np.count_nonzero(fld2.mask) / np.size(fld2))) + print("(global_average)-- apply ma.average along axis = {} // validate: {}".format(a, fld2.shape)) + avg1, sofw = np.ma.average(fld2, axis=a, weights=wgt, returned=True) # sofw is sum of weights + + return np.ma.average(avg1) + + +def spatial_average(indata, weights=None, spatial_dims=None): + """Compute spatial average. + + Parameters + ---------- + indata : xr.DataArray + input data + weights : np.ndarray or xr.DataArray, optional + the weights to apply, see Notes for default behavior + spatial_dims : list, optional + list of dimensions to average, see Notes for default behavior + + Returns + ------- + xr.DataArray + weighted average of `indata` + + Notes + ----- + When `weights` is not provided, tries to find sensible values. + If there is a 'lat' dimension, use `cos(lat)`. + If there is a 'ncol' dimension, looks for `area` in `indata`. + Otherwise, set to equal weights. + + Makes an attempt to identify the spatial variables when `spatial_dims` is None. + Will average over `ncol` if present, and then will check for `lat` and `lon`. + When none of those three are found, raise an AdfError. + """ + import warnings + + if weights is None: + #Calculate spatial weights: + if 'lat' in indata.coords: + weights = np.cos(np.deg2rad(indata.lat)) + weights.name = "weights" + elif 'ncol' in indata.dims: + if 'area' in indata: + warnings.warn("area variable being used to generated normalized weights.") + weights = indata['area'] / indata['area'].sum() + else: + warnings.warn("\t We need a way to get area variable. Using equal weights.") + weights = xr.DataArray(1.) + weights.name = "weights" + else: + weights = xr.DataArray(1.) + weights.name = "weights" + warnings.warn("Un-recognized spatial dimensions: using equal weights for all grid points.") + #End if + #End if + + #Apply weights to input data: + weighted = indata.weighted(weights) + + # we want to average over all non-time dimensions + if spatial_dims is None: + if 'ncol' in indata.dims: + spatial_dims = ['ncol'] + else: + spatial_dims = [dimname for dimname in indata.dims if (('lat' in dimname.lower()) or ('lon' in dimname.lower()))] + + if not spatial_dims: + #Scripts using this function likely expect the horizontal dimensions + #to be removed via the application of the mean. So in order to avoid + #possibly unexpected behavior due to arrays being incorrectly dimensioned + #(which could be difficult to debug) the ADF should die here: + emsg = "spatial_average: No spatial dimensions were identified," + emsg += " so can not perform average." + raise AdfError(emsg) + + return weighted.mean(dim=spatial_dims, keep_attrs=True) + + +def wgt_rmse(fld1, fld2, wgt): + """Calculate the area-weighted RMSE. + + Parameters + ---------- + fld1, fld2 : array-like + 2-dimensional spatial fields with the same shape. + They can be xarray DataArray or numpy arrays. + wgt : array-like + the weight vector, expected to be 1-dimensional, + matching length of one dimension of the data. + + Returns + ------- + float + root mean squared error + + Notes: + ```rmse = sqrt( mean( (fld1 - fld2)**2 ) )``` + """ + assert len(fld1.shape) == 2, "Input fields must have exactly two dimensions." + assert fld1.shape == fld2.shape, "Input fields must have the same array shape." + # in case these fields are in dask arrays, compute them now. + if hasattr(fld1, "compute"): + fld1 = fld1.compute() + if hasattr(fld2, "compute"): + fld2 = fld2.compute() + if isinstance(fld1, xr.DataArray) and isinstance(fld2, xr.DataArray): + return (np.sqrt(((fld1 - fld2)**2).weighted(wgt).mean())).values.item() + else: + check = [len(wgt) == s for s in fld1.shape] + if ~np.any(check): + raise IOError(f"Sorry, weight array has shape {wgt.shape} which is not compatible with data of shape {fld1.shape}") + check = [len(wgt) != s for s in fld1.shape] + dimsize = fld1.shape[np.argwhere(check).item()] # want to get the dimension length for the dim that does not match the size of wgt + warray = np.tile(wgt, (dimsize, 1)).transpose() # May need more logic to ensure shape is correct. + warray = warray / np.sum(warray) # normalize + wmse = np.sum(warray * (fld1 - fld2)**2) + return np.sqrt( wmse ).item() + + +####### +# Time-weighted averaging + +def annual_mean(data, whole_years=False, time_name='time'): + """Calculate annual averages from monthly time series data. + + Parameters + ---------- + data : xr.DataArray or xr.Dataset + monthly data values with temporal dimension + whole_years : bool, optional + whether to restrict endpoints of the average to + start at first January and end at last December + time_name : str, optional + name of the time dimension, defaults to `time` + + Returns + ------- + result : xr.DataArray or xr.Dataset + `data` reduced to annual averages + + Notes + ----- + This function assumes monthly data, and weights the average by the + number of days in each month. + + `result` includes an attribute that reports the date range used for the average. + """ + assert time_name in data.coords, f"Did not find the expected time coordinate '{time_name}' in the data" + if whole_years: + first_january = np.argwhere((data.time.dt.month == 1).values)[0].item() + last_december = np.argwhere((data.time.dt.month == 12).values)[-1].item() + data_to_avg = data.isel(time=slice(first_january,last_december+1)) # PLUS 1 BECAUSE SLICE DOES NOT INCLUDE END POINT + else: + data_to_avg = data + date_range_string = f"{data_to_avg['time'][0]} -- {data_to_avg['time'][-1]}" + + # this provides the normalized monthly weights in each year + # -- do it for each year to allow for non-standard calendars (360-day) + # -- and also to provision for data with leap years + days_gb = data_to_avg.time.dt.daysinmonth.groupby('time.year').map(lambda x: x / x.sum()) + # weighted average with normalized weights: = SUM x_i * w_i (implied division by SUM w_i) + result = (data_to_avg * days_gb).groupby('time.year').sum(dim='time') + result.attrs['averaging_period'] = date_range_string + result.attrs['units'] = data.attrs.get("units",None) + return result + + +def seasonal_mean(data, season=None, is_climo=None): + """Calculates the time-weighted seasonal average (or average over all time). + + Parameters + ---------- + data : xarray.DataArray or xarray.Dataset + data to be averaged + season : str, optional + the season to extract from `data` + If season is `ANN` or None, average all available time. + is_climo : bool, optional + If True, expects data to have time or month dimenion of size 12. + If False, then 'time' must be a coordinate, + and the `time.dt.days_in_month` attribute must be available. + + Returns + ------- + xarray.DataArray or xarray.Dataset + the average of `data` in season `season` + + Notes + ----- + If the data is a climatology, the code will make an attempt to understand the time or month + dimension, but will assume that it is ordered from January to December. + If the data is a climatology and is just a numpy array with one dimension that is size 12, + it will assume that dimension is time running from January to December. + """ + if season is not None: + assert season in ["ANN", "DJF", "JJA", "MAM", "SON"], f"Unrecognized season string provided: '{season}'" + elif season is None: + season = "ANN" + + try: + month_length = data.time.dt.days_in_month + except (AttributeError, TypeError): + # do our best to determine the temporal dimension and assign weights + if not is_climo: + raise ValueError("Non-climo file provided, but without a decoded time dimension.") + else: + # CLIMO file: try to determine which dimension is month + has_time = False + if isinstance(data, xr.DataArray): + has_time = 'time' in data.dims + if not has_time: + if "month" in data.dims: + data = data.rename({"month":"time"}) + has_time = True + if not has_time: + # this might happen if a pure numpy array gets passed in + # --> assumes ordered January to December. + assert ((12 in data.shape) and (data.shape.count(12) == 1)), f"Sorry, {data.shape.count(12)} dimensions have size 12, making determination of which dimension is month ambiguous. Please provide a `time` or `month` dimension." + time_dim_num = data.shape.index(12) + fakedims = [f"dim{n}" for n in range(len(data.shape))] + fakedims[time_dim_num] = "time" + data = xr.DataArray(data, dims=fakedims, attrs=data.attrs) + timefix = pd.date_range(start='1/1/1999', end='12/1/1999', freq='MS') # generic time coordinate from a non-leap-year + data = data.assign_coords({"time":timefix}) + month_length = data.time.dt.days_in_month + #End try/except + + data = data.sel(time=data.time.dt.month.isin(seasons[season])) # directly take the months we want based on season kwarg + return data.weighted(data.time.dt.daysinmonth).mean(dim='time', keep_attrs=True) + + + +####### + + +def domain_stats(data, domain): + """Provides statistics in specified region. + + Parameters + ---------- + data : xarray.DataArray + data values + domain : list or tuple or numpy.ndarray + the domain specification as: + [west_longitude, east_longitude, south_latitude, north_latitude] + + Returns + ------- + x_region_mean : float + the regional area-weighted average + x_region_max : float + the maximum value in the region + x_region_min : float + the minimum value in the region + + Notes + ----- + Currently assumes 'lat' is a dimension and uses `cos(lat)` as weight. + Should use `spatial_average` + + See Also + -------- + spatial_average + + """ + x_region = data.sel(lat=slice(domain[2],domain[3]), lon=slice(domain[0],domain[1])) + x_region_mean = x_region.weighted(np.cos(np.deg2rad(x_region['lat']))).mean().item() + x_region_min = x_region.min().item() + x_region_max = x_region.max().item() + return x_region_mean, x_region_max, x_region_min + + + + +# +# -- vertical interpolation code -- +# + +def pres_from_hybrid(psfc, hya, hyb, p0=100000.): + """Calculates pressure field + + pressure derived with the formula: + ```p = a(k)*p0 + b(k)*ps``` + + Parameters + ---------- + psfc + surface pressure + hya, hyb + hybrid-sigma A and B coefficients + p0 : optional + reference pressure, defaults to 100000 Pa + + Returns + ------- + pressure, size is same as `psfc` with `len(hya)` levels + """ + return hya*p0 + hyb*psfc + +##### + +def vert_remap(x_mdl, p_mdl, plev): + """Apply simple 1-d interpolation to a field + + Parameters + ---------- + x_mdl : xarray.DataArray or numpy.ndarray + input data + p_mdl : xarray.DataArray or numpy.ndarray + pressure field, same shape as `x_mdl` + plev : xarray.DataArray or numpy.ndarray + the new pressures + + Returns + ------- + output + `x_mdl` interpolated to `plev` + + Notes + ----- + Interpolation done in log pressure + """ + + #Determine array shape of output array: + out_shape = (plev.shape[0], x_mdl.shape[1]) + + #Initialize interpolated output numpy array: + output = np.full(out_shape, np.nan) + + #Perform 1-D interpolation in log-space: + for i in range(out_shape[1]): + output[:,i] = np.interp(np.log(plev), np.log(p_mdl[:,i]), x_mdl[:,i]) + #End for + + #Return interpolated output: + return output + +##### + +def lev_to_plev(data, ps, hyam, hybm, P0=100000., new_levels=None, + convert_to_mb=False): + """Interpolate model hybrid levels to specified pressure levels. + + Parameters + ---------- + data : + ps : + surface pressure + hyam, hybm : + hybrid-sigma A and B coefficients + P0 : float, optional + reference pressure, defaults to 100000 Pa + new_levels : numpy.ndarray, optional + 1-D array containing pressure levels in Pascals (Pa). + If not specified, then the levels will be set + to the GeoCAT defaults, which are (in hPa): + `1000, 925, 850, 700, 500, 400, 300, 250, 200, 150, 100, 70, 50, + 30, 20, 10, 7, 5, 3, 2, 1` + convert_to_mb : bool, optional + If True, then vertical (lev) dimension will have + values of mb/hPa, otherwise the units are Pa. + + Returns + ------- + data_interp_rename + data interpolated to new pressure levels + + Notes + ----- + The function `interp_hybrid_to_pressure` used here is dask-enabled, + and so can potentially be sped-up via the use of a DASK cluster. + """ + + #Temporary print statement to notify users to ignore warning messages. + #This should be replaced by a debug-log stdout filter at some point: + print("Please ignore the interpolation warnings that follow!") + + #Apply GeoCAT hybrid->pressure interpolation: + if new_levels is not None: + data_interp = gcomp.interpolation.interp_hybrid_to_pressure(data, ps, + hyam, + hybm, + p0=P0, + new_levels=new_levels + ) + else: + data_interp = gcomp.interpolation.interp_hybrid_to_pressure(data, ps, + hyam, + hybm, + p0=P0 + ) + + # data_interp may contain a dask array, which can cause + # trouble downstream with numpy functions, so call compute() here. + if hasattr(data_interp, "compute"): + data_interp = data_interp.compute() + + #Rename vertical dimension back to "lev" in order to work with + #the ADF plotting functions: + data_interp_rename = data_interp.rename({"plev": "lev"}) + + #Convert vertical dimension to mb/hPa, if requested: + if convert_to_mb: + data_interp_rename["lev"] = data_interp_rename["lev"] / 100.0 + + return data_interp_rename + +##### + +def pmid_to_plev(data, pmid, new_levels=None, convert_to_mb=False): + """Interpolate data from hybrid-sigma levels to isobaric levels. + + Parameters + ---------- + data : xarray.DataArray + field with a 'lev' coordinate + pmid : xarray.DataArray + the pressure field (Pa), same shape as `data` + new_levels : optional + the output pressure levels (Pa), defaults to standard levels + convert_to_mb : bool, optional + flag to convert output to mb (i.e., hPa), defaults to False + + Returns + ------- + output : xarray.DataArray + `data` interpolated onto `new_levels` + """ + + # determine pressure levels to interpolate to: + if new_levels is None: + pnew = 100.0 * np.array([1000, 925, 850, 700, 500, 400, + 300, 250, 200, 150, 100, 70, 50, + 30, 20, 10, 7, 5, 3, 2, 1]) # mandatory levels, converted to Pa + else: + pnew = new_levels + #End if + + # save name of DataArray: + data_name = data.name + + # reshape data and pressure assuming "lev" is the name of the coordinate + zdims = [i for i in data.dims if i != 'lev'] + dstack = data.stack(z=zdims) + pstack = pmid.stack(z=zdims) + output = vert_remap(dstack.values, pstack.values, pnew) + output = xr.DataArray(output, name=data_name, dims=("lev", "z"), + coords={"lev":pnew, "z":pstack['z']}) + output = output.unstack() + + # convert vertical dimension to mb/hPa, if requested: + if convert_to_mb: + output["lev"] = output["lev"] / 100.0 + #End if + + #Return interpolated output: + return output + + + + +def validate_dims(fld, list_of_dims): + """Check if specified dimensions are in a DataArray. + + Parameters + ---------- + fld : xarray.DataArray + field to check for named dimensions + list_of_dims : list + list of strings that specifiy the dimensions to check for + + Returns + ------- + dict + dict with keys that are "has_{x}" where x is the name from + `list_of_dims` and values that are boolean + + """ + if not isinstance(list_of_dims, list): + list_of_dims = list(list_of_dims) + return { "_".join(["has",f"{v}"]):(v in fld.dims) for v in list_of_dims} + + +def lat_lon_validate_dims(fld): + """Check if input field has lat and lon. + + Parameters + ---------- + fld : xarray.DataArray + data with named dimensions + + Returns + ------- + bool + True if lat and lon are both dimensions, False otherwise. + + See Also + -------- + validate_dims + """ + # note: we can only handle variables that reduce to (lat,lon) + if len(fld.dims) > 3: + return False + validate = validate_dims(fld, ['lat','lon']) + if not all(validate.values()): + return False + else: + return True + + +def zm_validate_dims(fld): + """Check for dimensions for zonal average. + + Looks for dimensions called 'lev' and 'lat'. + + + Parameters + ---------- + fld : xarray.DataArray + field to check for lat and/or lev dimensions + Returns + ------- + tuple + (has_lat, has_lev) each are bool + None + If 'lat' is not in dimensions, returns None. + """ + # note: we can only handle variables that reduce to (lev, lat) or (lat,) + if len(fld.dims) > 4: + print(f"Sorry, too many dimensions: {fld.dims}") + return None + validate = validate_dims(fld, ['lev','lat']) + has_lev, has_lat = validate['has_lev'], validate['has_lat'] + return has_lat, has_lev + + +def zonal_mean_xr(fld): + """Average over all dimensions except `lev` and `lat`.""" + if isinstance(fld, xr.DataArray): + d = fld.dims + davgovr = [dim for dim in d if dim not in ('lev','lat')] + else: + raise IOError("zonal_mean_xr requires Xarray DataArray input.") + return fld.mean(dim=davgovr) + +##################### +#END HELPER FUNCTIONS \ No newline at end of file diff --git a/lib/adf_variable_defaults.yaml b/lib/adf_variable_defaults.yaml index 60743359c..434ae5fc7 100644 --- a/lib/adf_variable_defaults.yaml +++ b/lib/adf_variable_defaults.yaml @@ -69,7 +69,8 @@ # Available ADF Default Plot Types #+++++++++++++ default_ptypes: ["Tables","LatLon","LatLon_Vector","Zonal","Meridional", - "NHPolar","SHPolar","TimeSeries","Special"] + "NHPolar","SHPolar","TimeSeries","ENSO","GlobalHistogramTS", + "GlobalHistogramClimo","Special"] #+++++++++++++ # Constants @@ -156,6 +157,56 @@ AODDUST: pct_diff_colormap: "PuOr_r" AODVIS: + category: "Aerosols" + colormap: "Oranges" + contour_levels_range: [0.00, 1, 0.1] + diff_colormap: "PuOr_r" + diff_contour_range: [-0.5, 0.5, 0.05] + scale_factor: 1 + add_offset: 0 + new_unit: "" + +D550_SO4: + category: "Aerosols" + colormap: "Oranges" + contour_levels_range: [0.05, 0.6, 0.05] + diff_colormap: "PuOr_r" + diff_contour_range: [-0.1, 0.1, 0.01] + scale_factor: 1 + add_offset: 0 + new_unit: "" + +D550_SS: + category: "Aerosols" + colormap: "Oranges" + contour_levels_range: [0.05, 0.6, 0.05] + diff_colormap: "PuOr_r" + diff_contour_range: [-0.1, 0.1, 0.01] + scale_factor: 1 + add_offset: 0 + new_unit: "" + +D550_BC: + category: "Aerosols" + colormap: "Oranges" + contour_levels_range: [0.05, 0.6, 0.05] + diff_colormap: "PuOr_r" + diff_contour_range: [-0.1, 0.1, 0.01] + scale_factor: 1 + add_offset: 0 + new_unit: "" + +D550_DU: + category: "Aerosols" + colormap: "Oranges" + contour_levels_range: [0.05, 0.6, 0.05] + diff_colormap: "PuOr_r" + diff_contour_range: [-0.1, 0.1, 0.01] + scale_factor: 1 + add_offset: 0 + new_unit: "" + +D550_POM: category: "Aerosols" colormap: "Oranges" contour_levels_range: [0.05, 0.6, 0.05] @@ -182,35 +233,181 @@ AODVISdn: pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" -BURDENBC: +cb_BC: + colormap: "Oranges" + contour_levels_range: [0, 5.5, .5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-1, 1.1, 0.1] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" category: "Aerosols" + colormap: "plasma_r" + scale_factor: 1000000 + add_offset: 0 + new_unit: 'g m$^{-2}$' pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" + diff_colormap: "RdBu_r" + obs_file: "BURDENBC_MERRA2_monthly_climo_1degree_200001-202506.nc" + obs_var_name: "BURDENBC" + obs_name: "MERRA2" + obs_scale_factor: 1000000 + obs_add_offset: 0 -BURDENDUST: +cb_SULFATE: + colormap: "Oranges" + contour_levels_range: [0, 11, 1 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-2.25, 2.5, 0.25] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" category: "Aerosols" + colormap: "plasma_r" + scale_factor: 1000000 + add_offset: 0 + new_unit: 'g m$^{-2}$' pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" + diff_contour_range: [-1000, 1100, 100] + diff_colormap: "RdBu_r" + obs_file: "BURDENDUST_CAMS_monthly_climo_1degree_200301-202412.nc" + obs_var_name: "BURDENDUST" + obs_name: "CAMS" + obs_scale_factor: 1000000 + obs_add_offset: 0 -BURDENPOM: +cb_isoprene: + colormap: "Oranges" + contour_levels_range: [0, 105, 5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-50, 52.5, 2.5] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" category: "Aerosols" + colormap: "plasma_r" + scale_factor: 1000000 + add_offset: 0 + new_unit: 'g m$^{-2}$' pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" + diff_colormap: "RdBu_r" -BURDENSEASALT: + +cb_monoterp: + colormap: "Oranges" + contour_levels_range: [0, 55, 5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-20, 22.5, 2.5] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" category: "Aerosols" + colormap: "plasma_r" + scale_factor: 1000000 + add_offset: 0 + new_unit: 'g m$^{-2}$' + diff_contour_range: [-200, 200, 25] + diff_colormap: "RdBu_r" pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" + obs_file: "BURDENSEASALT_CAMS_monthly_climo_1degree_200301-202412.nc" + obs_var_name: "BURDENSEASALT" + obs_name: "CAMS" + obs_scale_factor: 1000000 + obs_add_offset: 0 -BURDENSO4: +cb_DMS: + colormap: "Oranges" + contour_levels_range: [0, 2.25, .25 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-0.1, 0.11, 0.01] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" category: "Aerosols" + colormap: "plasma_r" + scale_factor: 1000000 + add_offset: 0 + new_unit: 'g m$^{-2}$' pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" + diff_colormap: "RdBu_r" + obs_file: "BURDENSO4_CAMS_monthly_climo_1degree_200301-202412.nc" + obs_name: "CAMS" + obs_var_name: "BURDENSO4" + obs_scale_factor: 1000000 + obs_add_offset: 0 -BURDENSOA: +cb_DUST: + colormap: "Oranges" + contour_levels: [1, 10, 20, 30, 40, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 999, 1000] + diff_colormap: "PuOr_r" + log_normal: true + diff_contour_range: [-600, 650, 50] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" category: "Aerosols" + +cb_OM: + colormap: "Oranges" + contour_levels_range: [0, 105, 5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-50, 52.5, 2.5] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" + category: "Aerosols" + +cb_H2O2: + colormap: "Oranges" + contour_levels_range: [0, 11, 1 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-2.25, 2.5, 0.25] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" + category: "Aerosols" + +cb_H2SO4: + colormap: "Oranges" + contour_levels_range: [0, 1.1, .1 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-0.1, 0.11, 0.01] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" + category: "Aerosols" + +cb_SALT: + colormap: "Oranges" + contour_levels_range: [0, 105, 5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-50, 55, 5] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" + category: "Aerosols" + +cb_SO2: + colormap: "Oranges" + contour_levels_range: [0, 22, 2 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-5, 6, 1] + scale_factor: 1000000 + add_offset: 0 + new_unit: "1e-6 kg/m2" + category: "Aerosols" + colormap: "plasma_r" + scale_factor: 1000000 + add_offset: 0 + new_unit: 'g m$^{-2}$' pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" + diff_colormap: "RdBu_r" DMS: category: "Aerosols" @@ -518,6 +715,150 @@ SAD_SULFC: pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" +#+++++++++++++++++ +# Category: Surface emissions +#+++++++++++++++++ + +SFSOA: + colormap: "Oranges" + contour_levels_range: [0, 105, 5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-50, 55, 5] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + derivable_from: ["SFSOA_A1", "SFSOA_LV", "SFSOA_NA", "SFSOA_SV"] + +SFSS: + colormap: "Oranges" + contour_levels_range: [0, 2100, 100] + diff_colormap: "PuOr_r" + diff_contour_range: [-500, 550, 50] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + derivable_from: ["SFSS_A1", "SFSS_A2", "SFSS_A3"] + +SFBC: + colormap: "Oranges" + contour_levels_range: [0, 11, 1 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-1, 1.1, .1] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + derivable_from: ["SFBC_A","SFBC_AC","SFBC_AI","SFBC_AX","SFBC_N","SFBC_NI","BC_AX_CMXF","BC_NI_CMXF","BC_N_CMXF"] + +SFH2O2: + colormap: "Oranges" + contour_levels_range: [0, 105, 5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-50, 55, 5] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + +SFH2SO4: + colormap: "Oranges" + contour_levels_range: [0, 105, 5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-50, 55, 5] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + +SFDMS: + colormap: "Oranges" + contour_levels_range: [0, 11, 1 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-10, 11, 1] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + +SFOM: + colormap: "Oranges" + contour_levels_range: [0, 45, 5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-20, 22.5, 2.5] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + derivable_from: ["SFOM_AC", "SFOM_AI", "SFOM_NI", "OM_NI_CMXF"] + +SFDUST: + colormap: "Oranges" + contour_levels: [1, 250, 500, 1000, 1500, 2000, 2500, 3000, 4000, 5000] + diff_colormap: "PuOr_r" + #log_normal: true + diff_contour_range: [-600, 650, 50] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + derivable_from: [ "SFDST_A2", "SFDST_A3"] + +SFSO2_net: + colormap: "Oranges" + contour_levels_range: [0, 105, 5 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-50, 55, 5] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + derivable_from: ["SFSO2", "SO2_CMXF"] + +SFSO4: + colormap: "Oranges" + contour_levels: [0, .5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20] + diff_colormap: "PuOr_r" + diff_contour_range: [-1, 1.1, .1] + scale_factor: 100000000000000 + add_offset: 0 + new_unit: "1e-14 kg/m2/s" + category: "Surface emissions" + derivable_from: [ "SFSO4_PR", "SO4_PR_CMXF"] + #["SFSO4_A1", "SFSO4_A2", "SFSO4_AC", "SFSO4_NA", "SFSO4_PR"] + +SFmonoterp: + colormap: "Oranges" + contour_levels: [-4, -2, 0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 550, 600 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-100, 105, 5] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + +SFisoprene: + colormap: "Oranges" + contour_levels_range: [0, 2100, 100 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-500, 550, 50] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + +SFVOC: + colormap: "Oranges" + contour_levels_range: [0, 2100, 100 ] + diff_colormap: "PuOr_r" + diff_contour_range: [-500, 550, 50] + scale_factor: 1000000000000 + add_offset: 0 + new_unit: "1e-12 kg/m2/s" + category: "Surface emissions" + derivable_from: [ "SFisoprene", "SFisoprene"] + #+++++++++++++++++ # Category: Budget #+++++++++++++++++ @@ -1691,6 +2032,11 @@ TREFHT: obs_file: "TREFHT_ERA5_monthly_climo_197901-202112.nc" obs_name: "ERA5" obs_var_name: "TREFHT" + contour_levels_range: [220,320, 5] + diff_contour_range: [-10, 10, 1] + scale_factor: 1 + add_offset: 0 + new_unit: "K" TS: colormap: "Blues" @@ -1877,6 +2223,10 @@ OMEGA500: category: "State" pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" + scale_factor: 864 + add_offset: 0 + new_unit: "hPa d$^{-1}$" + hist_bins: [-105, -100, -95, -90, -85, -80, -75, -70, -65, -60, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100] PINT: category: "State" @@ -2264,6 +2614,71 @@ TOT_ICLD_VISTAU: pct_diff_contour_levels: [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] pct_diff_colormap: "PuOr_r" +CLDTOT_CAL: + colormap: "cividis" + contour_levels_range: [0, 105, 5] + diff_colormap: "RdBu_r" + diff_contour_range: [-40, 40, 5] + scale_factor: 1. + add_offset: 0 + new_unit: "Percent" + obs_file: "CALIPSO_GOCCP_3.1.2_climo_200606-202012.nc" + obs_name: "CALIPSO" + obs_var_name: "CLDTOT_CAL" + category: "COSP" + +CLDHGH_CAL: + colormap: "cividis" + contour_levels_range: [0, 105, 5] + diff_colormap: "RdBu_r" + diff_contour_range: [-40, 40, 5] + scale_factor: 1. + add_offset: 0 + new_unit: "Percent" + obs_file: "CALIPSO_GOCCP_3.1.2_climo_200606-202012.nc" + obs_name: "CALIPSO" + obs_var_name: "CLDHGH_CAL" + category: "COSP" + +CLDMED_CAL: + colormap: "cividis" + contour_levels_range: [0, 105, 5] + diff_colormap: "RdBu_r" + diff_contour_range: [-40, 40, 5] + scale_factor: 1. + add_offset: 0 + new_unit: "Percent" + obs_file: "CALIPSO_GOCCP_3.1.2_climo_200606-202012.nc" + obs_name: "CALIPSO" + obs_var_name: "CLDMED_CAL" + category: "COSP" + +CLDLOW_CAL: + colormap: "cividis" + contour_levels_range: [0, 105, 5] + diff_colormap: "RdBu_r" + diff_contour_range: [-40, 40, 5] + scale_factor: 1. + add_offset: 0 + new_unit: "Percent" + obs_file: "CALIPSO_GOCCP_3.1.2_climo_200606-202012.nc" + obs_name: "CALIPSO" + obs_var_name: "CLDLOW_CAL" + category: "COSP" + +CLD_CAL: + colormap: "cividis" + contour_levels_range: [0, 105, 5] + diff_colormap: "RdBu_r" + diff_contour_range: [-40, 40, 5] + scale_factor: 1. + add_offset: 0 + new_unit: "Percent" + obs_file: "CALIPSO_GOCCP_3.1.2_climo_200606-202012.nc" + obs_name: "CALIPSO" + obs_var_name: "CLD_CAL" + category: "COSP" + #+++++++++++++++++ # Category: Other @@ -2385,7 +2800,7 @@ utendwtem: budget_tables: # INPUTS #list of the gaseous variables to be caculated. - GAS_VARIABLES: ['CH4','CH3CCL3', 'CO', 'O3', 'ISOP', 'MTERP', 'CH3OH', 'CH3COCH3'] + GAS_VARIABLES: ['CH4','CH3CCL3', 'CO', 'O3', 'ISOP', 'MTERP', 'CH3OH', 'CH3COCH3','DMS','DMS_OASISS'] # list of the aerosol variables to be caculated. AEROSOL_VARIABLES: ['AOD','SOA', 'SALT', 'DUST', 'POM', 'BC', 'SO4'] @@ -2423,7 +2838,10 @@ budget_tables: 'DUST':168.0456, 'CH3CCL3':133.4042, 'CH3OH':32, - 'CH3COCH3':58} + 'CH3COCH3':58, + 'DMS':62.136, + 'DMS_OASISS':62.136, + 'AOD':1} # Avogadro's Number AVO: 6.022e23 @@ -2439,7 +2857,6 @@ budget_tables: #----------- - # Plot Specific formatting ########################## diff --git a/lib/adf_web.py b/lib/adf_web.py index e39981f8f..beddf011e 100644 --- a/lib/adf_web.py +++ b/lib/adf_web.py @@ -22,13 +22,14 @@ import os import os.path - from pathlib import Path #+++++++++++++++++++++++++++++++++++++++++++++++++ #import non-standard python modules, including ADF #+++++++++++++++++++++++++++++++++++++++++++++++++ +import markdown + #ADF modules: from adf_obs import AdfObs @@ -117,7 +118,6 @@ def __init__(self, config_file, debug=False): #Extract needed variables from yaml file: case_names = self.get_cam_info('cam_case_name', required=True) - #Also extract baseline case (if applicable), and append to case_names list: if not self.compare_obs: baseline_name = self.get_baseline_info('cam_case_name', required=True) @@ -157,7 +157,7 @@ def __init__(self, config_file, debug=False): mdtf_path += f"_{syear[0]}_{eyear[0]}" self.external_package_links['MDTF'] = mdtf_path #End if - + #Add all relevant paths to dictionary for specific case: self.__case_web_paths[case_name] = {'website_dir': website_dir, 'img_pages_dir': img_pages_dir, @@ -182,6 +182,27 @@ def __init__(self, config_file, debug=False): 'table_pages_dir': table_pages_dir, 'css_files_dir': css_files_dir} #End if + + # Gather ADF run env info + active_env = self.get_active_conda_environment() + if not active_env: + active_env = "--" + + run_info = '' + if self.debug_log: + log_name = self.debug_fname + run_info = f"{log_name}".replace("debug","run_info").replace(".log",".md") + self.run_info = run_info + self._write_run_info_to_log(config_file, active_env) + #Do nothing if user is not requesting a website to be generated: + if self.create_html and self.debug_log: + plot_path = Path(self.plot_location[0]) + + #Create directory path where the website will be built: + website_dir = plot_path / "website" + Path(website_dir).mkdir(parents=True, exist_ok=True) + run_info = f"{website_dir}/{run_info}" + self._write_run_info_to_web(run_info, config_file, active_env) ######### @@ -192,6 +213,91 @@ def create_html(self): return self.get_basic_info('create_html') ######### + def _write_run_info_to_web(self, run_info, config_file, active_env): + """ + If user requests webpage, then add run info to webpages table of contents + """ + four_space = "    " + two_space = "  " + font_22 = "style='font-size:22px;'" + font_18 = "style='font-size:18px;'" + font_16 = "style='font-size:16px;'" + + with open(run_info, "w") as f: + + # Gather config yaml file info + f.write("

") + f.write(f"Config file used
") + f.write(f"{two_space}{config_file}

") + + f.write(f" Config file options
") + for key,val in self.config_dict().items(): + if isinstance(val,dict): + f.write(f"{two_space}{key}:
") + for key2,val2 in val.items(): + f.write(f"{four_space}{key2}: {val2}
") + elif isinstance(val,list): + f.write(f"{two_space}{key}:
") + for val2 in val: + f.write(f"{four_space}{val2}
") + else: + f.write(f"{two_space}{key}: {val}
") + + # Gather Conda environment + f.write("\n") + f.write(f"
Conda env used
") + f.write(f"{two_space}{active_env}") + + # Gather Git info + git_info = self.get_git_info() + f.write("\n") + f.write(f"

Git Info
") + for key,val in git_info.items(): + f.write(f"{two_space}{key}: {val}
") + f.write("

") + + def _write_run_info_to_log(self, config_file, active_env): + + log_msg = "adf_info: ADF run info:" + + # Gather config yaml file info + config_file_msg = "\nConfig file used:" + msg = f"{config_file_msg}\n{'-' * (len(config_file_msg))}\n {config_file}\n" + log_msg += msg + + + config_msg = "\n Config file options:" + msg = f"{config_msg}\n {'- ' * (int(len(config_msg)/2)-1)}" + log_msg += msg + + for key,val in self.config_dict().items(): + if isinstance(val,dict): + log_msg += f"\n {key}:" + for key2,val2 in val.items(): + log_msg += f"\n {key2}: {val2}" + elif isinstance(val,list): + log_msg += f"\n {key}:" + for val2 in val: + log_msg += f"\n {val2}" + else: + log_msg += f"\n {key}: {val}" + + # Gather Conda environment + conda_msg = "\nConda env used:" + msg = f"{conda_msg}\n{'-' * (len(conda_msg)-1)}\n" + log_msg += f"\n {msg}" + log_msg += f" {active_env}" + + # Gather Git info + git_info = self.get_git_info() + git_msg = "\nGit Info:" + msg = f"{git_msg}\n{'-' * (len(git_msg)-1)}\n" + log_msg += f"\n {msg}" + + for key,val in git_info.items(): + log_msg += f" {key}: {val}\n" + + self.debug_log(log_msg) def add_website_data(self, web_data, web_name, case_name, category = None, @@ -358,12 +464,13 @@ def jinja_enumerate(arg): #Notify user that script has started: print("\n Generating Diagnostics webpages...") + case_sites = OrderedDict() + #If there is more than one non-baseline case, then create new website directory: if self.num_cases > 1: main_site_path = Path(self.get_basic_info('cam_diag_plot_loc', required=True)) main_site_path = main_site_path / "main_website" main_site_path.mkdir(exist_ok=True) - case_sites = OrderedDict() else: main_site_path = "" #Set main_site_path to blank value #End if @@ -611,7 +718,7 @@ def jinja_enumerate(arg): if web_data.name == case1: rend_kwarg_dict["disp_table_name"] = case1 rend_kwarg_dict["disp_table_html"] = table_html - + if web_data.name == "Case Comparison": rend_kwarg_dict["disp_table_name"] = "Case Comparison" rend_kwarg_dict["disp_table_html"] = table_html @@ -696,6 +803,30 @@ def jinja_enumerate(arg): index_html_file = \ self.__case_web_paths[web_data.case]['website_dir'] / "index.html" + # Create run info web page + run_info_md_file = \ + self.__case_web_paths[web_data.case]['website_dir'] / self.run_info + + # Read the markdown file + with open(run_info_md_file, "r", encoding="utf-8") as mdfile: + md_text = mdfile.read() + + # Convert markdown to HTML + run_info_html = markdown.markdown(md_text) + index_title = "CAM Diagnostics" + run_info_html_file = self.__case_web_paths[web_data.case]['website_dir'] / "run_info.html" + run_info_tmpl = jinenv.get_template('template_run_info.html') + run_info_rndr = run_info_tmpl.render(title=index_title, + case_name=web_data.case, + base_name=data_name, + case_yrs=case_yrs, + baseline_yrs=baseline_yrs, + plot_types=plot_types, + run_info=run_info_html) + + with open(run_info_html_file, "w", encoding="utf-8") as htmlfile: + htmlfile.write(run_info_rndr) + #Re-et plot types list: if web_data.case == 'multi-case': plot_types = multi_plot_type_html @@ -706,19 +837,18 @@ def jinja_enumerate(arg): #List of ADF default plot types avail_plot_types = res["default_ptypes"] - + #Check if current plot type is in ADF default. #If not, add it so the index.html file can include it for ptype in plot_types.keys(): if ptype not in avail_plot_types: - avail_plot_types.append(plot_types) - - + avail_plot_types.append(ptype) + # External packages that can be run through ADF avail_external_packages = {'MDTF':'mdtf_html_path', 'CVDP':'cvdp_html_path'} - + #Construct index.html - index_title = "AMP Diagnostics Prototype" + index_title = "CAM Diagnostics" index_tmpl = jinenv.get_template('template_index.html') index_rndr = index_tmpl.render(title=index_title, case_name=web_data.case, @@ -728,7 +858,8 @@ def jinja_enumerate(arg): plot_types=plot_types, avail_plot_types=avail_plot_types, avail_external_packages=avail_external_packages, - external_package_links=self.external_package_links) + external_package_links=self.external_package_links, + run_info=run_info_html) #Write Mean diagnostics index HTML file: with open(index_html_file, 'w', encoding='utf-8') as ofil: @@ -787,4 +918,4 @@ def jinja_enumerate(arg): print(" ...Webpages have been generated successfully.") #++++++++++++++++++++ #End Class definition -#++++++++++++++++++++ \ No newline at end of file +#++++++++++++++++++++ diff --git a/lib/externals/CVDP/CVDP_readme.pdf b/lib/externals/CVDP/CVDP_readme.pdf new file mode 100644 index 000000000..313a47ec6 Binary files /dev/null and b/lib/externals/CVDP/CVDP_readme.pdf differ diff --git a/lib/externals/CVDP/driver.ncl b/lib/externals/CVDP/driver.ncl new file mode 100644 index 000000000..5b165596a --- /dev/null +++ b/lib/externals/CVDP/driver.ncl @@ -0,0 +1,173 @@ +; +; CVDP driver script. To run the CVDP at the command line type: ncl driver.ncl +; To run the CVDP at the command line, put it in background mode, and write the terminal output +; to a file named file.out, type: ncl driver.ncl >&! file.out & +; +;============================================================================================ + outdir = "/project/CVDP/" ; location of output files (must end in a "/") + ; It is recommended that a new or empty directory be pointed to here + ; as existing files in outdir can get removed. + + namelists_only = "False" ; Set to True to only create the variable namelists. Useful + ; upon running the package for the first time to verify that the correct + ; files are being selected by the package. (See files in namelist_byvar/ directory) + ; Set to False to run the entire package. + + obs = "True" ; True = analyze and plot observations (specified in namelist_obs), False = do not + scale_timeseries = "False" ; True = scale timeseries so that x-axis length is comparable across timeseries, False = do not + output_data = "True" ; True = output selected calculated data to a netCDF file. Make sure .nc files from previous CVDP + ; runs are not in outdir or they will get added to or modified. + compute_modes_mon = "True" ; True = compute DJF, MAM, JJA, SON, Annual and Monthly Atmospheric Modes of Variability + ; False = do not compute the Monthly Atmospheric Modes of Variability (saves computation time) +;- - - - - - - - - - - - - - - - - - + opt_climo = "Full" ; Full = remove climatology based on full record of each simulation, + ; Custom = set climatological period using climo_syear (climatological start year) and climo_eyear (climatological end year) + + if (opt_climo.eq."Custom") then ; When climo_syear and climo_eyear are positive, remove the climatology/annual cycle based on these years. + climo_syear = -30 ; Both settings should be within the range of years of all specified model runs and observational datasets. + climo_eyear = 0 ; When climo_syear is negative, remove the climatology/annual cycle relative to the end of each model run + end if ; or observational dataset. Example: climo_syear = -25, climo_eyear = 0 will result in the climatology + ; being removed from the last 26 years of each model run and observations. +;- - - - - - - - - - - - - - - - - - + colormap = 0 ; 0 = default colormaps, 1 = colormaps better for color blindness + + output_type = "png" ; png = create png files, ps = create postscript files as well as png files (for web viewing). + + png_scale = 1.5 ; Set the output .png size. Value between .1->5. Any value > 1 (< 1) increases (decreases) png size. + ; When output_type = "png" a value of 1 will result in a png sized 1500 (H) x 1500 (W) before automatic cropping of white space + ; When output_type = "ps" a value of 1 will result in a png density setting of 144 before automatic cropping of white space + webpage_title = "Title goes here" ; Set webpage title + + tar_output = "False" ; True = tar up all output in outdir and remove individual files, False = do not + ; Note: ALL files in outdir will be tarred up and then removed from the outdir directory. + +;---Advanced Options---------------------------------------------------------------------- + zp = "ncl_scripts/" ; directory path of CVDP NCL scripts. (must end in a "/") + ; Examples: "ncl_scripts/" if all code is local, or on CGD or CISL systems: "~asphilli/CESM-diagnostics/CVDP/Release/v4.1.0/ncl_scripts/" + ; Regardless of this setting the following files should be in one directory: namelist, driver.ncl, and namelist_obs. + ; If pointing to code in ~asphilli make sure the driver script version #s match between this script and the script in ~asphilli. + + ncl_exec = "ncl" ; This can be changed to a different path if a different version of NCL needs to be used, such as "/different/path/to/bin/ncl" + + run_style = "parallel" ; parallel = allow simple python-based parallelization to occur. X number of CVDP NCL scripts will be called at once. + ; X is set via max_num_tasks. Terminal output will be harder to follow. + ; serial = call CVDP NCL scripts serially. + + max_num_tasks = 4 ; Set the number of CVDP NCL scripts that can be called at once. If greater than 1 the scripts will be called in parallel. (If unsure set to 3) + + modular = "False" ; True = Run only those CVDP scripts specified in modular_list. + ; False = Run all CVDP scripts (Default) + + modular_list = "pdo,aice.trends_timeseries,sst.indices" ; When modular = "True" list the CVDP scripts that will be run. + ; Example: modular_list = "amoc,amo,pr.trends_timeseries" + ; For a list of available scripts see complete_list at line 72. + + machine_casesen = "True" ; True = Your filesystem is case sensitive (Default) + ; False = Your filesystem is case insensitive +;========END USER MODIFICATIONS=========================================================== + version = "5.2.0" + + print("Starting: Climate Variability Diagnostics Package ("+systemfunc("date")+")") + + complete_list = "psl.nam_nao,psl.pna_npo,tas.trends_timeseries,snd.trends,psl.trends,amo,pdo,sst.indices,pr.trends_timeseries,"+\ + "psl.sam_psa,sst.mean_stddev,psl.mean_stddev,pr.mean_stddev,sst.trends_timeseries,amoc,tas.mean_stddev,"+\ + "snd.mean_stddev,aice.mean_stddev,aice.trends_timeseries,ipo" + + loadscript(zp+"functions.ncl") + outfiles = (/"ts","trefht","psl","prect","snowdp","moc","maxnum","aice_nh","aice_sh"/) + rm_obsfiles(outfiles) + + if (isfilepresent2(outdir+"metrics_orig.txt")) then ; remove metrics_orig.txt file if present + system("rm "+outdir+"metrics_orig.txt") + end if + + if (opt_climo.eq."Custom") then + if (climo_syear.ge.climo_eyear) then + print("Specified custom climatology start year (climo_syear) cannot be greater than or equal to the specified end year (climo_eyear), exiting CVDP.") + exit + end if + else + climo_syear = -999 + climo_eyear = -999 + end if + + if (.not.isfilepresent2(outdir)) then + system("mkdir -p "+outdir) + end if + envvar_str = " export OUTDIR="+outdir+"; export OBS="+obs+"; export SCALE_TIMESERIES="+scale_timeseries+"; "+\ + "export OUTPUT_DATA="+output_data+"; export VERSION="+version+"; export PNG_SCALE="+png_scale+"; "+\ + "export OPT_CLIMO="+opt_climo+"; export CLIMO_SYEAR="+climo_syear+"; export CLIMO_EYEAR="+climo_eyear+"; "+\ + "export COMPUTE_MODES_MON="+compute_modes_mon+"; export OUTPUT_TYPE="+output_type+"; export MACHINE="+machine_casesen+"; "+\ + "export COLORMAP="+colormap+"; export CVDP_SCRIPTS="+zp+"; export MAX_TASKS="+max_num_tasks+";" + ncl_exec = ncl_exec+" -n -Q" + + system(envvar_str + " "+str_sub_str(ncl_exec," -Q","")+" "+zp+"namelist.ncl") ; create variable namelists + if (namelists_only.eq."True") then + print("Variable namelists have been created. Examine files in namelist_byvar/ directory to verify CVDP file selection.") + print("Finished: Climate Variability Diagnostics Package ("+systemfunc("date")+")") + rm_obsfiles(outfiles) + exit + end if +;------------------------------ +; Call CVDP calculation scripts +; + if (modular.eq."True") then + cm_list = str_sub_str(modular_list," ","") ; remove spaces if present + cm_list = str_sub_str(cm_list,",",".ncl,") ; add .ncl in to end of each script name + else + cm_list = str_sub_str(complete_list,",",".ncl,") ; add .ncl in to end of each script name + end if + cm_list = cm_list+".ncl" ; add .ncl in to last script name + + if (run_style.eq."parallel") then + cm_list = str_sub_str(cm_list,","," "+zp) + system(envvar_str+" python "+zp+"runTasks.py "+zp+cm_list) + else + cm_list = str_sub_str(cm_list,","," "+ncl_exec+" "+zp) + cm_list = str_sub_str(cm_list,".ncl",".ncl;") + system(envvar_str+" "+ncl_exec+" "+zp+cm_list) + end if +;------------------------------- +; Finalize netCDF files, create metrics tables, and finalize images. + + if (output_data.eq."True") then ; finalize output nc files + system(envvar_str + " "+ncl_exec+" "+zp+"ncfiles.append.ncl") + end if + + met_files = systemfunc("ls "+outdir+"metrics.*.txt 2> /dev/null") + if (dimsizes(met_files).eq.9) then ; if all 9 metrics text files are present, create metrics table(s) + system(" export OUTDIR="+outdir+"; "+ncl_exec+" "+zp+"metrics.ncl") + end if + + image_finalize(outdir,output_type,max_num_tasks,zp,toint(144*png_scale)) ; trim whitespace, convert to .png (if necessary) and apply watermarks to images + + system("cp "+zp+"cas-cvdp.png "+outdir) + system("cp namelist_byvar/* "+outdir) + system("cp namelist "+outdir) + if (obs.eq."True") then + system("cp namelist_obs "+outdir) + end if +;------------------------------- +; Create webpages + quote = str_get_dq() + system(" export OUTDIR="+outdir+"; export VERSION="+version+"; export OUTPUT_DATA="+output_data+"; "+\ + "export OPT_CLIMO="+opt_climo+"; export CLIMO_SYEAR="+climo_syear+"; export CLIMO_EYEAR="+climo_eyear+"; "+\ + "export OBS="+obs+"; export CVDP_SCRIPTS="+zp+"; "+ncl_exec+" 'webtitle="+quote+webpage_title+quote+"' "+zp+"webpage.ncl") + delete(quote) +;------------------------------- +; Create tar file + if (tar_output.eq."True") then + if (isfilepresent2(outdir+"cvdp.tar")) then + system("rm "+outdir+"cvdp.tar") + end if + system("cd "+outdir+"; tar -cf cvdp.tar *") + system("cd "+outdir+"; rm *.gif *.png *.ps *.txt *.html *.nc namelist*") + end if +;------------------------------- +; Cleanup + rm_obsfiles(outfiles) + delete([/outfiles,outdir,obs,scale_timeseries,output_data,opt_climo,climo_syear,climo_eyear,\ + png_scale,webpage_title,compute_modes_mon,met_files/]) + + print("Finished: Climate Variability Diagnostics Package ("+systemfunc("date")+")") + diff --git a/lib/externals/CVDP/namelist b/lib/externals/CVDP/namelist new file mode 100644 index 000000000..a2bdab3cd --- /dev/null +++ b/lib/externals/CVDP/namelist @@ -0,0 +1,21 @@ +CESM2 LENS 1001.001 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1001.001.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 +CESM2 LENS 1021.002 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1021.002.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 +CESM2 LENS 1041.003 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1041.003.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 +CESM2 LENS 1061.004 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1061.004.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 +CESM2 LENS 1081.005 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1081.005.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 +CESM2 LENS 1101.006 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1101.006.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 +CESM2 LENS 1121.007 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1121.007.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 +CESM2 LENS 1141.008 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1141.008.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 +CESM2 LENS 1161.009 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1161.009.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 +CESM2 LENS 1181.010 | /glade/campaign/cgd/cesm/CESM2-LE/{atm,lnd,ocn,ice}/proc/tseries/month_1/{MOC,SNOWDP,TS,TREFHT,PSL,PRECT,aice}/b.e21.B{HIST,SSP370}cmip6.f09_g17.LE2-1181.010.{cam.h0,clm2.h0,pop.h,cice.h}* | 1950 | 2049 + +CESM1 LENS #1 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.001.*.nc | 1950 | 2049 +CESM1 LENS #2 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.002.*.nc | 1950 | 2049 +CESM1 LENS #3 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.003.*.nc | 1950 | 2049 +CESM1 LENS #4 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.004.*.nc | 1950 | 2049 +CESM1 LENS #5 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.005.*.nc | 1950 | 2049 +CESM1 LENS #6 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.006.*.nc | 1950 | 2049 +CESM1 LENS #7 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.007.*.nc | 1950 | 2049 +CESM1 LENS #8 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.008.*.nc | 1950 | 2049 +CESM1 LENS #9 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.009.*.nc | 1950 | 2049 +CESM1 LENS #10 | /glade/campaign/cesm/collections/cesmLE/CESM-CAM5-BGC-LE/{atm,ice,lnd,ocn}/proc/tseries/monthly/*/b.e11.B*C5CNBDRD.f09_g16.010.*.nc | 1950 | 2049 diff --git a/lib/externals/CVDP/namelist_obs b/lib/externals/CVDP/namelist_obs new file mode 100644 index 000000000..15d6261d8 --- /dev/null +++ b/lib/externals/CVDP/namelist_obs @@ -0,0 +1,32 @@ +TS | ERSST v5 | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/ersstv5.185401-201912.nc | 1920 | 2018 +PSL | ERA20C_ERAI | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/era20c_erai.mon.mean.msl.190001-201901.nc | 1920 | 2018 +TREFHT | BEST | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/best.tas.185001-201902.nc | 1920 | 2018 +PRECT | GPCC | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/gpcc.pr.10.comb_v2018v6mon.189101-201903.nc | 1920 | 2018 +aice_nh | Walsh and Chapman | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/walsh_chapman.NH.seaice.187001-201112.nc | 1953 | 2011 +aice_sh | NASA Bootstrap SH | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/seaice_conc_monthly_sh_NASA_Bootstrap.nsidc.v03r01.197811-201702.nc | 1979 | 2016 +MOC | CESM1 Forced Ocean Simulation | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/g.e11_LENS.GECOIAF.T62_g16.009.pop.h.MOC.194801-201512.nc | 1948 | 2015 + +TS | HadISST | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/hadisst.187001-201912.nc | 1920 | 2018 +PSL | CERA20C_ERAI | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/cera20c_erai.mon.mean.msl.190101-201901.nc | 1920 | 2018 +TREFHT | GISTEMP | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/gistemp.tas.188001-201912.nc | 1920 | 2018 +PRECT | GPCC | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/gpcc.pr.10.comb_v2018v6mon.189101-201903.nc | 1920 | 2018 +aice_nh | Walsh and Chapman | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/walsh_chapman.NH.seaice.187001-201112.nc | 1953 | 2011 +aice_sh | NASA Bootstrap SH | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/seaice_conc_monthly_sh_NASA_Bootstrap.nsidc.v03r01.197811-201702.nc | 1979 | 2016 +MOC | CESM1 Forced Ocean Simulation | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/g.e11_LENS.GECOIAF.T62_g16.009.pop.h.MOC.194801-201512.nc | 1948 | 2015 + +TS | ERSST v5 | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/ersstv5.185401-201912.nc | 1979 | 2018 +PSL | ERAI | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/erai.mon.mean.msl.197901-201901.nc | 1979 | 2018 +TREFHT | BEST | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/best.tas.185001-201902.nc | 1979 | 2018 +PRECT | GPCP | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/gpcp.mon.mean.197901-201903.nc | 1979 | 2018 +aice_nh | NASA CDR NH | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/seaice_conc_monthly_nh_NOAA_NSIDC_CDR.v03r01.197811-201702.nc | 1979 | 2016 +aice_sh | NASA CDR SH | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/seaice_conc_monthly_sh_NOAA_NSIDC_CDR.v03r01.197811-201702.nc | 1979 | 2016 +MOC | CESM1 Forced Ocean Simulation | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/g.e11_LENS.GECOIAF.T62_g16.009.pop.h.MOC.194801-201512.nc | 1979 | 2015 + +TS | HadISST | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/hadisst.187001-201912.nc | 1980 | 2017 +PSL | MERRA2 | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/merra2.mon.SLP.198001-201803.nc | 1980 | 2017 +TREFHT | GISTEMP | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/gistemp.tas.188001-201912.nc | 1980 | 2017 +PRECT | GPCP | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/gpcp.mon.mean.197901-201903.nc | 1980 | 2017 +aice_nh | NASA Bootstrap NH | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/seaice_conc_monthly_nh_NASA_Bootstrap.nsidc.v03r01.197811-201702.nc | 1980 | 2016 +aice_sh | NASA Bootstrap SH | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/seaice_conc_monthly_sh_NASA_Bootstrap.nsidc.v03r01.197811-201702.nc | 1980 | 2016 +MOC | CESM1 Forced Ocean Simulation | /glade/campaign/cgd/cas/asphilli/CVDP-OBS/g.e11_LENS.GECOIAF.T62_g16.009.pop.h.MOC.194801-201512.nc | 1980 | 2015 + diff --git a/lib/externals/CVDP/ncl_scripts/aice.mean_stddev.ncl b/lib/externals/CVDP/ncl_scripts/aice.mean_stddev.ncl new file mode 100644 index 000000000..52a03ff83 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/aice.mean_stddev.ncl @@ -0,0 +1,696 @@ +; Calculates SIC hemispheric means and standard deviations +; +; Variables used: sic +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: aice.mean_stddev.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_aice_nh") + na = asciiread("namelist_byvar/namelist_aice_nh",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + nsim_sh = numAsciiRow("namelist_byvar/namelist_aice_sh") + na_sh = asciiread("namelist_byvar/namelist_aice_sh",(/nsim/),"string") + names_sh = new(nsim,"string") + paths_sh = new(nsim,"string") + syear_sh = new(nsim,"integer",-999) + eyear_sh = new(nsim,"integer",-999) + do gg = 0,nsim-1 + names_sh(gg) = str_strip(str_get_field(na_sh(gg),1,delim)) + paths_sh(gg) = str_strip(str_get_field(na_sh(gg),2,delim)) + syear_sh(gg) = stringtointeger(str_strip(str_get_field(na_sh(gg),3,delim))) + eyear_sh(gg) = stringtointeger(str_strip(str_get_field(na_sh(gg),4,delim))) + end do + nyr_sh = eyear_sh-syear_sh+1 + nyr_max_sh = max(nyr_sh) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_stddev_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.stddev.djf") + wks_stddev_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.stddev.mam") + wks_stddev_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.stddev.jja") + wks_stddev_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.stddev.son") + wks_stddev_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.stddev.ann") + wks_mean_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.mean.djf") + wks_mean_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.mean.mam") + wks_mean_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.mean.jja") + wks_mean_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.mean.son") + wks_mean_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.mean.ann") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_stddev_djf,"BkBlAqGrYeOrReViWh200") + gsn_define_colormap(wks_stddev_mam,"BkBlAqGrYeOrReViWh200") + gsn_define_colormap(wks_stddev_jja,"BkBlAqGrYeOrReViWh200") + gsn_define_colormap(wks_stddev_son,"BkBlAqGrYeOrReViWh200") + gsn_define_colormap(wks_stddev_ann,"BkBlAqGrYeOrReViWh200") + gsn_define_colormap(wks_mean_djf,"BkBlAqGrYeOrReViWh200") + gsn_define_colormap(wks_mean_mam,"BkBlAqGrYeOrReViWh200") + gsn_define_colormap(wks_mean_jja,"BkBlAqGrYeOrReViWh200") + gsn_define_colormap(wks_mean_son,"BkBlAqGrYeOrReViWh200") + gsn_define_colormap(wks_mean_ann,"BkBlAqGrYeOrReViWh200") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_stddev_djf,"cb_rainbow") + gsn_define_colormap(wks_stddev_mam,"cb_rainbow") + gsn_define_colormap(wks_stddev_jja,"cb_rainbow") + gsn_define_colormap(wks_stddev_son,"cb_rainbow") + gsn_define_colormap(wks_stddev_ann,"cb_rainbow") + gsn_define_colormap(wks_mean_djf,"cb_rainbow") + gsn_define_colormap(wks_mean_mam,"cb_rainbow") + gsn_define_colormap(wks_mean_jja,"cb_rainbow") + gsn_define_colormap(wks_mean_son,"cb_rainbow") + gsn_define_colormap(wks_mean_ann,"cb_rainbow") + end if + + + plot_mean_nh_djf = new(nsim,"graphic") + plot_mean_nh_mam = new(nsim,"graphic") + plot_mean_nh_jja = new(nsim,"graphic") + plot_mean_nh_son = new(nsim,"graphic") + plot_mean_nh_ann = new(nsim,"graphic") + plot_stddev_nh_djf = new(nsim,"graphic") + plot_stddev_nh_mam = new(nsim,"graphic") + plot_stddev_nh_jja = new(nsim,"graphic") + plot_stddev_nh_son = new(nsim,"graphic") + plot_stddev_nh_ann = new(nsim,"graphic") + + plot_mean_sh_djf = new(nsim,"graphic") + plot_mean_sh_mam = new(nsim,"graphic") + plot_mean_sh_jja = new(nsim,"graphic") + plot_mean_sh_son = new(nsim,"graphic") + plot_mean_sh_ann = new(nsim,"graphic") + plot_stddev_sh_djf = new(nsim,"graphic") + plot_stddev_sh_mam = new(nsim,"graphic") + plot_stddev_sh_jja = new(nsim,"graphic") + plot_stddev_sh_son = new(nsim,"graphic") + plot_stddev_sh_ann = new(nsim,"graphic") + + do ee = 0,nsim-1 + aice_nh_flag = 0 + aice_nh = data_read_in_ice(paths(ee),"aice_nh",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(aice_nh,"is_all_missing")) then + delete(aice_nh) + aice_nh_flag = 1 + end if + + if (aice_nh_flag.eq.0) then + do ff = 0,1 + aice_nhT = aice_nh + if (ff.eq.1) then + if (OPT_CLIMO.eq."Full") then + aice_nhT = rmMonAnnCycTLL(aice_nhT) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = aice_nhT + delete(temp_arr&time) + temp_arr&time = cd_calendar(aice_nhT&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + aice_nhT = calcMonAnomTLL(aice_nhT,climo) + delete(climo) + end if + end if + aice_nh_seas = runave_n_Wrap(aice_nhT,3,0,0) + aice_nh_seas(0,:,:) = (/ dim_avg_n(aice_nhT(:1,:,:),0) /) + aice_nh_seas(dimsizes(aice_nhT&time)-1,:,:) = (/ dim_avg_n(aice_nhT(dimsizes(aice_nhT&time)-2:,:,:),0) /) + aice_nh_ann = runave_n_Wrap(aice_nhT,12,0,0) + delete(aice_nhT) + + if (ff.eq.0) then + aice_nh_mean_djf = dim_avg_n_Wrap(aice_nh_seas(0::12,:,:),0) + aice_nh_mean_mam = dim_avg_n_Wrap(aice_nh_seas(3::12,:,:),0) + aice_nh_mean_jja = dim_avg_n_Wrap(aice_nh_seas(6::12,:,:),0) + aice_nh_mean_son = dim_avg_n_Wrap(aice_nh_seas(9::12,:,:),0) + aice_nh_mean_ann = dim_avg_n_Wrap(aice_nh_ann(5::12,:,:),0) + end if + if (ff.eq.1) then + aice_nh_sd_djf = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),aice_nh_seas(0::12,:,:),False,False,0),0) + aice_nh_sd_mam = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),aice_nh_seas(3::12,:,:),False,False,0),0) + aice_nh_sd_jja = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),aice_nh_seas(6::12,:,:),False,False,0),0) + aice_nh_sd_son = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),aice_nh_seas(9::12,:,:),False,False,0),0) + aice_nh_sd_ann = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),aice_nh_ann(5::12,:,:),False,False,0),0) + end if + delete([/aice_nh_seas,aice_nh_ann/]) + end do + delete(aice_nh) + copy_VarMeta(aice_nh_mean_djf,aice_nh_sd_djf) + copy_VarMeta(aice_nh_mean_mam,aice_nh_sd_mam) + copy_VarMeta(aice_nh_mean_jja,aice_nh_sd_jja) + copy_VarMeta(aice_nh_mean_son,aice_nh_sd_son) + copy_VarMeta(aice_nh_mean_ann,aice_nh_sd_ann) + end if + + aice_sh_flag = 0 + aice_sh = data_read_in_ice(paths_sh(ee),"aice_sh",syear_sh(ee),eyear_sh(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(aice_sh,"is_all_missing")) then + delete(aice_sh) + aice_sh_flag = 1 + end if + if (aice_sh_flag.eq.0) then + do ff = 0,1 + aice_shX = aice_sh + if (ff.eq.1) then + if (OPT_CLIMO.eq."Full") then + aice_shX = rmMonAnnCycTLL(aice_shX) + else + check_custom_climo(names_sh(ee),syear_sh(ee),eyear_sh(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = aice_shX + delete(temp_arr&time) + temp_arr&time = cd_calendar(aice_shX&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + aice_shX = calcMonAnomTLL(aice_shX,climo) + delete(climo) + end if + end if + aice_sh_seas = runave_n_Wrap(aice_shX,3,0,0) + aice_sh_seas(0,:,:) = (/ dim_avg_n(aice_shX(:1,:,:),0) /) + aice_sh_seas(dimsizes(aice_shX&time)-1,:,:) = (/ dim_avg_n(aice_shX(dimsizes(aice_shX&time)-2:,:,:),0) /) + aice_sh_ann = runave_n_Wrap(aice_shX,12,0,0) + delete(aice_shX) + + if (ff.eq.0) then + aice_sh_mean_djf = dim_avg_n_Wrap(aice_sh_seas(0::12,:,:),0) + aice_sh_mean_mam = dim_avg_n_Wrap(aice_sh_seas(3::12,:,:),0) + aice_sh_mean_jja = dim_avg_n_Wrap(aice_sh_seas(6::12,:,:),0) + aice_sh_mean_son = dim_avg_n_Wrap(aice_sh_seas(9::12,:,:),0) + aice_sh_mean_ann = dim_avg_n_Wrap(aice_sh_ann(5::12,:,:),0) + end if + if (ff.eq.1) then + aice_sh_sd_djf = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr_sh(ee)-1,1),aice_sh_seas(0::12,:,:),False,False,0),0) + aice_sh_sd_mam = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr_sh(ee)-1,1),aice_sh_seas(3::12,:,:),False,False,0),0) + aice_sh_sd_jja = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr_sh(ee)-1,1),aice_sh_seas(6::12,:,:),False,False,0),0) + aice_sh_sd_son = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr_sh(ee)-1,1),aice_sh_seas(9::12,:,:),False,False,0),0) + aice_sh_sd_ann = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr_sh(ee)-1,1),aice_sh_ann(5::12,:,:),False,False,0),0) + end if + delete([/aice_sh_seas,aice_sh_ann/]) + end do + delete(aice_sh) + copy_VarMeta(aice_sh_mean_djf,aice_sh_sd_djf) + copy_VarMeta(aice_sh_mean_mam,aice_sh_sd_mam) + copy_VarMeta(aice_sh_mean_jja,aice_sh_sd_jja) + copy_VarMeta(aice_sh_mean_son,aice_sh_sd_son) + copy_VarMeta(aice_sh_mean_ann,aice_sh_sd_ann) + end if + + if (OUTPUT_DATA.eq."True".and.aice_nh_flag.eq.0) then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.aice.mean_stddev.nh."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + nh_mean_djf = aice_nh_mean_djf + if (isatt(nh_mean_djf,"lat2d")) then ; if there is a lat2d there will be a lon2d + delete(nh_mean_djf@lat2d) + delete(nh_mean_djf@lon2d) + LAT2D = aice_nh_mean_djf@lat2d + copy_VarCoords(nh_mean_djf,LAT2D) + LON2D = aice_nh_mean_djf@lon2d + copy_VarCoords(nh_mean_djf,LON2D) + z->lat2d_ice_nh = set_varAtts(LAT2D,"Northern Hemisphere ice grid 2-dimensional latitudes","","") + z->lon2d_ice_nh = set_varAtts(LON2D,"Northern Hemisphere ice grid 2-dimensional longitudes","","") + delete([/LAT2D,LON2D/]) + nh_mean_djf@coordinates ="lat2d_ice_nh lon2d_ice_nh" + end if + if (isatt(nh_mean_djf,"area")) then + delete(nh_mean_djf@area) + end if + nh_mean_djf@long_name = nh_mean_djf@long_name+" mean" + nh_mean_mam = (/ aice_nh_mean_mam /) + copy_VarMeta(nh_mean_djf,nh_mean_mam) + nh_mean_jja = (/ aice_nh_mean_jja /) + copy_VarMeta(nh_mean_djf,nh_mean_jja) + nh_mean_son = (/ aice_nh_mean_son /) + copy_VarMeta(nh_mean_djf,nh_mean_son) + nh_mean_ann = (/ aice_nh_mean_ann /) + copy_VarMeta(nh_mean_djf,nh_mean_ann) + nh_sd_djf = aice_nh_sd_djf + if (isatt(nh_sd_djf,"lat2d")) then + delete(nh_sd_djf@lat2d) + delete(nh_sd_djf@lon2d) + nh_sd_djf@coordinates ="lat2d_ice_nh lon2d_ice_nh" + end if + if (isatt(nh_sd_djf,"area")) then + delete(nh_sd_djf@area) + end if + nh_sd_djf@long_name = nh_sd_djf@long_name+" standard deviation" + nh_sd_mam = (/ aice_nh_sd_mam /) + copy_VarMeta(nh_sd_djf,nh_sd_mam) + nh_sd_jja = (/ aice_nh_sd_jja /) + copy_VarMeta(nh_sd_djf,nh_sd_jja) + nh_sd_son = (/ aice_nh_sd_son /) + copy_VarMeta(nh_sd_djf,nh_sd_son) + nh_sd_ann = (/ aice_nh_sd_ann /) + copy_VarMeta(nh_sd_djf,nh_sd_ann) + z->sic_nh_spatialmean_djf = set_varAtts(nh_mean_djf,"Northern Hemisphere sic mean (DJF)","","") + z->sic_nh_spatialmean_mam = set_varAtts(nh_mean_mam,"Northern Hemisphere sic mean (MAM)","","") + z->sic_nh_spatialmean_jja = set_varAtts(nh_mean_jja,"Northern Hemisphere sic mean (JJA)","","") + z->sic_nh_spatialmean_son = set_varAtts(nh_mean_son,"Northern Hemisphere sic mean (SON)","","") + z->sic_nh_spatialmean_ann = set_varAtts(nh_mean_ann,"Northern Hemisphere sic mean (annual)","","") + + z->sic_nh_spatialstddev_djf = set_varAtts(nh_sd_djf,"Northern Hemisphere sic standard deviation (DJF)","","") + z->sic_nh_spatialstddev_mam = set_varAtts(nh_sd_mam,"Northern Hemisphere sic standard deviation (MAM)","","") + z->sic_nh_spatialstddev_jja = set_varAtts(nh_sd_jja,"Northern Hemisphere sic standard deviation (JJA)","","") + z->sic_nh_spatialstddev_son = set_varAtts(nh_sd_son,"Northern Hemisphere sic standard deviation (SON)","","") + z->sic_nh_spatialstddev_ann = set_varAtts(nh_sd_ann,"Northern Hemisphere sic standard deviation (annual)","","") + delete([/nh_mean_djf,nh_mean_mam,nh_mean_jja,nh_mean_son,nh_mean_ann/]) + delete([/nh_sd_djf,nh_sd_mam,nh_sd_jja,nh_sd_son,nh_sd_ann/]) + delete(z) + end if + if (OUTPUT_DATA.eq."True".and.aice_sh_flag.eq.0) then + modname = str_sub_str(names_sh(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.aice.mean_stddev.sh."+syear_sh(ee)+"-"+eyear_sh(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_sh(ee)+" from "+syear_sh(ee)+"-"+eyear_sh(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_sh(ee)+"-"+eyear_sh(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + sh_mean_djf = aice_sh_mean_djf + if (isatt(sh_mean_djf,"lat2d")) then ; if there is a lat2d there will be a lon2d + delete(sh_mean_djf@lat2d) + delete(sh_mean_djf@lon2d) + LAT2D = aice_sh_mean_djf@lat2d + copy_VarCoords(sh_mean_djf,LAT2D) + LON2D = aice_sh_mean_djf@lon2d + copy_VarCoords(sh_mean_djf,LON2D) + z->lat2d_ice_sh = set_varAtts(LAT2D,"Southern Hemisphere ice grid 2-dimensional latitudes","","") + z->lon2d_ice_sh = set_varAtts(LON2D,"Southern Hemisphere ice grid 2-dimensional longitudes","","") + delete([/LAT2D,LON2D/]) + sh_mean_djf@coordinates ="lat2d_ice_sh lon2d_ice_sh" + end if + if (isatt(sh_mean_djf,"area")) then + delete(sh_mean_djf@area) + end if + sh_mean_djf@long_name = sh_mean_djf@long_name+" mean" + sh_mean_djf!0 = "j2" + sh_mean_djf!1 = "i2" + sh_mean_mam = (/ aice_sh_mean_mam /) + copy_VarMeta(sh_mean_djf,sh_mean_mam) + sh_mean_jja = (/ aice_sh_mean_jja /) + copy_VarMeta(sh_mean_djf,sh_mean_jja) + sh_mean_son = (/ aice_sh_mean_son /) + copy_VarMeta(sh_mean_djf,sh_mean_son) + sh_mean_ann = (/ aice_sh_mean_ann /) + copy_VarMeta(sh_mean_djf,sh_mean_ann) + sh_sd_djf = aice_sh_sd_djf + if (isatt(sh_sd_djf,"lat2d")) then + delete(sh_sd_djf@lat2d) + delete(sh_sd_djf@lon2d) + sh_sd_djf@coordinates ="lat2d_ice_sh lon2d_ice_sh" + end if + if (isatt(sh_sd_djf,"area")) then + delete(sh_sd_djf@area) + end if + sh_sd_djf@long_name = sh_sd_djf@long_name+" standard deviation" + sh_sd_djf!0 = "j2" + sh_sd_djf!1 = "i2" + sh_sd_mam = (/ aice_sh_sd_mam /) + copy_VarMeta(sh_sd_djf,sh_sd_mam) + sh_sd_jja = (/ aice_sh_sd_jja /) + copy_VarMeta(sh_sd_djf,sh_sd_jja) + sh_sd_son = (/ aice_sh_sd_son /) + copy_VarMeta(sh_sd_djf,sh_sd_son) + sh_sd_ann = (/ aice_sh_sd_ann /) + copy_VarMeta(sh_sd_djf,sh_sd_ann) + z->sic_sh_spatialmean_djf = set_varAtts(sh_mean_djf,"Southern Hemisphere sic mean (DJF)","","") + z->sic_sh_spatialmean_mam = set_varAtts(sh_mean_mam,"Southern Hemisphere sic mean (MAM)","","") + z->sic_sh_spatialmean_jja = set_varAtts(sh_mean_jja,"Southern Hemisphere sic mean (JJA)","","") + z->sic_sh_spatialmean_son = set_varAtts(sh_mean_son,"Southern Hemisphere sic mean (SON","","") + z->sic_sh_spatialmean_ann = set_varAtts(sh_mean_ann,"Southern Hemisphere sic mean (annual)","","") + + z->sic_sh_spatialstddev_djf = set_varAtts(sh_sd_djf,"Southern Hemisphere sic standard deviation (DJF)","","") + z->sic_sh_spatialstddev_mam = set_varAtts(sh_sd_mam,"Southern Hemisphere sic standard deviation (MAM)","","") + z->sic_sh_spatialstddev_jja = set_varAtts(sh_sd_jja,"Southern Hemisphere sic standard deviation (JJA)","","") + z->sic_sh_spatialstddev_son = set_varAtts(sh_sd_son,"Southern Hemisphere sic standard deviation (SON)","","") + z->sic_sh_spatialstddev_ann = set_varAtts(sh_sd_ann,"Southern Hemisphere sic standard deviation (annual)","","") + delete([/sh_mean_djf,sh_mean_mam,sh_mean_jja,sh_mean_son,sh_mean_ann/]) + delete([/sh_sd_djf,sh_sd_mam,sh_sd_jja,sh_sd_son,sh_sd_ann/]) + delete(z) + end if + if (aice_nh_flag.eq.0) then + aice_nh_mean_djf = where(aice_nh_mean_djf.lt.1,aice_nh_mean_djf@_FillValue,aice_nh_mean_djf) + aice_nh_mean_mam = where(aice_nh_mean_mam.lt.1,aice_nh_mean_mam@_FillValue,aice_nh_mean_mam) + aice_nh_mean_jja = where(aice_nh_mean_jja.lt.1,aice_nh_mean_jja@_FillValue,aice_nh_mean_jja) + aice_nh_mean_son = where(aice_nh_mean_son.lt.1,aice_nh_mean_son@_FillValue,aice_nh_mean_son) + aice_nh_mean_ann = where(aice_nh_mean_ann.lt.1,aice_nh_mean_ann@_FillValue,aice_nh_mean_ann) + aice_nh_sd_djf = where(aice_nh_sd_djf.eq.0,aice_nh_sd_djf@_FillValue,aice_nh_sd_djf) + aice_nh_sd_mam = where(aice_nh_sd_mam.eq.0,aice_nh_sd_mam@_FillValue,aice_nh_sd_mam) + aice_nh_sd_jja = where(aice_nh_sd_jja.eq.0,aice_nh_sd_jja@_FillValue,aice_nh_sd_jja) + aice_nh_sd_son = where(aice_nh_sd_son.eq.0,aice_nh_sd_son@_FillValue,aice_nh_sd_son) + aice_nh_sd_ann = where(aice_nh_sd_ann.eq.0,aice_nh_sd_ann@_FillValue,aice_nh_sd_ann) + end if + if (aice_sh_flag.eq.0) then + aice_sh_mean_djf = where(aice_sh_mean_djf.lt.1,aice_sh_mean_djf@_FillValue,aice_sh_mean_djf) + aice_sh_mean_mam = where(aice_sh_mean_mam.lt.1,aice_sh_mean_mam@_FillValue,aice_sh_mean_mam) + aice_sh_mean_jja = where(aice_sh_mean_jja.lt.1,aice_sh_mean_jja@_FillValue,aice_sh_mean_jja) + aice_sh_mean_son = where(aice_sh_mean_son.lt.1,aice_sh_mean_son@_FillValue,aice_sh_mean_son) + aice_sh_mean_ann = where(aice_sh_mean_ann.lt.1,aice_sh_mean_ann@_FillValue,aice_sh_mean_ann) + aice_sh_sd_djf = where(aice_sh_sd_djf.eq.0,aice_sh_sd_djf@_FillValue,aice_sh_sd_djf) + aice_sh_sd_mam = where(aice_sh_sd_mam.eq.0,aice_sh_sd_mam@_FillValue,aice_sh_sd_mam) + aice_sh_sd_jja = where(aice_sh_sd_jja.eq.0,aice_sh_sd_jja@_FillValue,aice_sh_sd_jja) + aice_sh_sd_son = where(aice_sh_sd_son.eq.0,aice_sh_sd_son@_FillValue,aice_sh_sd_son) + aice_sh_sd_ann = where(aice_sh_sd_ann.eq.0,aice_sh_sd_ann@_FillValue,aice_sh_sd_ann) + end if +;========================================================================================== + res = True + res@mpGeophysicalLineColor = "gray42" + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@mpGridAndLimbOn = False + res@mpLandFillColor = "gray75" + res@mpFillDrawOrder = "PostDraw" + res@mpPerimDrawOrder = "PostDraw" + + res@mpOutlineOn = True + res@mpMinLatF = 40. + res@mpCenterLonF = 0. + res@gsnPolar = "NH" + res@gsnDraw = False + res@gsnFrame = False + res@gsnAddCyclic = True + res@cnLevelSelectionMode = "ExplicitLevels" + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@trGridType = "TriangularMesh" +; res@cnFillMode = "RasterFill" + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.03 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.03 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + if (nsim.le.5) then + res@gsnLeftStringFontHeightF = 0.018 + res@gsnCenterStringFontHeightF = 0.022 + res@gsnRightStringFontHeightF = 0.018 + else + res@gsnLeftStringFontHeightF = 0.024 + res@gsnCenterStringFontHeightF = 0.028 + res@gsnRightStringFontHeightF = 0.024 + end if + + + res@cnLevelSelectionMode = "ExplicitLevels" + + sres = res + res@cnLevels = (/4,8,12,16,20,24,28,32,36/) + sres@cnLevels = (/5,10,15,20,30,40,50,60,70,80,85,90,95,99/) + contour_means = sres@cnLevels ; for use in paneling section + contour_sd = res@cnLevels + if (COLORMAP.eq.0) then + res@cnFillColors = (/42,29,80,95,105,120,140,161,170,193/) ; radar: (/5,6,7,8,9,11,12,13,14,15/) + sres@cnFillColors = (/52,42,34,24,65,80,95,105,120,140,155,161,170,184,193/) + end if + if (COLORMAP.eq.1) then + res@cnFillColors = (/2,18,34,50,66,82,98,114,137,162/) + sres@cnFillColors = (/8,26,38,50,62,74,86,98,110,122,134,146,158,170,182/) + end if + + if (aice_nh_flag.eq.0) then + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnRightString = aice_nh_sd_djf@units + res@gsnCenterString = names(ee) + plot_stddev_nh_djf(ee) = gsn_csm_contour_map(wks_stddev_djf,aice_nh_sd_djf,res) + plot_stddev_nh_mam(ee) = gsn_csm_contour_map(wks_stddev_mam,aice_nh_sd_mam,res) + plot_stddev_nh_jja(ee) = gsn_csm_contour_map(wks_stddev_jja,aice_nh_sd_jja,res) + plot_stddev_nh_son(ee) = gsn_csm_contour_map(wks_stddev_son,aice_nh_sd_son,res) + plot_stddev_nh_ann(ee) = gsn_csm_contour_map(wks_stddev_ann,aice_nh_sd_ann,res) + + sres@gsnLeftString = syear(ee)+"-"+eyear(ee) + sres@gsnRightString = aice_nh_mean_djf@units + sres@gsnCenterString = names(ee) + plot_mean_nh_djf(ee) = gsn_csm_contour_map(wks_mean_djf,aice_nh_mean_djf,sres) + plot_mean_nh_mam(ee) = gsn_csm_contour_map(wks_mean_mam,aice_nh_mean_mam,sres) + plot_mean_nh_jja(ee) = gsn_csm_contour_map(wks_mean_jja,aice_nh_mean_jja,sres) + plot_mean_nh_son(ee) = gsn_csm_contour_map(wks_mean_son,aice_nh_mean_son,sres) + plot_mean_nh_ann(ee) = gsn_csm_contour_map(wks_mean_ann,aice_nh_mean_ann,sres) + delete([/aice_nh_sd_djf,aice_nh_sd_mam,aice_nh_sd_jja,aice_nh_sd_son,aice_nh_sd_ann/]) + delete([/aice_nh_mean_djf,aice_nh_mean_mam,aice_nh_mean_jja,aice_nh_mean_son,aice_nh_mean_ann/]) + end if + + delete(res@mpMinLatF) + delete(sres@mpMinLatF) + res@mpMaxLatF = -45. + res@gsnPolar = "SH" + sres@mpMaxLatF = -45. + sres@gsnPolar = "SH" + + if (aice_sh_flag.eq.0) then + res@gsnLeftString = syear_sh(ee)+"-"+eyear_sh(ee) + res@gsnRightString = aice_sh_sd_djf@units + res@gsnCenterString = names_sh(ee) + plot_stddev_sh_djf(ee) = gsn_csm_contour_map(wks_stddev_djf,aice_sh_sd_djf,res) + plot_stddev_sh_mam(ee) = gsn_csm_contour_map(wks_stddev_mam,aice_sh_sd_mam,res) + plot_stddev_sh_jja(ee) = gsn_csm_contour_map(wks_stddev_jja,aice_sh_sd_jja,res) + plot_stddev_sh_son(ee) = gsn_csm_contour_map(wks_stddev_son,aice_sh_sd_son,res) + plot_stddev_sh_ann(ee) = gsn_csm_contour_map(wks_stddev_ann,aice_sh_sd_ann,res) + + sres@gsnLeftString = syear_sh(ee)+"-"+eyear_sh(ee) + sres@gsnRightString = aice_sh_mean_djf@units + sres@gsnCenterString = names_sh(ee) + plot_mean_sh_djf(ee) = gsn_csm_contour_map(wks_mean_djf,aice_sh_mean_djf,sres) + plot_mean_sh_mam(ee) = gsn_csm_contour_map(wks_mean_mam,aice_sh_mean_mam,sres) + plot_mean_sh_jja(ee) = gsn_csm_contour_map(wks_mean_jja,aice_sh_mean_jja,sres) + plot_mean_sh_son(ee) = gsn_csm_contour_map(wks_mean_son,aice_sh_mean_son,sres) + plot_mean_sh_ann(ee) = gsn_csm_contour_map(wks_mean_ann,aice_sh_mean_ann,sres) + delete([/aice_sh_sd_djf,aice_sh_sd_mam,aice_sh_sd_jja,aice_sh_sd_son,aice_sh_sd_ann/]) + delete([/aice_sh_mean_djf,aice_sh_mean_mam,aice_sh_mean_jja,aice_sh_mean_son,aice_sh_mean_ann/]) + end if + delete([/res,sres/]) + end do + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelFontHeightF = 0.013 + panres@lbLabelStride = 1 + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + c_sd = (/4,8,12,16,20,24,28,32,36/) + if (dimsizes(c_sd).eq.dimsizes(contour_sd).and.all((c_sd - contour_sd).eq.0)) then ; needed to make sure contour intervals + panres@lbLabelAlignment = "ExternalEdges" ; set above match the labels set here + panres@lbLabelStrings = (/"0","4","8","12","16","20","24","28","32","36"," "/) + end if + delete([/c_sd,contour_sd/]) + + panres@txString = "SIC Standard Deviations (DJF)" + gsn_panel2(wks_stddev_djf,plot_stddev_nh_djf,(/nrow,ncol/),panres) + gsn_panel2(wks_stddev_djf,plot_stddev_sh_djf,(/nrow,ncol/),panres) + delete(wks_stddev_djf) + + panres@txString = "SIC Standard Deviations (MAM)" + gsn_panel2(wks_stddev_mam,plot_stddev_nh_mam,(/nrow,ncol/),panres) + gsn_panel2(wks_stddev_mam,plot_stddev_sh_mam,(/nrow,ncol/),panres) + delete(wks_stddev_mam) + + panres@txString = "SIC Standard Deviations (JJA)" + gsn_panel2(wks_stddev_jja,plot_stddev_nh_jja,(/nrow,ncol/),panres) + gsn_panel2(wks_stddev_jja,plot_stddev_sh_jja,(/nrow,ncol/),panres) + delete(wks_stddev_jja) + + panres@txString = "SIC Standard Deviations (SON)" + gsn_panel2(wks_stddev_son,plot_stddev_nh_son,(/nrow,ncol/),panres) + gsn_panel2(wks_stddev_son,plot_stddev_sh_son,(/nrow,ncol/),panres) + delete(wks_stddev_son) + + panres@txString = "SIC Standard Deviations (Annual)" + gsn_panel2(wks_stddev_ann,plot_stddev_nh_ann,(/nrow,ncol/),panres) + gsn_panel2(wks_stddev_ann,plot_stddev_sh_ann,(/nrow,ncol/),panres) + delete(wks_stddev_ann) + + if (isatt(panres,"lbLabelAlignment")) then + delete(panres@lbLabelAlignment) + delete(panres@lbLabelStrings) + end if + + c_me = (/5,10,15,20,30,40,50,60,70,80,85,90,95,99/) + if (dimsizes(c_me).eq.dimsizes(contour_means).and.all((c_me - contour_means).eq.0)) then ; needed to make sure contour intervals + panres@lbLabelAlignment = "ExternalEdges" ; set above match the labels set here + panres@lbLabelStrings = (/"1","5","10","15","20","30","40","50","60","70","80","85","90","95","99"," "/) + end if + delete([/c_me,contour_means/]) + + panres@txString = "SIC Means (DJF)" + gsn_panel2(wks_mean_djf,plot_mean_nh_djf,(/nrow,ncol/),panres) + gsn_panel2(wks_mean_djf,plot_mean_sh_djf,(/nrow,ncol/),panres) + delete(wks_mean_djf) + + panres@txString = "SIC Means (MAM)" + gsn_panel2(wks_mean_mam,plot_mean_nh_mam,(/nrow,ncol/),panres) + gsn_panel2(wks_mean_mam,plot_mean_sh_mam,(/nrow,ncol/),panres) + delete(wks_mean_mam) + + panres@txString = "SIC Means (JJA)" + gsn_panel2(wks_mean_jja,plot_mean_nh_jja,(/nrow,ncol/),panres) + gsn_panel2(wks_mean_jja,plot_mean_sh_jja,(/nrow,ncol/),panres) + delete(wks_mean_jja) + + panres@txString = "SIC Means (SON)" + gsn_panel2(wks_mean_son,plot_mean_nh_son,(/nrow,ncol/),panres) + gsn_panel2(wks_mean_son,plot_mean_sh_son,(/nrow,ncol/),panres) + delete(wks_mean_son) + + panres@txString = "SIC Means (Annual)" + gsn_panel2(wks_mean_ann,plot_mean_nh_ann,(/nrow,ncol/),panres) + gsn_panel2(wks_mean_ann,plot_mean_sh_ann,(/nrow,ncol/),panres) + delete(wks_mean_ann) + delete(panres) +;-------------------------------------------------------------------------------- + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + system("mv "+OUTDIR+"aice.stddev.djf.000001.png "+OUTDIR+"aice.stddev.nh.djf.png") + system("mv "+OUTDIR+"aice.stddev.djf.000002.png "+OUTDIR+"aice.stddev.sh.djf.png") + system("mv "+OUTDIR+"aice.stddev.mam.000001.png "+OUTDIR+"aice.stddev.nh.mam.png") + system("mv "+OUTDIR+"aice.stddev.mam.000002.png "+OUTDIR+"aice.stddev.sh.mam.png") + system("mv "+OUTDIR+"aice.stddev.jja.000001.png "+OUTDIR+"aice.stddev.nh.jja.png") + system("mv "+OUTDIR+"aice.stddev.jja.000002.png "+OUTDIR+"aice.stddev.sh.jja.png") + system("mv "+OUTDIR+"aice.stddev.son.000001.png "+OUTDIR+"aice.stddev.nh.son.png") + system("mv "+OUTDIR+"aice.stddev.son.000002.png "+OUTDIR+"aice.stddev.sh.son.png") + system("mv "+OUTDIR+"aice.stddev.ann.000001.png "+OUTDIR+"aice.stddev.nh.ann.png") + system("mv "+OUTDIR+"aice.stddev.ann.000002.png "+OUTDIR+"aice.stddev.sh.ann.png") + + system("mv "+OUTDIR+"aice.mean.djf.000001.png "+OUTDIR+"aice.mean.nh.djf.png") + system("mv "+OUTDIR+"aice.mean.djf.000002.png "+OUTDIR+"aice.mean.sh.djf.png") + system("mv "+OUTDIR+"aice.mean.mam.000001.png "+OUTDIR+"aice.mean.nh.mam.png") + system("mv "+OUTDIR+"aice.mean.mam.000002.png "+OUTDIR+"aice.mean.sh.mam.png") + system("mv "+OUTDIR+"aice.mean.jja.000001.png "+OUTDIR+"aice.mean.nh.jja.png") + system("mv "+OUTDIR+"aice.mean.jja.000002.png "+OUTDIR+"aice.mean.sh.jja.png") + system("mv "+OUTDIR+"aice.mean.son.000001.png "+OUTDIR+"aice.mean.nh.son.png") + system("mv "+OUTDIR+"aice.mean.son.000002.png "+OUTDIR+"aice.mean.sh.son.png") + system("mv "+OUTDIR+"aice.mean.ann.000001.png "+OUTDIR+"aice.mean.nh.ann.png") + system("mv "+OUTDIR+"aice.mean.ann.000002.png "+OUTDIR+"aice.mean.sh.ann.png") + else + system("psplit "+OUTDIR+"aice.stddev.djf.ps "+OUTDIR+"aice_sd") + system("mv "+OUTDIR+"aice_sd0001.ps "+OUTDIR+"aice.stddev.nh.djf.ps") + system("mv "+OUTDIR+"aice_sd0002.ps "+OUTDIR+"aice.stddev.sh.djf.ps") + system("psplit "+OUTDIR+"aice.stddev.mam.ps "+OUTDIR+"aice_sd") + system("mv "+OUTDIR+"aice_sd0001.ps "+OUTDIR+"aice.stddev.nh.mam.ps") + system("mv "+OUTDIR+"aice_sd0002.ps "+OUTDIR+"aice.stddev.sh.mam.ps") + system("psplit "+OUTDIR+"aice.stddev.jja.ps "+OUTDIR+"aice_sd") + system("mv "+OUTDIR+"aice_sd0001.ps "+OUTDIR+"aice.stddev.nh.jja.ps") + system("mv "+OUTDIR+"aice_sd0002.ps "+OUTDIR+"aice.stddev.sh.jja.ps") + system("psplit "+OUTDIR+"aice.stddev.son.ps "+OUTDIR+"aice_sd") + system("mv "+OUTDIR+"aice_sd0001.ps "+OUTDIR+"aice.stddev.nh.son.ps") + system("mv "+OUTDIR+"aice_sd0002.ps "+OUTDIR+"aice.stddev.sh.son.ps") + system("psplit "+OUTDIR+"aice.stddev.ann.ps "+OUTDIR+"aice_sd") + system("mv "+OUTDIR+"aice_sd0001.ps "+OUTDIR+"aice.stddev.nh.ann.ps") + system("mv "+OUTDIR+"aice_sd0002.ps "+OUTDIR+"aice.stddev.sh.ann.ps") + system("rm "+OUTDIR+"aice.stddev.???.ps") + + system("psplit "+OUTDIR+"aice.mean.djf.ps "+OUTDIR+"aice_m") + system("mv "+OUTDIR+"aice_m0001.ps "+OUTDIR+"aice.mean.nh.djf.ps") + system("mv "+OUTDIR+"aice_m0002.ps "+OUTDIR+"aice.mean.sh.djf.ps") + system("psplit "+OUTDIR+"aice.mean.mam.ps "+OUTDIR+"aice_m") + system("mv "+OUTDIR+"aice_m0001.ps "+OUTDIR+"aice.mean.nh.mam.ps") + system("mv "+OUTDIR+"aice_m0002.ps "+OUTDIR+"aice.mean.sh.mam.ps") + system("psplit "+OUTDIR+"aice.mean.jja.ps "+OUTDIR+"aice_m") + system("mv "+OUTDIR+"aice_m0001.ps "+OUTDIR+"aice.mean.nh.jja.ps") + system("mv "+OUTDIR+"aice_m0002.ps "+OUTDIR+"aice.mean.sh.jja.ps") + system("psplit "+OUTDIR+"aice.mean.son.ps "+OUTDIR+"aice_m") + system("mv "+OUTDIR+"aice_m0001.ps "+OUTDIR+"aice.mean.nh.son.ps") + system("mv "+OUTDIR+"aice_m0002.ps "+OUTDIR+"aice.mean.sh.son.ps") + system("psplit "+OUTDIR+"aice.mean.ann.ps "+OUTDIR+"aice_m") + system("mv "+OUTDIR+"aice_m0001.ps "+OUTDIR+"aice.mean.nh.ann.ps") + system("mv "+OUTDIR+"aice_m0002.ps "+OUTDIR+"aice.mean.sh.ann.ps") + system("rm "+OUTDIR+"aice.mean.???.ps") + end if + print("Finished: aice.mean_stddev.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/aice.trends_timeseries.ncl b/lib/externals/CVDP/ncl_scripts/aice.trends_timeseries.ncl new file mode 100644 index 000000000..2feb9611b --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/aice.trends_timeseries.ncl @@ -0,0 +1,1544 @@ +; Calculates SIC hemispheric trends and extent +; +; Variables used: sic +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: aice.trends_timeseries.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_aice_nh") + na = asciiread("namelist_byvar/namelist_aice_nh",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + nsim_sh = numAsciiRow("namelist_byvar/namelist_aice_sh") + na_sh = asciiread("namelist_byvar/namelist_aice_sh",(/nsim/),"string") + names_sh = new(nsim,"string") + paths_sh = new(nsim,"string") + syear_sh = new(nsim,"integer",-999) + eyear_sh = new(nsim,"integer",-999) + do gg = 0,nsim-1 + names_sh(gg) = str_strip(str_get_field(na_sh(gg),1,delim)) + paths_sh(gg) = str_strip(str_get_field(na_sh(gg),2,delim)) + syear_sh(gg) = stringtointeger(str_strip(str_get_field(na_sh(gg),3,delim))) + eyear_sh(gg) = stringtointeger(str_strip(str_get_field(na_sh(gg),4,delim))) + end do + nyr_sh = eyear_sh-syear_sh+1 + nyr_max_sh = max(nyr_sh) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_trends_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.trends.djf") + wks_trends_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.trends.mam") + wks_trends_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.trends.jja") + wks_trends_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.trends.son") + wks_trends_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.trends.ann") + wks_trends_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.trends.mon") + + wks_iceext_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.extent.djf") + wks_iceext_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.extent.mam") + wks_iceext_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.extent.jja") + wks_iceext_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.extent.son") + wks_iceext_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.extent.ann") + wks_iceext_febmar = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.extent.febmar") + wks_iceext_sep = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.extent.sep") + wks_iceext_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"aice.extent.mon") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_trends_djf,"ncl_default") + gsn_define_colormap(wks_trends_mam,"ncl_default") + gsn_define_colormap(wks_trends_jja,"ncl_default") + gsn_define_colormap(wks_trends_son,"ncl_default") + gsn_define_colormap(wks_trends_ann,"ncl_default") + gsn_define_colormap(wks_trends_mon,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_trends_djf,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mam,"BlueDarkRed18") + gsn_define_colormap(wks_trends_jja,"BlueDarkRed18") + gsn_define_colormap(wks_trends_son,"BlueDarkRed18") + gsn_define_colormap(wks_trends_ann,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mon,"BlueDarkRed18") + end if + + plot_trends_nh_djf = new(nsim,"graphic") + plot_trends_nh_mam = new(nsim,"graphic") + plot_trends_nh_jja = new(nsim,"graphic") + plot_trends_nh_son = new(nsim,"graphic") + plot_trends_nh_ann = new(nsim,"graphic") + plot_trends_nh_mon = new(nsim,"graphic") + plot_iceext_nh_djf = new(nsim,"graphic") + plot_iceext_nh_mam = new(nsim,"graphic") + plot_iceext_nh_jja = new(nsim,"graphic") + plot_iceext_nh_son = new(nsim,"graphic") + plot_iceext_nh_ann = new(nsim,"graphic") + plot_iceext_nh_mon = new(nsim,"graphic") + plot_iceext_nh_mon_anom = new(nsim,"graphic") + plot_iceext_nh_feb = new(nsim,"graphic") + plot_iceext_nh_mar = new(nsim,"graphic") + plot_iceext_nh_sep = new(nsim,"graphic") + plot_iceext_nh_climo = new(nsim,"graphic") + + plot_trends_sh_djf = new(nsim,"graphic") + plot_trends_sh_mam = new(nsim,"graphic") + plot_trends_sh_jja = new(nsim,"graphic") + plot_trends_sh_son = new(nsim,"graphic") + plot_trends_sh_ann = new(nsim,"graphic") + plot_trends_sh_mon = new(nsim,"graphic") + plot_iceext_sh_djf = new(nsim,"graphic") + plot_iceext_sh_mam = new(nsim,"graphic") + plot_iceext_sh_jja = new(nsim,"graphic") + plot_iceext_sh_son = new(nsim,"graphic") + plot_iceext_sh_ann = new(nsim,"graphic") + plot_iceext_sh_mon = new(nsim,"graphic") + plot_iceext_sh_mon_anom = new(nsim,"graphic") + plot_iceext_sh_feb = new(nsim,"graphic") + plot_iceext_sh_mar = new(nsim,"graphic") + plot_iceext_sh_sep = new(nsim,"graphic") + plot_iceext_sh_climo = new(nsim,"graphic") + + if (isfilepresent2("obs_aice_nh")) then + plot_iceext_nh_obs = new((/6,nsim/),"graphic") + end if + if (isfilepresent2("obs_aice_sh")) then + plot_iceext_sh_obs = new((/6,nsim/),"graphic") + end if + + time_mon2 = ispan(0,11,1) + time_mon2@units = "months since 0000-01-01 00:00:00" + time_mon2@long_name = "Time" + time_mon2@standard_name = "time" + time_mon2@calendar = "standard" + time_mon2!0 = "time_mon2" + time_mon2&time_mon2 = time_mon2 + + do ee = 0,nsim-1 + aice_nh_flag = 0 + aice_nh = data_read_in_ice(paths(ee),"aice_nh",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(aice_nh,"is_all_missing")) then + delete(aice_nh) + aice_nh_flag = 1 + end if + + ph_s = "" ; flag that will be used to denote if pole hole area filled in via pole_hole_area attribute + if (aice_nh_flag.eq.0) then + if (isatt(aice_nh,"area")) then + area3d = aice_nh@area + area3d_c = conform(aice_nh,area3d,(/1,2/)) + aice_nh_sum = aice_nh +; aice_nh_sum = (/ (where((aice_nh/100.).ge.0.15,(aice_nh/100.),aice_nh@_FillValue))*area3d_c /) ; ice area calculation (all cells > 15% kept) + aice_nh_sum = (/ where(aice_nh.ge.15,1.,aice_nh@_FillValue) /) ; ice extent calculation (all cells greater than 15% treated as 100% covered) + aice_nh_sum = aice_nh_sum*area3d_c + wgts = aice_nh_sum(0,:,:) + wgts = 1. + aice_nh_sum_mon = aice_nh_sum(:,0,0) ; preallocate array to retain metadata + aice_nh_sum_mon = (/ wgt_areasum2(aice_nh_sum,wgts,0) /) +; do gg = 0,dimsizes(aice_nh&time)-1 +; aice_nh_sum_mon(gg) = (/ sum(aice_nh_sum(gg,:,:)) /) +; end do + + if (isatt(aice_nh,"pole_hole_area")) then ; special attribute set up to account for pole hole in grids. NSIDC assumes hole is 100% ice covered as of Jan 2016 + ph_area = todouble(aice_nh_sum_mon@pole_hole_area) ; format: start YYYYMM, end YYYYMM, area, start YYYYMM, end YYYYMM, area, etc. + dimZ_ph = dimsizes(ph_area)/3 ; only used for Northern Hemisphere + temp_area_arr = aice_nh_sum_mon + temp_area_arr&time = cd_calendar(aice_nh_sum_mon&time,1) +; printVarSummary(temp_area_arr) +; print(ph_area) + do gg = 0,dimZ_ph-1 + temp_area_arr({ph_area(gg*3):ph_area(gg*3+1)}) = temp_area_arr({ph_area(gg*3):ph_area(gg*3+1)}) + tofloat(ph_area(gg*3+2)) +; print(ph_area(gg*3)+" "+ph_area(gg*3+1)+" "+tofloat(ph_area(gg*3+2))) + end do + aice_nh_sum_mon = (/ temp_area_arr /) + delete([/ph_area,dimZ_ph,temp_area_arr/]) + ph_s = "*" + end if + + aice_nh_sum_mon = aice_nh_sum_mon/1.e12 + aice_nh_sum_mon@units = "10^12 m2" + aice_nh_sum_mon@long_name = "sea_ice_extent" + if (isatt(aice_nh_sum_mon,"coordinates")) then + delete(aice_nh_sum_mon@coordinates) + end if + delete([/aice_nh_sum,area3d,area3d_c,wgts/]) + + taice = new((/dimsizes(aice_nh_sum_mon),1,1/),typeof(aice_nh_sum_mon)) + taice!0 = "time" + taice!1 = "lat" + taice!2 = "lon" + taice(:,0,0) = (/ aice_nh_sum_mon /) ; convert to 3D array so we can use clmMonTLL and calcMonAnomTLL + if (OPT_CLIMO.eq."Full") then + taice = rmMonAnnCycTLL(taice) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = taice + temp_arr&time = cd_calendar(aice_nh_sum_mon&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + taice = calcMonAnomTLL(taice,climo) + delete(climo) + end if + aice_nh_sum_mon_anom = aice_nh_sum_mon + aice_nh_sum_mon_anom = (/ taice(:,0,0) /) + aice_nh_sum_mon_anom@long_name = "sea_ice_extent_anomaly" + delete(taice) + + aice_nh_sum_feb = aice_nh_sum_mon(1::12) + delete(aice_nh_sum_feb&time) + aice_nh_sum_feb@long_name = "February sea_ice_extent" + aice_nh_sum_feb!0 = "TIME" + aice_nh_sum_feb&TIME = ispan(syear(ee),eyear(ee),1) + aice_nh_sum_feb&TIME@units = "YYYY" + aice_nh_sum_feb&TIME@long_name = "time" + aice_nh_sum_mar = aice_nh_sum_mon(2::12) + aice_nh_sum_mar@long_name = "March sea_ice_extent" + copy_VarCoords(aice_nh_sum_feb,aice_nh_sum_mar) + aice_nh_sum_sep = aice_nh_sum_mon(8::12) + aice_nh_sum_sep@long_name = "September sea_ice_extent" + copy_VarCoords(aice_nh_sum_feb,aice_nh_sum_sep) + + aice_nh_sum_climo = new(12,typeof(aice_nh_sum_mon)) + copy_VarAtts(aice_nh_sum_mon,aice_nh_sum_climo) + aice_nh_sum_climo@long_name = "climatological_sea_ice_extent" + aice_nh_sum_climo!0 = "time_mon2" + aice_nh_sum_climo&time_mon2 = time_mon2 + do gg = 0,11 + aice_nh_sum_climo(gg) = (/ avg(aice_nh_sum_mon(gg::12)) /) + end do + + temp = runave_Wrap(aice_nh_sum_mon,3,0) + aice_nh_sum_djf = temp(0::12) + aice_nh_sum_mam = temp(3::12) + aice_nh_sum_jja = temp(6::12) + aice_nh_sum_son = temp(9::12) + delete(temp) + temp = runave_Wrap(aice_nh_sum_mon,12,0) + aice_nh_sum_ann = temp(5::12) + delete(temp) + + delete(aice_nh_sum_djf&time) + aice_nh_sum_djf!0 = "TIME" + aice_nh_sum_djf&TIME = ispan(syear(ee),eyear(ee),1) + aice_nh_sum_djf&TIME@units = "YYYY" + aice_nh_sum_djf&TIME@long_name = "time" + copy_VarMeta(aice_nh_sum_djf,aice_nh_sum_mam) + copy_VarMeta(aice_nh_sum_djf,aice_nh_sum_jja) + copy_VarMeta(aice_nh_sum_djf,aice_nh_sum_son) + copy_VarMeta(aice_nh_sum_djf,aice_nh_sum_ann) + end if + + if (OPT_CLIMO.eq."Full") then + aice_nh = rmMonAnnCycTLL(aice_nh) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = aice_nh + delete(temp_arr&time) + temp_arr&time = cd_calendar(aice_nh&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + aice_nh = calcMonAnomTLL(aice_nh,climo) + delete(climo) + end if + + dimZ = dimsizes(aice_nh) + dim_j = dimZ(1) + dim_i = dimZ(2) + tttt = dtrend_msg_n(ispan(0,dimsizes(aice_nh&time)-1,1),aice_nh,False,True,0) + aice_nh_trends_mon = aice_nh(0,:,:) + aice_nh_trends_mon = (/ onedtond(tttt@slope, (/dim_j,dim_i/) ) /) + aice_nh_trends_mon = aice_nh_trends_mon*dimsizes(aice_nh&time) + aice_nh_trends_mon@units = aice_nh@units+" "+nyr(ee)+"yr~S~-1~N~" + delete(tttt) + + aice_nh_seas = runave_n_Wrap(aice_nh,3,0,0) + aice_nh_seas(0,:,:) = (/ dim_avg_n(aice_nh(:1,:,:),0) /) + aice_nh_seas(dimsizes(aice_nh&time)-1,:,:) = (/ dim_avg_n(aice_nh(dimsizes(aice_nh&time)-2:,:,:),0) /) + aice_nh_ann = runave_n_Wrap(aice_nh,12,0,0) + delete(aice_nh) + + aice_nh_trends_seas = aice_nh_seas(:3,:,:) + aice_nh_trends_seas = aice_nh_trends_seas@_FillValue + aice_nh_trends_ann = aice_nh_trends_seas(0,:,:) + do ff = 0,4 + if (ff.le.3) then + tarr = aice_nh_seas(ff*3::12,:,:) + end if + if (ff.eq.4) then + tarr = aice_nh_ann(5::12,:,:) + end if + tttt = dtrend_msg_n(ispan(0,dimsizes(tarr&time)-1,1),tarr,False,True,0) + if (ff.le.3) then + aice_nh_trends_seas(ff,:,:) = (/ onedtond(tttt@slope, (/dim_j,dim_i/) ) /) + end if + if (ff.eq.4) then + aice_nh_trends_ann = (/ onedtond(tttt@slope, (/dim_j,dim_i/) ) /) + end if + delete([/tarr,tttt/]) + end do + aice_nh_trends_seas = aice_nh_trends_seas*nyr(ee) + aice_nh_trends_seas@units = aice_nh_seas@units+" "+nyr(ee)+"yr~S~-1~N~" + aice_nh_trends_ann = aice_nh_trends_ann*nyr(ee) + aice_nh_trends_ann@units = aice_nh_ann@units+" "+nyr(ee)+"yr~S~-1~N~" + delete([/aice_nh_seas,aice_nh_ann,dim_j,dim_i,dimZ/]) + end if + + aice_sh_flag = 0 + aice_sh = data_read_in_ice(paths_sh(ee),"aice_sh",syear_sh(ee),eyear_sh(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(aice_sh,"is_all_missing")) then + delete(aice_sh) + aice_sh_flag = 1 + end if + if (aice_sh_flag.eq.0) then + if (isatt(aice_sh,"area")) then + area3d = aice_sh@area + area3d_c = conform(aice_sh,area3d,(/1,2/)) + aice_sh_sum = aice_sh +; aice_sh_sum = (/ (where((aice_sh/100.).ge.0.15,(aice_sh/100.),aice_sh@_FillValue))*area3d_c /) ; ice area calculation (all cells > 15% kept) + aice_sh_sum = (/ where(aice_sh.ge.15,1.,aice_sh@_FillValue) /) ; ice extent calculation (all cells greater than 15% treated as 100% covered) + aice_sh_sum = aice_sh_sum*area3d_c + wgts = aice_sh_sum(0,:,:) + wgts = 1. + aice_sh_sum_mon = aice_sh_sum(:,0,0) ; preallocate array to retain metadata + aice_sh_sum_mon = (/ wgt_areasum2(aice_sh_sum,wgts,0) /) +; do gg = 0,dimsizes(aice_sh&time)-1 +; aice_sh_sum_mon(gg) = (/ sum(aice_sh_sum(gg,:,:)) /) +; end do + aice_sh_sum_mon = aice_sh_sum_mon/1.e12 + aice_sh_sum_mon@units = "10^12 m2" + aice_sh_sum_mon@long_name = "sea_ice_extent" + if (isatt(aice_sh_sum_mon,"coordinates")) then + delete(aice_sh_sum_mon@coordinates) + end if + delete([/aice_sh_sum,area3d,area3d_c,wgts/]) + + taice = new((/dimsizes(aice_sh_sum_mon),1,1/),typeof(aice_sh_sum_mon)) + taice!0 = "time" + taice!1 = "lat" + taice!2 = "lon" + taice(:,0,0) = (/ aice_sh_sum_mon /) ; convert to 3D array so we can use clmMonTLL and calcMonAnomTLL + if (OPT_CLIMO.eq."Full") then + taice = rmMonAnnCycTLL(taice) + else + check_custom_climo(names_sh(ee),syear_sh(ee),eyear_sh(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = taice + temp_arr&time = cd_calendar(aice_sh_sum_mon&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + taice = calcMonAnomTLL(taice,climo) + delete(climo) + end if + aice_sh_sum_mon_anom = aice_sh_sum_mon + aice_sh_sum_mon_anom = (/ taice(:,0,0) /) + aice_sh_sum_mon_anom@long_name = "sea_ice_extent_anomaly" + delete(taice) + + aice_sh_sum_feb = aice_sh_sum_mon(1::12) + delete(aice_sh_sum_feb&time) + aice_sh_sum_feb@long_name = "February sea_ice_extent" + aice_sh_sum_feb!0 = "TIME" + aice_sh_sum_feb&TIME = ispan(syear_sh(ee),eyear_sh(ee),1) + aice_sh_sum_feb&TIME@units = "YYYY" + aice_sh_sum_feb&TIME@long_name = "time" + aice_sh_sum_mar = aice_sh_sum_mon(2::12) + aice_sh_sum_mar@long_name = "March sea_ice_extent" + copy_VarCoords(aice_sh_sum_feb,aice_sh_sum_mar) + aice_sh_sum_sep = aice_sh_sum_mon(8::12) + aice_sh_sum_sep@long_name = "September sea_ice_extent" + copy_VarCoords(aice_sh_sum_feb,aice_sh_sum_sep) + + aice_sh_sum_climo = new(12,typeof(aice_sh_sum_mon)) + copy_VarAtts(aice_sh_sum_mon,aice_sh_sum_climo) + aice_sh_sum_climo@long_name = "climatological_sea_ice_extent" + aice_sh_sum_climo!0 = "time_mon2" + aice_sh_sum_climo&time_mon2 = time_mon2 + do gg = 0,11 + aice_sh_sum_climo(gg) = (/ avg(aice_sh_sum_mon(gg::12)) /) + end do + + temp = runave_Wrap(aice_sh_sum_mon,3,0) + aice_sh_sum_djf = temp(0::12) + aice_sh_sum_mam = temp(3::12) + aice_sh_sum_jja = temp(6::12) + aice_sh_sum_son = temp(9::12) + delete(temp) + temp = runave_Wrap(aice_sh_sum_mon,12,0) + aice_sh_sum_ann = temp(5::12) + delete(temp) + + delete(aice_sh_sum_djf&time) + aice_sh_sum_djf!0 = "TIME" + aice_sh_sum_djf&TIME = ispan(syear_sh(ee),eyear_sh(ee),1) + aice_sh_sum_djf&TIME@units = "YYYY" + aice_sh_sum_djf&TIME@long_name = "time" + copy_VarMeta(aice_sh_sum_djf,aice_sh_sum_mam) + copy_VarMeta(aice_sh_sum_djf,aice_sh_sum_jja) + copy_VarMeta(aice_sh_sum_djf,aice_sh_sum_son) + copy_VarMeta(aice_sh_sum_djf,aice_sh_sum_ann) + end if + + if (OPT_CLIMO.eq."Full") then + aice_sh = rmMonAnnCycTLL(aice_sh) + else + check_custom_climo(names_sh(ee),syear_sh(ee),eyear_sh(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = aice_sh + delete(temp_arr&time) + temp_arr&time = cd_calendar(aice_sh&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + aice_sh = calcMonAnomTLL(aice_sh,climo) + delete(climo) + end if + + dimZ = dimsizes(aice_sh) + dim_j = dimZ(1) + dim_i = dimZ(2) + tttt = dtrend_msg_n(ispan(0,dimsizes(aice_sh&time)-1,1),aice_sh,False,True,0) + aice_sh_trends_mon = aice_sh(0,:,:) + aice_sh_trends_mon = (/ onedtond(tttt@slope, (/dim_j,dim_i/) ) /) + aice_sh_trends_mon = aice_sh_trends_mon*dimsizes(aice_sh&time) + aice_sh_trends_mon@units = aice_sh@units+" "+nyr_sh(ee)+"yr~S~-1~N~" + delete(tttt) + + aice_sh_seas = runave_n_Wrap(aice_sh,3,0,0) + aice_sh_seas(0,:,:) = (/ dim_avg_n(aice_sh(:1,:,:),0) /) + aice_sh_seas(dimsizes(aice_sh&time)-1,:,:) = (/ dim_avg_n(aice_sh(dimsizes(aice_sh&time)-2:,:,:),0) /) + aice_sh_ann = runave_n_Wrap(aice_sh,12,0,0) + delete(aice_sh) + + aice_sh_trends_seas = aice_sh_seas(:3,:,:) + aice_sh_trends_seas = aice_sh_trends_seas@_FillValue + aice_sh_trends_ann = aice_sh_trends_seas(0,:,:) + do ff = 0,4 + if (ff.le.3) then + tarr = aice_sh_seas(ff*3::12,:,:) + end if + if (ff.eq.4) then + tarr = aice_sh_ann(5::12,:,:) + end if + tttt = dtrend_msg_n(ispan(0,dimsizes(tarr&time)-1,1),tarr,False,True,0) + if (ff.le.3) then + aice_sh_trends_seas(ff,:,:) = (/ onedtond(tttt@slope, (/dim_j,dim_i/) ) /) + end if + if (ff.eq.4) then + aice_sh_trends_ann = (/ onedtond(tttt@slope, (/dim_j,dim_i/) ) /) + end if + delete([/tarr,tttt/]) + end do + aice_sh_trends_seas = aice_sh_trends_seas*nyr_sh(ee) + aice_sh_trends_seas@units = aice_sh_seas@units+" "+nyr_sh(ee)+"yr~S~-1~N~" + aice_sh_trends_ann = aice_sh_trends_ann*nyr_sh(ee) + aice_sh_trends_ann@units = aice_sh_ann@units+" "+nyr_sh(ee)+"yr~S~-1~N~" + delete([/aice_sh_seas,aice_sh_ann,dim_j,dim_i,dimZ/]) + end if + + if (OUTPUT_DATA.eq."True".and.aice_nh_flag.eq.0) then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.aice.trends_timeseries.nh."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + nh_trends_seas = aice_nh_trends_seas + if (isatt(nh_trends_seas,"lat2d")) then ; if there is a lat2d there will be a lon2d + LAT2D = nh_trends_seas@lat2d + LON2D = nh_trends_seas@lon2d + delete(nh_trends_seas@lat2d) + delete(nh_trends_seas@lon2d) + copy_VarCoords(nh_trends_seas(0,:,:),LAT2D) + copy_VarCoords(nh_trends_seas(0,:,:),LON2D) + z->lat2d_ice_nh = set_varAtts(LAT2D,"Northern Hemisphere ice grid 2-dimensional latitudes","","") + z->lon2d_ice_nh = set_varAtts(LON2D,"Northern Hemisphere ice grid 2-dimensional longitudes","","") + delete([/LAT2D,LON2D/]) + nh_trends_seas@coordinates ="lat2d_ice_nh lon2d_ice_nh" + end if + if (isatt(nh_trends_seas,"area")) then + delete(nh_trends_seas@area) + end if + nh_trends_ann = (/ aice_nh_trends_ann /) + copy_VarMeta(nh_trends_seas(0,:,:),nh_trends_ann) + nh_trends_mon = (/ aice_nh_trends_mon /) + copy_VarMeta(nh_trends_seas(0,:,:),nh_trends_mon) + z->sic_nh_trends_djf = set_varAtts(nh_trends_seas(0,:,:),"Northern Hemisphere sic trends (DJF)","","") + z->sic_nh_trends_mam = set_varAtts(nh_trends_seas(1,:,:),"Northern Hemisphere sic trends (MAM)","","") + z->sic_nh_trends_jja = set_varAtts(nh_trends_seas(2,:,:),"Northern Hemisphere sic trends (JJA)","","") + z->sic_nh_trends_son = set_varAtts(nh_trends_seas(3,:,:),"Northern Hemisphere sic trends (SON)","","") + z->sic_nh_trends_ann = set_varAtts(nh_trends_ann,"Northern Hemisphere sic trends (annual)","","") + z->sic_nh_trends_mon = set_varAtts(nh_trends_mon,"Northern Hemisphere sic trends (monthly)","","") + + if (isvar("aice_nh_sum_djf")) then + nh_sum_climo = (/ aice_nh_sum_climo /) + copy_VarAtts(aice_nh_sum_djf,nh_sum_climo) + nh_sum_climo!0 = "time_mon2" + nh_sum_climo&time_mon2 = time_mon2 + if (isatt(nh_sum_climo,"lat2d")) then + delete(nh_sum_climo@lat2d) + delete(nh_sum_climo@lon2d) + end if + if (isatt(nh_sum_climo,"area")) then + delete(nh_sum_climo@area) + end if + z->sic_nh_extent_climo = set_varAtts(nh_sum_climo,"Northern Hemisphere sic extent climatology","","") + nh_sum_djf = aice_nh_sum_djf + if (isatt(nh_sum_djf,"lat2d")) then + delete(nh_sum_djf@lat2d) + delete(nh_sum_djf@lon2d) + end if + if (isatt(nh_sum_djf,"area")) then + delete(nh_sum_djf@area) + end if + nh_sum_mam = (/ aice_nh_sum_mam /) + copy_VarMeta(nh_sum_djf,nh_sum_mam) + nh_sum_jja = (/ aice_nh_sum_jja /) + copy_VarMeta(nh_sum_djf,nh_sum_jja) + nh_sum_son = (/ aice_nh_sum_son /) + copy_VarMeta(nh_sum_djf,nh_sum_son) + nh_sum_ann = (/ aice_nh_sum_ann /) + copy_VarMeta(nh_sum_djf,nh_sum_ann) + nh_sum_feb = (/ aice_nh_sum_feb /) + copy_VarMeta(nh_sum_djf,nh_sum_feb) + nh_sum_mar = (/ aice_nh_sum_mar /) + copy_VarMeta(nh_sum_djf,nh_sum_mar) + nh_sum_sep = (/ aice_nh_sum_sep /) + copy_VarMeta(nh_sum_djf,nh_sum_sep) + nh_sum_mon = aice_nh_sum_mon + nh_sum_mon_anom = aice_nh_sum_mon_anom + if (isatt(nh_sum_mon,"lat2d")) then + delete(nh_sum_mon@lat2d) + delete(nh_sum_mon@lon2d) + delete(nh_sum_mon_anom@lat2d) + delete(nh_sum_mon_anom@lon2d) + end if + if (isatt(nh_sum_mon,"area")) then + delete(nh_sum_mon@area) + delete(nh_sum_mon_anom@area) + end if + z->sic_nh_extent_djf = set_varAtts(nh_sum_djf,"Northern Hemisphere sic extent timeseries (DJF)","","") + z->sic_nh_extent_mam = set_varAtts(nh_sum_mam,"Northern Hemisphere sic extent timeseries (MAM)","","") + z->sic_nh_extent_jja = set_varAtts(nh_sum_jja,"Northern Hemisphere sic extent timeseries (JJA)","","") + z->sic_nh_extent_son = set_varAtts(nh_sum_son,"Northern Hemisphere sic extent timeseries (SON)","","") + z->sic_nh_extent_ann = set_varAtts(nh_sum_ann,"Northern Hemisphere sic extent timeseries (annual)","","") + z->sic_nh_extent_mon = set_varAtts(nh_sum_mon,"Northern Hemisphere sic extent timeseries (monthly)","","") + z->sic_nh_extent_mon_anom = set_varAtts(nh_sum_mon_anom,"Northern Hemisphere sic extent anomaly timeseries (monthly)","","") + z->sic_nh_extent_feb = set_varAtts(nh_sum_feb,"Northern Hemisphere sic extent timeseries (February)","","") + z->sic_nh_extent_mar = set_varAtts(nh_sum_mar,"Northern Hemisphere sic extent timeseries (March)","","") + z->sic_nh_extent_sep = set_varAtts(nh_sum_sep,"Northern Hemisphere sic extent timeseries (September)","","") + delete([/nh_sum_djf,nh_sum_mam,nh_sum_jja,nh_sum_son,nh_sum_ann,nh_sum_feb,nh_sum_mar,nh_sum_sep,nh_sum_mon,nh_sum_mon_anom/]) + end if + delete([/nh_trends_seas,nh_trends_ann,nh_trends_mon/]) + delete(z) + end if + if (OUTPUT_DATA.eq."True".and.aice_sh_flag.eq.0) then + modname = str_sub_str(names_sh(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.aice.trends_timeseries.sh."+syear_sh(ee)+"-"+eyear_sh(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_sh(ee)+" from "+syear_sh(ee)+"-"+eyear_sh(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_sh(ee)+"-"+eyear_sh(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + sh_trends_seas = aice_sh_trends_seas + if (isatt(sh_trends_seas,"lat2d")) then ; if there is a lat2d there will be a lon2d + LAT2D = sh_trends_seas@lat2d + LON2D = sh_trends_seas@lon2d + delete(sh_trends_seas@lat2d) + delete(sh_trends_seas@lon2d) + copy_VarCoords(sh_trends_seas(0,:,:),LAT2D) + copy_VarCoords(sh_trends_seas(0,:,:),LON2D) + z->lat2d_ice_sh = set_varAtts(LAT2D,"Northern Hemisphere ice grid 2-dimensional latitudes","","") + z->lon2d_ice_sh = set_varAtts(LON2D,"Northern Hemisphere ice grid 2-dimensional longitudes","","") + delete([/LAT2D,LON2D/]) + sh_trends_seas@coordinates ="lat2d_ice_sh lon2d_ice_sh" + end if + if (isatt(sh_trends_seas,"area")) then + delete(sh_trends_seas@area) + end if + sh_trends_seas!1 = "j2" + sh_trends_seas!2 = "i2" + sh_trends_seas@long_name = sh_trends_seas@long_name+" trends" + sh_trends_ann = (/ aice_sh_trends_ann /) + copy_VarMeta(sh_trends_seas(0,:,:),sh_trends_ann) + sh_trends_mon = (/ aice_sh_trends_mon /) + copy_VarMeta(sh_trends_seas(0,:,:),sh_trends_mon) + z->sic_sh_trends_djf = set_varAtts(sh_trends_seas(0,:,:),"Southern Hemisphere sic trends (DJF)","","") + z->sic_sh_trends_mam = set_varAtts(sh_trends_seas(1,:,:),"Southern Hemisphere sic trends (MAM)","","") + z->sic_sh_trends_jja = set_varAtts(sh_trends_seas(2,:,:),"Southern Hemisphere sic trends (JJA)","","") + z->sic_sh_trends_son = set_varAtts(sh_trends_seas(3,:,:),"Southern Hemisphere sic trends (SON)","","") + z->sic_sh_trends_ann = set_varAtts(sh_trends_ann,"Southern Hemisphere sic trends (annual)","","") + z->sic_sh_trends_mon = set_varAtts(sh_trends_mon,"Southern Hemisphere sic trends (monthly)","","") + + if (isvar("aice_sh_sum_djf")) then + sh_sum_climo = (/ aice_sh_sum_climo /) + copy_VarAtts(aice_sh_sum_djf,sh_sum_climo) + sh_sum_climo!0 = "time_mon2" + sh_sum_climo&time_mon2 = time_mon2 + if (isatt(sh_sum_climo,"lat2d")) then + delete(sh_sum_climo@lat2d) + delete(sh_sum_climo@lon2d) + end if + if (isatt(sh_sum_climo,"area")) then + delete(sh_sum_climo@area) + end if + z->sic_sh_extent_climo = set_varAtts(sh_sum_climo,"Southern Hemisphere sic extent climatology","","") + sh_sum_djf = aice_sh_sum_djf + if (isatt(sh_sum_djf,"lat2d")) then + delete(sh_sum_djf@lat2d) + delete(sh_sum_djf@lon2d) + end if + if (isatt(sh_sum_djf,"area")) then + delete(sh_sum_djf@area) + end if + sh_sum_mam = (/ aice_sh_sum_mam /) + copy_VarMeta(sh_sum_djf,sh_sum_mam) + sh_sum_jja = (/ aice_sh_sum_jja /) + copy_VarMeta(sh_sum_djf,sh_sum_jja) + sh_sum_son = (/ aice_sh_sum_son /) + copy_VarMeta(sh_sum_djf,sh_sum_son) + sh_sum_ann = (/ aice_sh_sum_ann /) + copy_VarMeta(sh_sum_djf,sh_sum_ann) + sh_sum_feb = (/ aice_sh_sum_feb /) + copy_VarMeta(sh_sum_djf,sh_sum_feb) + sh_sum_mar = (/ aice_sh_sum_mar /) + copy_VarMeta(sh_sum_djf,sh_sum_mar) + sh_sum_sep = (/ aice_sh_sum_sep /) + copy_VarMeta(sh_sum_djf,sh_sum_sep) + sh_sum_mon = aice_sh_sum_mon + sh_sum_mon_anom = aice_sh_sum_mon_anom + if (isatt(sh_sum_mon,"lat2d")) then + delete(sh_sum_mon@lat2d) + delete(sh_sum_mon@lon2d) + delete(sh_sum_mon_anom@lat2d) + delete(sh_sum_mon_anom@lon2d) + end if + if (isatt(sh_sum_mon,"area")) then + delete(sh_sum_mon@area) + delete(sh_sum_mon_anom@area) + end if + z->sic_sh_extent_djf = set_varAtts(sh_sum_djf,"Southern Hemisphere sic extent timeseries (DJF)","","") + z->sic_sh_extent_mam = set_varAtts(sh_sum_mam,"Southern Hemisphere sic extent timeseries (MAM)","","") + z->sic_sh_extent_jja = set_varAtts(sh_sum_jja,"Southern Hemisphere sic extent timeseries (JJA)","","") + z->sic_sh_extent_son = set_varAtts(sh_sum_son,"Southern Hemisphere sic extent timeseries (SON)","","") + z->sic_sh_extent_ann = set_varAtts(sh_sum_ann,"Southern Hemisphere sic extent timeseries (annual)","","") + z->sic_sh_extent_mon = set_varAtts(sh_sum_mon,"Southern Hemisphere sic extent timeseries (monthly)","","") + z->sic_sh_extent_mon_anom = set_varAtts(sh_sum_mon_anom,"Southern Hemisphere sic extent anomaly timeseries (monthly)","","") + z->sic_sh_extent_feb = set_varAtts(sh_sum_feb,"Southern Hemisphere sic extent timeseries (February)","","") + z->sic_sh_extent_mar = set_varAtts(sh_sum_mar,"Southern Hemisphere sic extent timeseries (March)","","") + z->sic_sh_extent_sep = set_varAtts(sh_sum_sep,"Southern Hemisphere sic extent timeseries (September)","","") + delete([/sh_sum_djf,sh_sum_mam,sh_sum_jja,sh_sum_son,sh_sum_ann,sh_sum_feb,sh_sum_mar,sh_sum_sep,sh_sum_mon,sh_sum_mon_anom/]) + end if + delete([/sh_trends_seas,sh_trends_ann,sh_trends_mon/]) + delete(z) + end if + if (aice_nh_flag.eq.0) then + aice_nh_trends_seas = where(aice_nh_trends_seas.eq.0,aice_nh_trends_seas@_FillValue,aice_nh_trends_seas) + aice_nh_trends_ann = where(aice_nh_trends_ann.eq.0,aice_nh_trends_ann@_FillValue,aice_nh_trends_ann) + aice_nh_trends_mon = where(aice_nh_trends_mon.eq.0,aice_nh_trends_mon@_FillValue,aice_nh_trends_mon) + end if + if (aice_sh_flag.eq.0) then + aice_sh_trends_seas = where(aice_sh_trends_seas.eq.0,aice_sh_trends_seas@_FillValue,aice_sh_trends_seas) + aice_sh_trends_ann = where(aice_sh_trends_ann.eq.0,aice_sh_trends_ann@_FillValue,aice_sh_trends_ann) + aice_sh_trends_mon = where(aice_sh_trends_mon.eq.0,aice_sh_trends_mon@_FillValue,aice_sh_trends_mon) + end if +;========================================================================================== + res = True + res@gsnPolar = "NH" + res@mpMinLatF = 40. + res@mpCenterLonF = 0. + res@mpGeophysicalLineColor = "gray42" + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@mpGridAndLimbOn = False + res@mpLandFillColor = "gray75" + res@mpFillDrawOrder = "PostDraw" + res@mpPerimDrawOrder = "PostDraw" + + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + res@gsnAddCyclic = True + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@trGridType = "TriangularMesh" +; res@cnFillMode = "RasterFill" + res@lbLabelBarOn = False + + res@cnLevelSelectionMode = "ExplicitLevels" + res@cnLevels = (/-90,-70,-50,-45,-40,-35,-30,-25,-20,-15,-10,-5,0,5,10,15,20,25,30,35,40,45,50,70,90/) + cmap = gsn_retrieve_colormap(wks_trends_djf) + dimc = dimsizes(cmap) + cmap2 = cmap(::-1,:) + res@cnFillPalette = cmap2(:dimc(0)-3,:) + delete([/cmap,cmap2,dimc/]) + + res@gsnLeftStringOrthogonalPosF = -0.03 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.03 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + if (nsim.le.5) then + res@gsnLeftStringFontHeightF = 0.018 + res@gsnCenterStringFontHeightF = 0.022 + res@gsnRightStringFontHeightF = 0.018 + else + res@gsnLeftStringFontHeightF = 0.024 + res@gsnCenterStringFontHeightF = 0.028 + res@gsnRightStringFontHeightF = 0.024 + end if + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray18" + if (wks_type.eq."png") then + xyres@xyLineThicknessF = 4. + else + xyres@xyLineThicknessF = 2. + end if + if (isfilepresent2("obs_aice_nh").and.ee.eq.0) then + xyres@xyLineColor = "black" + else + xyres@xyLineColor = "royalblue" + end if + xyres@tiYAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnLeftStringFontHeightF = 0.0155 + xyres@gsnCenterStringFontHeightF = 0.0155 + xyres@gsnRightStringFontHeightF = 0.012 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnLeftStringFontHeightF = 0.024 + xyres@gsnCenterStringFontHeightF = 0.024 + xyres@gsnRightStringFontHeightF = 0.020 + end if + xyres@gsnLeftStringOrthogonalPosF = 0.025 + xyres@gsnRightStringOrthogonalPosF = xyres@gsnLeftStringOrthogonalPosF + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@xyMonoDashPattern = True + xyres@gsnLeftString = "" + xyres@gsnCenterString = "" + xyres@gsnRightString = "" + + xyres_c = xyres + xyres_c@trXMinF = 1 + xyres_c@trXMaxF = 12 + xyres_c@vpWidthF = 0.65 + xyres_c@vpHeightF = 0.45 + if (isfilepresent2("obs_aice_nh").and.ee.eq.0) then + xyres_c@xyLineColor = "black" + else + xyres_c@xyLineColors = (/"royalblue","gray60"/) + end if + xyres_c@tmXBMode = "Explicit" ; explicit labels + xyres_c@tmXBValues = ispan(1,12,1) + xyres_c@tmXBLabels = (/"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"/) + xyres_c@tmXTOn = False + xyres_c@gsnLeftStringOrthogonalPosF = 0.025 + xyres_c@gsnCenterStringOrthogonalPosF = xyres_c@gsnLeftStringOrthogonalPosF + xyres_c@gsnRightStringOrthogonalPosF = xyres_c@gsnLeftStringOrthogonalPosF + + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+0.5 + + xyres2 = xyres + xyres2@xyLineColor = "gray60" + xyres2@xyCurveDrawOrder = "PreDraw" + + if (aice_nh_flag.eq.0) then + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnRightString = aice_nh_trends_seas@units + res@gsnCenterString = names(ee) + + plot_trends_nh_djf(ee) = gsn_csm_contour_map(wks_trends_djf,aice_nh_trends_seas(0,:,:),res) + plot_trends_nh_mam(ee) = gsn_csm_contour_map(wks_trends_mam,aice_nh_trends_seas(1,:,:),res) + plot_trends_nh_jja(ee) = gsn_csm_contour_map(wks_trends_jja,aice_nh_trends_seas(2,:,:),res) + plot_trends_nh_son(ee) = gsn_csm_contour_map(wks_trends_son,aice_nh_trends_seas(3,:,:),res) + plot_trends_nh_ann(ee) = gsn_csm_contour_map(wks_trends_ann,aice_nh_trends_ann,res) + plot_trends_nh_mon(ee) = gsn_csm_contour_map(wks_trends_mon,aice_nh_trends_mon,res) + delete([/aice_nh_trends_seas,aice_nh_trends_ann,aice_nh_trends_mon/]) + + if (isvar("aice_nh_sum_djf")) then + xyres@gsnLeftString = names(ee)+ph_s + if (isfilepresent2("obs_aice_nh").and.ee.eq.0) then + aice_nh_sum_djf_obs_min = min(aice_nh_sum_djf) + aice_nh_sum_djf_obs_max = max(aice_nh_sum_djf) + aice_nh_sum_mam_obs_min = min(aice_nh_sum_mam) + aice_nh_sum_mam_obs_max = max(aice_nh_sum_mam) + aice_nh_sum_jja_obs_min = min(aice_nh_sum_jja) + aice_nh_sum_jja_obs_max = max(aice_nh_sum_jja) + aice_nh_sum_son_obs_min = min(aice_nh_sum_son) + aice_nh_sum_son_obs_max = max(aice_nh_sum_son) + aice_nh_sum_ann_obs_min = min(aice_nh_sum_ann) + aice_nh_sum_ann_obs_max = max(aice_nh_sum_ann) + aice_nh_sum_mon_obs_min = min(aice_nh_sum_mon) + aice_nh_sum_mon_obs_max = max(aice_nh_sum_mon) + aice_nh_sum_mon_anom_obs_min = min(aice_nh_sum_mon_anom) + aice_nh_sum_mon_anom_obs_max = max(aice_nh_sum_mon_anom) + aice_nh_sum_feb_obs_min = min(aice_nh_sum_feb) + aice_nh_sum_feb_obs_max = max(aice_nh_sum_feb) + aice_nh_sum_mar_obs_min = min(aice_nh_sum_mar) + aice_nh_sum_mar_obs_max = max(aice_nh_sum_mar) + aice_nh_sum_sep_obs_min = min(aice_nh_sum_sep) + aice_nh_sum_sep_obs_max = max(aice_nh_sum_sep) + aice_nh_obs_djf = aice_nh_sum_djf + aice_nh_obs_mam = aice_nh_sum_mam + aice_nh_obs_jja = aice_nh_sum_jja + aice_nh_obs_son = aice_nh_sum_son + aice_nh_obs_ann = aice_nh_sum_ann + aice_nh_obs_mon = aice_nh_sum_mon + aice_nh_obs_mon_anom = aice_nh_sum_mon_anom + aice_nh_obs_feb = aice_nh_sum_feb + aice_nh_obs_mar = aice_nh_sum_mar + aice_nh_obs_sep = aice_nh_sum_sep + aice_nh_obs_climo = aice_nh_sum_climo + end if + + xyres_c@gsnLeftString = syear(ee)+"-"+eyear(ee) + xyres_c@gsnCenterString = names(ee)+ph_s ; ph_s is used to denote extent timeseries that have had pole hole areas added in + xyres_c@gsnRightString = "("+str_sub_str(str_sub_str(aice_nh_sum_climo@units,"m2","m~S~2~N~"),"10^12","10~S~12~N~")+")" + if (ee.eq.0) then + plot_iceext_nh_climo(ee) = gsn_csm_xy(wks_iceext_mon,ispan(1,12,1),aice_nh_sum_climo,xyres_c) + end if + if (ee.ge.1.) then + if (isvar("aice_nh_obs_climo")) then + tarr = new((/2,12/),float) + tarr(0,:) = (/ tofloat(aice_nh_sum_climo) /) + tarr(1,:) = (/ tofloat(aice_nh_obs_climo) /) + plot_iceext_nh_climo(ee) = gsn_csm_xy(wks_iceext_mon,ispan(1,12,1),tarr,xyres_c) + delete(tarr) + else + plot_iceext_nh_climo(ee) = gsn_csm_xy(wks_iceext_mon,ispan(1,12,1),aice_nh_sum_climo,xyres_c) + end if + end if + + if (ee.ge.1.and.isvar("aice_nh_sum_djf_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_djf),aice_nh_sum_djf_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_djf),aice_nh_sum_djf_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_djf)-1,1),aice_nh_sum_djf,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_djf@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_djf(ee) = gsn_csm_xy(wks_iceext_djf,ispan(syear(ee),eyear(ee),1),aice_nh_sum_djf,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_djf")) then + plot_iceext_nh_obs_djf = gsn_csm_xy(wks_iceext_djf,ispan(syear(0),eyear(0),1),aice_nh_obs_djf,xyres2) + overlay(plot_iceext_nh_djf(ee),plot_iceext_nh_obs_djf) + end if + + if (ee.ge.1.and.isvar("aice_nh_sum_mam_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_mam),aice_nh_sum_mam_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_mam),aice_nh_sum_mam_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_mam)-1,1),aice_nh_sum_mam,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_mam@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_mam(ee) = gsn_csm_xy(wks_iceext_mam,ispan(syear(ee),eyear(ee),1),aice_nh_sum_mam,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_mam")) then + plot_iceext_nh_obs_mam = gsn_csm_xy(wks_iceext_mam,ispan(syear(0),eyear(0),1),aice_nh_obs_mam,xyres2) + overlay(plot_iceext_nh_mam(ee),plot_iceext_nh_obs_mam) + end if + + if (ee.ge.1.and.isvar("aice_nh_sum_jja_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_jja),aice_nh_sum_jja_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_jja),aice_nh_sum_jja_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_jja)-1,1),aice_nh_sum_jja,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_jja@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_jja(ee) = gsn_csm_xy(wks_iceext_jja,ispan(syear(ee),eyear(ee),1),aice_nh_sum_jja,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_jja")) then + plot_iceext_nh_obs_jja = gsn_csm_xy(wks_iceext_jja,ispan(syear(0),eyear(0),1),aice_nh_obs_jja,xyres2) + overlay(plot_iceext_nh_jja(ee),plot_iceext_nh_obs_jja) + end if + + if (ee.ge.1.and.isvar("aice_nh_sum_son_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_son),aice_nh_sum_son_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_son),aice_nh_sum_son_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_son)-1,1),aice_nh_sum_son,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_son@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_son(ee) = gsn_csm_xy(wks_iceext_son,ispan(syear(ee),eyear(ee),1),aice_nh_sum_son,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_son")) then + plot_iceext_nh_obs_son = gsn_csm_xy(wks_iceext_son,ispan(syear(0),eyear(0),1),aice_nh_obs_son,xyres2) + overlay(plot_iceext_nh_son(ee),plot_iceext_nh_obs_son) + end if + + if (ee.ge.1.and.isvar("aice_nh_sum_ann_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_ann),aice_nh_sum_ann_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_ann),aice_nh_sum_ann_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_ann)-1,1),aice_nh_sum_ann,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_ann@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_ann(ee) = gsn_csm_xy(wks_iceext_ann,ispan(syear(ee),eyear(ee),1),aice_nh_sum_ann,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_ann")) then + plot_iceext_nh_obs_ann = gsn_csm_xy(wks_iceext_ann,ispan(syear(0),eyear(0),1),aice_nh_obs_ann,xyres2) + overlay(plot_iceext_nh_ann(ee),plot_iceext_nh_obs_ann) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_nh_sum_feb_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_feb),aice_nh_sum_feb_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_feb),aice_nh_sum_feb_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_feb)-1,1),aice_nh_sum_feb,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_feb@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_feb(ee) = gsn_csm_xy(wks_iceext_febmar,ispan(syear(ee),eyear(ee),1),aice_nh_sum_feb,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_feb")) then + plot_iceext_nh_obs_feb = gsn_csm_xy(wks_iceext_febmar,ispan(syear(0),eyear(0),1),aice_nh_obs_feb,xyres2) + overlay(plot_iceext_nh_feb(ee),plot_iceext_nh_obs_feb) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_nh_sum_mar_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_mar),aice_nh_sum_mar_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_mar),aice_nh_sum_mar_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_mar)-1,1),aice_nh_sum_mar,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_mar@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_mar(ee) = gsn_csm_xy(wks_iceext_febmar,ispan(syear(ee),eyear(ee),1),aice_nh_sum_mar,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_mar")) then + plot_iceext_nh_obs_mar = gsn_csm_xy(wks_iceext_febmar,ispan(syear(0),eyear(0),1),aice_nh_obs_mar,xyres2) + overlay(plot_iceext_nh_mar(ee),plot_iceext_nh_obs_mar) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_nh_sum_sep_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_sep),aice_nh_sum_sep_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_sep),aice_nh_sum_sep_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_sep)-1,1),aice_nh_sum_sep,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_sep@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_sep(ee) = gsn_csm_xy(wks_iceext_sep,ispan(syear(ee),eyear(ee),1),aice_nh_sum_sep,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_sep")) then + plot_iceext_nh_obs_sep = gsn_csm_xy(wks_iceext_sep,ispan(syear(0),eyear(0),1),aice_nh_obs_sep,xyres2) + overlay(plot_iceext_nh_sep(ee),plot_iceext_nh_obs_sep) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_nh_sum_mon_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_mon),aice_nh_sum_mon_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_mon),aice_nh_sum_mon_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_mon)-1,1),aice_nh_sum_mon,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_mon@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_mon(ee) = gsn_csm_xy(wks_iceext_mon,fspan(syear(ee),eyear(ee)+.91667,dimsizes(aice_nh_sum_mon)),aice_nh_sum_mon,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_mon")) then + plot_iceext_nh_obs_mon = gsn_csm_xy(wks_iceext_mon,fspan(syear(0),eyear(0)+.91667,dimsizes(aice_nh_obs_mon)),aice_nh_obs_mon,xyres2) + overlay(plot_iceext_nh_mon(ee),plot_iceext_nh_obs_mon) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_nh_sum_mon_anom_obs_min")) then + xyres@trYMinF = min((/min(aice_nh_sum_mon_anom),aice_nh_sum_mon_anom_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_nh_sum_mon_anom),aice_nh_sum_mon_anom_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_nh_sum_mon_anom)-1,1),aice_nh_sum_mon_anom,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr(ee),2,True)+aice_nh_sum_mon_anom@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_nh_mon_anom(ee) = gsn_csm_xy(wks_iceext_mon,fspan(syear(ee),eyear(ee)+.91667,dimsizes(aice_nh_sum_mon_anom)),aice_nh_sum_mon_anom,xyres) + if (ee.ge.1.and.isvar("aice_nh_obs_mon_anom")) then + plot_iceext_nh_obs_mon_anom = gsn_csm_xy(wks_iceext_mon,fspan(syear(0),eyear(0)+.91667,dimsizes(aice_nh_obs_mon_anom)),aice_nh_obs_mon_anom,xyres2) + overlay(plot_iceext_nh_mon_anom(ee),plot_iceext_nh_obs_mon_anom) + end if + delete([/aice_nh_sum_djf,aice_nh_sum_mam,aice_nh_sum_jja,aice_nh_sum_son,aice_nh_sum_ann,aice_nh_sum_feb,aice_nh_sum_mar,aice_nh_sum_sep,aice_nh_sum_mon,aice_nh_sum_mon_anom,tttt/]) + end if + end if + + delete(res@mpMinLatF) + res@mpMaxLatF = -45. + res@gsnPolar = "SH" + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr_sh(ee)*1.)/nyr_max_sh) + else + xyres@vpWidthF = 0.9 + end if + xyres2@vpWidthF = xyres@vpWidthF + xyres@trXMinF = syear_sh(ee)-.5 + xyres@trXMaxF = eyear_sh(ee)+0.5 + if (aice_sh_flag.eq.0) then + res@gsnLeftString = syear_sh(ee)+"-"+eyear_sh(ee) + res@gsnRightString = aice_sh_trends_seas@units + res@gsnCenterString = names_sh(ee) + plot_trends_sh_djf(ee) = gsn_csm_contour_map(wks_trends_djf,aice_sh_trends_seas(0,:,:),res) + plot_trends_sh_mam(ee) = gsn_csm_contour_map(wks_trends_mam,aice_sh_trends_seas(1,:,:),res) + plot_trends_sh_jja(ee) = gsn_csm_contour_map(wks_trends_jja,aice_sh_trends_seas(2,:,:),res) + plot_trends_sh_son(ee) = gsn_csm_contour_map(wks_trends_son,aice_sh_trends_seas(3,:,:),res) + plot_trends_sh_ann(ee) = gsn_csm_contour_map(wks_trends_ann,aice_sh_trends_ann,res) + plot_trends_sh_mon(ee) = gsn_csm_contour_map(wks_trends_mon,aice_sh_trends_mon,res) + delete([/aice_sh_trends_seas,aice_sh_trends_ann,aice_sh_trends_mon/]) + + if (isvar("aice_sh_sum_djf")) then + xyres@gsnLeftString = names_sh(ee) + if (isfilepresent2("obs_aice_sh").and.ee.eq.0) then + aice_sh_sum_djf_obs_min = min(aice_sh_sum_djf) + aice_sh_sum_djf_obs_max = max(aice_sh_sum_djf) + aice_sh_sum_mam_obs_min = min(aice_sh_sum_mam) + aice_sh_sum_mam_obs_max = max(aice_sh_sum_mam) + aice_sh_sum_jja_obs_min = min(aice_sh_sum_jja) + aice_sh_sum_jja_obs_max = max(aice_sh_sum_jja) + aice_sh_sum_son_obs_min = min(aice_sh_sum_son) + aice_sh_sum_son_obs_max = max(aice_sh_sum_son) + aice_sh_sum_ann_obs_min = min(aice_sh_sum_ann) + aice_sh_sum_ann_obs_max = max(aice_sh_sum_ann) + aice_sh_sum_mon_obs_min = min(aice_sh_sum_mon) + aice_sh_sum_mon_obs_max = max(aice_sh_sum_mon) + aice_sh_sum_mon_anom_obs_min = min(aice_sh_sum_mon_anom) + aice_sh_sum_mon_anom_obs_max = max(aice_sh_sum_mon_anom) + aice_sh_sum_feb_obs_min = min(aice_sh_sum_feb) + aice_sh_sum_feb_obs_max = max(aice_sh_sum_feb) + aice_sh_sum_mar_obs_min = min(aice_sh_sum_mar) + aice_sh_sum_mar_obs_max = max(aice_sh_sum_mar) + aice_sh_sum_sep_obs_min = min(aice_sh_sum_sep) + aice_sh_sum_sep_obs_max = max(aice_sh_sum_sep) + aice_sh_obs_djf = aice_sh_sum_djf + aice_sh_obs_mam = aice_sh_sum_mam + aice_sh_obs_jja = aice_sh_sum_jja + aice_sh_obs_son = aice_sh_sum_son + aice_sh_obs_ann = aice_sh_sum_ann + aice_sh_obs_mon = aice_sh_sum_mon + aice_sh_obs_mon_anom = aice_sh_sum_mon_anom + aice_sh_obs_feb = aice_sh_sum_feb + aice_sh_obs_mar = aice_sh_sum_mar + aice_sh_obs_sep = aice_sh_sum_sep + aice_sh_obs_climo = aice_sh_sum_climo + end if + + xyres_c@gsnLeftString = syear_sh(ee)+"-"+eyear_sh(ee) + xyres_c@gsnCenterString = names_sh(ee) + xyres_c@gsnRightString = "("+str_sub_str(str_sub_str(aice_sh_sum_climo@units,"m2","m~S~2~N~"),"10^12","10~S~12~N~")+")" + if (ee.eq.0) then + plot_iceext_sh_climo(ee) = gsn_csm_xy(wks_iceext_mon,ispan(1,12,1),aice_sh_sum_climo,xyres_c) + end if + if (ee.ge.1.) then + if (isvar("aice_sh_obs_climo")) then + tarr = new((/2,12/),float) + tarr(0,:) = (/ tofloat(aice_sh_sum_climo) /) + tarr(1,:) = (/ tofloat(aice_sh_obs_climo) /) + plot_iceext_sh_climo(ee) = gsn_csm_xy(wks_iceext_mon,ispan(1,12,1),tarr,xyres_c) + delete(tarr) + else + plot_iceext_sh_climo(ee) = gsn_csm_xy(wks_iceext_mon,ispan(1,12,1),aice_sh_sum_climo,xyres_c) + end if + end if + + if (ee.ge.1.and.isvar("aice_sh_sum_djf_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_djf),aice_sh_sum_djf_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_djf),aice_sh_sum_djf_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_djf)-1,1),aice_sh_sum_djf,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_djf@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_djf(ee) = gsn_csm_xy(wks_iceext_djf,ispan(syear_sh(ee),eyear_sh(ee),1),aice_sh_sum_djf,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_djf")) then + plot_iceext_sh_obs_djf = gsn_csm_xy(wks_iceext_djf,ispan(syear_sh(0),eyear_sh(0),1),aice_sh_obs_djf,xyres2) + overlay(plot_iceext_sh_djf(ee),plot_iceext_sh_obs_djf) + end if + + if (ee.ge.1.and.isvar("aice_sh_sum_mam_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_mam),aice_sh_sum_mam_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_mam),aice_sh_sum_mam_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_mam)-1,1),aice_sh_sum_mam,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_mam@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_mam(ee) = gsn_csm_xy(wks_iceext_mam,ispan(syear_sh(ee),eyear_sh(ee),1),aice_sh_sum_mam,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_mam")) then + plot_iceext_sh_obs_mam = gsn_csm_xy(wks_iceext_mam,ispan(syear_sh(0),eyear_sh(0),1),aice_sh_obs_mam,xyres2) + overlay(plot_iceext_sh_mam(ee),plot_iceext_sh_obs_mam) + end if + + if (ee.ge.1.and.isvar("aice_sh_sum_jja_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_jja),aice_sh_sum_jja_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_jja),aice_sh_sum_jja_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_jja)-1,1),aice_sh_sum_jja,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_jja@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_jja(ee) = gsn_csm_xy(wks_iceext_jja,ispan(syear_sh(ee),eyear_sh(ee),1),aice_sh_sum_jja,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_jja")) then + plot_iceext_sh_obs_jja = gsn_csm_xy(wks_iceext_jja,ispan(syear_sh(0),eyear_sh(0),1),aice_sh_obs_jja,xyres2) + overlay(plot_iceext_sh_jja(ee),plot_iceext_sh_obs_jja) + end if + + if (ee.ge.1.and.isvar("aice_sh_sum_son_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_son),aice_sh_sum_son_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_son),aice_sh_sum_son_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_son)-1,1),aice_sh_sum_son,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_son@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_son(ee) = gsn_csm_xy(wks_iceext_son,ispan(syear_sh(ee),eyear_sh(ee),1),aice_sh_sum_son,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_son")) then + plot_iceext_sh_obs_son = gsn_csm_xy(wks_iceext_son,ispan(syear_sh(0),eyear_sh(0),1),aice_sh_obs_son,xyres2) + overlay(plot_iceext_sh_son(ee),plot_iceext_sh_obs_son) + end if + + if (ee.ge.1.and.isvar("aice_sh_sum_ann_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_ann),aice_sh_sum_ann_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_ann),aice_sh_sum_ann_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_ann)-1,1),aice_sh_sum_ann,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_ann@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_ann(ee) = gsn_csm_xy(wks_iceext_ann,ispan(syear_sh(ee),eyear_sh(ee),1),aice_sh_sum_ann,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_ann")) then + plot_iceext_sh_obs_ann = gsn_csm_xy(wks_iceext_ann,ispan(syear_sh(0),eyear_sh(0),1),aice_sh_obs_ann,xyres2) + overlay(plot_iceext_sh_ann(ee),plot_iceext_sh_obs_ann) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_sh_sum_feb_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_feb),aice_sh_sum_feb_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_feb),aice_sh_sum_feb_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_feb)-1,1),aice_sh_sum_feb,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_feb@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_feb(ee) = gsn_csm_xy(wks_iceext_febmar,ispan(syear_sh(ee),eyear_sh(ee),1),aice_sh_sum_feb,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_feb")) then + plot_iceext_sh_obs_feb = gsn_csm_xy(wks_iceext_febmar,ispan(syear_sh(0),eyear_sh(0),1),aice_sh_obs_feb,xyres2) + overlay(plot_iceext_sh_feb(ee),plot_iceext_sh_obs_feb) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_sh_sum_mar_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_mar),aice_sh_sum_mar_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_mar),aice_sh_sum_mar_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_mar)-1,1),aice_sh_sum_mar,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_mar@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_mar(ee) = gsn_csm_xy(wks_iceext_febmar,ispan(syear_sh(ee),eyear_sh(ee),1),aice_sh_sum_mar,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_mar")) then + plot_iceext_sh_obs_mar = gsn_csm_xy(wks_iceext_febmar,ispan(syear_sh(0),eyear_sh(0),1),aice_sh_obs_mar,xyres2) + overlay(plot_iceext_sh_mar(ee),plot_iceext_sh_obs_mar) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_sh_sum_sep_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_sep),aice_sh_sum_sep_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_sep),aice_sh_sum_sep_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_sep)-1,1),aice_sh_sum_sep,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_sep@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_sep(ee) = gsn_csm_xy(wks_iceext_sep,ispan(syear_sh(ee),eyear_sh(ee),1),aice_sh_sum_sep,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_sep")) then + plot_iceext_sh_obs_sep = gsn_csm_xy(wks_iceext_sep,ispan(syear_sh(0),eyear_sh(0),1),aice_sh_obs_sep,xyres2) + overlay(plot_iceext_sh_sep(ee),plot_iceext_sh_obs_sep) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_sh_sum_mon_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_mon),aice_sh_sum_mon_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_mon),aice_sh_sum_mon_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_mon)-1,1),aice_sh_sum_mon,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_mon@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_mon(ee) = gsn_csm_xy(wks_iceext_mon,fspan(syear_sh(ee),eyear_sh(ee)+.91667,dimsizes(aice_sh_sum_mon)),aice_sh_sum_mon,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_mon")) then + plot_iceext_sh_obs_mon = gsn_csm_xy(wks_iceext_mon,fspan(syear_sh(0),eyear_sh(0)+.91667,dimsizes(aice_sh_obs_mon)),aice_sh_obs_mon,xyres2) + overlay(plot_iceext_sh_mon(ee),plot_iceext_sh_obs_mon) + end if + delete(tttt) + + if (ee.ge.1.and.isvar("aice_sh_sum_mon_anom_obs_min")) then + xyres@trYMinF = min((/min(aice_sh_sum_mon_anom),aice_sh_sum_mon_anom_obs_min/))-1 + xyres@trYMaxF = max((/max(aice_sh_sum_mon_anom),aice_sh_sum_mon_anom_obs_max/))+1 + xyres2@trYMinF = xyres@trYMinF + xyres2@trYMaxF = xyres@trYMaxF + end if + tttt = dtrend_msg(ispan(0,dimsizes(aice_sh_sum_mon_anom)-1,1),aice_sh_sum_mon_anom,False,True) + xyres@gsnRightString = str_sub_str(str_sub_str(decimalPlaces(tttt@slope*nyr_sh(ee),2,True)+aice_sh_sum_mon_anom@units,"m2","m~S~2~N~"),"10^12"," 10~S~12~N~") + plot_iceext_sh_mon_anom(ee) = gsn_csm_xy(wks_iceext_mon,fspan(syear_sh(ee),eyear_sh(ee)+.91667,dimsizes(aice_sh_sum_mon_anom)),aice_sh_sum_mon_anom,xyres) + if (ee.ge.1.and.isvar("aice_sh_obs_mon_anom")) then + plot_iceext_sh_obs_mon_anom = gsn_csm_xy(wks_iceext_mon,fspan(syear_sh(0),eyear_sh(0)+.91667,dimsizes(aice_sh_obs_mon_anom)),aice_sh_obs_mon_anom,xyres2) + overlay(plot_iceext_sh_mon_anom(ee),plot_iceext_sh_obs_mon_anom) + end if + + delete([/aice_sh_sum_djf,aice_sh_sum_mam,aice_sh_sum_jja,aice_sh_sum_son,aice_sh_sum_ann,aice_sh_sum_feb,aice_sh_sum_mar,aice_sh_sum_sep,aice_sh_sum_mon,aice_sh_sum_mon_anom,tttt/]) + end if + end if + delete([/res,xyres,xyres2,xyres_c,ph_s/]) +; print("Done with ee = "+ee) + end do + delete(time_mon2) + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + panres@lbLabelFontHeightF = 0.013 + panres@lbLabelStride = 1 + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.0185 + panres@gsnPanelBottom = 0.50 + panres@pmLabelBarWidthF = 0.5 + panres@pmLabelBarHeightF = 0.04 + panres@lbLabelFontHeightF = 0.01 + else + panres@txFontHeightF = 0.0125 + panres@gsnPanelBottom = 0.50 + panres@pmLabelBarWidthF = 0.5 + panres@pmLabelBarHeightF = 0.04 + panres@lbLabelFontHeightF = 0.01 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + ncol_sh = floattointeger(sqrt(nsim_sh)) + nrow_sh = (nsim_sh/ncol_sh)+mod(nsim_sh,ncol_sh) + + panres@txString = "SIC Trends (DJF)" + gsn_panel2(wks_trends_djf,plot_trends_nh_djf,(/nrow,ncol/),panres) + gsn_panel2(wks_trends_djf,plot_trends_sh_djf,(/nrow_sh,ncol_sh/),panres) + delete(wks_trends_djf) + + panres@txString = "SIC Trends (MAM)" + gsn_panel2(wks_trends_mam,plot_trends_nh_mam,(/nrow,ncol/),panres) + gsn_panel2(wks_trends_mam,plot_trends_sh_mam,(/nrow_sh,ncol_sh/),panres) + delete(wks_trends_mam) + + panres@txString = "SIC Trends (JJA)" + gsn_panel2(wks_trends_jja,plot_trends_nh_jja,(/nrow,ncol/),panres) + gsn_panel2(wks_trends_jja,plot_trends_sh_jja,(/nrow_sh,ncol_sh/),panres) + delete(wks_trends_jja) + + panres@txString = "SIC Trends (SON)" + gsn_panel2(wks_trends_son,plot_trends_nh_son,(/nrow,ncol/),panres) + gsn_panel2(wks_trends_son,plot_trends_sh_son,(/nrow_sh,ncol_sh/),panres) + delete(wks_trends_son) + + panres@txString = "SIC Trends (Annual)" + gsn_panel2(wks_trends_ann,plot_trends_nh_ann,(/nrow,ncol/),panres) + gsn_panel2(wks_trends_ann,plot_trends_sh_ann,(/nrow_sh,ncol_sh/),panres) + delete(wks_trends_ann) + + panres@txString = "SIC Trends (Monthly)" + gsn_panel2(wks_trends_mon,plot_trends_nh_mon,(/nrow,ncol/),panres) + gsn_panel2(wks_trends_mon,plot_trends_sh_mon,(/nrow_sh,ncol_sh/),panres) + delete(wks_trends_mon) + delete(panres) + + panres2 = True + panres2@gsnMaximize = True + panres2@gsnPaperOrientation = "portrait" + panres2@gsnPanelYWhiteSpacePercent = 3.0 + if (nsim.le.5) then + panres2@txFontHeightF = 0.024 + else + panres2@txFontHeightF = 0.016 + end if + panres3 = panres2 + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres2@gsnPanelScalePlotIndex = tt(0) + delete(tt) + + tt = ind(nyr_sh.eq.nyr_max_sh) + panres3@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + + if (nsim.le.12) then + lp = (/nsim,1/) + lp_sh = (/nsim_sh,1/) + else + lp = (/nrow,ncol/) ;(/nsim/2+1,nsim/8+1/) + lp_sh = (/nrow_sh,ncol_sh/) + end if + + panres2@txString = "SIC NH Extent (DJF)" + gsn_panel2(wks_iceext_djf,plot_iceext_nh_djf,lp,panres2) + panres3@txString = "SIC SH Extent (DJF)" + gsn_panel2(wks_iceext_djf,plot_iceext_sh_djf,lp_sh,panres3) + delete(wks_iceext_djf) + + panres2@txString = "SIC NH Extent (MAM)" + gsn_panel2(wks_iceext_mam,plot_iceext_nh_mam,lp,panres2) + panres3@txString = "SIC SH Extent (MAM)" + gsn_panel2(wks_iceext_mam,plot_iceext_sh_mam,lp_sh,panres3) + delete(wks_iceext_mam) + + panres2@txString = "SIC NH Extent (JJA)" + gsn_panel2(wks_iceext_jja,plot_iceext_nh_jja,lp,panres2) + panres3@txString = "SIC SH Extent (JJA)" + gsn_panel2(wks_iceext_jja,plot_iceext_sh_jja,lp_sh,panres3) + delete(wks_iceext_jja) + + panres2@txString = "SIC NH Extent (SON)" + gsn_panel2(wks_iceext_son,plot_iceext_nh_son,lp,panres2) + panres3@txString = "SIC SH Extent (SON)" + gsn_panel2(wks_iceext_son,plot_iceext_sh_son,lp_sh,panres3) + delete(wks_iceext_son) + + panres2@txString = "SIC NH Extent (Annual)" + gsn_panel2(wks_iceext_ann,plot_iceext_nh_ann,lp,panres2) + panres3@txString = "SIC SH Extent (Annual)" + gsn_panel2(wks_iceext_ann,plot_iceext_sh_ann,lp_sh,panres3) + delete(wks_iceext_ann) + + panres2@txString = "SIC NH Extent (February)" + gsn_panel2(wks_iceext_febmar,plot_iceext_nh_mar,lp,panres2) + panres3@txString = "SIC SH Extent (Feburary)" + gsn_panel2(wks_iceext_febmar,plot_iceext_sh_mar,lp_sh,panres3) + + panres2@txString = "SIC NH Extent (March)" + gsn_panel2(wks_iceext_febmar,plot_iceext_nh_mar,lp,panres2) + panres3@txString = "SIC SH Extent (March)" + gsn_panel2(wks_iceext_febmar,plot_iceext_sh_mar,lp_sh,panres3) + delete(wks_iceext_febmar) + + panres2@txString = "SIC NH Extent (September)" + gsn_panel2(wks_iceext_sep,plot_iceext_nh_sep,lp,panres2) + panres3@txString = "SIC SH Extent (September)" + gsn_panel2(wks_iceext_sep,plot_iceext_sh_sep,lp_sh,panres3) + delete(wks_iceext_sep) + + panres2@txString = "SIC NH Extent (Monthly)" + gsn_panel2(wks_iceext_mon,plot_iceext_nh_mon,lp,panres2) + panres3@txString = "SIC SH Extent (Monthly)" + gsn_panel2(wks_iceext_mon,plot_iceext_sh_mon,lp_sh,panres3) + panres2@txString = "SIC NH Extent (Monthly Anomalies)" + gsn_panel2(wks_iceext_mon,plot_iceext_nh_mon_anom,lp,panres2) + panres3@txString = "SIC SH Extent (Monthly Anomalies)" + gsn_panel2(wks_iceext_mon,plot_iceext_sh_mon_anom,lp_sh,panres3) + + if (nsim.le.5) then + panres2@txFontHeightF = 0.017 + else + panres2@txFontHeightF = 0.014 + end if + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + ncol_sh = floattointeger(sqrt(nsim_sh)) + nrow_sh = (nsim_sh/ncol_sh)+mod(nsim_sh,ncol_sh) + + panres2@txString = "SIC NH Extent Climatology" + gsn_panel2(wks_iceext_mon,plot_iceext_nh_climo,(/nrow,ncol/),panres2) + panres2@txString = "SIC SH Extent Climatology" + gsn_panel2(wks_iceext_mon,plot_iceext_sh_climo,(/nrow_sh,ncol_sh/),panres2) + delete(wks_iceext_mon) +;-------------------------------------------------------------------------------- + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + system("mv "+OUTDIR+"aice.trends.djf.000001.png "+OUTDIR+"aice.trends.nh.djf.png") + system("mv "+OUTDIR+"aice.trends.djf.000002.png "+OUTDIR+"aice.trends.sh.djf.png") + system("mv "+OUTDIR+"aice.trends.mam.000001.png "+OUTDIR+"aice.trends.nh.mam.png") + system("mv "+OUTDIR+"aice.trends.mam.000002.png "+OUTDIR+"aice.trends.sh.mam.png") + system("mv "+OUTDIR+"aice.trends.jja.000001.png "+OUTDIR+"aice.trends.nh.jja.png") + system("mv "+OUTDIR+"aice.trends.jja.000002.png "+OUTDIR+"aice.trends.sh.jja.png") + system("mv "+OUTDIR+"aice.trends.son.000001.png "+OUTDIR+"aice.trends.nh.son.png") + system("mv "+OUTDIR+"aice.trends.son.000002.png "+OUTDIR+"aice.trends.sh.son.png") + system("mv "+OUTDIR+"aice.trends.ann.000001.png "+OUTDIR+"aice.trends.nh.ann.png") + system("mv "+OUTDIR+"aice.trends.ann.000002.png "+OUTDIR+"aice.trends.sh.ann.png") + system("mv "+OUTDIR+"aice.trends.mon.000001.png "+OUTDIR+"aice.trends.nh.mon.png") + system("mv "+OUTDIR+"aice.trends.mon.000002.png "+OUTDIR+"aice.trends.sh.mon.png") + + if (isfilepresent2(OUTDIR+"aice.extent.djf.000001.png")) then + system("mv "+OUTDIR+"aice.extent.djf.000001.png "+OUTDIR+"aice.extent.nh.djf.png") + system("mv "+OUTDIR+"aice.extent.djf.000002.png "+OUTDIR+"aice.extent.sh.djf.png") + system("mv "+OUTDIR+"aice.extent.mam.000001.png "+OUTDIR+"aice.extent.nh.mam.png") + system("mv "+OUTDIR+"aice.extent.mam.000002.png "+OUTDIR+"aice.extent.sh.mam.png") + system("mv "+OUTDIR+"aice.extent.jja.000001.png "+OUTDIR+"aice.extent.nh.jja.png") + system("mv "+OUTDIR+"aice.extent.jja.000002.png "+OUTDIR+"aice.extent.sh.jja.png") + system("mv "+OUTDIR+"aice.extent.son.000001.png "+OUTDIR+"aice.extent.nh.son.png") + system("mv "+OUTDIR+"aice.extent.son.000002.png "+OUTDIR+"aice.extent.sh.son.png") + system("mv "+OUTDIR+"aice.extent.ann.000001.png "+OUTDIR+"aice.extent.nh.ann.png") + system("mv "+OUTDIR+"aice.extent.ann.000002.png "+OUTDIR+"aice.extent.sh.ann.png") + system("mv "+OUTDIR+"aice.extent.febmar.000001.png "+OUTDIR+"aice.extent.nh.feb.png") + system("mv "+OUTDIR+"aice.extent.febmar.000002.png "+OUTDIR+"aice.extent.sh.feb.png") + system("mv "+OUTDIR+"aice.extent.febmar.000003.png "+OUTDIR+"aice.extent.nh.mar.png") + system("mv "+OUTDIR+"aice.extent.febmar.000004.png "+OUTDIR+"aice.extent.sh.mar.png") + system("mv "+OUTDIR+"aice.extent.sep.000001.png "+OUTDIR+"aice.extent.nh.sep.png") + system("mv "+OUTDIR+"aice.extent.sep.000002.png "+OUTDIR+"aice.extent.sh.sep.png") + system("mv "+OUTDIR+"aice.extent.mon.000001.png "+OUTDIR+"aice.extent.nh.mon.png") + system("mv "+OUTDIR+"aice.extent.mon.000002.png "+OUTDIR+"aice.extent.sh.mon.png") + system("mv "+OUTDIR+"aice.extent.mon.000003.png "+OUTDIR+"aice.extent.anom.nh.mon.png") + system("mv "+OUTDIR+"aice.extent.mon.000004.png "+OUTDIR+"aice.extent.anom.sh.mon.png") + system("mv "+OUTDIR+"aice.extent.mon.000005.png "+OUTDIR+"aice.extent.nh.climo.png") + system("mv "+OUTDIR+"aice.extent.mon.000006.png "+OUTDIR+"aice.extent.sh.climo.png") + end if + else + system("psplit "+OUTDIR+"aice.trends.djf.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.trends.nh.djf.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.trends.sh.djf.ps") + system("psplit "+OUTDIR+"aice.trends.mam.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.trends.nh.mam.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.trends.sh.mam.ps") + system("psplit "+OUTDIR+"aice.trends.jja.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.trends.nh.jja.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.trends.sh.jja.ps") + system("psplit "+OUTDIR+"aice.trends.son.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.trends.nh.son.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.trends.sh.son.ps") + system("psplit "+OUTDIR+"aice.trends.ann.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.trends.nh.ann.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.trends.sh.ann.ps") + system("psplit "+OUTDIR+"aice.trends.mon.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.trends.nh.mon.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.trends.sh.mon.ps") + system("rm "+OUTDIR+"aice.trends.???.ps") + + if (isfilepresent2(OUTDIR+"aice.extent.djf.ps")) then + system("psplit "+OUTDIR+"aice.extent.djf.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.extent.nh.djf.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.extent.sh.djf.ps") + system("psplit "+OUTDIR+"aice.extent.mam.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.extent.nh.mam.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.extent.sh.mam.ps") + system("psplit "+OUTDIR+"aice.extent.jja.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.extent.nh.jja.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.extent.sh.jja.ps") + system("psplit "+OUTDIR+"aice.extent.son.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.extent.nh.son.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.extent.sh.son.ps") + system("psplit "+OUTDIR+"aice.extent.ann.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.extent.nh.ann.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.extent.sh.ann.ps") + system("psplit "+OUTDIR+"aice.extent.febmar.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.extent.nh.feb.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.extent.sh.feb.ps") + system("mv "+OUTDIR+"aice_tr0003.ps "+OUTDIR+"aice.extent.nh.mar.ps") + system("mv "+OUTDIR+"aice_tr0004.ps "+OUTDIR+"aice.extent.sh.mar.ps") + system("psplit "+OUTDIR+"aice.extent.sep.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.extent.nh.sep.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.extent.sh.sep.ps") + system("psplit "+OUTDIR+"aice.extent.mon.ps "+OUTDIR+"aice_tr") + system("mv "+OUTDIR+"aice_tr0001.ps "+OUTDIR+"aice.extent.nh.mon.ps") + system("mv "+OUTDIR+"aice_tr0002.ps "+OUTDIR+"aice.extent.sh.mon.ps") + system("mv "+OUTDIR+"aice_tr0003.ps "+OUTDIR+"aice.extent.anom.nh.mon.ps") + system("mv "+OUTDIR+"aice_tr0004.ps "+OUTDIR+"aice.extent.anom.sh.mon.ps") + system("mv "+OUTDIR+"aice_tr0005.ps "+OUTDIR+"aice.extent.nh.climo.ps") + system("mv "+OUTDIR+"aice_tr0006.ps "+OUTDIR+"aice.extent.sh.climo.ps") + system("rm "+OUTDIR+"aice.extent.???.ps "+OUTDIR+"aice.extent.febmar.ps") + end if + end if + print("Finished: aice.trends_timeseries.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/amo.ncl b/lib/externals/CVDP/ncl_scripts/amo.ncl new file mode 100644 index 000000000..d6a301f9f --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/amo.ncl @@ -0,0 +1,803 @@ +; Calculates the AMO pattern, timeseries, and spectra. +; +; Variables used: ts +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: amo.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_ts") + na = asciiread("namelist_byvar/namelist_ts",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) +;---------TAS Regressions coding------------------------------------------------- + nsim_tas = numAsciiRow("namelist_byvar/namelist_trefht") + na_tas = asciiread("namelist_byvar/namelist_trefht",(/nsim_tas/),"string") + names_tas = new(nsim_tas,"string") + paths_tas = new(nsim_tas,"string") + syear_tas = new(nsim_tas,"integer",-999) + eyear_tas = new(nsim_tas,"integer",-999) + + do gg = 0,nsim_tas-1 + names_tas(gg) = str_strip(str_get_field(na_tas(gg),1,delim)) + paths_tas(gg) = str_strip(str_get_field(na_tas(gg),2,delim)) + syear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),3,delim))) + eyear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),4,delim))) + end do + delete(na_tas) + nyr_tas = eyear_tas-syear_tas+1 +;---------PR Regressions coding------------------------------------------------- + nsim_pr = numAsciiRow("namelist_byvar/namelist_prect") + na_pr = asciiread("namelist_byvar/namelist_prect",(/nsim_pr/),"string") + names_pr = new(nsim_pr,"string") + paths_pr = new(nsim_pr,"string") + syear_pr = new(nsim_pr,"integer",-999) + eyear_pr = new(nsim_pr,"integer",-999) + + do gg = 0,nsim_pr-1 + names_pr(gg) = str_strip(str_get_field(na_pr(gg),1,delim)) + paths_pr(gg) = str_strip(str_get_field(na_pr(gg),2,delim)) + syear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),3,delim))) + eyear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),4,delim))) + end do + delete(na_pr) + nyr_pr = eyear_pr-syear_pr+1 +;------------------------------------------------------------------------------------------------- + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks = gsn_open_wks(wks_type,getenv("OUTDIR")+"amo") + wks4 = gsn_open_wks(wks_type,getenv("OUTDIR")+"amo.prreg") + wks2 = gsn_open_wks(wks_type,getenv("OUTDIR")+"amo.powspec") + wks3 = gsn_open_wks(wks_type,getenv("OUTDIR")+"amo.timeseries") + + if (COLORMAP.eq."0") then + gsn_define_colormap(wks,"ncl_default") + gsn_define_colormap(wks2,"cb_9step") + gsn_define_colormap(wks3,"ncl_default") + gsn_define_colormap(wks4,"MPL_BrBG") + end if + if (COLORMAP.eq."1") then + gsn_define_colormap(wks,"BlueDarkRed18") + gsn_define_colormap(wks2,"cb_9step") + gsn_define_colormap(wks3,"ncl_default") + gsn_define_colormap(wks4,"BrownBlue12") + end if + + map = new(nsim,"graphic") + map_sst = new(nsim,"graphic") + map_tasreg = new(nsim,"graphic") + map_prreg = new(nsim,"graphic") + mapLP = new(nsim,"graphic") + mapLP_sst = new(nsim,"graphic") + mapLP_tasreg = new(nsim,"graphic") + mapLP_prreg = new(nsim,"graphic") + pspec = new(nsim,"graphic") + xyplot = new(nsim,"graphic") + xyplot2 = new(nsim,"graphic") + if (isfilepresent2("obs_ts")) then + pspec_obs = new(nsim,"graphic") + end if + + tasreg_frame = 1 ; *reg_frame = flag to create regressions .ps/.png files. Created/used instead of *reg_plot_flag + ; so that if {tas,pr} regressions are not created for the last simulation listed that .ps/png files are created + prreg_frame = 1 + + do ee = 0,nsim-1 + sstT = data_read_in(paths(ee),"TS",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(sstT,"is_all_missing").or.nyr(ee).lt.15) then + delete(sstT) + continue + end if + sstT = where(sstT.le.-1.8,-1.8,sstT) ; set all values below -1.8 to -1.8 + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") ; mask out land (this is redundant for data that is already masked) + basemap = d->LSMASK + lsm = landsea_mask(basemap,sstT&lat,sstT&lon) + sstT = mask(sstT,conform(sstT,lsm,(/1,2/)).ge.1,False) + delete([/lsm,basemap/]) + delete(d) + + sstT = lonFlip(sstT) ; orient longitudes from -180:180 (set to 0:360 in data_read_in function) + if (OPT_CLIMO.eq."Full") then + sstT = rmMonAnnCycTLL(sstT) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sstT + delete(temp_arr&time) + temp_arr&time = cd_calendar(sstT&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sstT = calcMonAnomTLL(sstT,climo) + delete(climo) + end if + coswgt=cos(rad*sstT&lat) + coswgt!0 = "lat" + coswgt&lat= sstT&lat + natl_aa = wgt_areaave(sstT(:,{0:60},{-80:0}),coswgt({0.:60.}),1.0,0) + global_aa = wgt_areaave(sstT(:,{-60:60},:),coswgt({-60.:60.}),1.0,0) + + finarr = new((/2,dimsizes(natl_aa)/),typeof(natl_aa),-999.) ; timeseries plot + finarr!1 = "time" + finarr&time = sstT&time + finarr(0,:) = (/ natl_aa - global_aa /) + finarr(1,:) = (/ runave(finarr(0,:),121,0) /) ; originally 61 + + sstT = (/ sstT - conform(sstT, global_aa, 0) /) ; remove global mean from each timestep of SST anomalies prior to regressions + delete([/natl_aa,global_aa/]) + + finreg = sstT(0,:,:) + finreg = (/ regCoef(finarr(0,:),sstT(lat|:,lon|:,time|:)) /) + finregLP = sstT(0,:,:) + finregLP = (/ regCoef(finarr(1,:),runave(sstT(lat|:,lon|:,time|:),121,0)) /) + delete([/sstT/]) + + do gg = 0,2 + finreg = (/ smth9(finreg,0.5,0.25,True) /) + end do + delete([/coswgt/]) + finreg@syear = syear(ee) + finreg@eyear = eyear(ee) + finregLP@syear = syear(ee) + finregLP@eyear = eyear(ee) + +;---------TAS Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_tas(ee),eyear(ee),eyear_tas(ee)/)))) then + tasreg_plot_flag = 1 + else + if (syear(ee).eq.syear_tas(ee)) then ; check that the start and end years match for ts, tas, and psl + if (eyear(ee).eq.eyear_tas(ee)) then + tasreg_plot_flag = 0 + else + tasreg_plot_flag = 1 + end if + else + tasreg_plot_flag = 1 + end if + end if + + if (tasreg_plot_flag.eq.0) then + tas = data_read_in(paths_tas(ee),"TREFHT",syear_tas(ee),eyear_tas(ee)) + if (isatt(tas,"is_all_missing")) then + tasreg_plot_flag = 1 + delete(tas) + end if + + if (tasreg_plot_flag.eq.0) then ; only continue if both TAS/SST fields are present + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,tas&lat,tas&lon) + tas = mask(tas,conform(tas,lsm,(/1,2/)).eq.0,False) + delete(lsm) + + if (OPT_CLIMO.eq."Full") then + tas = rmMonAnnCycTLL(tas) + else + check_custom_climo(names_tas(ee),syear_tas(ee),eyear_tas(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = tas + delete(temp_arr&time) + temp_arr&time = cd_calendar(tas&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + tas = calcMonAnomTLL(tas,climo) + delete(climo) + end if + finreg_tas = tas(0,:,:) + finreg_tas = (/ regCoef(finarr(0,:),tas(lat|:,lon|:,time|:)) /) + finregLP_tas = tas(0,:,:) + finregLP_tas = (/ regCoef(finarr(1,:),runave(tas(lat|:,lon|:,time|:),121,0)) /) + delete(tas) + end if + end if +;---------PR Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_pr(ee),eyear(ee),eyear_pr(ee)/)))) then + prreg_plot_flag = 1 + else + if (syear(ee).eq.syear_pr(ee)) then ; check that the start and end years match for pr and psl + if (eyear(ee).eq.eyear_pr(ee)) then + prreg_plot_flag = 0 + else + prreg_plot_flag = 1 + end if + else + prreg_plot_flag = 1 + end if + end if + + if (prreg_plot_flag.eq.0) then + pr = data_read_in(paths_pr(ee),"PRECT",syear_pr(ee),eyear_pr(ee)) + if (isatt(pr,"is_all_missing")) then + prreg_plot_flag = 1 + delete(pr) + end if + + if (prreg_plot_flag.eq.0) then ; only continue if both SST/PR fields are present + if (OPT_CLIMO.eq."Full") then + pr = rmMonAnnCycTLL(pr) + else + check_custom_climo(names_pr(ee),syear_pr(ee),eyear_pr(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = pr + delete(temp_arr&time) + temp_arr&time = cd_calendar(pr&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + pr = calcMonAnomTLL(pr,climo) + delete(climo) + end if + finreg_pr = pr(0,:,:) + finreg_pr = (/ regCoef(finarr(0,:),pr(lat|:,lon|:,time|:)) /) + finregLP_pr = pr(0,:,:) + finregLP_pr = (/ regCoef(finarr(1,:),runave(pr(lat|:,lon|:,time|:),121,0)) /) + delete(pr) + end if + end if +;--------------------------------------------------------------------------------------------- + if (tasreg_frame.eq.1.and.tasreg_plot_flag.eq.0) then ; tasreg_frame = flag to create regressions .ps/.png files + tasreg_frame = 0 + end if + if (prreg_frame.eq.1.and.prreg_plot_flag.eq.0) then ; prreg_frame = flag to create regressions .ps/.png files + prreg_frame = 0 + end if +;--------------------------------------------------------------------------------------------- + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.amo."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->amo_pattern_mon = set_varAtts(lonFlip(finreg),"AMO regression pattern (monthly)","","") ; flip longitudes back to running from 0:360. + z->amo_pattern_lowpass_mon = set_varAtts(lonFlip(finregLP),"AMO low-pass regression pattern (monthly)","","") ; flip longitudes back to running from 0:360. + amo_ts = finarr(0,:) + amo_ts@units = "C" + amo_ts_LP = finarr(1,:) + amo_ts_LP@units = "C" + z->amo_timeseries_mon = set_varAtts(amo_ts,"AMO timeseries (monthly)","","") + z->amo_timeseries_lowpass_mon = set_varAtts(amo_ts_LP,"AMO low-pass timeseries (monthly)","","") + delete([/modname,fn,amo_ts,amo_ts_LP/]) + + if (tasreg_plot_flag.eq.0) then + modname = str_sub_str(names_tas(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.amo.tas."+syear_tas(ee)+"-"+eyear_tas(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z_tas = addfile(fn,"c") + z_tas@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z_tas@notes = "Data from "+names_tas(ee)+" from "+syear_tas(ee)+"-"+eyear_tas(ee) + if (OPT_CLIMO.eq."Full") then + z_tas@climatology = syear_tas(ee)+"-"+eyear_tas(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z_tas@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z_tas@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z_tas@Conventions = "CF-1.6" + else + z_tas = addfile(fn,"w") + end if + z_tas->amo_tas_regression_mon = set_varAtts(finreg_tas,"tas regression onto AMO timeseries (monthly)","","") + z_tas->amo_tas_regression_lowpass_mon = set_varAtts(finregLP_tas,"tas low-pass regression onto AMO timeseries (monthly)","","") + delete([/modname,fn,z_tas/]) + end if + if (prreg_plot_flag.eq.0) then + modname = str_sub_str(names_pr(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.amo.pr."+syear_pr(ee)+"-"+eyear_pr(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z_pr = addfile(fn,"c") + z_pr@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z_pr@notes = "Data from "+names_pr(ee)+" from "+syear_pr(ee)+"-"+eyear_pr(ee) + if (OPT_CLIMO.eq."Full") then + z_pr@climatology = syear_pr(ee)+"-"+eyear_pr(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z_pr@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z_pr@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z_pr@Conventions = "CF-1.6" + else + z_pr = addfile(fn,"w") + end if + z_pr->amo_pr_regression_mon = set_varAtts(finreg_pr,"pr regression onto AMO timeseries (monthly)","","") + z_pr->amo_pr_regression_lowpass_mon = set_varAtts(finregLP_pr,"pr low-pass regression onto AMO timeseries (monthly)","","") + delete([/modname,fn,z_pr/]) + end if + end if +;------------------------------------------------------------------------ + iopt = 0 + jave = (7*nyr(ee))/100 + val1 = .95 + val2 = .99 + if (jave.eq.0) then + jave = 1 + end if + pct = 0.1 + spectra_mvf = False ; missing value flag + if (any(ismissing(finarr(0,:)))) then ; check for missing data + print("Missing data detected for "+names(ee)+", not creating AMO spectra") + spectra_mvf = True + if (isfilepresent2("obs_ts").and.ee.eq.0) then + spectra_mvf_obs = True ; missing value flag + end if + else + if (isfilepresent2("obs_ts").and.ee.eq.0) then + spectra_mvf_obs = False ; missing value flag + end if + sdof = specx_anal(dim_standardize(finarr(0,:),0),iopt,jave,pct) + splt1 = specx_ci(sdof,val1,val2) + if (OUTPUT_DATA.eq."True") then + splt1!0 = "ncurves" + splt1&ncurves = ispan(0,3,1) + splt1&ncurves@long_name = "power spectra curves" + splt1&ncurves@units = "1" + splt1!1 = "frequency" + splt1&frequency = sdof@frq + splt1&frequency@units = "1" + splt1@units_info = "df refers to frequency interval; data are standardized so there are no physical units" + splt1@units = "1/df" + splt1@info = "(0,:)=spectrum,(1,:)=Markov red noise spectrum, (2,:)="+val1+"% confidence bound for Markhov, (3,:)="+val2+"% confidence bound for Markhov" + z->amo_spectra = set_varAtts(splt1,"AMO (monthly) power spectra, Markov spectrum and confidence curves","","") + end if + if (isfilepresent2("obs_ts").and.ee.eq.0) then + sdof_obs = sdof + end if + delete([/iopt,jave,pct/]) + end if + if (isvar("z")) then + delete(z) + end if +;========================================================================= + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 0. + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + res@vpYF = 0.95 + res@vpHeightF = 0.3 + res@vpXF = 0.2 + res@vpWidthF = 0.6 + +; res@cnFillMode = "RasterFill" + res@cnLevelSelectionMode = "ExplicitLevels" + if (COLORMAP.eq."0") then + res@cnLevels = fspan(-4.,4.,21) + end if + if (COLORMAP.eq."1") then + res@cnLevels = fspan(-3.2,3.2,17) + end if + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = 0.005 + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnCenterString = names(ee) + res@gsnRightString = "" + + res4 = res ; res4 = pr regression resources + delete(res4@cnLevels) + if (COLORMAP.eq.0) then + res4@cnLevels = (/-5,-4,-3,-2,-1,-.75,-.5,-.25,-.1,0,.1,.25,.5,.75,1,2,3,4,5/) + else + res4@cnLevels = (/-3,-2,-1,-.5,-.1,0,.1,.5,1,2,3/) + end if + + + res2 = True ; res2 = tas regression resources + res2@gsnDraw = False + res2@gsnFrame = False + res2@cnLevelSelectionMode = "ExplicitLevels" + res2@cnLevels = res@cnLevels + + res2@cnLineLabelsOn = False + res2@cnFillOn = True + res2@cnLinesOn = False + res2@cnFillMode = "AreaFill" + res2@lbLabelBarOn = False + res2@cnInfoLabelOn = False + res2@gsnRightString = "" + res2@gsnLeftString = "" + res2@gsnCenterString = "" + res2@gsnAddCyclic = True + + + if (isfilepresent2("obs_ts").and.ee.eq.0) then ; for pattern correlation table + patcor = new((/nsim,dimsizes(finreg&lat),dimsizes(finreg&lon)/),typeof(finreg)) + patcor!1 = "lat" + patcor&lat = finreg&lat + patcor!2 = "lon" + patcor&lon = finreg&lon + patcor(ee,:,:) = (/ finreg /) + end if + if (isfilepresent2("obs_ts").and.ee.ge.1.and.isvar("patcor")) then + patcor(ee,:,:) = (/ totype(linint2(finreg&lon,finreg&lat,finreg,True,patcor&lon,patcor&lat,0),typeof(patcor)) /) + end if + + map(ee) = gsn_csm_contour_map(wks,finreg,res) + mapLP(ee) = gsn_csm_contour_map(wks,finregLP,res) + + if (tasreg_plot_flag.eq.0) then + if (names(ee).eq.names_tas(ee)) then + res@gsnCenterString = names(ee) + else + res@gsnCenterString = names(ee)+" / "+names_tas(ee) + end if + map_sst(ee) = gsn_csm_contour_map(wks,finreg,res) + map_tasreg(ee) = gsn_csm_contour(wks,finreg_tas,res2) + overlay(map_sst(ee),map_tasreg(ee)) + delete(finreg_tas) + + mapLP_sst(ee) = gsn_csm_contour_map(wks,finregLP,res) + mapLP_tasreg(ee) = gsn_csm_contour(wks,finregLP_tas,res2) + overlay(mapLP_sst(ee),mapLP_tasreg(ee)) + delete(finregLP_tas) + end if + delete([/finreg,finregLP/]) + + if (prreg_plot_flag.eq.0) then + res4@gsnCenterString = names_pr(ee) + map_prreg(ee) = gsn_csm_contour_map(wks4,finreg_pr,res4) + delete(finreg_pr) + mapLP_prreg(ee) = gsn_csm_contour_map(wks4,finregLP_pr,res4) + delete(finregLP_pr) + end if + + pres = True + pres@vpXF = 0.07 + pres@trYMinF = 0. + pres@trXMinF = 0.0 +; pres@trYMaxF = 82. + pres@trXMaxF = 0.0832 + pres@tiYAxisString = "Power" ; yaxis + pres@xyLineColor = "black" + pres@gsnFrame = False + pres@gsnDraw = False + + pres@tmXBLabelDeltaF = -.8 + pres@tmXTLabelDeltaF = -.8 + pres@pmLegendDisplayMode = "Never" + pres@xyLineThicknesses = (/3.5,2.,1.,1./) + pres@xyDashPatterns = (/0,0,0,0/) + pres@xyLineColors = (/"foreground","red","blue","green"/) + pres@xyLabelMode = "custom" + pres@xyLineLabelFontColors = pres@xyLineColors + pres@xyExplicitLabels = (/"","",val1*100+"%",val2*100+"%"/) + pres@tmXTOn = True + pres@tmYROn = False + pres@tmXTLabelsOn = True + pres@tmXUseBottom = False + pres@tmXTMode = "Explicit" + pres@tmXBMode = "Explicit" + pres@tmXTValues = (/".00167",".00833",".01667",".02778",".0416",".0556",".0832"/) + pres@tmXTLabels = (/"50","10","5","3","2","1.5","1"/) + pres@tmXBValues = (/".0",".01",".02",".03",".042",".056",".083"/) + pres@tmXBLabels = pres@tmXBValues + pres@tmXTLabelFontHeightF = 0.018 + pres@tmXBLabelFontHeightF = 0.018 + pres@tmYLLabelFontHeightF = 0.018 + pres@tiYAxisString = "Variance" ;"Power (~S~o~N~C~S~2~N~ / cycles mo~S~-1~N~)" ; yaxis + pres@tiXAxisString = "Frequency (cycles mo~S~-1~N~)" + pres@tiMainString = "" + pres@txFontHeightF = 0.015 + pres@xyLineLabelFontHeightF = 0.022 + pres@tiXAxisFontHeightF = 0.025 + pres@tiYAxisFontHeightF = 0.025 + pres@tiMainFontHeightF = 0.03 + pres@gsnRightStringOrthogonalPosF = -0.115 + + pres@tiMainOn = False + pres@gsnCenterString = "Period (years)" + pres@gsnCenterStringFontHeightF = pres@tiYAxisFontHeightF + pres@gsnRightStringFontHeightF = pres@tiYAxisFontHeightF - 0.005 + pres@gsnRightString = syear(ee)+"-"+eyear(ee)+" " + pres@gsnLeftString = "" + if (wks_type.eq."png") then + pres@xyLineThicknessF = 3.5 + res@mpGeophysicalLineThicknessF = 2. + else + pres@xyLineThicknessF = 1.5 + res@mpGeophysicalLineThicknessF = 1. + end if + pres@gsnCenterString = names(ee) + if (spectra_mvf.eq.False) then + pspec(ee) = gsn_csm_xy(wks2,sdof@frq,splt1,pres) + if (isfilepresent2("obs_ts").and.ee.ge.1.and.spectra_mvf_obs.eq.False) then + pres@xyLineColors = (/"gray70","black","black","black"/) + pres@xyCurveDrawOrder = "PreDraw" + pres@gsnCenterString = "" + pres@gsnRightString = "" + pspec_obs(ee) = gsn_csm_xy(wks2,sdof_obs@frq,sdof_obs@spcx,pres) + overlay(pspec(ee),pspec_obs(ee)) + delete(pres@xyCurveDrawOrder) + end if + delete([/sdof,splt1/]) + end if + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnRightString = "" + xyres@gsnLeftString = "" + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + xyres@gsnXYBarChart = False + xyres@gsnAboveYRefLineColor = 185 + xyres@gsnBelowYRefLineColor = 35 + xyres@xyLineThicknessF = 0.1 + xyres@xyLineColor = "gray70" +; xyres@xyLineColors = (/ xyres@gsnAboveYRefLineColor, xyres@gsnBelowYRefLineColor/) + xyres@tiYAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnStringFontHeightF = 0.017 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnStringFontHeightF = 0.024 + end if + xyres@gsnCenterStringOrthogonalPosF = 0.025 + + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnCenterString = "" + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+1.5 + + xyres2 = xyres + delete(xyres2@gsnXYBarChart) + delete(xyres2@gsnAboveYRefLineColor) + delete(xyres2@gsnBelowYRefLineColor) +; delete(xyres2@xyLineColors) + xyres2@xyLineColor = "black" + if (wks_type.eq."png") then + xyres2@xyLineThicknessF = 3.5 + else + xyres2@xyLineThicknessF = 2.5 + end if + + xyres@gsnCenterString = names(ee) + xyplot(ee) = gsn_csm_xy(wks3,fspan(syear(ee),eyear(ee)+.91667,dimsizes(finarr&time)),finarr(0,:),xyres) ; use standardized timeseries + xyplot2(ee) = gsn_csm_xy(wks3,fspan(syear(ee),eyear(ee)+.91667,dimsizes(finarr&time)),finarr(1,:),xyres2) + overlay(xyplot(ee),xyplot2(ee)) + delete([/val1,val2,finarr,res,pres,xyres,xyres2/]) + end do + + if (isvar("patcor")) then ; for pattern correlation table + clat = cos(0.01745329*patcor&lat) +; finpaco = "AMO (Monthly) " ; Must be 18 characters long +; finrms = finpaco + finpr = "AMO (Monthly) " ; Must be 18 characters long + line3 = " " ; Must be 18 characters long + line4 = line3 + header = (/"","Pattern Correlations/RMS Differences Observations vs. Model(s)",""/) + do hh = 1,nsim-1 + dimY = dimsizes(tochar(names(hh))) + nchar = dimY + nchar = where(nchar.le.10,10,nchar) + if (dimY.lt.10) then + ntb = "" + do ii = 0,10-dimY-1 + ntb = ntb+" " + end do + ntb = ntb+names(hh) + else + ntb = names(hh) + end if + + ntc = "" + do ii = 0,nchar-1 + ntc = ntc+"-" + end do + format2 = "%"+(nchar-5+1)+".2f" + format3 = "%4.2f" + line3 = line3+" "+ntb + line4 = line4+" "+ntc + if (all(ismissing(patcor(hh,:,:)))) then + finpr = finpr+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr = finpr+sprintf(format2,(pattern_cor(patcor(0,:,:),patcor(hh,:,:),clat,0)))+"/"+sprintf(format3,(wgt_arearmse(patcor(0,:,:),patcor(hh,:,:),clat,1.0,0))) + end if + end do + if (dimsizes(tochar(line4)).ge.8190) then ; system or fortran compiler limit + print("Metrics table warning: Not creating metrics table as size of comparison results in a invalid ascii row size.") + else + write_table(getenv("OUTDIR")+"metrics.amo.txt","w",[/header/],"%s") + write_table(getenv("OUTDIR")+"metrics.amo.txt","a",[/line3/],"%s") + write_table(getenv("OUTDIR")+"metrics.amo.txt","a",[/line4/],"%s") + write_table(getenv("OUTDIR")+"metrics.amo.txt","a",[/finpr/],"%s") + end if + delete([/finpr,line3,line4,format2,format3,nchar,ntc,clat,patcor,ntb,dimY,header/]) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.55 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + panres@lbLabelFontHeightF = 0.013 + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + + panres@txString = "AMO (Monthly)" + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + gsn_panel2(wks,map,(/nrow,ncol/),panres) + panres@txString = "AMO Low Pass (Monthly)" + gsn_panel2(wks,mapLP,(/nrow,ncol/),panres) + + if (tasreg_frame.eq.0) then + panres@txString = "AMO SST/TAS Regressions (Monthly)" + gsn_panel2(wks,map_sst,(/nrow,ncol/),panres) + panres@txString = "AMO SST/TAS Low Pass Regressions (Monthly)" + gsn_panel2(wks,mapLP_sst,(/nrow,ncol/),panres) + end if + delete(wks) + + if (prreg_frame.eq.0) then + panres@txString = "AMO PR Regressions (Monthly)" + gsn_panel2(wks4,map_prreg,(/nrow,ncol/),panres) + panres@txString = "AMO PR Low Pass Regressions (Monthly)" + gsn_panel2(wks4,mapLP_prreg,(/nrow,ncol/),panres) + end if + delete(wks4) + + delete(panres@gsnPanelLabelBar) + panres@txString = "AMO (Monthly)" + gsn_panel2(wks2,pspec,(/nrow,ncol/),panres) + delete(wks2) + + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + panres@txString = "AMO (Monthly)" + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) ;(/nsim/2+1,nsim/8+1/) + end if + gsn_panel2(wks3,xyplot,lp,panres) + delete(wks3) + delete([/map,pspec,syear,eyear,nyr,nyr_max,SCALE_TIMESERIES,lp/]) +;-------------------------------------------------------------------------------------------------- + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + if (tasreg_frame.eq.0) then + system("mv "+OUTDIR+"amo.000001.png "+OUTDIR+"amo.png") + system("mv "+OUTDIR+"amo.000002.png "+OUTDIR+"amo.lp.png") + system("mv "+OUTDIR+"amo.000003.png "+OUTDIR+"amo.tasreg.png") + system("mv "+OUTDIR+"amo.000004.png "+OUTDIR+"amo.lp.tasreg.png") + else + system("mv "+OUTDIR+"amo.000001.png "+OUTDIR+"amo.png") + system("mv "+OUTDIR+"amo.000002.png "+OUTDIR+"amo.lp.png") + end if + if (prreg_frame.eq.0) then + system("mv "+OUTDIR+"amo.prreg.000001.png "+OUTDIR+"amo.prreg.png") + system("mv "+OUTDIR+"amo.prreg.000002.png "+OUTDIR+"amo.lp.prreg.png") + end if + else + system("psplit "+OUTDIR+"amo.ps "+OUTDIR+"amo_nn") + if (tasreg_frame.eq.0) then + system("mv "+OUTDIR+"amo_nn0001.ps "+OUTDIR+"amo.ps") + system("mv "+OUTDIR+"amo_nn0002.ps "+OUTDIR+"amo.lp.ps") + system("mv "+OUTDIR+"amo_nn0003.ps "+OUTDIR+"amo.tasreg.ps") + system("mv "+OUTDIR+"amo_nn0004.ps "+OUTDIR+"amo.lp.tasreg.ps") + else + system("mv "+OUTDIR+"amo_nn0001.ps "+OUTDIR+"amo.ps") + system("mv "+OUTDIR+"amo_nn0002.ps "+OUTDIR+"amo.lp.ps") + end if + if (prreg_frame.eq.0) then + system("psplit "+OUTDIR+"amo.prreg.ps "+OUTDIR+"amo_oo") + system("mv "+OUTDIR+"amo_oo0001.ps "+OUTDIR+"amo.prreg.ps") + system("mv "+OUTDIR+"amo_oo0002.ps "+OUTDIR+"amo.lp.prreg.ps") + end if + end if + print("Finished: amo.ncl") +end + diff --git a/lib/externals/CVDP/ncl_scripts/amoc.ncl b/lib/externals/CVDP/ncl_scripts/amoc.ncl new file mode 100644 index 000000000..11ec3aacc --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/amoc.ncl @@ -0,0 +1,933 @@ +; Calculates MOC means/standard deviations, AMOC EOF1/PC1, +; regressions onto AMOC PC1, and lag correlations vs. AMO +; +; Variables used: moc, ts, tas +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: amoc.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_moc") + na = asciiread("namelist_byvar/namelist_moc",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + +;-----------TS/TAS read in for AMOC regressions------------------------------------------ + + nsim_trefht = numAsciiRow("namelist_byvar/namelist_trefht") + na_trefht = asciiread("namelist_byvar/namelist_trefht",(/nsim_trefht/),"string") + names_trefht = new(nsim_trefht,"string") + paths_trefht = new(nsim_trefht,"string") + syear_trefht = new(nsim_trefht,"integer",-999) + eyear_trefht = new(nsim_trefht,"integer",-999) + + do gg = 0,nsim_trefht-1 + names_trefht(gg) = str_strip(str_get_field(na_trefht(gg),1,delim)) + paths_trefht(gg) = str_strip(str_get_field(na_trefht(gg),2,delim)) + syear_trefht(gg) = stringtointeger(str_strip(str_get_field(na_trefht(gg),3,delim))) + eyear_trefht(gg) = stringtointeger(str_strip(str_get_field(na_trefht(gg),4,delim))) + end do + delete(na_trefht) + nyr_trefht = eyear_trefht-syear_trefht+1 + + nsim_ts = numAsciiRow("namelist_byvar/namelist_ts") + na_ts = asciiread("namelist_byvar/namelist_ts",(/nsim_ts/),"string") + names_ts = new(nsim_ts,"string") + paths_ts = new(nsim_ts,"string") + syear_ts = new(nsim_ts,"integer",-999) + eyear_ts = new(nsim_ts,"integer",-999) + + do gg = 0,nsim_ts-1 + names_ts(gg) = str_strip(str_get_field(na_ts(gg),1,delim)) + paths_ts(gg) = str_strip(str_get_field(na_ts(gg),2,delim)) + syear_ts(gg) = stringtointeger(str_strip(str_get_field(na_ts(gg),3,delim))) + eyear_ts(gg) = stringtointeger(str_strip(str_get_field(na_ts(gg),4,delim))) + end do + delete(na_ts) + nyr_ts = eyear_ts-syear_ts+1 + + pi=4.*atan(1.0) + rad=(pi/180.) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_mean = gsn_open_wks(wks_type,getenv("OUTDIR")+"amoc.mean.ann") + wks_stddev = gsn_open_wks(wks_type,getenv("OUTDIR")+"amoc.stddev.ann") + wks_amoc = gsn_open_wks(wks_type,getenv("OUTDIR")+"amoc.ann") + wks_amoc_ts = gsn_open_wks(wks_type,getenv("OUTDIR")+"amoc.timeseries.ann") + wks_amoc_powspec = gsn_open_wks(wks_type,getenv("OUTDIR")+"amoc.powspec.ann") + wks_amoc_sstreg = gsn_open_wks(wks_type,getenv("OUTDIR")+"amoc.sstreg.ann") + wks_amoc_tasreg = gsn_open_wks(wks_type,getenv("OUTDIR")+"amoc.tasreg.ann") + wks_amoc_amo = gsn_open_wks(wks_type,getenv("OUTDIR")+"amoc_amo.leadlag.ann") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_mean,"rainbow+white") + gsn_define_colormap(wks_stddev,"rainbow+white") + gsn_define_colormap(wks_amoc,"ncl_default") + gsn_define_colormap(wks_amoc_ts,"ncl_default") + gsn_define_colormap(wks_amoc_powspec,"ncl_default") + gsn_define_colormap(wks_amoc_sstreg,"ncl_default") + gsn_define_colormap(wks_amoc_tasreg,"ncl_default") + gsn_define_colormap(wks_amoc_amo,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_mean,"BlueDarkRed18") + gsn_define_colormap(wks_stddev,"cb_rainbow") + gsn_define_colormap(wks_amoc,"BlueDarkRed18") + gsn_define_colormap(wks_amoc_ts,"ncl_default") + gsn_define_colormap(wks_amoc_powspec,"cb_9step") + gsn_define_colormap(wks_amoc_sstreg,"BlueDarkRed18") + gsn_define_colormap(wks_amoc_tasreg,"BlueDarkRed18") + gsn_define_colormap(wks_amoc_amo,"ncl_default") + end if + plot_mean_ann = new(nsim,"graphic") + plot_stddev_ann = new(nsim,"graphic") + plot_amoc_ann = new(nsim,"graphic") + plot_amoc_ts_ann = new(nsim,"graphic") + plot_amoc_powspec_ann = new(nsim,"graphic") + plot_amoc_sstreg_ann = new(nsim,"graphic") + plot_amoc_tasreg_ann = new(nsim,"graphic") + plot_amoc_amo_ann = new(nsim,"graphic") + if (isfilepresent2("obs_moc")) then + pspec_obs = new(nsim,"graphic") + end if + + do ee = 0,nsim-1 + mocT = data_read_in_ocean_MOC(paths(ee),"MOC",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(mocT,"is_all_missing")) then + delete(mocT) + continue + end if + lat = tofloat(mocT&lat) + lev = tofloat(mocT&lev) + ny = dimsizes(lat) + nz = dimsizes(lev) +;----------------------------------------------------------------------------------- +; compute annual means and standard deviations +;----------------------------------------------------------------------------------- + moc_ann = runave_n_Wrap(mocT,12,0,0) + moc_mean_ann = dim_avg_n_Wrap(moc_ann(5::12,:,:),0) + delete(moc_ann) + + if (OPT_CLIMO.eq."Full") then + mocT = rmMonAnnCycTLL(mocT) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = mocT + delete(temp_arr&time) + temp_arr&time = cd_calendar(mocT&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + mocT = calcMonAnomTLL(mocT,climo) + delete(climo) + end if + moc_ann2 = runave_n_Wrap(mocT,12,0,0) + moc_sd_ann = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),moc_ann2(5::12,:,:),False,False,0),0) + copy_VarMeta(moc_mean_ann,moc_sd_ann) + delete(moc_ann2) + + moc_sd_ann = where(moc_sd_ann.lt.0.001,moc_sd_ann@_FillValue,moc_sd_ann) + moc_mean_ann = where(ismissing(moc_sd_ann),moc_mean_ann@_FillValue,moc_mean_ann) +;----------------------------------------------------------------------------------- +;-----calculate AMOC EOF1 +;----------------------------------------------------------------------------------- + temp = runave_n_Wrap(mocT,12,0,0) ; form annual averages + amoc = temp(5::12,:,:) + delete([/temp,mocT/]) + + atl_begin = ind_nearest_coord (-33.0, lat, 0) ; set missing values based on variance, and mask Atlantic south of 33S + vareps = 1.e-6 + amocvar = conform(amoc,dim_variance_n_Wrap(amoc,0),(/1,2/)) + amoc@_FillValue = 1.e20 + amoc(:,:,0:atl_begin-1) = amoc@_FillValue + amoc = where(amocvar.lt.vareps,amoc@_FillValue,amoc) + delete(amocvar) + + dlat = lat ; Compute latitudinal weights (in meters) + rEarth = 6.37122e8 ; Earth radius in m + do iy=0,ny-1 + if (iy.gt.0.and.iy.lt.ny-1) then + dy0 = (lat(iy)-lat(iy-1))/2.0 + dy1 = (lat(iy+1)-lat(iy))/2.0 + dlat(iy) = (dy0+dy1)*rEarth + delete(dy0) + delete(dy1) + end if + if (iy.eq.0) then + dy1 = (lat(iy+1)-lat(iy))/2.0 + dlat(iy) = (2.*dy1)*rEarth + delete(dy1) + end if + if (iy.eq.ny-1) then + dy0 = (lat(iy)-lat(iy-1))/2.0 + dlat(iy) = (2.*dy0)*rEarth + delete(dy0) + end if + end do + + dz = lev ; compute vertical weights (in meters) + do iz=0,nz-1 + if (iz.gt.0.and.iz.lt.nz-1) then + dz(iz) = (lev(iz)-lev(iz-1))/2.0 + (lev(iz+1)-lev(iz))/2.0 + end if + if (iz.eq.0) then + dz(iz) = (lev(iz+1)-lev(iz))/2.0 + end if + if (iz.eq.nz-1) then + dz(iz) = (lev(iz)-lev(iz-1))/2.0 + end if + end do + + test = dlat(0)*dz(0) + wgt = new((/nz,ny/),typeof(test)) ; weight the data + delete(test) + do iz=0,nz-1 + do iy=0,ny-1 + wgt(iz,iy) = dlat(iy)*dz(iz) + end do + end do + amocW = amoc*conform(amoc, wgt, (/1,2/)) ; same units as "amoc" + delete(wgt) + copy_VarMeta(amoc,amocW) + amocW@long_name = "area weighted "+amoc@long_name + + workeof = eofunc_Wrap(amocW(lev|:,lat|:,time|:), 3, 75) + workeof_ts = eofunc_ts_Wrap (amocW(lev|:,lat|:,time|:), workeof, False) + delete(amocW) + amoc_pc_ann = dim_standardize(workeof_ts(0,:),0) + moc_reg_ann = amoc(0,:,:) + moc_reg_ann = (/ regCoef(amoc_pc_ann,amoc(lev|:,lat|:,time|:)) /) + sig_pcv = eofunc_north2(workeof@pcvar,dimsizes(amoc_pc_ann),False) + if (sig_pcv(0)) then ; if True then significant + moc_reg_ann@pcvar = tofloat(sprintf("%4.1f", workeof@pcvar(0)))+"%*" + else + moc_reg_ann@pcvar = tofloat(sprintf("%4.1f", workeof@pcvar(0)))+"%" + end if + delete(sig_pcv) + + delete([/atl_begin,lat,lev,dz,dlat,amoc,workeof,workeof_ts,ny,nz/]) + if (max(moc_reg_ann&lev).ge.2000) then + if (.not.ismissing(moc_reg_ann({2000.},{38}))) then + if (moc_reg_ann({2000.},{38}).lt.0) then ; arbitrary attempt to make all plots have the same sign.. + moc_reg_ann = moc_reg_ann*-1. + amoc_pc_ann = amoc_pc_ann*-1. + end if + end if + end if +;---------------------------------------------------------------------------------------- + iopt = 0 ; calculate spectra of AMOC PC1 + jave = (1*nyr(ee))/100 + if (jave.eq.0) then + jave = 1 + end if + val1 = .95 + val2 = .99 + pct = 0.1 + spectra_mvf = False ; missing value flag for amoc + spectra_mvf_obs = True ; missing value flag for obs amoc + if (any(ismissing(amoc_pc_ann))) then + print("Missing data detected for "+names(ee)+", not creating AMOC spectra") + spectra_mvf = True + else + if (isfilepresent2("obs_moc").and.ee.eq.0) then + spectra_mvf_obs = False ; missing value flag for obs amoc + end if + sdof = specx_anal(amoc_pc_ann,iopt,jave,pct) + splt1 = specx_ci(sdof,val1,val2) + splt1!0 = "ncurves" + splt1&ncurves = ispan(0,3,1) + splt1&ncurves@long_name = "power spectra curves" + splt1&ncurves@units = "1" + splt1!1 = "frequency2" + splt1&frequency2 = sdof@frq + splt1&frequency2@long_name = "power spectra frequency" + splt1&frequency2@units = "1" + splt1@units_info = "df refers to frequency interval; data are standardized so there are no physical units" + splt1@units = "1/df" + splt1@info = "(0,:)=spectrum,(1,:)=Markov red noise spectrum, (2,:)="+val1+"% confidence bound for Markhov, (3,:)="+val2+"% confidence bound for Markhov" + if (isfilepresent2("obs_moc").and.ee.eq.0) then + sdof_obs = sdof + end if + delete([/iopt,jave,pct/]) + end if +;-------------------Read in TS and TAS for regressions onto PC1 and for AMO calculation---------------------------------------- + if (syear(ee).eq.syear_ts(ee)) then + if (eyear(ee).eq.eyear_ts(ee)) then +; print("Years match") + sstreg_plot_flag = 0 + else +; print("End years do not match, skipping SST regressions in psl.nam_nao.ncl.") + sstreg_plot_flag = 1 + end if + else +; print("Start years do not match, skipping SST regressions in psl.nam_nao.ncl.") + sstreg_plot_flag = 1 + end if + + if (sstreg_plot_flag.eq.0) then + sst = data_read_in(paths_ts(ee),"TS",syear_ts(ee),eyear_ts(ee)) + + sst = where(sst.le.-1.8,-1.8,sst) + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,sst&lat,sst&lon) + sst = mask(sst,conform(sst,lsm,(/1,2/)).ge.1,False) + delete([/lsm,basemap/]) + delete(d) + + if (OPT_CLIMO.eq."Full") then + sst = rmMonAnnCycTLL(sst) + else + check_custom_climo(names_ts(ee),syear_ts(ee),eyear_ts(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sst + delete(temp_arr&time) + temp_arr&time = cd_calendar(sst&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sst = calcMonAnomTLL(sst,climo) + delete(climo) + end if + temp = runave_n_Wrap(sst,12,0,0) ; form annual averages + sst_ann = temp(5::12,:,:) + delete([/temp,sst/]) + + sst_reg_ann = sst_ann(0,:,:) ; SST regression onto AMOC PC1 + sst_reg_ann = (/ regCoef(amoc_pc_ann,sst_ann(lat|:,lon|:,time|:)) /) + +; Compute AMO timeseries + sst_ann = lonFlip(sst_ann) ; orient longitudes from -180:180 (set to 0:360 in data_read_in function) for AMO calculation + coswgt=cos(rad*sst_ann&lat) + coswgt!0 = "lat" + coswgt&lat= sst_ann&lat + natl_aa = wgt_areaave(sst_ann(:,{0:60},{-80:0}),coswgt({0.:60.}),1.0,0) + global_aa = wgt_areaave(sst_ann(:,{-60:60},:),coswgt({-60.:60.}),1.0,0) + + AMO = new((/dimsizes(natl_aa)/),"float",-999.) ; timeseries plot + AMO!0 = "time" + AMO&time = sst_ann&time + AMO = (/ natl_aa - global_aa /) + delete([/coswgt,natl_aa,global_aa,sst_ann/]) + end if +;------------------------------------------------------------------------------------------------------------- + if (syear(ee).eq.syear_trefht(ee)) then + if (eyear(ee).eq.eyear_trefht(ee)) then +; print("Years match") + tasreg_plot_flag = 0 + else +; print("End years do not match, skipping SST regressions in psl.nam_nao.ncl.") + tasreg_plot_flag = 1 + end if + else +; print("Start years do not match, skipping SST regressions in psl.nam_nao.ncl.") + tasreg_plot_flag = 1 + end if + + if (tasreg_plot_flag.eq.0) then + tas = data_read_in(paths_trefht(ee),"TREFHT",syear_trefht(ee),eyear_trefht(ee)) + if (OPT_CLIMO.eq."Full") then + tas = rmMonAnnCycTLL(tas) + else + check_custom_climo(names_trefht(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = tas + delete(temp_arr&time) + temp_arr&time = cd_calendar(tas&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + tas = calcMonAnomTLL(tas,climo) + delete(climo) + end if + + temp = runave_n_Wrap(tas,12,0,0) ; form annual averages + tas_ann = temp(5::12,:,:) + delete([/temp,tas/]) + + tas_reg_ann = tas_ann(0,:,:) ; TAS regression onto AMOC PC1 + tas_reg_ann = (/ regCoef(amoc_pc_ann,tas_ann(lat|:,lon|:,time|:)) /) + delete(tas_ann) + end if +;---------------compute AMOC/AMO lead/lags----------------------------------------------------------------------------- + if (nyr(ee).ge.90.and.isvar("AMO")) then ; need a minimum number of years to compute lead/lag correlations + nwt = 51 + pda = 15 ; longest period + pdb = 1 ; shortest period + fca = 1./pda ; ==> lowest allowed frequency + fcb = 1./pdb ; ==> highest allowed frequency + ihp = 0 ; 0 ==> low pass filter, fcb ignored + nsigma = 1. + twgt = filwgts_lanczos (nwt, ihp, fca, fcb, nsigma) + AMO_wgt = wgt_runave_Wrap(AMO,twgt,0) + amoc_pc_ann_wgt = wgt_runave_Wrap(amoc_pc_ann,twgt,0) + + mxlag = 15 + x_Lead_y = esccr(amoc_pc_ann_wgt,AMO_wgt,mxlag) + y_Lead_x = esccr(AMO_wgt,amoc_pc_ann_wgt,mxlag) ; switch the order of the series + + ccr = new ( 2*mxlag+1, float) + ccr(0:mxlag-1) = y_Lead_x(1:mxlag:-1) ; "negative lag", -1 reverses order + ccr(mxlag:) = x_Lead_y(0:mxlag) ; "positive lag" + delete([/x_Lead_y,y_Lead_x,AMO_wgt,amoc_pc_ann_wgt/]) + end if + if (sstreg_plot_flag.eq.0) then + delete(AMO) + end if +;--------------------------------------------------------------------------------------------- + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.amoc."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + + if (spectra_mvf.eq.False) then + z->amoc_spectra_ann = set_varAtts(splt1,"AMOC (monthly) power spectra, Markov spectrum and confidence curves","","") + end if + if (nyr(ee).ge.90.and.isvar("ccr")) then + time_lag_cor = ispan(mxlag*-1,mxlag,1) + time_lag_cor@units = "months since 0000-01-01 00:00:00" + time_lag_cor@long_name = "Time" + time_lag_cor@standard_name = "time" + time_lag_cor@calendar = "standard" + time_lag_cor!0 = "time_lag_cor" + time_lag_cor&time_lag_cor = time_lag_cor + ccr!0 = "time_lag_cor" + ccr&time_lag_cor = time_lag_cor + ccr@long_name = "AMOC AMO lead lag correlation" + z->amoc_amo_lag_cor = set_varAtts(ccr,"","1","") + delete(time_lag_cor) + end if + TIME = ispan(0,dimsizes(amoc_pc_ann)-1,1) + TIME@units = "years since "+syear(ee)+"-01-15 00:00:00" + TIME@long_name = "Time" + TIME@standard_name = "time" + TIME@calendar = "standard" + TIME!0 = "TIME" + TIME&TIME = TIME + amoc_pc_ann!0 = "TIME" + amoc_pc_ann&TIME = TIME + amoc_pc_ann@long_name = "AMOC pc1 timeseries (annual)" + z->amoc_timeseries_ann = set_varAtts(amoc_pc_ann,"","1","") + lat_amoc = moc_reg_ann&lat + lat_amoc!0 = "lat_amoc" + lat_amoc&lat_amoc = lat_amoc + delete(moc_reg_ann&lat) + moc_reg_ann!1 = "lat_amoc" + moc_reg_ann&lat_amoc = lat_amoc + delete(moc_mean_ann&lat) + moc_mean_ann!1 = "lat_amoc" + moc_mean_ann&lat_amoc = lat_amoc + delete(moc_sd_ann&lat) + moc_sd_ann!1 = "lat_amoc" + moc_sd_ann&lat_amoc = lat_amoc + z->amoc_mean_ann = set_varAtts(moc_mean_ann,"AMOC mean (annual)","","") + z->amoc_stddev_ann = set_varAtts(moc_sd_ann,"AMOC standard deviation (annual)","","") + z->amoc_pattern_ann = set_varAtts(moc_reg_ann,"AMOC regression onto AMOC principal component timeseries (annual)","","") + delete([/modname,fn,TIME,lat_amoc/]) + delete(z) + + if (sstreg_plot_flag.eq.0) then + modname = str_sub_str(names_ts(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.amoc.ts."+syear_ts(ee)+"-"+eyear_ts(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_ts(ee)+" from "+syear_ts(ee)+"-"+eyear_ts(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_ts(ee)+"-"+eyear_ts(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + else + z = addfile(fn,"w") + end if + z->amoc_sst_regression_ann = set_varAtts(sst_reg_ann,"sst regression onto AMOC principal component timeseries (annual)","","") + delete(z) + end if + if (tasreg_plot_flag.eq.0) then + modname = str_sub_str(names_trefht(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.amoc.tas."+syear_trefht(ee)+"-"+eyear_trefht(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_trefht(ee)+" from "+syear_trefht(ee)+"-"+eyear_trefht(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_trefht(ee)+"-"+eyear_trefht(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + else + z = addfile(fn,"w") + end if + z->amoc_tas_regression_ann = set_varAtts(tas_reg_ann,"tas regression onto AMOC PC1 (annual)","","") + delete(z) + end if + end if + + moc_mean_ann&lev = moc_mean_ann&lev/1000. + moc_mean_ann&lev@units = "km" + moc_sd_ann&lev = moc_sd_ann&lev/1000. + moc_sd_ann&lev@units = "km" + moc_reg_ann&lev = moc_reg_ann&lev/1000. + moc_reg_ann&lev@units = "km" +;======================================================================================================================= + mocres = True ; plot mods desired + mocres@gsnDraw = False + mocres@gsnFrame = False + mocres@cnFillOn = True ; turn on color fill + mocres@cnMissingValFillColor = "gray50" + mocres@cnMissingValFillPattern = 0 + mocres@cnLinesOn = True + mocres@cnLineLabelsOn = False +; mocres@cnLineLabelFontColor = "white" +; mocres@cnLineLabelBackgroundColor = -1 + mocres@lbLabelBarOn = False + + mocres@cnInfoLabelOn = False ; Turn off informational label + mocres@cnLevelSelectionMode = "ExplicitLevels" ; manually set the contour levels + if (nsim.le.7) then + mocres@tmXBLabelFontHeightF = 0.01 + mocres@tmYLLabelFontHeightF = 0.01 + mocres@gsnLeftStringFontHeightF = 0.0125 + mocres@gsnCenterStringFontHeightF = 0.0125 + mocres@gsnRightStringFontHeightF = 0.011 + else + mocres@tmXBLabelFontHeightF = 0.014 + mocres@tmYLLabelFontHeightF = 0.014 + mocres@gsnLeftStringFontHeightF = 0.017 + mocres@gsnCenterStringFontHeightF = 0.017 + mocres@gsnRightStringFontHeightF = 0.0155 + end if + mocres@tiYAxisFontHeightF = mocres@tmXBLabelFontHeightF + mocres@gsnCenterStringOrthogonalPosF = -0.96 + mocres@gsnCenterStringParallelPosF = 0.80 + + mocres@tmXBLabelsOn = True + mocres@tmXTLabelsOn = False + mocres@tmXTOn = False + mocres@tmYRLabelsOn = False + mocres@tmYROn = False + mocres@cnMonoLineThickness = False + mocres@cnMonoLineDashPattern = False + mocres@vpWidthF = 0.375 + mocres@vpHeightF = 0.28 + + mocres@trYReverse = True ; reverses y-axis + mocres@gsnYAxisIrregular2Linear = True + mocres@gsnXAxisIrregular2Linear = True + mocres@tiYAxisString= "depth (km)" + mocres@tiXAxisString= "" + mocres@gsnCenterString = "" + mocres@trXMinF = 0. + mocres@trXMaxF = 90. + mocres@tmXBMode = "Explicit" + mocres@tmXBValues = (/0.,30.,60.,90./) + mocres@tmXBLabels = (/"0~S~o~N~N","30~S~o~N~N","60~S~o~N~N","90~S~o~N~N"/) + + mocres@gsnCenterString = syear(ee)+"-"+eyear(ee) + mocres@gsnRightString = moc_mean_ann@units + mocres@gsnLeftString = names(ee) + + + mocres@cnLevels = ispan(-4,28,2) + mocres@cnLineThicknesses = (/1,1,2,1,1,1,1,2,1,1,1,1,2,1,1,1,1/) + mocres@cnLineDashPatterns = (/1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/) + plot_mean_ann(ee) = gsn_csm_contour(wks_mean,moc_mean_ann,mocres) + delete(moc_mean_ann) + delete(mocres@cnLevels) + delete(mocres@cnLineThicknesses) + delete(mocres@cnLineDashPatterns) + + mocres@cnLevels = (/.1,.3,.5,1.0,1.5,2.0,2.5,3.0,4.0,5.0/) + if (COLORMAP.eq.0) then + mocres@cnFillColors = (/20,38,54,80,95,125,175,185,195,205,236/) + end if + if (COLORMAP.eq.1) then + mocres@cnFillColors = (/14,23,35,47,63,79,95,111,124,155,175/) + end if + plot_stddev_ann(ee) = gsn_csm_contour(wks_stddev,moc_sd_ann,mocres) + delete(moc_sd_ann) + delete(mocres@cnLevels) + delete(mocres@cnFillColors) + + mocres@cnLevels = fspan(-2,2,41) + mocres@cnMonoLineThickness = True + mocres@cnMonoLineDashPattern = True + mocres@cnLineDashPattern = 0 + mocres@gsnCenterString = syear(ee)+"-"+eyear(ee) + mocres@gsnRightString = moc_reg_ann@pcvar + mocres@gsnLeftString = names(ee) + plot_amoc_ann(ee) = gsn_csm_contour(wks_amoc,moc_reg_ann,mocres) + delete(moc_reg_ann) + delete(mocres) + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnXYBarChart = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + xyres@gsnAboveYRefLineColor = 185 + xyres@gsnBelowYRefLineColor = 35 + if (wks_type.eq."png") then + xyres@xyLineThicknessF = .5 + else + xyres@xyLineThicknessF = .2 + end if + xyres@xyLineColor = "gray52" + xyres@tiYAxisString = "" + xyres@tiXAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnStringFontHeightF = 0.017 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnStringFontHeightF = 0.024 + end if + xyres@gsnCenterStringOrthogonalPosF = 0.025 + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnLeftString = "" + xyres@gsnRightString = "" + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+1.5 + + xyres@gsnCenterString = names(ee) + plot_amoc_ts_ann(ee) = gsn_csm_xy(wks_amoc_ts,ispan(syear(ee),eyear(ee),1),amoc_pc_ann,xyres) ; use standardized timeseries + delete(amoc_pc_ann) + delete(xyres) + + pres = True + pres@vpXF = 0.07 + pres@trYMinF = 0. + pres@trXMinF = 0.0 + pres@trXMaxF = 0.5 + pres@tiYAxisString = "Power" ; yaxis + pres@xyLineColor = "black" + pres@gsnFrame = False + pres@gsnDraw = False + + pres@tmXBLabelDeltaF = -.8 + pres@tmXTLabelDeltaF = -.8 + pres@pmLegendDisplayMode = "Never" + pres@xyLineThicknesses = (/3.5,2.,1.,1./) + pres@xyDashPatterns = (/0,0,0,0/) + pres@xyLineColors = (/"foreground","red","blue","green"/) + pres@xyLabelMode = "custom" + pres@xyLineLabelFontColors = pres@xyLineColors + pres@xyExplicitLabels = (/"","",val1*100+"%",val2*100+"%"/) + pres@tmXTOn = True + pres@tmYROn = False + pres@tmXTLabelsOn = True + pres@tmXUseBottom = False + pres@tmXTMode = "Explicit" + pres@tmXTValues = (/".02",".10",".20",".3333",".50"/) + pres@tmXTLabels = (/"50","10","5","3","2"/) + + pres@tmXTLabelFontHeightF = 0.018 + pres@tmXBLabelFontHeightF = 0.018 + pres@tmYLLabelFontHeightF = 0.018 + pres@tiYAxisString = "Variance" ;"Power (~S~o~N~C~S~2~N~ / cycles mo~S~-1~N~)" ; yaxis + pres@tiXAxisString = "Frequency (cycles mo~S~-1~N~)" + pres@tiMainString = "" + pres@txFontHeightF = 0.015 + pres@xyLineLabelFontHeightF = 0.022 + pres@tiXAxisFontHeightF = 0.025 + pres@tiYAxisFontHeightF = 0.025 + pres@tiMainFontHeightF = 0.03 + pres@gsnRightStringOrthogonalPosF = -0.115 + + pres@tiMainOn = False + pres@gsnCenterString = "Period (years)" + pres@gsnCenterStringFontHeightF = pres@tiYAxisFontHeightF + pres@gsnRightStringFontHeightF = pres@tiYAxisFontHeightF - 0.005 + pres@gsnRightString = "" + pres@gsnLeftString = "" + pres@gsnCenterString = names(ee) + pres@gsnRightString = syear(ee)+"-"+eyear(ee)+" " + if (spectra_mvf.eq.False) then + plot_amoc_powspec_ann(ee) = gsn_csm_xy(wks_amoc_powspec,sdof@frq,splt1,pres) + if (isfilepresent2("obs_moc").and.ee.ge.1.and.spectra_mvf_obs.eq.False) then + pres@xyLineColors = (/"gray70","black","black","black"/) + pres@xyCurveDrawOrder = "PreDraw" + pres@gsnCenterString = "" + pres@gsnRightString = "" + pspec_obs(ee) = gsn_csm_xy(wks2,sdof_obs@frq,sdof_obs@spcx,pres) + overlay(plot_amoc_powspec_ann(ee),pspec_obs(ee)) + delete(pres@xyCurveDrawOrder) + end if + delete([/splt1,sdof/]) + end if + delete(pres) + + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 0. + res@mpOutlineOn = True + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@gsnDraw = False + res@gsnFrame = False + res@vpYF = 0.95 + res@vpHeightF = 0.3 + res@vpXF = 0.2 + res@vpWidthF = 0.6 + +; res@cnFillMode = "RasterFill" + res@cnLevelSelectionMode = "ExplicitLevels" + if (COLORMAP.eq."0") then + res@cnLevels = fspan(-.5,.5,21) + end if + if (COLORMAP.eq."1") then + res@cnLevels = fspan(-.4,.4,17) + end if + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = 0.005 + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnCenterString = names(ee) + res@gsnRightString = "" + + if (sstreg_plot_flag.eq.0) then + plot_amoc_sstreg_ann(ee) = gsn_csm_contour_map(wks_amoc_sstreg,sst_reg_ann,res) + delete(sst_reg_ann) + end if + if (tasreg_plot_flag.eq.0) then + plot_amoc_tasreg_ann(ee) = gsn_csm_contour_map(wks_amoc_tasreg,tas_reg_ann,res) + delete(tas_reg_ann) + end if + delete(res) + + res2 = True + res2@gsnDraw = False + res2@gsnFrame = False + res2@trYMinF = -1. ; min((/-0.4,min(ccr)/)) + res2@trYMaxF = 1. ; max((/0.6,max(ccr)/)) + res2@vpWidthF = 0.6 + res2@vpHeightF = 0.4 + res2@gsnYRefLine = 0.0 + res2@gsnYRefLineColor = "gray42" + res2@gsnXRefLine = 0.0 + res2@gsnXRefLineColor = "gray42" + res2@xyLineColor = "royalblue" + if (wks_type.eq."png") then + res2@xyLineThicknessF = 3.5 + else + res2@xyLineThicknessF = 1.75 + end if + if (nsim.le.5) then + res2@tmXBLabelFontHeightF = 0.0125 + res2@tmYLLabelFontHeightF = 0.0125 + res2@gsnLeftStringFontHeightF = 0.013 + res2@gsnCenterStringFontHeightF = 0.017 + res2@gsnRightStringFontHeightF = 0.013 + else + res2@tmXBLabelFontHeightF = 0.018 + res2@tmYLLabelFontHeightF = 0.018 + res2@gsnLeftStringFontHeightF = 0.020 + res2@gsnCenterStringFontHeightF = 0.024 + res2@gsnRightStringFontHeightF = 0.020 + end if + res2@gsnLeftStringOrthogonalPosF = -1.01 + res2@gsnRightStringOrthogonalPosF = -1.01 + res2@gsnLeftStringParallelPosF = 0.01 + res2@gsnRightStringParallelPosF = 0.99 + + res2@gsnLeftString = "AMO leads" + res2@gsnCenterString = names(ee) + res2@gsnRightString = "AMOC PC1 leads" + if (nyr(ee).ge.90.and.isvar("ccr")) then ; need a minimum number of years to compute lead/lag correlations + res2@trXMinF = mxlag*-1 + res2@trXMaxF = mxlag + plot_amoc_amo_ann(ee) = gsn_csm_xy(wks_amoc_amo,ispan(mxlag*-1,mxlag,1),ccr,res2) + delete([/mxlag,ccr/]) + end if + delete(res2) + end do + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelFontHeightF = 0.013 + panres@lbLabelStride = 1 + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres@txString = "AMOC Means (Annual)" + gsn_panel2(wks_mean,plot_mean_ann,(/nrow,ncol/),panres) + delete(wks_mean) + + panres@txString = "AMOC Standard Deviations (Annual)" + gsn_panel2(wks_stddev,plot_stddev_ann,(/nrow,ncol/),panres) + delete(wks_stddev) + + panres@txString = "AMOC EOF1 (Annual)" + gsn_panel2(wks_amoc,plot_amoc_ann,(/nrow,ncol/),panres) + delete(wks_amoc) + + panres@txString = "AMOC TAS Regressions (Annual)" + gsn_panel2(wks_amoc_tasreg,plot_amoc_tasreg_ann,(/nrow,ncol/),panres) + delete(wks_amoc_tasreg) + + panres@txString = "AMOC SST Regressions (Annual)" + gsn_panel2(wks_amoc_sstreg,plot_amoc_sstreg_ann,(/nrow,ncol/),panres) + delete(wks_amoc_sstreg) + delete(panres) + + panres2 = True + if (nsim.le.5) then + panres2@txFontHeightF = 0.024 + else + panres2@txFontHeightF = 0.016 + end if + panres2@gsnMaximize = True + panres2@gsnPaperOrientation = "portrait" + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) + end if + panres2@gsnPanelYWhiteSpacePercent = 3.0 + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres2@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + panres2@txString = "AMOC PC1 (Annual)" + gsn_panel2(wks_amoc_ts,plot_amoc_ts_ann,(/nrow,ncol/),panres2) + delete(wks_amoc_ts) + + if (isatt(panres2,"gsnPanelScalePlotIndex")) then + delete(panres2@gsnPanelScalePlotIndex) + end if + panres2@txString = "AMOC PC1 (Annual, detrended)" + gsn_panel2(wks_amoc_powspec,plot_amoc_powspec_ann,(/nrow,ncol/),panres2) + delete(wks_amoc_powspec) + + + panres2@txString = "AMO / AMOC PC1 Lag Correlation (Annual)" + gsn_panel2(wks_amoc_amo,plot_amoc_amo_ann,(/nrow,ncol/),panres2) + delete(wks_amoc_amo) + delete(panres2) + print("Finished: amoc.ncl") +end + + diff --git a/lib/externals/CVDP/ncl_scripts/cas-cvdp.png b/lib/externals/CVDP/ncl_scripts/cas-cvdp.png new file mode 100755 index 000000000..0558852e6 Binary files /dev/null and b/lib/externals/CVDP/ncl_scripts/cas-cvdp.png differ diff --git a/lib/externals/CVDP/ncl_scripts/copyright.gif b/lib/externals/CVDP/ncl_scripts/copyright.gif new file mode 100644 index 000000000..619067e90 Binary files /dev/null and b/lib/externals/CVDP/ncl_scripts/copyright.gif differ diff --git a/lib/externals/CVDP/ncl_scripts/copyright2.gif b/lib/externals/CVDP/ncl_scripts/copyright2.gif new file mode 100644 index 000000000..cf2ab9c09 Binary files /dev/null and b/lib/externals/CVDP/ncl_scripts/copyright2.gif differ diff --git a/lib/externals/CVDP/ncl_scripts/functions.ncl b/lib/externals/CVDP/ncl_scripts/functions.ncl new file mode 100644 index 000000000..216759543 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/functions.ncl @@ -0,0 +1,1269 @@ +;================================================================================================= +; create blank array for use when something may be/is wrong. +; +undef("create_empty_array") +function create_empty_array(yS:numeric,yE:numeric,mS:numeric,mE:numeric,opttype:string) +local yS,yE,mS,mE,opttype +begin + if (ismissing(yS).or.ismissing(yE)) then + yS = 1 + yE = 50 + end if + timeT = yyyymm_time(yS, yE, "integer") + time = timeT({yS*100+mS:yE*100+mE}) + if (opttype.eq."time_lat_lon") then + blankarr = new((/dimsizes(time),90,180/),"float",1.e20) + blankarr!0 = "time" ; time coordinate variable assigned below + blankarr&time = time + blankarr!1 = "lat" + blankarr&lat = fspan(-89,89,90) + blankarr!2 = "lon" + blankarr&lon = fspan(0,358,180) + blankarr&lat@units = "degrees_north" + blankarr&lon@units = "degrees_east" + end if + if (opttype.eq."time_lev_lat") then + blankarr = new((/dimsizes(time),41,90/),"float",1.e20) + blankarr!0 = "time" ; time coordinate variable assigned below + blankarr&time = time + blankarr!1 = "lev" + blankarr&lev =fspan(0,5000,41) + blankarr!2 = "lat" + blankarr&lat = fspan(-89,89,90) + blankarr&lat@units = "degrees_north" + blankarr&lev@units = "m" + blankarr&lev@positive = "down" + end if + blankarr@units = "" + blankarr@is_all_missing = True + return(blankarr) + delete([/yS,yE,mS,mE,opttype,blankarr,timeT,time/]) +end +;=================================================================================================== +; read in atmospheric/land data from selected files +; assign time coordinate variables, check for issues with the array, assign _FillValue (if needed) +; assign dimension names (for ease-of-use), check and modify units +; +; vname settings at top of this script can be modified if a different variable name is +; encountered. For instance, if a TS data file has the TS array named as "sfc_t", one +; could add "sfc_t" to the vname TS coding as follows: +; if (vn.eq."TS") then +; vname = (/"TS","ts","sst","sfc_t"/) +; end if +; +undef("data_read_in") +function data_read_in(zpath:string,vn:string,yearS:integer,yearE:integer) +; path for TS file(s), variable name, start year, and end year are read in. +local zpath,vn,cpath0,tfiles,c,arr,farr,yearS,yearE,mocheck,fils_precc,fils_precl +begin + if (vn.eq."TS") then + vname = (/"TS","ts","sst","t_surf","skt"/) + end if + if (vn.eq."PSL") then + vname = (/"PSL","psl","slp","SLP","prmsl","msl","slp_dyn"/) + end if + if (vn.eq."TREFHT") then + vname = (/"TREFHT","tas","temp","air","temperature_anomaly","temperature","t2m","t_ref","T2","tempanomaly"/) + end if + if (vn.eq."PRECT") then + vname = (/"PRECC","PRECL","PRECT","pr","PPT","ppt","p","P","precip","PRECIP","tp","prcp","prate"/) + end if + if (vn.eq."SNOWDP") then + vname = (/"SNOWDP","snd"/) + end if + + if (ismissing(zpath) ) then + print("File missing, creating blank array of data. View "+vn+" namelist for details.") + arr = create_empty_array(yearS,yearE,1,12,"time_lat_lon") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + else + cpath0 = stringtochar(zpath) + if (any(cpath0.eq.tochar("*")).or.any(cpath0.eq.tochar("{"))) then ; check for "*" and "{" denoting multiple files + tfiles = systemfunc("ls "+zpath+" 2> /dev/null") ; /dev/null suppresses all standard error output + if (vn.eq."PRECT") then ; special section for precip, as might need to do PRECC+PRECL + b = addfile(tfiles(0),"r") ; check for PRECC + if (isfilevar(b,"PRECC").or.isfilevar(b,"PRECL")) then ; PRECC/PRECL section + fils_precc = str_match(tfiles,"PRECC") + fils_precl = str_match(tfiles,"PRECL") + if (any(ismissing(fils_precc)).or.any(ismissing(fils_precl))) then + print("Fatal: Need both PRECC and PRECL file(s), creating blank array") + print(fils_precc) + print(fils_precl) + arr = create_empty_array(yearS,yearE,1,12,"time_lat_lon") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + break + end if + c = addfiles(fils_precc,"r") + arr = c[:]->PRECC + c2 = addfiles(fils_precl,"r") + arr = (/ arr+c2[:]->PRECL /) + arr@long_name = "Large-scale (stable) + convective precipitation rate (liq + ice)" + delete([/c2,fils_precc,fils_precl/]) + else ; pr, ppt, PPT, PRECT multiple/single file read-in here.. + c = addfiles(tfiles,"r") + do ii=0,dimsizes(vname)-1 + if (isfilevar(c[0],vname(ii))) then + arr = c[:]->$vname(ii)$ + break + end if + end do + end if + delete(b) + else + c = addfiles(tfiles,"r") + do ii=0,dimsizes(vname)-1 + if (isfilevar(c[0],vname(ii))) then + arr = c[:]->$vname(ii)$ + break + end if + end do + end if + nfil = dimsizes(tfiles) + cpathS = stringtochar(tfiles(0)) ; this section will work for PRECC/PRECL, as it will read the first + cpathE = stringtochar(tfiles(nfil-1)) ; PRECC file and the last PRECL file. + ncharS = dimsizes(cpathS) + ncharE = dimsizes(cpathE) + sydata = stringtointeger(charactertostring(cpathS(ncharS-17:ncharS-14))) + smdata = stringtointeger(charactertostring(cpathS(ncharS-13:ncharS-12))) + eydata = stringtointeger(charactertostring(cpathE(ncharE-10:ncharE-7))) + emdata = stringtointeger(charactertostring(cpathE(ncharE-6:ncharE-5))) + delete([/cpathS,cpathE,ncharS,ncharE,nfil/]) +; delete(c) + else + c = addfile(zpath,"r") + do i=0,dimsizes(vname)-1 + if (isfilevar(c,vname(i))) then + arr = c->$vname(i)$ + break + end if + end do + cpath = stringtochar(zpath) + nchar = dimsizes(cpath) + sydata = stringtointeger(charactertostring(cpath(nchar-17:nchar-14))) + smdata = stringtointeger(charactertostring(cpath(nchar-13:nchar-12))) + eydata = stringtointeger(charactertostring(cpath(nchar-10:nchar-7))) + emdata = stringtointeger(charactertostring(cpath(nchar-6:nchar-5))) + delete([/cpath,nchar/]) +; delete(c) + end if + delete([/cpath0/]) + end if + + if (isvar("arr").eq.False) then + print("Variable ("+vn+") not found. Examine input file "+zpath+". Creating empty array and continuing") + arr = create_empty_array(yearS,yearE,1,12,"time_lat_lon") + end if + + if (isshort(arr)) then + arrT = short2flt(arr) + delete(arr) + arr = arrT + delete(arrT) + end if + + if (.not.isatt(arr,"_FillValue")) then ; assign _FillValue if one is not present + if (isatt(arr,"missing_value")) then + arr@_FillValue = arr@missing_value + else + arr@_FillValue = default_fillvalue(typeof(arr)) + end if + end if + + dimz = dimsizes(arr) + if (any(dimz.eq.1)) then + arrT = rm_single_dims(arr) + delete(arr) + arr = arrT + delete(arrT) + end if + if (dimsizes(dimz).le.2) then + print("Possible curvilinear (or unstructured) grid detected. The CVDP cannot analyze curvilinear data. Please regrid to a rectilinear grid for inclusion in CVDP comparisons.") + print("Input file: "+zpath) + print("Setting array to all missing") + delete(arr) + arr = create_empty_array(yearS,yearE,smdata,emdata,"time_lat_lon") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + end if + delete(dimz) + + arr!0 = "time" + arr!1 = "lat" + arr!2 = "lon" + +; if (isatt(arr,"valid_range")) then ; check to make sure data is in valid range. Reset to stay within the valid range if needed. +; if (type(arr@valid_range).eq.type(arr)) then ; Coding added in v5.0.0 but removed in v5.1.0 due to valid_range attributes not always being correct. +; arr = where(arr.lt.arr@valid_range(0),arr@valid_range(0),arr) ; (By convention they should be, and should be the same type as the variable itself.) +; arr = where(arr.gt.arr@valid_range(1),arr@valid_range(1),arr) ; This resulted in error outs. Added check to verify type of attribute and variable are same, +; end if ; before deciding to remove this section of code. +; end if + + if (any(abs(arr).ge.1.e20)) then ; check for inf values or values way out of range, reset to _FillValue. + print("Values greater than 1.e20 or less than -1.e20 detected in "+zpath+", resetting to _FillValue") + arr = where(abs(arr).ge.1.e20,arr@_FillValue,arr) + end if + + if (yearS.lt.sydata.or.yearE.gt.eydata) then + print("Requested "+yearS+"-"+yearE+" time span is outside the input file "+zpath+" time span of "+sydata+"-"+eydata+"") + print("Setting array to all missing") + delete(arr) + arr = create_empty_array(yearS,yearE,smdata,emdata,"time_lat_lon") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + else + timeT = yyyymm_time(sydata, eydata, "integer") + time = timeT({sydata*100+smdata:eydata*100+emdata}) + if (iscoord(arr,"time")) then + delete(arr&time) + end if + dimz = dimsizes(arr) + if (dimz(0).eq.dimsizes(time)) then + arr&time = time + else + print("Possible mismatch detected between time specified in file name and file variables, setting array to missing") + print("File = "+zpath) + print("Read from file name: "+min(time)+"-"+max(time)) + delete(arr) + arr = create_empty_array(yearS,yearE,smdata,emdata,"time_lat_lon") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + end if + delete(dimz) + delete([/time,timeT/]) + end if + delete([/sydata,smdata,eydata,emdata/]) + +; printVarSummary(arr) +; printVarSummary(arr({sy*100+1:ey*100+12},:,:)) + if (arr&lat(0).ge.0) then + farr = arr({yearS*100+1:yearE*100+12},::-1,:) ; flip the latitudes + else + farr = arr({yearS*100+1:yearE*100+12},:,:) + end if +; printVarSummary(farr) + delete(arr) + + mocheck = (/(yearS*100+1)-min(farr&time),(yearE*100+12) - max(farr&time)/) + if (any(mocheck.ne.0)) then ; previously: if (mod(dimsizes(farr&time),12).ne.0) then + if (mocheck(0).ne.0) then + print("First requested year is incomplete") + end if + if (mocheck(1).ne.0) then + print("Last requested year is incomplete") + end if + print("Incomplete data year(s) requested for file "+zpath+", printing out time and creating blank array") + print("Time requested: "+yearS+"-"+yearE) + print(farr&time) + delete(farr) + farr = create_empty_array(yearS,yearE,1,12,"time_lat_lon") + end if + delete(mocheck) + + if (farr&lon(0).lt.0) then + farr = lonFlip(farr) ; lon flip + end if + if (min(farr&lon).lt.0.or.max(farr&lon).gt.360) then + print(farr&lon) + print("path = "+zpath) + print("Fatal: Longitudes not in expected 0-360E range, creating blank array") + delete(farr) + farr = create_empty_array(yearS,yearE,1,12,"time_lat_lon") + end if + + if (vn.eq."TREFHT".or.vn.eq."TS") then ; units check + if (farr@units.eq."K".or.farr@units.eq."Kelvin".or.farr@units.eq."deg_k".or.farr@units.eq."deg_K") then + if (max(farr).ge.100) then ; data sets can be anomalies with units of K, so check for range before subtracting + farr = farr-273.15 + end if + farr@units = "C" + end if + if (farr@units.eq."degrees_C".or.farr@units.eq."degrees C".or.farr@units.eq."degree_C".or.farr@units.eq."degree C") then + farr@units = "C" + end if + end if + if (vn.eq."PSL") then + if (farr@units.eq."Pa".or.farr@units.eq."Pascals".or.farr@units.eq."Pascal") then + farr = farr/100. + farr@units = "hPa" + end if + end if + if (vn.eq."PRECT") then ; convert (if necessary) to mm/day + if (farr@units.eq."m/s".or.farr@units.eq."m s-1") then + farr = farr*86400000. + end if + if (farr@units.eq."kg m-2 s-1".or.farr@units.eq."kg/m2/s".or.farr@units.eq."kg/m^2/s".or.farr@units.eq."kg/(s*m2)".or.farr@units.eq."mm/s") then + farr = farr*86400. + end if + if (farr@units.eq."m".or.farr@units.eq."m/month".or.farr@units.eq."cm".or.farr@units.eq."cm/month".or.farr@units.eq."mm".or.farr@units.eq."mm/month") then + yr = toint(farr&time)/100 + mo = toint(farr&time - (yr*100)) + days = days_in_month(yr,mo) + do gg = 0,dimsizes(farr&time)-1 + farr(gg,:,:) = (/ farr(gg,:,:) / days(gg) /) + end do + if (farr@units.eq."cm".or.farr@units.eq."cm/month") then + farr = farr*10. ; convert from cm/day to mm/day + end if + if (farr@units.eq."m".or.farr@units.eq."m/month") then + farr = farr*1000. ; convert from m/day to mm/day + end if + end if + if (farr@units.eq."m/day".or.farr@units.eq."m day-1") then + farr = farr*1000. + end if + farr@units = "mm/day" + end if + if (vn.eq."SNOWDP") then + if (.not.isatt(farr,"is_all_missing")) then + if (farr@units.ne."m".and.farr@units.ne."meters") then + print("Warning: SNOWDP/snd units may not be in meters. listed units = "+farr@units) + end if + end if + end if + + date = farr&time ; switch time to be CF-conforming + delete(farr&time) + yyyy = date/100 + mm = date-(yyyy*100) + days = (days_in_month(yyyy,mm))/2 + hms = days + hms = 0 ; hours, minutes, seconds all the same (=0) + time = cd_inv_calendar(yyyy,mm,days,hms,hms,hms,"months since "+min(yyyy)+"-01-15 00:00:00",0) + time@long_name = "Time" + time@standard_name = "time" + time@actual_range = (/min(time),max(time)/) + time!0 = "time" + time&time = time + farr&time = time + delete([/time,yyyy,mm,days,hms,date/]) + return(farr) +end +;================================================================================================= +; read in MOC ocean data from given files +; +; assign time coordinate variables, check for issues with the array, assign _FillValue (if needed) +; assign dimension names (for ease-of-use), check and modify units +; +undef("data_read_in_ocean_MOC") +function data_read_in_ocean_MOC(zpath:string,vn:string,yearS:integer,yearE:integer) +; path for MOC file(s), variable name, start year, and end year are read in. +local zpath,vn,cpath0,ta,tfiles,c,arr,farr,yearS,yearE,mocheck,dimC,lev +begin + if (vn.eq."MOC") then + vname = (/"MOC","msftmyz","stfmmc","msftmz"/) + end if + + if (ismissing(zpath) ) then + print("File missing, creating blank array of data. View "+vn+" namelist for details.") + arr = create_empty_array(yearS,yearE,1,12,"time_lev_lat") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + else + cpath0 = stringtochar(zpath) + + ta = stringtochar("*") + if (any(cpath0.eq.ta(0)).or.any(cpath0.eq."{")) then ; check for "*" and "{" denoting multiple files + tfiles = systemfunc("ls "+zpath+" 2> /dev/null") ; /dev/null suppresses all standard error output + c = addfiles(tfiles,"r") + do ii=0,dimsizes(vname)-1 + if (isfilevar(c[0],vname(ii))) then + dimC = filevardimsizes(c[0],"MOC") + if (vname(ii).eq."MOC") then ; CCSM/CESM file + if (dimC(2).ge.2) then + arr = dim_sum_n_Wrap(c[:]->$vname(ii)$(:,1,:,:,:),1) ; select Atl+Med+Labrador+GIN sea+Arctic+Hudson Bay transport region and sum over moc_comp + else + arr = c[:]->$vname(ii)$(:,1,0,:,:) ; select Atl+Med+Labrador+GIN sea+Arctic+Hudson Bay transport region and the only moc_comp dimension + end if + else ; CMIP file + arr = c[:]->$vname(ii)$(:,0,:,:) ; CMIP file: 0th basin/region = atlantic_ocean (CMIP3) or atlantic_arctic_ocean (CMIP5) + end if + delete(dimC) + break + end if + end do + nfil = dimsizes(tfiles) + cpathS = stringtochar(tfiles(0)) + cpathE = stringtochar(tfiles(nfil-1)) + ncharS = dimsizes(cpathS) + ncharE = dimsizes(cpathE) + sydata = stringtointeger(charactertostring(cpathS(ncharS-17:ncharS-14))) + smdata = stringtointeger(charactertostring(cpathS(ncharS-13:ncharS-12))) + eydata = stringtointeger(charactertostring(cpathE(ncharE-10:ncharE-7))) + emdata = stringtointeger(charactertostring(cpathE(ncharE-6:ncharE-5))) + delete([/cpathS,cpathE,ncharS,ncharE,nfil/]) +; delete(c) + else + c = addfile(zpath,"r") + do i=0,dimsizes(vname)-1 + if (isfilevar(c,vname(i))) then + dimC = filevardimsizes(c,"MOC") + if (vname(i).eq."MOC") then ; CCSM/CESM file + if (dimC(2).ge.2) then + arr = dim_sum_n_Wrap(c->$vname(i)$(:,1,:,:,:),1) ; select Atl+Med+Labrador+GIN sea+Arctic+Hudson Bay transport region and sum over moc_comp + else + arr = c->$vname(i)$(:,1,0,:,:) ; select Atl+Med+Labrador+GIN sea+Arctic+Hudson Bay transport region + end if + else ; CMIP file + arr = c->$vname(i)$(:,0,:,:) ; CMIP file: 0th basin/region = atlantic_ocean (CMIP3) or atlantic_arctic_ocean (CMIP5) + end if + delete(dimC) + break + end if + end do + cpath = stringtochar(zpath) + nchar = dimsizes(cpath) + sydata = stringtointeger(charactertostring(cpath(nchar-17:nchar-14))) + smdata = stringtointeger(charactertostring(cpath(nchar-13:nchar-12))) + eydata = stringtointeger(charactertostring(cpath(nchar-10:nchar-7))) + emdata = stringtointeger(charactertostring(cpath(nchar-6:nchar-5))) + delete([/cpath,nchar/]) +; delete(c) + end if + delete([/ta,cpath0/]) + end if + + if (isvar("arr").eq.False) then + print("Variable ("+vn+") not found. Examine input file "+zpath+". Creating empty array and continuing") + arr = create_empty_array(yearS,yearE,1,12,"time_lev_lat") + end if + if (isshort(arr)) then + arrT = short2flt(arr) + delete(arr) + arr = arrT + delete(arrT) + end if + if (.not.isatt(arr,"_FillValue")) then ; assign _FillValue if one is not present + if (isatt(arr,"missing_value")) then + arr@_FillValue = arr@missing_value + else + arr@_FillValue = default_fillvalue(typeof(arr)) + end if + end if + arr!0 = "time" + arr!1 = "lev" + arr!2 = "lat" + + if (isatt(arr,"coordinates")) then + delete(arr@coordinates) + end if + + if (arr&lev@units.eq."centimeters".or.arr&lev@units.eq."cm") then + lev = arr&lev + lev@units = "m" + lev = lev/100. + lev&lev = lev + delete(arr&lev) + arr&lev = lev +; print("Level converted to m from cm") +; printVarSummary(lev) +; print(lev) + delete(lev) + end if + + if (arr&lev(2).lt.0) then ; check for negative levels + lev = arr&lev + lev = lev*-1. + if (any(lev.lt.0)) then + print("Error detected in MOC level sign conversion") + print(lev) + end if + lev@positive = "down" + lev&lev = lev + delete(arr&lev) + arr&lev = lev +; print("Levels converted from negative downwards to positive downwards") +; printVarSummary(lev) +; print(lev) + delete(lev) + end if + +; if (isatt(arr,"valid_range")) then ; check to make sure data is in valid range. Reset to stay within the valid range if needed. +; arr = where(arr.lt.arr@valid_range(0),arr@valid_range(0),arr) ; See note about removed valid_range check up above. +; arr = where(arr.gt.arr@valid_range(1),arr@valid_range(1),arr) +; end if + + if (any(abs(arr).ge.1.e20)) then ; check for inf values or values way out of range, reset to _FillValue. + print("Values greater than 1.e20 or less than -1.e20 detected in "+zpath+", resetting to _FillValue") + arr = where(abs(arr).ge.1.e20,arr@_FillValue,arr) + end if + + if (yearS.lt.sydata.or.yearE.gt.eydata) then + print("Requested "+yearS+"-"+yearE+" time span is outside the input file "+zpath+" time span of "+sydata+"-"+eydata+"") + print("Setting array to all missing") + delete(arr) + arr = create_empty_array(yearS,yearE,smdata,emdata,"time_lev_lat") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + else + timeT = yyyymm_time(sydata, eydata, "integer") + time = timeT({sydata*100+smdata:eydata*100+emdata}) + if (iscoord(arr,"time")) then + delete(arr&time) + end if + dimz = dimsizes(arr) + if (dimz(0).eq.dimsizes(time)) then + arr&time = time + else + print("Possible mismatch detected between time specified in file name and file variables, setting array to missing") + print("File = "+zpath) + print("Read from file name: "+min(time)+"-"+max(time)) + delete(arr) + arr = create_empty_array(yearS,yearE,smdata,emdata,"time_lev_lat") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + end if + delete(dimz) + delete([/time,timeT/]) + end if + delete([/sydata,smdata,eydata,emdata/]) + +; printVarSummary(arr) +; printVarSummary(arr({sy*100+1:ey*100+12},:,:)) + if (arr&lat(0).ge.0) then + farr = arr({yearS*100+1:yearE*100+12},:,::-1) ; flip the latitudes + else + farr = arr({yearS*100+1:yearE*100+12},:,:) + end if +; printVarSummary(farr) + delete(arr) + + mocheck = (/(yearS*100+1)-min(farr&time),(yearE*100+12) - max(farr&time)/) + if (any(mocheck.ne.0)) then ; previously: if (mod(dimsizes(farr&time),12).ne.0) then + if (mocheck(0).ne.0) then + print("First requested year is incomplete") + end if + if (mocheck(1).ne.0) then + print("Last requested year is incomplete") + end if + print("Incomplete data year(s) requested for file "+zpath+", printing out time and creating blank array") + print("Time requested: "+yearS+"-"+yearE) + print(farr&time) + delete(farr) + farr = create_empty_array(yearS,yearE,1,12,"time_lev_lat") + end if + delete(mocheck) + + ; check units for MOC array. CMIP5 = "kg s-1" CMIP3 = "m3 s-1" CCSM3 = "Sverdrups" CCSM4 = "Sverdrups" + + if (farr@units.eq."Sverdrups") then + farr@units = "Sv" + end if + if (farr@units.eq."kg s-1".or.farr@units.eq."KG S-1".or.farr@units.eq."kg/s".or.farr@units.eq."KG/S") then ; 1 Sv = 1.e9 kg/s + farr = (/ farr/1.e9 /) + farr@units = "Sv" + end if + if (farr@units.eq."m3 s-1".or.farr@units.eq."M3 S-1".or.farr@units.eq."m3/s".or.farr@units.eq."M3/S") then ; 1 Sv = 1.e6 m3/s + farr = (/ farr/1.e6 /) + farr@units = "Sv" + end if + +; printVarSummary(farr) + + date = farr&time ; switch time to be CF-conforming + delete(farr&time) + yyyy = date/100 + mm = date-(yyyy*100) + days = (days_in_month(yyyy,mm))/2 + hms = days + hms = 0 ; hours, minutes, seconds all the same (=0) + time = cd_inv_calendar(yyyy,mm,days,hms,hms,hms,"months since "+min(yyyy)+"-01-15 00:00:00",0) + time@long_name = "Time" + time@standard_name = "time" + time!0 = "time" + time&time = time + farr&time = time + delete([/time,yyyy,mm,days,hms,date/]) + return(farr) +end +;================================================================================================= +; read in ice data from given files +; +; assign time coordinate variables, check for issues with the array, assign _FillValue (if needed) +; assign dimension names (for ease-of-use), check and modify units +; +undef("data_read_in_ice") +function data_read_in_ice(zpath:string,vn:string,yearS:integer,yearE:integer) +; path for ice file(s), variable name, start year, and end year are read in. +local zpath,vn,cpath0,ta,tfiles,c,arr,farr,yearS,yearE,mocheck,dimC,lev +begin + if (vn.eq."aice_nh") then + vname = (/"aice_nh","aice","sic","SIC","CN","ice","icec","siconc"/) + end if + if (vn.eq."aice_sh") then + vname = (/"aice_sh","aice","sic","SIC","CN","ice","icec","siconc"/) + end if + + if (ismissing(zpath) ) then + print("File missing, creating blank array of data. View "+vn+" namelist for details.") + arr = create_empty_array(yearS,yearE,1,12,"time_lat_lon") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + else + cpath0 = stringtochar(zpath) + + ta = stringtochar("*") + tfiles = systemfunc("ls "+zpath+" 2> /dev/null") ; /dev/null suppresses all standard error output + c = addfiles(tfiles,"r") + do ii=0,dimsizes(vname)-1 + if (isfilevar(c[0],vname(ii))) then + if (vname(ii).eq."aice_nh".or.vname(ii).eq."aice_sh".or.vname(ii).eq."aice") then ; CCSM/CESM file + arr = c[:]->$vname(ii)$ + if (isatt(arr,"coordinates")) then + strarr = str_split(arr@coordinates," ") + if (any(strarr.eq."TLON")) then ; CESM longitude 2D coordinate + dimZ = dimsizes(c[0]->TLON) + if (dimsizes(dimZ).eq.3) then + arr@lon2d = c[0]->TLON(0,:,:) + else + arr@lon2d = c[0]->TLON + end if + delete(dimZ) + end if + if (any(strarr.eq."TLAT")) then ; CESM latitude 2D coordinate + dimZ = dimsizes(c[0]->TLAT) + if (dimsizes(dimZ).eq.3) then + arr@lat2d = c[0]->TLAT(0,:,:) + else + arr@lat2d = c[0]->TLAT + end if + delete(dimZ) + end if + delete(strarr) +; else +; print("2D coordinates for ice data are not detected") + end if + if (isatt(arr,"cell_measures").and.isfilevar(c[0],"tarea")) then ; if an attribute named cell_measures exists, and tarea is on file(0) + if (arr@cell_measures.eq."area: tarea") then + arr@area = totype(c[0]->tarea,typeof(arr)) ; in units of m^2 + end if + end if + else ; CMIP or other file + if (vname(ii).eq."CN") then ; GFDL file + arrT = c[:]->$vname(ii)$ + arr = dim_sum_n_Wrap(arrT,1) + delete(arrT) + arr = where(arr.ge.1,1,arr) ; optional + else + arr = c[:]->$vname(ii)$ + end if + if (isatt(arr,"coordinates")) then + strarr = str_split(arr@coordinates," ") + if (any(strarr.eq."lon")) then ; IPCC longitude 2D coordinate + arr@lon2d = c[0]->lon + end if + if (any(strarr.eq."lat")) then ; IPCC latitude 2D coordinate + arr@lat2d = c[0]->lat + end if + if (any(strarr.eq."longitude")) then ; NSIDC longitude 2D coordinate + arr@lon2d = c[0]->longitude + end if + if (any(strarr.eq."latitude")) then ; NSIDC latitude 2D coordinate + arr@lat2d = c[0]->latitude + end if + delete(strarr) +; else +; print("2D coordinates for ice data are not detected") + end if + dir_name = str_split(tfiles(0),"/") + if (dimsizes(dir_name).ge.8) then + dir_name_new = "/"+str_join(dir_name(:4),"/")+"/fx/areacello/"+dir_name(7)+"/r0i0p0/*.nc" + ufile = systemfunc("ls "+dir_name_new+" 2> /dev/null") ; /dev/null suppresses all standard error output + delete(dir_name_new) + else + ufile = new(1,string) + end if + if (.not.ismissing(ufile)) then + d = addfile(ufile,"r") + arr@area = totype(d->areacello,typeof(arr)) + dimQ = dimsizes(arr) + if (dimsizes(ndtooned(arr@area)).ne.(dimQ(1)*dimQ(2))) then ; the dimension sizes of areacello + delete(arr@area) ; do not match sizes of area j,i dimensions + end if + delete(dimQ) + end if + + if (isfilevar(c[0],"AREA")) then ; check to see if there is an AREA array present and if so use it + areaT = c[0]->AREA + if (areaT@units.eq."km^2") then + area_unit_km2_to_m2 = True + areaT = areaT*1000000. + areaT@units = "m^2" + end if + areaT@_FillValue = 1.e20 + arr@area = totype(areaT,typeof(arr)) + if (isatt(areaT,"pole_hole_area")) then ; format of ystart, yend, value, ystart, yend, value + if (isvar("area_unit_km2_to_m2")) then + extra_area = tofloat(areaT@pole_hole_area) + extra_area(2::3) = extra_area(2::3)*1000000. ; convert pole hole area from km^2->m^2 + arr@pole_hole_area = totype(extra_area,typeof(arr)) + delete(extra_area) + else + arr@pole_hole_area = totype(areaT@pole_hole_area,typeof(arr)) + end if + end if + delete(areaT) + end if + delete([/dir_name,ufile/]) + end if + break + end if + end do + nfil = dimsizes(tfiles) + cpathS = stringtochar(tfiles(0)) + cpathE = stringtochar(tfiles(nfil-1)) + ncharS = dimsizes(cpathS) + ncharE = dimsizes(cpathE) + sydata = stringtointeger(charactertostring(cpathS(ncharS-17:ncharS-14))) + smdata = stringtointeger(charactertostring(cpathS(ncharS-13:ncharS-12))) + eydata = stringtointeger(charactertostring(cpathE(ncharE-10:ncharE-7))) + emdata = stringtointeger(charactertostring(cpathE(ncharE-6:ncharE-5))) + delete([/cpathS,cpathE,ncharS,ncharE,nfil,ta,cpath0/]) + end if + + if (isvar("arr").eq.False) then + print("Variable ("+vn+") not found. Examine input file "+zpath+". Creating empty array and continuing") + arr = create_empty_array(yearS,yearE,1,12,"time_lat_lon") + end if + + if (.not.isatt(arr,"area")) then ; calculate grid cell areas manually (not implemented) +; print("Grid cell areas not found.") + end if + + if (isshort(arr)) then + arrT = short2flt(arr) + delete(arr) + arr = arrT + delete(arrT) + end if + if (.not.isatt(arr,"_FillValue")) then ; assign _FillValue if one is not present + if (isatt(arr,"missing_value")) then + arr@_FillValue = arr@missing_value + else + arr@_FillValue = default_fillvalue(typeof(arr)) + end if + end if + arr!0 = "time" + arr!1 = "j" + arr!2 = "i" + + if (.not.isatt(arr,"lat2d")) then ; if latitudes are 1D, make sure latitudes run from south to north + + if (arr&j(0).ge.0) then ; calculate area of 1D lat/lon arrays + tarr = arr(:,::-1,:) + delete(arr) + arr = tarr + delete(tarr) + end if + + if (min(arr&i).ge.0.and.max(arr&i).le.360) then + fctr = 111120 ; how many meters per degree of latitude (approximate) + pi=4.*atan(1.0) + rad=(pi/180.) + lat = tofloat(arr&j) + dimlat = dimsizes(lat) + latr = new(dimlat,typeof(lat)) + do gg = 0,dimlat-1 + if (gg.eq.0) then + latr(gg) = abs(-90-(lat(1)+lat(0))/2.) + end if + if (gg.ge.1.and.gg.lt.dimlat-1) then + latr(gg) = abs((lat(gg-1)+lat(gg))/2. - (lat(gg)+lat(gg+1))/2.) + end if + if (gg.eq.dimlat-1) then + latr(gg) = abs(90 - (lat(dimlat-2)+lat(dimlat-1))/2.) + end if + end do + lon = tofloat(arr&i) + dimlon = dimsizes(lon) + lonr = new(dimlon,typeof(lon)) + do gg = 0,dimlon-1 + if (gg.eq.0) then + lonr(gg) = abs( (lon(1)+lon(0))/2. - (((lon(dimlon-1)+(lon(0)+360))/2.)-360) ) + end if + if (gg.ge.1.and.gg.lt.dimlon-1) then + lonr(gg) = abs((lon(gg)+lon(gg+1))/2. - (lon(gg-1)+lon(gg))/2.) + end if + if (gg.eq.dimlon-1) then + lonr(gg) = abs(((lon(dimlon-1)+(lon(0)+360))/2.) - (lon(gg-1)+lon(gg))/2.) + end if + end do + area = tofloat(arr(0,:,:)) + area = area@_FillValue + area@long_name = "Area of grid box" + area@units = "m2" + +; printVarSummary(area) + do ff = 0,dimlat-1 + do gg = 0,dimlon-1 + area(ff,gg) = (/ (fctr*latr(ff))*(cos(rad*lat(ff))*lonr(gg)*fctr) /) ; cosine weighting + end do + end do +; print("Total area = "+sum(area)) + arr@area = totype(area,typeof(arr)) + delete([/lat,lon,latr,lonr,area,fctr,pi,rad,dimlat,dimlon/]) + end if + end if + + if (.not.isatt(arr,"is_all_missing")) then ; erase data in hemisphere not specified via vn + if (isatt(arr,"lat2d")) then + tlat2 = conform(arr,arr@lat2d,(/1,2/)) + tlon2 = conform(arr,arr@lon2d,(/1,2/)) + if (vn.eq."aice_nh") then + arr = where(tlat2.ge.0,arr,arr@_FillValue) + end if + if (vn.eq."aice_sh") then + arr = where(tlat2.lt.0,arr,arr@_FillValue) + end if + delete([/tlat2,tlon2/]) + else + if (vn.eq."aice_nh") then + arr(:,{:-1.},:) = arr@_FillValue + end if + if (vn.eq."aice_sh") then + arr(:,{0:},:) = arr@_FillValue + end if + end if + end if + + if (yearS.lt.sydata.or.yearE.gt.eydata) then + print("Requested "+yearS+"-"+yearE+" time span is outside the input file "+zpath+" time span of "+sydata+"-"+eydata+"") + print("Setting array to all missing") + delete(arr) + arr = create_empty_array(yearS,yearE,smdata,emdata,"time_lat_lon") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + else + timeT = yyyymm_time(sydata, eydata, "integer") + time = timeT({sydata*100+smdata:eydata*100+emdata}) + if (iscoord(arr,"time")) then + delete(arr&time) + end if + dimz = dimsizes(arr) + if (dimz(0).eq.dimsizes(time)) then + arr&time = time + else + print("Possible mismatch detected between time specified in file name and file variables, setting array to missing") + print("File = "+zpath) + print("Read from file name: "+min(time)+"-"+max(time)) + delete(arr) + arr = create_empty_array(yearS,yearE,smdata,emdata,"time_lat_lon") + sydata = yearS ; assign these variables based on yearS/yearE provided in namelist. Doesn't matter + eydata = yearE ; as data array is totally missing.. + smdata = 1 + emdata = 12 + end if + delete(dimz) + delete([/time,timeT/]) + end if + delete([/sydata,smdata,eydata,emdata/]) + farr = arr({yearS*100+1:yearE*100+12},:,:) +; printVarSummary(farr) + delete(arr) + + mocheck = (/(yearS*100+1)-min(farr&time),(yearE*100+12) - max(farr&time)/) + if (any(mocheck.ne.0)) then ; previously: if (mod(dimsizes(farr&time),12).ne.0) then + if (mocheck(0).ne.0) then + print("First requested year is incomplete") + end if + if (mocheck(1).ne.0) then + print("Last requested year is incomplete") + end if + print("Incomplete data year(s) requested for file "+zpath+", printing out time and creating blank array") + print("Time requested: "+yearS+"-"+yearE) + print("From file: Times present from "+min(farr&time)+"-"+max(farr&time)) + delete(farr) + farr = create_empty_array(yearS,yearE,1,12,"time_lat_lon") + end if + delete(mocheck) + + if (farr@units.eq."0-1".or.farr@units.eq."1") then ; GFDL units, NSIDC units + farr = (/ farr*100. /) + farr@units = "%" + end if + + date = farr&time ; switch time to be CF-conforming + delete(farr&time) + yyyy = date/100 + mm = date-(yyyy*100) + days = (days_in_month(yyyy,mm))/2 + hms = days + hms = 0 ; hours, minutes, seconds all the same (=0) + time = cd_inv_calendar(yyyy,mm,days,hms,hms,hms,"months since "+min(yyyy)+"-01-15 00:00:00",0) + time@long_name = "Time" + time@standard_name = "time" + time!0 = "time" + time&time = time + farr&time = time + delete([/time,yyyy,mm,days,hms,date/]) + return(farr) +end +;================================================================================================= +; alters the formatting of the Y-axis +; +; not currently used +; +undef("y_axis_check") +function y_axis_check(temparr:numeric,tempres:logical) +local temparr,tempres,minval,maxval +begin + minval = min(temparr) + maxval = max(temparr) + if (minval.gt.-1.and.minval.lt.0.and.maxval.lt.1.and.maxval.gt.0) then + tempres@tmYLFormat = "0@;*.2f" + else + tempres@tmYLFormat = "0@*+^sg" + end if + return(tempres) + delete([/tempres,temparr,minval,maxval/]) +end +;================================================================================================= +; Check that the user-specified climatological period is within the time range of the data +; +undef("check_custom_climo") +procedure check_custom_climo(mn:string,startyear:numeric,endyear:numeric,climo_startyear:numeric,climo_endyear:numeric) +local startyear,endyear,climo_startyear,climo_endyear,mn +begin + do gg = 0,dimsizes(startyear)-1 + if (climo_startyear.ge.0) then ; exact years specified for climatological period + if (climo_startyear.ge.startyear(gg).and.climo_endyear.le.endyear(gg)) then + else + print("check_custom_climo: Warning! Beginning and/or ending of climatological period is outside time range of data.") + print("Dataset: "+mn+", years = "+startyear(gg)+":"+endyear(gg)+", set climatological period = "+climo_startyear+":"+climo_endyear) + print("The diagnostics package will proceed, but one or more dataset(s) will not have the full climatological period removed and/or the package may fail with the following message: fatal:NclOneDValGetRangeIndex: start coordinate index out of range.") + end if + else ; relative years specified for climatological period + if ((endyear(gg)-startyear(gg)+1).lt.(climo_endyear-climo_startyear+1)) then + print("check_custom_climo: Warning! Beginning and/or ending of climatological period is outside time range of data.") + print("Dataset: "+mn+", years = "+startyear(gg)+":"+endyear(gg)+", set climatological period = "+(endyear(gg)+climo_startyear)+":"+(endyear(gg)+climo_endyear)) + print("The diagnostics package will proceed, but one or more dataset(s) will not have the full climatological period removed and/or the package may fail with the following message: fatal:NclOneDValGetRangeIndex: start coordinate index out of range.") + end if + if (abs(climo_startyear).ge.(endyear(gg)-startyear+1)) then + print("check_custom_climo: Warning! Dataset: "+mn+", climatology start year "+(endyear(gg)+climo_startyear)+" is outside of analysis time period ("+startyear(gg)+":"+endyear(gg)+"), exiting script.") + exit + end if + end if + end do +end +;================================================================================================== +; In version 6.2.1 the behavior of isfilepresent switched, where only files readable by NCL return +; True. Previously if a file (or directory) simply existed, isfilepresent would return True. A new +; function has been created in v6.2.1, fileexists, that acts like the previous version of isfilepresent +; did. To compensate for this, check the NCL version number, and use isfilepresent/fileexists when +; appropriate. +; +undef("isfilepresent2") +function isfilepresent2(fdpres:string) +local nclver, num0, num1, ra +begin + nclver = stringtochar(get_ncl_version()) + + num0 = toint(tostring(nclver(0))) + num1 = toint(tostring(nclver(2))) + num2 = toint(tostring(nclver(4))) + if (num0.le.5) then + ra = isfilepresent(fdpres) + end if + if (num0.eq.6) then + if (num1.le.1) then + ra = isfilepresent(fdpres) + end if + if (num1.eq.2) then + if (num2.eq.0) then + ra = isfilepresent(fdpres) + else + ra = fileexists(fdpres) + end if + end if + if (num1.ge.3) then + ra = fileexists(fdpres) + end if + end if + if (num0.ge.7) then + ra = fileexists(fdpres) + end if + return(ra) + delete([/nclver,num0,num1,ra/]) +end +;================================================================================================= +; +undef("table_link_setup") +function table_link_setup(ipath:string,iname:string,ltxt:string) +; image name, along with link text +local ipath, iname, ltxt, otxt, quote +begin + quote = str_get_dq() + if (isfilepresent2(ipath+iname)) then + otxt = ""+ltxt+"" + else + otxt = ltxt + end if + return(otxt) + delete([/ipath,iname,ltxt,otxt,quote/]) +end +;================================================================================================= +undef ("gsn_panel2") +procedure gsn_panel2(wksp:graphic,plotp:graphic,lpl:numeric,panelres:logical) +; checks to make sure at least one image is present in plot before paneling, +; thereby eliminating error message: +; Error: gsn_panel: all of the plots passed to gsn_panel appear to be invalid + +local wksp, plotp, lpl, panelres +begin + if (.not.all(ismissing(plotp))) then + gsn_panel(wksp,plotp,lpl,panelres) + end if +end +;================================================================================================= +undef ("eofunc_north2") +function eofunc_north2(eval[*]:numeric, N[1]:integer, prinfo[1]:logical) +; +; North, G.R. et al (1982): Sampling Errors in the Estimation of Empirical Orthogonal Functions. +; Mon. Wea. Rev., 110, 699–706. +; doi: http://dx.doi.org/10.1175/1520-0493(1982)110<0699:SEITEO>2.0.CO;2 +; +; Usage after 'eofunc'. Here ntim was used, +; prinfo = True +; sig = eval_north(eof@eval, ntim, prinfo) +; +; Copied directly from v6.3.0 contributed.ncl for use in the package regardless of NCL version. +; +local neval, dlam, low, high, sig, n +begin + neval = dimsizes(eval) + if (neval.eq.1) + print("eofunc_north: neval=1, no testing can be performed") + sig = True + sig@long_name = "EOF separation is not testable N=1" + sig@N = N + return(sig) + end if + + dlam = eval * sqrt(2.0/N) ; eq 24 + low = eval-dlam + high = eval+dlam + + sig = new(dimsizes(eval), logical) + sig = False ; default is not significantly separated + +; first and last eigenvalues are special cales + + if (eval(0).gt.high(1)) then + sig(0) = True + end if + if (eval(neval-1).lt.low(neval-2)) then + sig(neval-1) = True + end if + +; loop over other eignvalues + + if (N.gt.2) then + do n=1,neval-2 + if (eval(n).lt.low(n-1) .and. eval(n).gt.high(n+1)) then + sig(n) = True + end if + end do + end if + + if (prinfo) then + print(dlam+" "+low+" "+eval+" "+high+" "+sig) + end if + + sig@long_name = "EOF separation" + sig@N = N + return(sig) +end +;================================================================================================= +; Standardize and set attributes for array. Remove NCL-added and superfluous attributes, +; set missing_value equal to _FillValue, provide options to set long_name, units, and comment_cvdp +; attributes. For last three inputs "" means leave as set and "delete" means delete the attribute. +; This function will be used immediately prior to an array being written to a netCDF file. +; +undef("set_varAtts") +function set_varAtts(zarr:numeric,loname:string,uni:string,com_cvdp:string) + +local zarr,loname,uni,com_cvdp +begin + if (isatt(zarr,"anomaly_op_ncl")) then + delete(zarr@anomaly_op_ncl) + end if + if (isatt(zarr,"average_op_ncl")) then + delete(zarr@average_op_ncl) + end if + if (isatt(zarr,"cell_measures")) then + delete(zarr@cell_measures) + end if + if (isatt(zarr,"cell_methods")) then + delete(zarr@cell_methods) + end if + if (isatt(zarr,"lonFlip")) then + delete(zarr@lonFlip) + end if + if (isatt(zarr,"runave_op_ncl")) then + delete(zarr@runave_op_ncl) + end if + if (isatt(zarr,"stddev_op_ncl")) then + delete(zarr@stddev_op_ncl) + end if + if (isatt(zarr,"sum_op_ncl")) then + delete(zarr@sum_op_ncl) + end if + if (isatt(zarr,"time")) then + delete(zarr@time) + end if + if (isatt(zarr,"wgt_areaave_op_ncl")) then + delete(zarr@wgt_areaave_op_ncl) + end if + + if (isatt(zarr,"_FillValue")) then ; set missing_value = _FillValue + if (isatt(zarr,"missing_value")) then + delete(zarr@missing_value) + end if + zarr@missing_value = zarr@_FillValue + end if + + if (loname.eq."delete") then + delete(zarr@long_name) + else + if (loname.ne."") then ; "" = leave as is + zarr@long_name = loname + end if + end if + if (uni.eq."delete") then + delete(zarr@units) + else + if (uni.ne."") then ; "" = leave as is + zarr@units = uni + end if + end if + if (com_cvdp.eq."delete") then + delete(zarr@comment_cvdp) + else + if (com_cvdp.ne."") then ; "" = leave as is + zarr@comment_cvdp = com_cvdp + end if + end if + + return(zarr) +end +;================================================================================================================= +; For all images in outdir, trim white space, conver to .png (if necessary) and add watermark +; odir = Output directory, otype = output file type (.ps, .png, .eps), max_nt = max number of tasks allowed at once, +; zp0 = path of CVDP scripts, pngsize = size (in ImageMagick units) of png converted from ps +; +undef("image_finalize") +procedure image_finalize(odir[1]:string,otype[1]:string,max_nt[1]:integer,zp0[1]:string,pngsize[1]:integer) +local odir,otype,max_nt,zp0,pngsize,ofiles,ofilesS,ofilesT,gg,filesize,ofiles_png,numPlotsCompleted,numJobsActive,pid,command +begin + ofiles = systemfunc("ls "+odir+"*."+otype) + if (otype.ne."png") then + ofilesS = systemfunc("ls "+outdir+"*."+output_type) + ofilesT = systemfunc("ls -l "+outdir+"*."+output_type) + do gg = 0,dimsizes(ofilesT)-1 ; check for empty .ps files, remove + filesize = tofloat(str_get_field(ofilesT(gg),5," ")) + if (filesize.lt.10000) then + print("Removing: "+ofilesT(gg)) + system("rm "+ofilesS(gg)) + end if + end do + ofiles_png = str_sub_str(ofiles,"."+otype,".png") + oreso = "-density "+pngsize+" -trim +repage -border 8" + else + ofiles_png = ofiles + oreso = "-trim +repage -border 15x30" + end if + + do ff = 0,1 ; first time through trim and add border, second time through add watermark + numPlotsCompleted = 0 + numJobsActive = 0 + do gg = 0,dimsizes(ofiles)-1 + do while (numJobsActive.ge.(max_num_tasks*2)) + pid = subprocess_wait(0, True) ; check if any tasks have completed; block until something completes... + if (pid.gt.0) then + numPlotsCompleted = numPlotsCompleted + 1 + numJobsActive = numJobsActive - 1 + break + end if + end do + if (ff.eq.0) then + if (otype.eq."png") then + command = "convert "+oreso+" -bordercolor white -background white -flatten "+ofiles(gg)+" "+ofiles_png(gg) + else + command = "ps2epsi "+ofiles(gg)+" "+str_sub_str(ofiles(gg),"."+otype,".eps")+"; convert "+oreso+" -bordercolor white -background white -flatten "+str_sub_str(ofiles(gg),"."+otype,".eps")+" "+ofiles_png(gg) + end if + else + command = "composite -dissolve 50% -gravity northeast "+zp0+"copyright.gif "+ofiles_png(gg)+" "+ofiles_png(gg) + end if + pid = subprocess(command) + numJobsActive = numJobsActive + 1 + end do + sleep(10) ; wait 10 seconds for last batch of conversions to complete + end do +;--------------------------------------- +; Add watermark to metrics graphics + + ofiles := systemfunc("ls "+odir+"*.gif") + numPlotsCompleted = 0 + numJobsActive = 0 + if (.not.ismissing(ofiles(0))) then + do gg = 0,dimsizes(ofiles)-1 + do while (numJobsActive.ge.(max_num_tasks*2)) + pid = subprocess_wait(0, True) ; check if any tasks have completed; block until something completes... + if (pid.gt.0) then + numPlotsCompleted = numPlotsCompleted + 1 + numJobsActive = numJobsActive - 1 + break + end if + end do + command = "composite -dissolve 100% -gravity northeast "+zp0+"copyright2.gif "+ofiles(gg)+" "+ofiles(gg) + pid = subprocess(command) + numJobsActive = numJobsActive + 1 + end do + sleep(10) ; wait 10 seconds for last batch of conversions to complete + end if +;--------------------------------------- +; Cleanup .eps files and ESMF regridding logs +; + if (otype.eq."ps") then + system("rm "+odir+"*.eps") + end if + if (isfilepresent2("PET0.RegridWeightGen.Log")) then + system("rm PET0.RegridWeightGen.Log") + end if +end +;================================================================================================================= +; For all images in outdir, trim white space, conver to .png (if necessary) and add watermark +; odir = Output directory, otype = output file type (.ps, .png, .eps), max_nt = max number of tasks allowed at once, +; zp0 = path of CVDP scripts, pngsize = size (in ImageMagick units) of png converted from ps +; +undef("rm_obsfiles") +procedure rm_obsfiles(ofi:string) +local ofi +begin + do gg = 0,dimsizes(ofi)-1 + if (isfilepresent2("obs_"+ofi(gg))) then + system("rm obs_"+ofi(gg)) + end if + end do +end + diff --git a/lib/externals/CVDP/ncl_scripts/ipo.ncl b/lib/externals/CVDP/ncl_scripts/ipo.ncl new file mode 100644 index 000000000..f22e911c5 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/ipo.ncl @@ -0,0 +1,716 @@ +; Calculates the IPO pattern, timeseries, and spectra. +; +; Variables used: ts +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: ipo.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_ts") + na = asciiread("namelist_byvar/namelist_ts",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) +;---------TAS Regressions coding------------------------------------------------- + nsim_tas = numAsciiRow("namelist_byvar/namelist_trefht") + na_tas = asciiread("namelist_byvar/namelist_trefht",(/nsim_tas/),"string") + names_tas = new(nsim_tas,"string") + paths_tas = new(nsim_tas,"string") + syear_tas = new(nsim_tas,"integer",-999) + eyear_tas = new(nsim_tas,"integer",-999) + + do gg = 0,nsim_tas-1 + names_tas(gg) = str_strip(str_get_field(na_tas(gg),1,delim)) + paths_tas(gg) = str_strip(str_get_field(na_tas(gg),2,delim)) + syear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),3,delim))) + eyear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),4,delim))) + end do + delete(na_tas) + nyr_tas = eyear_tas-syear_tas+1 +;---------PR Regressions coding------------------------------------------------- + nsim_pr = numAsciiRow("namelist_byvar/namelist_prect") + na_pr = asciiread("namelist_byvar/namelist_prect",(/nsim_pr/),"string") + names_pr = new(nsim_pr,"string") + paths_pr = new(nsim_pr,"string") + syear_pr = new(nsim_pr,"integer",-999) + eyear_pr = new(nsim_pr,"integer",-999) + + do gg = 0,nsim_pr-1 + names_pr(gg) = str_strip(str_get_field(na_pr(gg),1,delim)) + paths_pr(gg) = str_strip(str_get_field(na_pr(gg),2,delim)) + syear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),3,delim))) + eyear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),4,delim))) + end do + delete(na_pr) + nyr_pr = eyear_pr-syear_pr+1 +;------------------------------------------------------------------------------------------------- + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks = gsn_open_wks(wks_type,getenv("OUTDIR")+"ipo") + wks4 = gsn_open_wks(wks_type,getenv("OUTDIR")+"ipo.prreg") + wks2 = gsn_open_wks(wks_type,getenv("OUTDIR")+"ipo.powspec") + wks3 = gsn_open_wks(wks_type,getenv("OUTDIR")+"ipo.timeseries") + + if (COLORMAP.eq."0") then + gsn_define_colormap(wks,"ncl_default") + gsn_define_colormap(wks2,"cb_9step") + gsn_define_colormap(wks3,"ncl_default") + gsn_define_colormap(wks4,"MPL_BrBG") + end if + if (COLORMAP.eq."1") then + gsn_define_colormap(wks,"BlueDarkRed18") + gsn_define_colormap(wks2,"cb_9step") + gsn_define_colormap(wks3,"ncl_default") + gsn_define_colormap(wks4,"BrownBlue12") + end if + map = new(nsim,"graphic") + map_sst = new(nsim,"graphic") + map_tasreg = new(nsim,"graphic") + map_prreg = new(nsim,"graphic") + pspec = new(nsim,"graphic") + xyplot = new(nsim,"graphic") + xyplot2 = new(nsim,"graphic") + if (isfilepresent2("obs_ts")) then + pspec_obs = new(nsim,"graphic") + end if + + fca = 1./157. + fcb = 0. + ihp = 0 + nsigma = 1 + nwgt = 217 + + wgt = new(nwgt,float) + wgt = filwgts_lancos(nwgt,ihp,fca,fcb,nsigma) ; create low pass filter + + + tasreg_frame = 1 ; *reg_frame = flag to create regressions .ps/.png files. Created/used instead of *reg_plot_flag + ; so that if {tas,pr} regressions are not created for the last simulation listed that .ps/png files are created + prreg_frame = 1 + do ee = 0,nsim-1 + sst = data_read_in(paths(ee),"TS",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(sst,"is_all_missing").or.nyr(ee).lt.40) then + delete(sst) + continue + end if + sst = where(sst.le.-1.8,-1.8,sst) ; set all values below -1.8 to -1.8 + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") ; mask out land (this is redundant for data that is already masked) + basemap = d->LSMASK + lsm = landsea_mask(basemap,sst&lat,sst&lon) + sst = mask(sst,conform(sst,lsm,(/1,2/)).ge.1,False) + delete([/lsm,basemap/]) + delete(d) + + if (OPT_CLIMO.eq."Full") then + sst = rmMonAnnCycTLL(sst) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sst + delete(temp_arr&time) + temp_arr&time = cd_calendar(sst&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sst = calcMonAnomTLL(sst,climo) + delete(climo) + end if + + sst = wgt_runave_n_Wrap(sst,wgt,1,0) ; apply low pass filter + + coswgt=cos(rad*sst&lat) + coswgt!0 = "lat" + coswgt&lat= sst&lat + do ff = 0,dimsizes(sst&time)-1 + sst(ff,:,:) = (/ sst(ff,:,:) - wgt_areaave(sst(ff,{-60:70},:),coswgt({-60.:70.}),1.0,0) /) + end do + delete(coswgt) + + sst_CW = sst + sst_CW = SqrtCosWeight(sst) + evecv = eofunc(sst_CW({lat|-40:60},{lon|110:290},time|:),2,75) + delete(sst_CW) + pcts = eofunc_ts(sst({lat|-40:60},{lon|110:290},time|:),evecv,False) + pctsS = dim_standardize(pcts(0,:),0) + delete([/pcts/]) + + ipo = sst(0,:,:) + ipo = ipo@_FillValue + ipo = (/ regCoef(pctsS,sst(lat|:,lon|:,time|:)) /) + ipo@syear = syear(ee) + ipo@eyear = eyear(ee) + + pc1 = pctsS + pc1!0 = "time" + pc1&time = sst&time + pc1@units = "1" + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(pc1),False) + if (sig_pcv(0)) then ; if True then significant + ipo@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + ipo@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete([/sig_pcv,evecv/]) + +; if (.not.ismissing(ipo({35},{160}))) then +; if (ipo({35},{160}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + if (.not.ismissing(ipo({40},{165}))) then + if (ipo({40},{165}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + ipo = ipo*-1. + pc1 = pc1*-1. + end if + end if + delete([/sst,pctsS/]) +;---------TAS Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_tas(ee),eyear(ee),eyear_tas(ee)/)))) then + tasreg_plot_flag = 1 + else + if (syear(ee).eq.syear_tas(ee)) then ; check that the start and end years match for ts, tas, and psl + if (eyear(ee).eq.eyear_tas(ee)) then + tasreg_plot_flag = 0 + else + tasreg_plot_flag = 1 + end if + else + tasreg_plot_flag = 1 + end if + end if + + if (tasreg_plot_flag.eq.0) then + tas = data_read_in(paths_tas(ee),"TREFHT",syear_tas(ee),eyear_tas(ee)) + if (isatt(tas,"is_all_missing")) then + tasreg_plot_flag = 1 + delete(tas) + end if + + if (tasreg_plot_flag.eq.0) then ; only continue if both TAS/SST fields are present + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,tas&lat,tas&lon) + tas = mask(tas,conform(tas,lsm,(/1,2/)).eq.0,False) + delete(lsm) + + if (OPT_CLIMO.eq."Full") then + tas = rmMonAnnCycTLL(tas) + else + check_custom_climo(names_tas(ee),syear_tas(ee),eyear_tas(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = tas + delete(temp_arr&time) + temp_arr&time = cd_calendar(tas&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + tas = calcMonAnomTLL(tas,climo) + delete(climo) + end if + finreg_tas = tas(0,:,:) + finreg_tas = (/ regCoef(pc1,tas(lat|:,lon|:,time|:)) /) + delete(tas) + end if + end if +;---------PR Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_pr(ee),eyear(ee),eyear_pr(ee)/)))) then + prreg_plot_flag = 1 + else + if (syear(ee).eq.syear_pr(ee)) then ; check that the start and end years match for pr and psl + if (eyear(ee).eq.eyear_pr(ee)) then + prreg_plot_flag = 0 + else + prreg_plot_flag = 1 + end if + else + prreg_plot_flag = 1 + end if + end if + + if (prreg_plot_flag.eq.0) then + pr = data_read_in(paths_pr(ee),"PRECT",syear_pr(ee),eyear_pr(ee)) + if (isatt(pr,"is_all_missing")) then + prreg_plot_flag = 1 + delete(pr) + end if + + if (prreg_plot_flag.eq.0) then ; only continue if both SST/PR fields are present + if (OPT_CLIMO.eq."Full") then + pr = rmMonAnnCycTLL(pr) + else + check_custom_climo(names_pr(ee),syear_pr(ee),eyear_pr(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = pr + delete(temp_arr&time) + temp_arr&time = cd_calendar(pr&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + pr = calcMonAnomTLL(pr,climo) + delete(climo) + end if + finreg_pr = pr(0,:,:) + finreg_pr = (/ regCoef(pc1,pr(lat|:,lon|:,time|:)) /) + delete(pr) + end if + end if +;--------------------------------------------------------------------------------------------- + if (tasreg_frame.eq.1.and.tasreg_plot_flag.eq.0) then ; tasreg_frame = flag to create regressions .ps/.png files + tasreg_frame = 0 + end if + if (prreg_frame.eq.1.and.prreg_plot_flag.eq.0) then ; prreg_frame = flag to create regressions .ps/.png files + prreg_frame = 0 + end if +;--------------------------------------------------------------------------------------------- + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.ipo."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->ipo_pattern_mon = set_varAtts(ipo,"IPO spatial pattern (monthly)","","") + z->ipo_timeseries_mon = set_varAtts(pc1,"IPO normalized principal component timeseries (monthly)","1","") + delete([/modname,fn/]) + if (tasreg_plot_flag.eq.0) then + modname = str_sub_str(names_tas(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.ipo.tas."+syear_tas(ee)+"-"+eyear_tas(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z_tas = addfile(fn,"c") + z_tas@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z_tas@notes = "Data from "+names_tas(ee)+" from "+syear_tas(ee)+"-"+eyear_tas(ee) + if (OPT_CLIMO.eq."Full") then + z_tas@climatology = syear_tas(ee)+"-"+eyear_tas(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z_tas@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z_tas@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z_tas@Conventions = "CF-1.6" + else + z_tas = addfile(fn,"w") + end if + z_tas->ipo_tas_regression_mon = set_varAtts(finreg_tas,"tas regression onto IPO timeseries (monthly)","","") + delete([/modname,fn,z_tas/]) + end if + if (prreg_plot_flag.eq.0) then + modname = str_sub_str(names_pr(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.ipo.pr."+syear_pr(ee)+"-"+eyear_pr(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z_pr = addfile(fn,"c") + z_pr@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z_pr@notes = "Data from "+names_pr(ee)+" from "+syear_pr(ee)+"-"+eyear_pr(ee) + if (OPT_CLIMO.eq."Full") then + z_pr@climatology = syear_pr(ee)+"-"+eyear_pr(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z_pr@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z_pr@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z_pr@Conventions = "CF-1.6" + else + z_pr = addfile(fn,"w") + end if + z_pr->ipo_pr_regression_mon = set_varAtts(finreg_pr,"pr regression onto IPO timeseries (monthly)","","") + delete([/modname,fn,z_pr/]) + end if + end if +;------------------------------------------------------------------------ + iopt = 0 + jave = (3*nyr(ee))/100 + val1 = .95 + val2 = .99 + if (jave.eq.0) then + jave = 1 + end if + pct = 0.1 + spectra_mvf = False ; missing value flag + spectra_mvf_obs = True ; missing value flag + if (any(ismissing(pc1))) then ; check for missing data + print("Missing data detected for "+names(ee)+", not creating IPO spectra") + spectra_mvf = True + else + if (isfilepresent2("obs_ts").and.ee.eq.0) then + spectra_mvf_obs = False ; missing value flag + end if + sdof = specx_anal(pc1,iopt,jave,pct) ; pc1 is standardized + splt1 = specx_ci(sdof,val1,val2) + + if (OUTPUT_DATA.eq."True") then + splt1!0 = "ncurves" + splt1&ncurves = ispan(0,3,1) + splt1&ncurves@long_name = "power spectra curves" + splt1&ncurves@units = "1" + splt1!1 = "frequency" + splt1&frequency = sdof@frq + splt1&frequency@units = "1" + splt1@units_info = "df refers to frequency interval; data are standardized so there are no physical units" + splt1@units = "1/df" + splt1@info = "(0,:)=spectrum,(1,:)=Markov red noise spectrum, (2,:)="+val1+"% confidence bound for Markhov, (3,:)="+val2+"% confidence bound for Markhov" + z->ipo_spectra = set_varAtts(splt1,"IPO (monthly) power spectra, Markov spectrum and confidence curves","","") + end if + if (isfilepresent2("obs_ts").and.ee.eq.0) then + sdof_obs = sdof + end if + delete([/iopt,jave,pct/]) + end if + if (isvar("z")) then + delete(z) + end if +;======================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + res@vpYF = 0.95 + res@vpHeightF = 0.3 + res@vpXF = 0.2 + res@vpWidthF = 0.6 + +; res@cnFillMode = "RasterFill" + res@cnLevelSelectionMode = "ExplicitLevels" + + if (COLORMAP.eq."0") then + res@cnLevels = fspan(-.65,.65,27) + end if + if (COLORMAP.eq."1") then + res@cnLevels = fspan(-.8,.8,17) + end if + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnCenterString = names(ee) + res@gsnRightString = ipo@pcvar + + res4 = res ; res4 = pr regression resources + delete(res4@cnLevels) + if (COLORMAP.eq.0) then + res4@cnLevels = (/-5,-4,-3,-2,-1,-.75,-.5,-.25,-.1,0,.1,.25,.5,.75,1,2,3,4,5/) + else + res4@cnLevels = (/-3,-2,-1,-.5,-.1,0,.1,.5,1,2,3/) + end if + + res2 = True ; res2 = tas regression resources + res2@gsnDraw = False + res2@gsnFrame = False + res2@cnLevelSelectionMode = "ExplicitLevels" + res2@cnLevels = res@cnLevels + + res2@cnLineLabelsOn = False + res2@cnFillOn = True + res2@cnLinesOn = False + res2@cnFillMode = "AreaFill" + res2@lbLabelBarOn = False + res2@cnInfoLabelOn = False + res2@gsnRightString = "" + res2@gsnLeftString = "" + res2@gsnCenterString = "" + res2@gsnAddCyclic = True + + map(ee) = gsn_csm_contour_map(wks,ipo,res) + + if (tasreg_plot_flag.eq.0) then + if (names(ee).eq.names_tas(ee)) then + res@gsnCenterString = names(ee) + else + res@gsnCenterString = names(ee)+" / "+names_tas(ee) + end if + map_sst(ee) = gsn_csm_contour_map(wks,ipo,res) + map_tasreg(ee) = gsn_csm_contour(wks,finreg_tas,res2) + overlay(map_sst(ee),map_tasreg(ee)) + delete([/finreg_tas/]) + end if + delete([/ipo/]) + if (prreg_plot_flag.eq.0) then + res4@gsnCenterString = names_pr(ee) + map_prreg(ee) = gsn_csm_contour_map(wks4,finreg_pr,res4) + delete(finreg_pr) + end if + + pres = True + pres@vpXF = 0.07 + pres@trYMinF = 0. + pres@trXMinF = 0.0 + pres@trXMaxF = 0.0832 + pres@tiYAxisString = "Power" ; yaxis + pres@xyLineColor = "black" + pres@gsnFrame = False + pres@gsnDraw = False + + pres@tmXBLabelDeltaF = -.8 + pres@tmXTLabelDeltaF = -.8 + pres@pmLegendDisplayMode = "Never" + pres@xyLineThicknesses = (/3.5,2.,1.,1./) + pres@xyDashPatterns = (/0,0,0,0/) + pres@xyLineColors = (/"foreground","red","blue","green"/) + pres@xyLabelMode = "custom" + pres@xyLineLabelFontColors = pres@xyLineColors + pres@xyExplicitLabels = (/"","",val1*100+"%",val2*100+"%"/) + pres@tmXTOn = True + pres@tmYROn = False + pres@tmXTLabelsOn = True + pres@tmXUseBottom = False + pres@tmXTMode = "Explicit" + pres@tmXBMode = "Explicit" + pres@tmXTValues = (/".00167",".00833",".01667",".02778",".0416",".0556",".0832"/) + pres@tmXTLabels = (/"50","10","5","3","2","1.5","1"/) + pres@tmXBValues = (/".0",".01",".02",".03",".042",".056",".083"/) + pres@tmXBLabels = pres@tmXBValues + pres@tmXTLabelFontHeightF = 0.018 + pres@tmXBLabelFontHeightF = 0.018 + pres@tmYLLabelFontHeightF = 0.018 + pres@tiYAxisString = "Variance" ;"Power (~S~o~N~C~S~2~N~ / cycles mo~S~-1~N~)" ; yaxis + pres@tiXAxisString = "Frequency (cycles mo~S~-1~N~)" + pres@tiMainString = "" + pres@txFontHeightF = 0.015 + pres@xyLineLabelFontHeightF = 0.022 + pres@tiXAxisFontHeightF = 0.025 + pres@tiYAxisFontHeightF = 0.025 + pres@tiMainFontHeightF = 0.03 + pres@gsnRightStringOrthogonalPosF = -0.115 + + pres@tiMainOn = False + pres@gsnCenterString = "Period (years)" + pres@gsnCenterStringFontHeightF = pres@tiYAxisFontHeightF + pres@gsnRightStringFontHeightF = pres@tiYAxisFontHeightF - 0.005 + pres@gsnRightString = syear(ee)+"-"+eyear(ee)+" " + pres@gsnLeftString = "" + if (wks_type.eq."png") then + pres@xyLineThicknessF = 3.5 + res@mpGeophysicalLineThicknessF = 2. + else + pres@xyLineThicknessF = 1.5 + res@mpGeophysicalLineThicknessF = 1. + end if + pres@gsnCenterString = names(ee) + if (spectra_mvf.eq.False) then + pres@trYMaxF = max(splt1(0,:))*1.1 + pspec(ee) = gsn_csm_xy(wks2,sdof@frq,splt1,pres) + if (isfilepresent2("obs_ts").and.ee.ge.1.and.spectra_mvf_obs.eq.False) then + pres@xyLineColors = (/"gray70","black","black","black"/) + pres@xyCurveDrawOrder = "PreDraw" + pres@gsnCenterString = "" + pres@gsnRightString = "" + pspec_obs(ee) = gsn_csm_xy(wks2,sdof_obs@frq,sdof_obs@spcx,pres) + overlay(pspec(ee),pspec_obs(ee)) + delete(pres@xyCurveDrawOrder) + end if + delete([/sdof,splt1/]) + end if + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnRightString = "" + xyres@gsnLeftString = "" + xyres@gsnFrame = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + xyres@gsnXYBarChart = False + xyres@gsnAboveYRefLineColor = 185 + xyres@gsnBelowYRefLineColor = 35 + xyres@xyLineThicknessF = 0.1 + xyres@xyLineColor = "gray70" + xyres@tiYAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnStringFontHeightF = 0.017 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnStringFontHeightF = 0.024 + end if + xyres@gsnCenterStringOrthogonalPosF = 0.025 + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnCenterString = "" + + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+1.5 + +; xyres2 = xyres +; delete(xyres2@gsnXYBarChart) +; delete(xyres2@gsnAboveYRefLineColor) +; delete(xyres2@gsnBelowYRefLineColor) +; xyres2@xyLineColor = "black" +; if (wks_type.eq."png") then +; xyres2@xyLineThicknessF = 3.5 +; else +; xyres2@xyLineThicknessF = 2.5 +; end if + + xyres@gsnCenterString = names(ee) + xyplot(ee) = gsn_csm_xy(wks3,fspan(syear(ee),eyear(ee)+.91667,dimsizes(pc1)),pc1,xyres) ; use standardized timeseries +; xyplot2(ee) = gsn_csm_xy(wks3,fspan(syear(ee),eyear(ee)+.91667,dimsizes(pc1)),runave(pc1,61,0),xyres2) +; overlay(xyplot(ee),xyplot2(ee)) + + delete([/val1,val2,pc1,res,pres,xyres/]) + end do + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.55 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + panres@lbLabelFontHeightF = 0.013 + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@txString = "IPO (Monthly)" + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + gsn_panel2(wks,map,(/nrow,ncol/),panres) + + if (tasreg_frame.eq.0) then + panres@txString = "IPO SST/TAS Regressions (Monthly)" + gsn_panel2(wks,map_sst,(/nrow,ncol/),panres) + end if + delete(wks) + + if (prreg_frame.eq.0) then + panres@txString = "IPO PR Regressions (Monthly)" + gsn_panel2(wks4,map_prreg,(/nrow,ncol/),panres) + end if + delete(wks4) + + delete(panres@gsnPanelLabelBar) + panres@txString = "IPO (Monthly)" + gsn_panel2(wks2,pspec,(/nrow,ncol/),panres) + delete(wks2) + + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) ;(/nsim/2+1,nsim/8+1/) + end if + panres@txString = "IPO (Monthly)" + gsn_panel2(wks3,xyplot,lp,panres) + delete(wks3) + delete([/map,pspec,syear,eyear,nyr,nyr_max,lp/]) +;-------------------------------------------------------------------------------------------------- + OUTDIR = getenv("OUTDIR") + + if (wks_type.eq."png") then + if (tasreg_frame.eq.0) then + system("mv "+OUTDIR+"ipo.000001.png "+OUTDIR+"ipo.png") + system("mv "+OUTDIR+"ipo.000002.png "+OUTDIR+"ipo.tasreg.png") + end if + else + if (tasreg_frame.eq.0) then + system("psplit "+OUTDIR+"ipo.ps "+OUTDIR+"ipo_nn") + system("mv "+OUTDIR+"ipo_nn0001.ps "+OUTDIR+"ipo.ps") + system("mv "+OUTDIR+"ipo_nn0002.ps "+OUTDIR+"ipo.tasreg.ps") + end if + end if + print("Finished: ipo.ncl") +end + diff --git a/lib/externals/CVDP/ncl_scripts/metrics.ncl b/lib/externals/CVDP/ncl_scripts/metrics.ncl new file mode 100644 index 000000000..b5b3a87f9 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/metrics.ncl @@ -0,0 +1,556 @@ +; This script takes all the metrics created by the various scripts and placed +; in metrics_orig.txt, calculates the total scores, reorganizes the data, +; and writes out a new metrics.txt file. + +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" + +undef("add_labelbar") +procedure add_labelbar(wks,plot,colors,labels) +local vph, vpw, nboxes, lbres, lbid, amres, annoid +begin + getvalues plot ; Get plot size for use in + "vpHeightF" : vph ; creating labelbar. + "vpWidthF" : vpw + end getvalues + + nboxes = dimsizes(colors) + + lbres = True ; labelbar only resources + lbres@lbAutoManage = False ; Necessary to control sizes + lbres@vpWidthF = 0.15 * vpw ; labelbar width + if (vph.eq..175) then ; minimum height + lbres@vpHeightF = 0.155 + lbres@lbLabelFontHeightF = 0.008 + end if + if (vph.gt..175.and.vph.lt..8601) then + lbres@vpHeightF = 0.85 * vph + lbres@lbLabelFontHeightF = 0.008+(((vph-.17)/.7101)*.0075) + end if + if (vph.ge..8601) then + lbres@vpHeightF = 0.7 * vph + lbres@lbLabelFontHeightF = 0.0105-(((vph-.8601)*10)*2) + end if + lbres@lbFillColors = colors ; labelbar colors + lbres@lbMonoFillPattern = True ; Solid fill pattern + + lbres@lbLabelAlignment = "InteriorEdges" ; center of box + lbres@lbOrientation = "Vertical" + lbres@lbPerimOn = False + lbres@lbFillOpacityF = 0.5 + + lbid = gsn_create_labelbar(wks,nboxes,labels,lbres) + amres = True + amres@amJust = "CenterLeft" + amres@amParallelPosF = 0.52 + amres@amOrthogonalPosF = 0.0 + plot@annoid = gsn_add_annotation(plot,lbid,amres) +end + + +begin + print("Starting: metrics.ncl") + + nclver = stringtochar(get_ncl_version()) ; check NCL version to turn off error messages + num0 = toint(tostring(nclver(0))) + num1 = toint(tostring(nclver(2))) + errmsg = True + if (num0.le.5) then + errmsg = False + end if + if (num0.eq.6) then + if (num1.le.4) then + errmsg = False + else + errmsg = True + end if + end if + if (num0.ge.7) then + errmsg = True + end if + delete([/num0,num1/]) + + OUTDIR = getenv("OUTDIR") + + nsim = numAsciiRow("namelist_byvar/namelist_trefht") ; retrieve total number of observational + models (all namelist_byvar/namelist have same # of rows) + na = asciiread("namelist_byvar/namelist_trefht",(/nsim/),"string") ; (It is not done via metrics.txt as there might be a space in names. + blankrow = ind(na.eq."") + if (.not.any(ismissing(blankrow))) then + goodrows = ind(na.ne."") + na2 = na(goodrows) + delete(na) + na = na2 + delete(na2) + nsim = dimsizes(na) + end if + nsim = nsim - 1 ; first listed dataset is what all others are compared to, thus, output metrics table has nsim-1 column + + files = (/"sst.indices.1","sst.indices.2","amo","pdo","psl.nam_nao","psl.sam_psa",\ + "sst.mean_stddev","psl.mean_stddev","pr.mean_stddev"/) + files = "metrics."+files + files = files+".txt" + + do gg = 0,dimsizes(files)-1 + if (.not.fileexists(OUTDIR+files(gg))) then + print("1 or more metrics files missing, cannot create summary metrics tables, exiting metrics.ncl") + exit + end if + end do + + ch = new((/nsim,dimsizes(files)/),"string") ; hold obs/simulation names + patcor_rms = new((/nsim,11/),"string") ; 11 metrics + cntr = 0 + + do gg = 0,dimsizes(files)-1 + nrow = numAsciiRow(OUTDIR+files(gg)) + a = asciiread(OUTDIR+files(gg),(/-1/),"string") + + t0 = tochar(a(3)) + sti0 = str_index_of_substr(a(4), " -",0) ; read in individual column headers from each metrics file + do hh = 0,dimsizes(sti0)-1 + if (hh.eq.(dimsizes(sti0)-1)) then + ch(hh,gg) = str_strip(tostring(t0(sti0(hh):))) + else + ch(hh,gg) = str_strip(tostring(t0(sti0(hh):sti0(hh+1)))) + end if + end do + delete([/sti0,t0/]) + + test = tochar(a(5:)) + if (dimsizes(dimsizes(test)).eq.2) then + patcor_rms(:,cntr) = str_split(tostring(test(0,18:))," ") + patcor_rms(:,cntr+1) = str_split(tostring(test(1,18:))," ") + cntr = cntr+2 + else + patcor_rms(:,cntr) = str_split(tostring(test(18:))," ") + cntr = cntr+1 + end if + delete(a) + delete([/test/]) + end do + delete(cntr) + +; do gg = 0,dimsizes(files)-1 ; Individual metrics files no longer removed in case comparison +; system("rm "+OUTDIR+files(gg)) ; is rerun. This ensures that the metrics tables get updated. +; end do + + names = ch(:,0) + do gg = 0,nsim-1 ; check to see if data is observations or models by seeing if every name matches + if (all(ch(gg,0).eq.ch(gg,1:))) then + names(gg) = ch(gg,0) + else + names(gg) = "OBS "+(gg+2) + end if + end do + delete(ch) + + names_nchar = max(dimsizes(tochar(names))) + spacer = "" + do gg = 0,names_nchar + spacer = spacer+" " + end do + delete(names_nchar) + pc_score = new(nsim,"string") + rms_score = new(nsim,"string") + do gg = 0,nsim-1 ; strip out pattern correlations, and calculated score for each model + pc = new(11,float,9.99) + rms = pc + do hh = 0,10 ; 11 metrics + n1 = str_split(patcor_rms(gg,hh),"/") +; print(n1) + pc(hh) = tofloat(n1(0)) ; strip out pattern correlations. 9.99 = missing. + rms(hh) = tofloat(n1(1)) ; strip out rms. 9.99 = missing. + delete(n1) + end do + if (any(ismissing(rms))) then + rms_score(gg) = "----" + else + rms_score(gg) = sprintf("%4.2f",avg(rms)) + end if + delete(rms) + +; total_score(gg) = ""+avg(pc) +; print("Simple average = "+avg(pc)) + + pc_z = pc + pc_z = pc_z@_FillValue + if (any(ismissing(pc))) then +; print("Missing Values detected") +; print(pc) + pc_score(gg) = "----" + else + do ii = 0,10 ; use Fisher's z-transformation to translate r->z + if (pc(ii).eq.1.0) then + pc_z(ii) = 0.5*(log( (1+1.001) / (1-1.001) )) ; needed when pattern correlation = 1.0 + else + pc_z(ii) = 0.5*(log( (1+pc(ii)) / (1-pc(ii)) )) + end if + end do + zavg = avg(pc_z) ; compute average of z + delete(pc_z) + + pc_score(gg) = sprintf("%4.2f",((2.71828^(2*zavg))-1)/ ((2.71828^(2*zavg))+1)) ; reverse process and convert z-avg -> r. +; print("average of Z-tranformed correlations = "+pc_score(gg)) ; r = (e^2Z - 1)/(e^2Z+1) ; e = 2.71828 + delete(zavg) + end if + delete(pc) + end do + pc_score = where(pc_score.eq." nan","----",pc_score) ; needed for when the nan's come out of the z-transform (likey due to numerous pattern correlations = 1) + + header = (/"","Pattern Correlations/RMS Differences Observations vs. Model(s)",""/) + write_table(OUTDIR+"metrics.txt","w",[/header/],"%s") + column_header1 = spacer+" ENSO TAS ENSO PSL El Nino La Nina AMO PDO NAM SAM SST sigma PSL sigma PR sigma Mean " + column_header2 = spacer+" (DJF+1) (DJF+1) Hov Hov (Monthly) (Monthly) (DJF) (DJF) (Ann) (Ann) (Ann) Score " + column_header3 = spacer+" --------- --------- --------- --------- --------- --------- --------- --------- --------- --------- --------- ---------" + write_table(OUTDIR+"metrics.txt","a",[/column_header1/],"%s") + write_table(OUTDIR+"metrics.txt","a",[/column_header2/],"%s") + write_table(OUTDIR+"metrics.txt","a",[/column_header3/],"%s") + + patcor_rms = where(patcor_rms.eq."9.99/9.99","----/----",patcor_rms) + spacer_char = tochar(spacer) + do gg = 0,nsim-1 + spacer_char1 = spacer_char + mname_char = tochar(names(gg)) + dimC = dimsizes(mname_char) + spacer_char1(:dimC-1) = mname_char + srow = tostring(spacer_char1) +; print(srow) + do hh = 0,10 + n1 = str_split(patcor_rms(gg,hh),"/") +; print("n1 = "+n1) + if (n1(0).eq."----") then + srow = srow+" "+patcor_rms(gg,hh) + else + if (tofloat(n1(0)).ge.0) then + srow = srow+" "+patcor_rms(gg,hh) + else + srow = srow+" "+patcor_rms(gg,hh) + end if + end if + delete(n1) + end do + srow = srow+" "+pc_score(gg)+"/"+rms_score(gg) + write_table(OUTDIR+"metrics.txt","a",[/srow/],"%s") + delete([/spacer_char1,dimC,mname_char,srow/]) + end do + delete([/spacer_char/]) + +; Create tables that are colored by value and sorted by value +; if there are less than 256 simulations+(number of observational datasets-1) +; (NCL can only create 255 tickmarks on one plot and each tickmark equals a +; model/obs below.) + + if (nsim.le.255) then + names!0 = "sim" + names&sim = ispan(0,nsim-1,1) + patcor = new((/nsim,12/),typeof(patcor_rms)) + rms = patcor + do gg = 0,nsim-1 + do hh = 0,11 + if (hh.le.10) then + n1 = str_split(patcor_rms(gg,hh),"/") + patcor(gg,hh) = n1(0) + rms(gg,hh) = n1(1) + else + patcor(gg,hh) = pc_score(gg) + rms(gg,hh) = rms_score(gg) + end if + end do + end do + delete([/pc_score,rms_score/]) + patcor!0 = "sim" + patcor&sim = ispan(0,nsim-1,1) + copy_VarCoords(patcor,rms) + + ncols = 12 + nrows = nsim + col_width = 1./ncols + row_width = 1./nrows + col_width2 = col_width/2. + row_width2 = row_width/2. + + fcolors = new(dimsizes(patcor),"integer") + colors = (/7,12,17,22,27,33,37,42,47,53,59,65/) + cnLevels = (/0.5,0.55,0.60,0.65,0.7,0.75,0.8,0.85,0.9,0.95,0.99/) + do gg = 0,dimsizes(cnLevels) + if (gg.eq.0) then + fcolors = where(patcor.lt.cnLevels(0),colors(0),fcolors) + end if + if (gg.ge.1.and.gg.lt.dimsizes(cnLevels)) then + fcolors = where(patcor.lt.cnLevels(gg).and.patcor.ge.cnLevels(gg-1),colors(gg),fcolors) + end if + if (gg.eq.dimsizes(cnLevels)) then + fcolors = where(patcor.ge.cnLevels(gg-1),colors(gg),fcolors) + end if + end do + fcolors = where(patcor.eq."----",75,fcolors) + + fcolorsR = new(dimsizes(rms),"integer") + colorsR = (/65,59,53,47,42,37,33,27,22,17,12,7/) + cnLevelsR = (/.05,.1,.2,.3,.4,.5,.6,.7,.8,.9,1./) + do gg = 0,dimsizes(cnLevelsR) + if (gg.eq.0) then + fcolorsR = where(rms.lt.cnLevelsR(0),colorsR(0),fcolorsR) + end if + if (gg.ge.1.and.gg.lt.dimsizes(cnLevelsR)) then + fcolorsR = where(rms.lt.cnLevelsR(gg).and.rms.ge.cnLevelsR(gg-1),colorsR(gg),fcolorsR) + end if + if (gg.eq.dimsizes(cnLevelsR)) then + fcolorsR = where(rms.ge.cnLevelsR(gg-1),colorsR(gg),fcolorsR) + end if + end do + fcolorsR = where(rms.eq."----",75,fcolorsR) +;-------------------------------------------------------------------------------------------- + wks_type = "png" ; output png + wks_type@wkWidth = 1500 + wks_type@wkHeight = 1500 + if (nsim.ge.80.and.nsim.lt.179) then + wks_type@wkWidth = 2500 + wks_type@wkHeight = 2500 + end if + if (nsim.ge.180) then + wks_type@wkWidth = 4000 + wks_type@wkHeight = 4000 + end if + wks = gsn_open_wks(wks_type,OUTDIR+"table") ; send graphics to PNG file + gsn_merge_colormaps(wks,"cmp_b2r","gsltod") + + resb = True ; resource list for blank plot that gsn_table will be overlaid on + resb@gsnDraw = False + resb@gsnFrame = False + resb@vpXF = 0.3 + title_loc = (/.185,0.075,.185,0.05/) ; default x/y ndc values for location of plot title and subtitle + b_int = 0.0 + if (nsim.le.32) then + resb@vpWidthF = 0.59 + resb@vpYF = 0.825 + resb@vpHeightF = nsim*0.025 + if (resb@vpHeightF.lt..175) then ; set a minimum height + resb@vpHeightF = .175 + end if + resb@tmXTLabelFontHeightF = 0.0125 + resb@tmXTMajorLengthF = 0.009 + end if + if (nsim.ge.33.and.nsim.lt.80) then + resb@vpWidthF = 0.59 + resb@vpYF = 0.865 + resb@vpHeightF = 0.8601 + resb@tmXTLabelFontHeightF = 0.0085 + resb@tmXTMajorLengthF = 0.009 + end if + if (nsim.ge.80.and.nsim.lt.109) then + resb@vpWidthF = 0.59 + resb@vpYF = 0.865 + resb@vpHeightF = 0.8602 + resb@tmXTLabelFontHeightF = 0.0065 + resb@tmXTMajorLengthF = 0.009 + b_int = .00185 + end if + if (nsim.ge.109.and.nsim.lt.150) then + resb@vpWidthF = 0.425 + resb@vpYF = 0.865 + resb@vpHeightF = 0.8603 + resb@tmXTLabelFontHeightF = 0.0045 + resb@tmXTMajorLengthF = 0.0065 + title_loc = (/.085,0.035,.085,0.025/) + b_int = .002 + end if + if (nsim.ge.150) then + resb@vpWidthF = 0.25 + resb@vpYF = 0.865 + resb@vpHeightF = 0.8604 + resb@tmXTLabelFontHeightF = 0.0025 + resb@tmXTMajorLengthF = 0.0045 + title_loc = (/.07,0.02,.07,0.0125/) + b_int = .002 + end if + resb@tmYLMajorLengthF = resb@tmXTMajorLengthF + resb@tmXTMajorOutwardLengthF = resb@tmXTMajorLengthF + resb@tmYLMajorOutwardLengthF = resb@tmXTMajorLengthF + resb@tmXTMajorLineColor = "gray55" + resb@tmYLMajorLineColor = resb@tmXTMajorLineColor + resb@tmXTLabelFont = 21 + resb@tmXTMode = "Explicit" ; Explicitly label X axis. The blank plot goes from 0 to 1, by default. + resb@tmXTValues = fspan(col_width2,1.-col_width2,ncols) + ncol_labels = (/"ENSO TAS (DJF~S~+1~N~)","ENSO PSL (DJF~S~+1~N~)","El Nin~H-13V2F35~D~FV-2H3F21~o Hovmo~H-14V2F35~H~FV-2H3~ller","La Nin~H-13V2F35~D~FV-2H3F21~a Hovmo~H-14V2F35~H~FV-2H3~ller","AMO","PDO", \ + "NAM (DJF)","SAM (DJF)","SST std dev (Ann)","PSL std dev (Ann)","PR std dev (Ann)","Mean Score"/) + resb@tmXTLabels = ncol_labels + resb@tmXTOn = True + resb@tmXUseBottom = False + resb@tmXTLabelsOn = True + resb@tmXBOn = False + resb@tmXTLabelAngleF = 70. + resb@tmXTLabelJust = "CenterLeft" + + resb@tmYLMode = "Explicit" + if (nsim.gt.1) then + resb@tmYLValues = fspan(row_width2,1.-row_width2,nrows) + else + resb@tmYLValues = row_width2 + end if + resb@tmYLLabelFontHeightF = resb@tmXTLabelFontHeightF + resb@tmYROn = False + resb@tiMainOn = False + + resT = True + resT@gsLineThicknessF = 2.0 + resT@gsLineColor = resb@tmXTMajorLineColor + resT@txFontHeightF = resb@tmXTLabelFontHeightF + resT@gsFillOpacityF = 0.5 + resT@tfPolyDrawOrder = "PreDraw" + + polyres = True + polyres@gsLineColor = "gray25" + polyres@gsLineThicknessF = 8.0 + polyres@gsLineDashPattern = 0 + polyres@tfPolyDrawOrder = "PostDraw" + + tres = True + tres@txFontHeightF = resb@tmYLLabelFontHeightF*1.2 + tres@txJust = "CenterLeft" + + tres2 = tres + tres2@txFontHeightF = resb@tmYLLabelFontHeightF*0.8 + do gg = 0,13 + namesF = names + patcorF = patcor + if (gg.eq.0) then + int_s = namesF&sim + s_txt = "" + end if + if (gg.eq.1) then ; sort names + namesF = str_upper(namesF) ; make all model names uppercase so sqsort sorts like this: A,b,C instead of this: A,C,b + sqsort(namesF) + int_s = namesF&sim + namesF = names(int_s) + s_txt = "Namelist (Alphab.)" + end if + if (gg.ge.2) then + patcorT = patcorF(:,gg-2) + sqsort(patcorT) + int_s = patcorT&sim(::-1) + namesF = names(int_s) + delete(patcorT) + s_txt = ncol_labels(gg-2) + end if + resb@tmYLLabels = namesF(::-1) ; this resource takes labels in reverse order as gsn_table + blank = gsn_csm_blank_plot(wks,resb) + add_labelbar(wks,blank,colors,""+decimalPlaces(cnLevels,2,True)) ; Attach labelbar + if (gg.eq.2) then + dum = gsn_add_polyline(wks,blank,(/.002,.083333,.083333,.002,.002/),(/.002-b_int,.002-b_int,.998+b_int,.998+b_int,.002-b_int/),polyres) + end if + if (gg.ge.3.and.gg.le.12) then + dum = gsn_add_polyline(wks,blank,(/(gg-2)*.083333,(gg-1)*.083333,(gg-1)*.083333,(gg-2)*.083333,(gg-2)*.083333/),(/.002-b_int,.002-b_int,.998+b_int,.998+b_int,.002-b_int/),polyres) + end if + if (gg.eq.13) then + dum = gsn_add_polyline(wks,blank,(/(gg-2)*.083333,.998,.998,(gg-2)*.083333,(gg-2)*.083333/),(/.002-b_int,.002-b_int,.998+b_int,.998+b_int,.002-b_int/),polyres) + end if + + getvalues blank + "vpXF" : vpx + "vpYF" : vpy ; Get position and size of the blank plot so we can + "vpWidthF" : vpw ; be sure to draw the table in same location. + "vpHeightF" : vph + end getvalues + x = (/vpx,vpx+vpw/) + y = (/vpy-vph,vpy/) + + resT@gsFillColor = fcolors(int_s,:) + + if (.not.errmsg) then ; turn off error messages output from gsn_table if NCL v6.4.0 or older + err = NhlGetErrorObjectId() + setvalues err + "errPrint" : "False" + end setvalues + end if + gsn_table(wks,dimsizes(patcorF),x,y,patcorF(int_s,:),resT) + if (.not.errmsg) then + setvalues err + "errPrint" : "True" + end setvalues + end if + gsn_text_ndc(wks,"Pattern Correlations",resb@vpXF-title_loc(0),resb@vpYF+title_loc(1),tres) + if (s_txt.ne."") then + gsn_text_ndc(wks,"Sorted by: "+s_txt,resb@vpXF-title_loc(2),resb@vpYF+title_loc(3),tres2) + end if + draw(blank) + frame(wks) + delete([/namesF,patcorF,int_s/]) + end do + do gg = 0,13 + namesF = names + rmsF = rms + if (gg.eq.0) then + int_s = namesF&sim + s_txt = "" + end if + if (gg.eq.1) then ; sort names + namesF = str_upper(namesF) ; make all model names uppercase so sqsort sorts like this: A,b,C instead of this: A,C,b + sqsort(namesF) + int_s = namesF&sim + namesF = names(int_s) + s_txt = "Name" + end if + if (gg.ge.2) then + rmsT = rmsF(:,gg-2) + rmsT = where(rmsT.eq."----","1000",rmsT) ; make sure values of ---- get put to bottom of sorted list + sqsort(rmsT) + rmsT = where(rmsT.eq."1000","----",rmsT) ; make sure values of ---- get put to bottom of sorted list + int_s = rmsT&sim + namesF = names(int_s) + delete(rmsT) + s_txt = ncol_labels(gg-2) + end if + resb@tmYLLabels = namesF(::-1) ; this resource takes labels in reverse order as gsn_table + blank = gsn_csm_blank_plot(wks,resb) + add_labelbar(wks,blank,colorsR,""+decimalPlaces(cnLevelsR,2,True)) ; Attach labelbar + if (gg.eq.2) then + dum = gsn_add_polyline(wks,blank,(/.002,.083333,.083333,.002,.002/),(/.002-b_int,.002-b_int,.998+b_int,.998+b_int,.002-b_int/),polyres) + end if + if (gg.ge.3.and.gg.le.12) then + dum = gsn_add_polyline(wks,blank,(/(gg-2)*.083333,(gg-1)*.083333,(gg-1)*.083333,(gg-2)*.083333,(gg-2)*.083333/),(/.002-b_int,.002-b_int,.998+b_int,.998+b_int,.002-b_int/),polyres) + end if + if (gg.eq.13) then + dum = gsn_add_polyline(wks,blank,(/(gg-2)*.083333,.998,.998,(gg-2)*.083333,(gg-2)*.083333/),(/.002-b_int,.002-b_int,.998+b_int,.998+b_int,.002-b_int/),polyres) + end if + + getvalues blank + "vpXF" : vpx + "vpYF" : vpy ; Get position and size of the blank plot so we can + "vpWidthF" : vpw ; be sure to draw the table in same location. + "vpHeightF" : vph + end getvalues + x = (/vpx,vpx+vpw/) + y = (/vpy-vph,vpy/) + resT@gsFillColor = fcolorsR(int_s,:) + if (.not.errmsg) then ; turn off error messages output from gsn_table if NCL v6.4.0 or older + err = NhlGetErrorObjectId() + setvalues err + "errPrint" : "False" + end setvalues + end if + gsn_table(wks,dimsizes(rmsF),x,y,rmsF(int_s,:),resT) + if (.not.errmsg) then + setvalues err + "errPrint" : "True" + end setvalues + end if + gsn_text_ndc(wks,"RMS Differences",resb@vpXF-title_loc(0),resb@vpYF+title_loc(1),tres) + if (s_txt.ne."") then + gsn_text_ndc(wks,"Sorted by: "+s_txt,resb@vpXF-title_loc(2),resb@vpYF+title_loc(3),tres2) + end if + draw(blank) + frame(wks) + delete([/namesF,rmsF,int_s/]) + end do + delete(wks) + fils = systemfunc("ls "+OUTDIR+"table*.png") + do gg = 0,dimsizes(fils)-1 + system("convert -density 144 -trim +repage -bordercolor white -border 20 -transparent white "+fils(gg)+" "+OUTDIR+"metrics.table_"+gg+".gif") + end do + system("rm "+OUTDIR+"table*.png") + end if + delete([/patcor_rms,names,nsim/]) + print("Finished: metrics.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/namelist.ncl b/lib/externals/CVDP/ncl_scripts/namelist.ncl new file mode 100644 index 000000000..e3a39518f --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/namelist.ncl @@ -0,0 +1,595 @@ +; use the user specified namelist / namelist_obs files to locate +; the files to be used, and write those file paths to namelist_byvar/namelist_* +; for use by other CVDP scripts. +; +; Note: ".nc" is removed from the paths given in namelist. +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: namelist.ncl") + o = getenv("OBS") + case_sens = getenv("MACHINE") + + if (o.eq."True") then + obsflag = True + else + obsflag = False + end if + + if (.not.isfilepresent2("namelist_byvar/")) then + system("mkdir namelist_byvar") + end if + + nsim = numAsciiRow("namelist") + na = asciiread("namelist",(/nsim/),"string") + + blankrow = ind(na.eq."") + if (.not.any(ismissing(blankrow))) then + goodrows = ind(na.ne."") + na2 = na(goodrows) + delete(na) + na = na2 + delete(na2) + nsim = dimsizes(na) + end if + + system(" export NSIM="+nsim) + + nentry = numAsciiCol("namelist") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + + delim = "|" + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + + delete([/na,delim/]) + + + do gg = 0,nsim-1 ; if path ends in .nc remove it. +; print(paths(gg)) ; (It will get appended to the end of the path automatically when searching below.) + paths(gg) = str_sub_str(paths(gg),".nc","") +; print(paths(gg)) + end do + +;----- Read in namelist_obs, and check number of supplied Observational datasets ------ + + maxnumobs = 0 ; set maximum number of obs datasets per variable. if(obsflag).eq.True, this will likely get altered. + + if (obsflag) then + nobs = numAsciiRow("namelist_obs") + nentryB = numAsciiCol("namelist_obs") + vnamesB = new(nobs,"string") + namesB = new(nobs,"string") + pathsB = new(nobs,"string") + syearBT = new(nobs,"string") + eyearBT = new(nobs,"string") + + na = asciiread("namelist_obs",(/nobs/),"string") +; print(na) + + delim = "|" + + do gg = 0,nobs-1 + vnamesB(gg) = str_strip(str_get_field(na(gg),1,delim)) + namesB(gg) = str_strip(str_get_field(na(gg),2,delim)) + pathsB(gg) = str_strip(str_get_field(na(gg),3,delim)) + syearBT(gg) = str_strip(str_get_field(na(gg),4,delim)) + eyearBT(gg) = str_strip(str_get_field(na(gg),5,delim)) + end do + namesB = where(namesB.eq."",namesB@_FillValue,namesB) + pathsB = where(pathsB.eq."",pathsB@_FillValue,pathsB) + syearBT = where(syearBT.eq."",syearBT@_FillValue,syearBT) + eyearBT = where(eyearBT.eq."",eyearBT@_FillValue,eyearBT) + + maxnumobs = max((/dimsizes(ind(vnamesB.eq."TS")),dimsizes(ind(vnamesB.eq."PSL")),dimsizes(ind(vnamesB.eq."TREFHT")), \ + dimsizes(ind(vnamesB.eq."PRECT")),dimsizes(ind(vnamesB.eq."MOC")),dimsizes(ind(vnamesB.eq."SNOWDP")), \ + dimsizes(ind(vnamesB.eq."aice_nh")),dimsizes(ind(vnamesB.eq."aice_sh"))/)) + syearB = stringtointeger(syearBT) + eyearB = stringtointeger(eyearBT) + + + do gg = 0,nobs-1 ; check to see if any names are duplicated. If they are, add a "_2", "_3" to the name + dupn = ind(namesB.eq.namesB(gg)) ; this is needed so that each output .nc file has a different name + if (dimsizes(dupn).ge.2) then + do hh = 1,dimsizes(dupn)-1 + namesB(dupn(hh)) = namesB(dupn(hh))+"_"+hh + end do + end if + delete(dupn) + end do + delete([/eyearBT,syearBT/]) + delete([/na,delim,nentryB,nobs/]) + asciiwrite("obs_maxnum",maxnumobs) + end if +; print(vnamesB+" "+namesB+" "+pathsB+" "+syearB+" "+eyearB) +;exit +;----- TS section--------------- + namelist_ts = new(nsim+maxnumobs,string) + if (obsflag) then + ts_i = ind(vnamesB.eq."TS") + if (.not.ismissing(ts_i(0))) then + incr = dimsizes(ts_i) + do gg = 0,incr-1 + namelist_ts(gg) = namesB(ts_i(gg))+" | "+pathsB(ts_i(gg))+" | "+syearB(ts_i(gg))+" | "+eyearB(ts_i(gg)) + end do + if (incr.lt.maxnumobs) then ; fill in the missing obs rows with the first obs file, altering the name slightly for .nc write-outs + if (.not.ismissing(namelist_ts(0))) then + nmiss = ind(ismissing(namelist_ts(:maxnumobs-1))) + do hh = nmiss(0),nmiss(dimsizes(nmiss)-1) + namelist_ts(hh) = namesB(ts_i(0))+"_"+hh+" | "+pathsB(ts_i(0))+" | "+syearB(ts_i(0))+" | "+eyearB(ts_i(0)) + end do + delete(nmiss) + end if + end if + asciiwrite("obs_ts",namelist_ts(0)) + delete(incr) + end if + delete(ts_i) + end if + + if (case_sens.eq."True") then + tstring1 = "TS,ts,t_surf,sst" ; list in order of likelihood/preference: CESM name, CMIP name, other + else + tstring1 = "TS,t_surf,sst" + end if + sstr := str_split(tstring1,",") + + do gg = 0,nsim-1 + do hh = 0,dimsizes(sstr)-1 + namelist_ts(gg+maxnumobs) = names(gg)+" | missing | "+syear(gg)+" | "+eyear(gg) ; set to missing as default + fsst := systemfunc("bash -c 'ls "+paths(gg)+"*."+sstr(hh)+".*.nc 2> /dev/null'") ; /dev/null suppresses all standard error output + if (.not.ismissing(fsst(0))) then + if (dimsizes(fsst).eq.1) then + fsst@path = fsst + else + fsst@path = paths(gg)+"*."+sstr(hh)+".*.nc" + end if + namelist_ts(gg+maxnumobs) = names(gg)+" | "+fsst@path+" | "+syear(gg)+" | "+eyear(gg) + break + else ; try different method to find files + tpath := str_sub_str(paths(gg),"/*/","/"+sstr(hh)+"/") + tpath = str_sub_str(tpath,"/*_","/"+sstr(hh)+"_") + fsst2 := systemfunc("bash -c 'ls "+tpath+"*.nc 2> /dev/null'") + if (.not.ismissing(fsst2(0))) then + if (str_match_bool(fsst2(0),sstr(hh))) then + namelist_ts(gg+maxnumobs) = names(gg)+" | "+tpath+"*.nc | "+syear(gg)+" | "+eyear(gg) + break + end if + end if + end if + end do + end do + asciiwrite("namelist_byvar/namelist_ts",namelist_ts) +;------- PSL section---------------------------- + namelist_psl = new(nsim+maxnumobs,string) + if (obsflag) then + psl_i = ind(vnamesB.eq."PSL") + if (.not.ismissing(psl_i(0))) then + incr = dimsizes(psl_i) + do gg = 0,incr-1 + namelist_psl(gg) = namesB(psl_i(gg))+" | "+pathsB(psl_i(gg))+" | "+syearB(psl_i(gg))+" | "+eyearB(psl_i(gg)) + end do + if (incr.lt.maxnumobs) then ; fill in the missing obs rows with the first obs file, altering the name slightly for .nc write-outs + if (.not.ismissing(namelist_psl(0))) then + nmiss = ind(ismissing(namelist_psl(:maxnumobs-1))) + do hh = nmiss(0),nmiss(dimsizes(nmiss)-1) + namelist_psl(hh) = namesB(psl_i(0))+"_"+hh+" | "+pathsB(psl_i(0))+" | "+syearB(psl_i(0))+" | "+eyearB(psl_i(0)) + end do + delete(nmiss) + end if + end if + asciiwrite("obs_psl",namelist_psl(0)) + delete(incr) + end if + delete(psl_i) + end if + + if (case_sens.eq."True") then + tstring1 = "PSL,psl,SLP,slp" ; list in order of likelihood/preference: CESM name, CMIP name, other + else + tstring1 = "PSL,slp" + end if + sstr := str_split(tstring1,",") + + do gg = 0,nsim-1 + do hh = 0,dimsizes(sstr)-1 + namelist_psl(gg+maxnumobs) = names(gg)+" | missing | "+syear(gg)+" | "+eyear(gg) ; set to missing as default + fsst := systemfunc("bash -c 'ls "+paths(gg)+"*."+sstr(hh)+".*.nc 2> /dev/null'") ; /dev/null suppresses all standard error output + if (.not.ismissing(fsst(0))) then + if (dimsizes(fsst).eq.1) then + fsst@path = fsst + else + fsst@path = paths(gg)+"*."+sstr(hh)+".*.nc" + end if + namelist_psl(gg+maxnumobs) = names(gg)+" | "+fsst@path+" | "+syear(gg)+" | "+eyear(gg) + break + else ; try different method to find files + tpath := str_sub_str(paths(gg),"/*/","/"+sstr(hh)+"/") + tpath = str_sub_str(tpath,"/*_","/"+sstr(hh)+"_") + fsst2 := systemfunc("bash -c 'ls "+tpath+"*.nc 2> /dev/null'") + if (.not.ismissing(fsst2(0))) then + if (str_match_bool(fsst2(0),sstr(hh))) then + namelist_psl(gg+maxnumobs) = names(gg)+" | "+tpath+"*.nc | "+syear(gg)+" | "+eyear(gg) + break + end if + end if + end if + end do + end do + asciiwrite("namelist_byvar/namelist_psl",namelist_psl) +;------- TREFHT section---------------------------- + namelist_trefht = new(nsim+maxnumobs,string) + if (obsflag) then + trefht_i = ind(vnamesB.eq."TREFHT") + if (.not.ismissing(trefht_i(0))) then + incr = dimsizes(trefht_i) + do gg = 0,incr-1 + namelist_trefht(gg) = namesB(trefht_i(gg))+" | "+pathsB(trefht_i(gg))+" | "+syearB(trefht_i(gg))+" | "+eyearB(trefht_i(gg)) + end do + if (incr.lt.maxnumobs) then ; fill in the missing obs rows with the first obs file, altering the name slightly for .nc write-outs + if (.not.ismissing(namelist_trefht(0))) then + nmiss = ind(ismissing(namelist_trefht(:maxnumobs-1))) + do hh = nmiss(0),nmiss(dimsizes(nmiss)-1) + namelist_trefht(hh) = namesB(trefht_i(0))+"_"+hh+" | "+pathsB(trefht_i(0))+" | "+syearB(trefht_i(0))+" | "+eyearB(trefht_i(0)) + end do + delete(nmiss) + end if + end if + asciiwrite("obs_trefht",namelist_trefht(0)) + delete(incr) + end if + delete(trefht_i) + end if + + if (case_sens.eq."True") then + tstring1 = "TREFHT,tas,t_ref,T2" ; list in order of likelihood/preference: CESM name, CMIP name, other + else + tstring1 = "TREFHT,tas,t_ref,T2" + end if + sstr := str_split(tstring1,",") + + do gg = 0,nsim-1 + do hh = 0,dimsizes(sstr)-1 + namelist_trefht(gg+maxnumobs) = names(gg)+" | missing | "+syear(gg)+" | "+eyear(gg) ; set to missing as default + fsst := systemfunc("bash -c 'ls "+paths(gg)+"*."+sstr(hh)+".*.nc 2> /dev/null'") ; /dev/null suppresses all standard error output + if (.not.ismissing(fsst(0))) then + if (dimsizes(fsst).eq.1) then + fsst@path = fsst + else + fsst@path = paths(gg)+"*."+sstr(hh)+".*.nc" + end if + namelist_trefht(gg+maxnumobs) = names(gg)+" | "+fsst@path+" | "+syear(gg)+" | "+eyear(gg) + break + else ; try different method to find files + tpath := str_sub_str(paths(gg),"/*/","/"+sstr(hh)+"/") + tpath = str_sub_str(tpath,"/*_","/"+sstr(hh)+"_") + fsst2 := systemfunc("bash -c 'ls "+tpath+"*.nc 2> /dev/null'") + if (.not.ismissing(fsst2(0))) then + if (str_match_bool(fsst2(0),sstr(hh))) then + namelist_trefht(gg+maxnumobs) = names(gg)+" | "+tpath+"*.nc | "+syear(gg)+" | "+eyear(gg) + break + end if + end if + end if + end do + end do + asciiwrite("namelist_byvar/namelist_trefht",namelist_trefht) +;------- PRECT section--(more complicated due to PRECC+PRECL, + pr being a common 2 letter combination)------ + namelist_prect = new(nsim+maxnumobs,string) + if (obsflag) then + prect_i = ind(vnamesB.eq."PRECT") + if (.not.ismissing(prect_i(0))) then + incr = dimsizes(prect_i) + do gg = 0,incr-1 + namelist_prect(gg) = namesB(prect_i(gg))+" | "+pathsB(prect_i(gg))+" | "+syearB(prect_i(gg))+" | "+eyearB(prect_i(gg)) + end do + if (incr.lt.maxnumobs) then ; fill in the missing obs rows with the first obs file, altering the name slightly for .nc write-ouprect + if (.not.ismissing(namelist_prect(0))) then + nmiss = ind(ismissing(namelist_prect(:maxnumobs-1))) + do hh = nmiss(0),nmiss(dimsizes(nmiss)-1) + namelist_prect(hh) = namesB(prect_i(0))+"_"+hh+" | "+pathsB(prect_i(0))+" | "+syearB(prect_i(0))+" | "+eyearB(prect_i(0)) + end do + delete(nmiss) + end if + end if + asciiwrite("obs_prect",namelist_prect(0)) + delete(incr) + end if + delete(prect_i) + end if + + if (case_sens.eq."True") then + tstring1 = "PRECT,PRECC,pr,precip,prate,prcp" ; list in order of likelihood/preference: CESM name, CMIP name, other + else + tstring1 = "PRECT,PRECC,pr,precip,prate,prcp" + end if + sstr := str_split(tstring1,",") + + do gg = 0,nsim-1 + do hh = 0,dimsizes(sstr)-1 + namelist_prect(gg+maxnumobs) = names(gg)+" | missing | "+syear(gg)+" | "+eyear(gg) ; set to missing as default + fsst := systemfunc("bash -c 'ls "+paths(gg)+"*."+sstr(hh)+".*.nc 2> /dev/null'") ; /dev/null suppresses all standard error output + if (.not.ismissing(fsst(0))) then + if (sstr(hh).eq."PRECC") then ; add PRECL to search string + if (dimsizes(fsst).eq.1) then + fsst@path = str_sub_str(fsst,".PRECC.",".{PRECC,PRECL}.") + else + fsst@path = str_sub_str(paths(gg)+"*."+sstr(hh)+".*.nc",".PRECC.",".{PRECC,PRECL}.") + end if + else + if (dimsizes(fsst).eq.1) then + fsst@path = fsst + else + fsst@path = paths(gg)+"*."+sstr(hh)+".*.nc" + end if + end if + namelist_prect(gg+maxnumobs) = names(gg)+" | "+fsst@path+" | "+syear(gg)+" | "+eyear(gg) + break + else ; if files have not been found, try the following + if (sstr(hh).eq."PRECC") then + tstring = "{PRECC,PRECL}" + else + tstring = sstr(hh) + end if + tpath := str_sub_str(paths(gg),"/*/","/"+tstring+"/") + tpath = str_sub_str(tpath,"/*_","/"+tstring+"_") + fsst2 := systemfunc("bash -c 'ls "+tpath+"*.nc 2> /dev/null'") + if (.not.ismissing(fsst2(0))) then + if (str_match_bool(fsst2(0),tstring)) then + x = addfile(fsst2(0),"r") + if (isfilevar(x,sstr(hh))) then + delete(x) + namelist_prect(gg+maxnumobs) = names(gg)+" | "+tpath+"*.nc | "+syear(gg)+" | "+eyear(gg) + break + else + delete(x) + end if + end if + end if + delete([/tpath,tstring/]) + end if + end do + end do + asciiwrite("namelist_byvar/namelist_prect",namelist_prect) +;----- SNOWDP section--------------- + namelist_snowdp = new(nsim+maxnumobs,string) + if (obsflag) then + snowdp_i = ind(vnamesB.eq."SNOWDP") + if (.not.ismissing(snowdp_i(0))) then + incr = dimsizes(snowdp_i) + do gg = 0,incr-1 + namelist_snowdp(gg) = namesB(snowdp_i(gg))+" | "+pathsB(snowdp_i(gg))+" | "+syearB(snowdp_i(gg))+" | "+eyearB(snowdp_i(gg)) + end do + if (incr.lt.maxnumobs) then ; fill in the missing obs rows with the first obs file, altering the name slightly for .nc write-outs + if (.not.ismissing(namelist_snowdp(0))) then + nmiss = ind(ismissing(namelist_snowdp(:maxnumobs-1))) + do hh = nmiss(0),nmiss(dimsizes(nmiss)-1) + namelist_snowdp(hh) = namesB(snowdp_i(0))+"_"+hh+" | "+pathsB(snowdp_i(0))+" | "+syearB(snowdp_i(0))+" | "+eyearB(snowdp_i(0)) + end do + delete(nmiss) + end if + end if + asciiwrite("obs_snowdp",namelist_snowdp(0)) + delete(incr) + end if + delete(snowdp_i) + end if + + tstring1 = "SNOWDP,snd" ; list in order of likelihood/preference: CESM name, CMIP name, other + sstr := str_split(tstring1,",") + + do gg = 0,nsim-1 + do hh = 0,dimsizes(sstr)-1 + namelist_snowdp(gg+maxnumobs) = names(gg)+" | missing | "+syear(gg)+" | "+eyear(gg) ; set to missing as default + fsst := systemfunc("bash -c 'ls "+paths(gg)+"*."+sstr(hh)+".*.nc 2> /dev/null'") ; /dev/null suppresses all standard error output + if (.not.ismissing(fsst(0))) then + if (dimsizes(fsst).eq.1) then + fsst@path = fsst + else + fsst@path = paths(gg)+"*."+sstr(hh)+".*.nc" + end if + namelist_snowdp(gg+maxnumobs) = names(gg)+" | "+fsst@path+" | "+syear(gg)+" | "+eyear(gg) + break + else ; try different method to find files + tpath := str_sub_str(paths(gg),"/*/","/"+sstr(hh)+"/") + tpath = str_sub_str(tpath,"/*_","/"+sstr(hh)+"_") + fsst2 := systemfunc("bash -c 'ls "+tpath+"*.nc 2> /dev/null'") + if (.not.ismissing(fsst2(0))) then + if (str_match_bool(fsst2(0),sstr(hh))) then + namelist_snowdp(gg+maxnumobs) = names(gg)+" | "+tpath+"*.nc | "+syear(gg)+" | "+eyear(gg) + break + end if + end if + end if + end do + end do + asciiwrite("namelist_byvar/namelist_snowdp",namelist_snowdp) +;------- MOC section---------------------------- + namelist_moc = new(nsim+maxnumobs,string) + if (obsflag) then + moc_i = ind(vnamesB.eq."MOC") + if (.not.ismissing(moc_i(0))) then + incr = dimsizes(moc_i) + do gg = 0,incr-1 + namelist_moc(gg) = namesB(moc_i(gg))+" | "+pathsB(moc_i(gg))+" | "+syearB(moc_i(gg))+" | "+eyearB(moc_i(gg)) + end do + if (incr.lt.maxnumobs) then ; fill in the missing obs rows with the first obs file, altering the name slightly for .nc write-outs + if (.not.ismissing(namelist_moc(0))) then + nmiss = ind(ismissing(namelist_moc(:maxnumobs-1))) + do hh = nmiss(0),nmiss(dimsizes(nmiss)-1) + namelist_moc(hh) = namesB(moc_i(0))+"_"+hh+" | "+pathsB(moc_i(0))+" | "+syearB(moc_i(0))+" | "+eyearB(moc_i(0)) + end do + delete(nmiss) + end if + end if + asciiwrite("obs_moc",namelist_moc(0)) + delete(incr) + end if + delete(moc_i) + end if + + if (case_sens.eq."True") then + tstring1 = "MOC,msftmyz,msftmz,stfmmc" ; list in order of likelihood/preference: CESM name, CMIP name, other + else + tstring1 = "MOC,msftmyz,msftmz,stfmmc" + end if + sstr := str_split(tstring1,",") + + do gg = 0,nsim-1 + do hh = 0,dimsizes(sstr)-1 + namelist_moc(gg+maxnumobs) = names(gg)+" | missing | "+syear(gg)+" | "+eyear(gg) ; set to missing as default + fsst := systemfunc("bash -c 'ls "+paths(gg)+"*."+sstr(hh)+".*.nc 2> /dev/null'") ; /dev/null suppresses all standard error output + if (.not.ismissing(fsst(0))) then + if (dimsizes(fsst).eq.1) then + fsst@path = fsst + else + fsst@path = paths(gg)+"*."+sstr(hh)+".*.nc" + end if + namelist_moc(gg+maxnumobs) = names(gg)+" | "+fsst@path+" | "+syear(gg)+" | "+eyear(gg) + break + else ; try different method to find files + tpath := str_sub_str(paths(gg),"/*/","/"+sstr(hh)+"/") + tpath = str_sub_str(tpath,"/*_","/"+sstr(hh)+"_") + fsst2 := systemfunc("bash -c 'ls "+tpath+"*.nc 2> /dev/null'") + if (.not.ismissing(fsst2(0))) then + if (str_match_bool(fsst2(0),sstr(hh))) then + namelist_moc(gg+maxnumobs) = names(gg)+" | "+tpath+"*.nc | "+syear(gg)+" | "+eyear(gg) + break + end if + end if + end if + end do + end do + asciiwrite("namelist_byvar/namelist_moc",namelist_moc) + +;------- aice_nh section---------------------------- + namelist_aice_nh = new(nsim+maxnumobs,string) + if (obsflag) then + aice_nh_i = ind(vnamesB.eq."aice_nh".or.vnamesB.eq."AICE_NH") + if (.not.ismissing(aice_nh_i(0))) then + incr = dimsizes(aice_nh_i) + do gg = 0,incr-1 + namelist_aice_nh(gg) = namesB(aice_nh_i(gg))+" | "+pathsB(aice_nh_i(gg))+" | "+syearB(aice_nh_i(gg))+" | "+eyearB(aice_nh_i(gg)) + end do + if (incr.lt.maxnumobs) then ; fill in the missing obs rows with the first obs file, altering the name slightly for .nc write-outs + if (.not.ismissing(namelist_aice_nh(0))) then + nmiss = ind(ismissing(namelist_aice_nh(:maxnumobs-1))) + do hh = nmiss(0),nmiss(dimsizes(nmiss)-1) + namelist_aice_nh(hh) = namesB(aice_nh_i(0))+"_"+hh+" | "+pathsB(aice_nh_i(0))+" | "+syearB(aice_nh_i(0))+" | "+eyearB(aice_nh_i(0)) + end do + delete(nmiss) + end if + end if + asciiwrite("obs_aice_nh",namelist_aice_nh(0)) + delete(incr) + end if + delete(aice_nh_i) + end if + + if (case_sens.eq."True") then + tstring1 = "aice_nh,aice,siconc,sic,CN" ; list in order of likelihood/preference: CESM name, CMIP name, other + else ; aice_nh (CESM1 nomenclature used in some data) should be checked before aice + tstring1 = "aice_nh,aice,siconc,sic,CN" + end if + sstr := str_split(tstring1,",") + + do gg = 0,nsim-1 + do hh = 0,dimsizes(sstr)-1 + namelist_aice_nh(gg+maxnumobs) = names(gg)+" | missing | "+syear(gg)+" | "+eyear(gg) ; set to missing as default + fsst := systemfunc("bash -c 'ls "+paths(gg)+"*."+sstr(hh)+".*.nc 2> /dev/null'") ; /dev/null suppresses all standard error output + if (.not.ismissing(fsst(0))) then + if (dimsizes(fsst).eq.1) then + fsst@path = fsst + else + fsst@path = paths(gg)+"*."+sstr(hh)+".*.nc" + end if + namelist_aice_nh(gg+maxnumobs) = names(gg)+" | "+fsst@path+" | "+syear(gg)+" | "+eyear(gg) + break + else ; try different method to find files + tpath := str_sub_str(paths(gg),"/*/","/"+sstr(hh)+"/") + tpath = str_sub_str(tpath,"/*_","/"+sstr(hh)+"_") + fsst2 := systemfunc("bash -c 'ls "+tpath+"*.nc 2> /dev/null'") + if (.not.ismissing(fsst2(0))) then + if (str_match_bool(fsst2(0),sstr(hh))) then + namelist_aice_nh(gg+maxnumobs) = names(gg)+" | "+tpath+"*.nc | "+syear(gg)+" | "+eyear(gg) + break + end if + end if + end if + end do + end do + asciiwrite("namelist_byvar/namelist_aice_nh",namelist_aice_nh) +;------- aice_sh section---------------------------- + namelist_aice_sh = new(nsim+maxnumobs,string) + if (obsflag) then + aice_sh_i = ind(vnamesB.eq."aice_sh".or.vnamesB.eq."AICE_SH") + if (.not.ismissing(aice_sh_i(0))) then + incr = dimsizes(aice_sh_i) + do gg = 0,incr-1 + namelist_aice_sh(gg) = namesB(aice_sh_i(gg))+" | "+pathsB(aice_sh_i(gg))+" | "+syearB(aice_sh_i(gg))+" | "+eyearB(aice_sh_i(gg)) + end do + if (incr.lt.maxnumobs) then ; fill in the missing obs rows with the first obs file, altering the name slightly for .nc write-outs + if (.not.ismissing(namelist_aice_sh(0))) then + nmiss = ind(ismissing(namelist_aice_sh(:maxnumobs-1))) + do hh = nmiss(0),nmiss(dimsizes(nmiss)-1) + namelist_aice_sh(hh) = namesB(aice_sh_i(0))+"_"+hh+" | "+pathsB(aice_sh_i(0))+" | "+syearB(aice_sh_i(0))+" | "+eyearB(aice_sh_i(0)) + end do + delete(nmiss) + end if + end if + asciiwrite("obs_aice_sh",namelist_aice_sh(0)) + delete(incr) + end if + delete(aice_sh_i) + end if + + if (case_sens.eq."True") then + tstring1 = "aice_sh,aice,siconc,sic,CN" ; list in order of likelihood/preference: CESM name, CMIP name, other + else ; aice_sh (CESM1 nomenclature used in some data) should be checked before aice + tstring1 = "aice_sh,aice,siconc,sic,CN" + end if + sstr := str_split(tstring1,",") + + do gg = 0,nsim-1 + do hh = 0,dimsizes(sstr)-1 + namelist_aice_sh(gg+maxnumobs) = names(gg)+" | missing | "+syear(gg)+" | "+eyear(gg) ; set to missing as default + fsst := systemfunc("bash -c 'ls "+paths(gg)+"*."+sstr(hh)+".*.nc 2> /dev/null'") ; /dev/null suppresses all standard error output + if (.not.ismissing(fsst(0))) then + if (dimsizes(fsst).eq.1) then + fsst@path = fsst + else + fsst@path = paths(gg)+"*."+sstr(hh)+".*.nc" + end if + namelist_aice_sh(gg+maxnumobs) = names(gg)+" | "+fsst@path+" | "+syear(gg)+" | "+eyear(gg) + break + else ; try different method to find files + tpath := str_sub_str(paths(gg),"/*/","/"+sstr(hh)+"/") + tpath = str_sub_str(tpath,"/*_","/"+sstr(hh)+"_") + fsst2 := systemfunc("bash -c 'ls "+tpath+"*.nc 2> /dev/null'") + if (.not.ismissing(fsst2(0))) then + if (str_match_bool(fsst2(0),sstr(hh))) then + namelist_aice_sh(gg+maxnumobs) = names(gg)+" | "+tpath+"*.nc | "+syear(gg)+" | "+eyear(gg) + break + end if + end if + end if + end do + end do + asciiwrite("namelist_byvar/namelist_aice_sh",namelist_aice_sh) +;---------------------------------------------------------------------------- + if (obsflag) then + delete([/vnamesB,namesB,pathsB,syearB,eyearB/]) + end if + print("Finished: namelist.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/ncfiles.append.ncl b/lib/externals/CVDP/ncl_scripts/ncfiles.append.ncl new file mode 100644 index 000000000..4ec09fa02 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/ncfiles.append.ncl @@ -0,0 +1,142 @@ +; Concatenate all .nc files from same model/observational dataset +; into a single .nc file. + +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +;load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: ncfiles.append.ncl") + + OUTDIR = getenv("OUTDIR") + o = getenv("OBS") +; + if (o.eq."True") then + obsflag = True + else + obsflag = False + end if + + nsim = numAsciiRow("namelist") + na = asciiread("namelist",(/nsim/),"string") + + blankrow = ind(na.eq."") + if (.not.any(ismissing(blankrow))) then + goodrows = ind(na.ne."") + na2 = na(goodrows) + delete(na) + na = na2 + delete(na2) + nsim = dimsizes(na) + end if + + nentry = numAsciiCol("namelist") + names = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + + delim = "|" + do gg = 0,nsim-1 + names(gg) = str_sub_str(str_sub_str(str_sub_str(str_sub_str(str_sub_str(str_strip(str_get_field(na(gg),1,delim))," ","_"),"/","_"),"'","_"),"(","_"),")","_") + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + + do gg = 0,nsim-1 + fils = systemfunc("ls "+OUTDIR+names(gg)+".*.nc 2> /dev/null") + if (.not.ismissing(fils(0))) then + dimf = dimsizes(fils) + ofile = OUTDIR+names(gg)+".cvdp_data."+syear(gg)+"-"+eyear(gg)+".nc" + if (dimf.eq.1) then + system("mv "+fils(0)+" "+ofile) + else + if (isfilepresent(ofile)) then ; if file master is present append individual data files to file master. + do hh = 0,dimf-1 + if (fils(hh).ne.ofile) then + system("ncks -A -h "+fils(hh)+" "+ofile) + end if + end do + else ; if file master is not present, append individual data files to last file in list, + do hh = 0,dimf-2 ; and when done move the last file to be the master file + system("ncks -A -h "+fils(hh)+" "+fils(dimf-1)) + end do + system("mv "+fils(dimf-1)+" "+ofile) + end if + if (dimsizes(fils(:dimf-2)).ge.2) then + system("rm "+str_sub_str(str_join(fils(:dimf-2)," "),ofile,"")) ; remove each script's file, but do not remove the master file (if present) + end if + end if + system("ncks -O "+ofile+" "+ofile) ; done to alphabetize output variable + delete([/dimf,ofile/]) + else +; print("NetCDF files not found for "+names+", skipping appending") + end if + delete(fils) + end do + delete([/nsim,na,blankrow,nentry,names,syear,eyear/]) +;------------------------------------------------ + if (obsflag) then + maxnumobs = asciiread("obs_maxnum",(/1/),"integer") + + namelist_files = (/"psl","prect","trefht","ts","snowdp","moc","aice_nh","aice_sh"/) + delim = "|" + cntr = 0 + namesB = new(maxnumobs*dimsizes(namelist_files),string) + do gg = 0,dimsizes(namelist_files)-1 ; grab all observational dataset names from namelist_$var files + na = asciiread("namelist_byvar/namelist_"+namelist_files(gg),(/maxnumobs/),"string") + namesB(cntr:cntr+maxnumobs-1) = str_sub_str(str_sub_str(str_sub_str(str_sub_str(str_sub_str(str_strip(str_get_field(na,1,delim))," ","_"),"/","_"),"'","_"),"(","_"),")","_") + cntr = cntr+maxnumobs + delete(na) + end do + + namesB = where(namesB.eq."",namesB@_FillValue,namesB) ; for blank names set them to _FillValue + if (any(namesB.eq."missing")) then + namesB(str_match_ind(namesB,"missing")) = namesB@_FillValue ; check for any names containing "missing", set to _FillValue + end if + delete([/delim,cntr,namelist_files/]) + + do gg = 0,dimsizes(namesB)-1 + if (.not.ismissing(namesB(gg))) then + fils = systemfunc("ls "+OUTDIR+namesB(gg)+".cvdp_data.*.nc 2> /dev/null") + if (.not.ismissing(fils(0))) then + dimf = dimsizes(fils) + fil0 = tochar(fils(0)) + suffix = tostring(fil0(dimsizes(fil0)-12:dimsizes(fil0)-1)) + delete(fil0) + ofi = OUTDIR+namesB(gg)+".cvdp_data."+suffix + if (dimf.ge.2) then + if (isfilepresent(ofi)) then ; if file master is present append individual data files to file master. + do hh = 0,dimf-1 + if (fils(hh).ne.ofi) then + system("ncks -A -h "+fils(hh)+" "+ofi) + end if + end do + else ; if file master is not present, append individual data files to last file in list, + do hh = 0,dimf-2 ; and when done move the last file to be the master file + system("ncks -A -h "+fils(hh)+" "+fils(dimf-1)) + end do + system("mv "+fils(dimf-1)+" "+ofi) + end if + + if (dimsizes(fils(:dimf-2)).ge.2) then + system("rm "+str_sub_str(str_join(fils(:dimf-2)," "),ofi,"")) ; remove each script's file, but do not remove the master file (if present) + end if + else + if (fils(0).ne.ofi) then + system("mv "+fils(0)+" "+ofi) + end if + end if + system("ncks -O "+ofi+" "+ofi) ; done to alphabetize output variable + delete([/dimf,ofi/]) + else +; print("NetCDF files not found for "+namesB(gg)+", skipping appending") + end if + delete(fils) + end if + end do + delete([/namesB/]) + end if + print("Finished: ncfiles.append.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/pdo.ncl b/lib/externals/CVDP/ncl_scripts/pdo.ncl new file mode 100644 index 000000000..36fa3eff8 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/pdo.ncl @@ -0,0 +1,774 @@ +; Calculates the PDO pattern, timeseries, and spectra. +; +; Variables used: ts +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: pdo.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_ts") + na = asciiread("namelist_byvar/namelist_ts",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) +;---------TAS Regressions coding------------------------------------------------- + nsim_tas = numAsciiRow("namelist_byvar/namelist_trefht") + na_tas = asciiread("namelist_byvar/namelist_trefht",(/nsim_tas/),"string") + names_tas = new(nsim_tas,"string") + paths_tas = new(nsim_tas,"string") + syear_tas = new(nsim_tas,"integer",-999) + eyear_tas = new(nsim_tas,"integer",-999) + + do gg = 0,nsim_tas-1 + names_tas(gg) = str_strip(str_get_field(na_tas(gg),1,delim)) + paths_tas(gg) = str_strip(str_get_field(na_tas(gg),2,delim)) + syear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),3,delim))) + eyear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),4,delim))) + end do + delete(na_tas) + nyr_tas = eyear_tas-syear_tas+1 +;---------PR Regressions coding------------------------------------------------- + nsim_pr = numAsciiRow("namelist_byvar/namelist_prect") + na_pr = asciiread("namelist_byvar/namelist_prect",(/nsim_pr/),"string") + names_pr = new(nsim_pr,"string") + paths_pr = new(nsim_pr,"string") + syear_pr = new(nsim_pr,"integer",-999) + eyear_pr = new(nsim_pr,"integer",-999) + + do gg = 0,nsim_pr-1 + names_pr(gg) = str_strip(str_get_field(na_pr(gg),1,delim)) + paths_pr(gg) = str_strip(str_get_field(na_pr(gg),2,delim)) + syear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),3,delim))) + eyear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),4,delim))) + end do + delete(na_pr) + nyr_pr = eyear_pr-syear_pr+1 +;------------------------------------------------------------------------------------------------- + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks = gsn_open_wks(wks_type,getenv("OUTDIR")+"pdo") + wks4 = gsn_open_wks(wks_type,getenv("OUTDIR")+"pdo.prreg") + wks2 = gsn_open_wks(wks_type,getenv("OUTDIR")+"pdo.powspec") + wks3 = gsn_open_wks(wks_type,getenv("OUTDIR")+"pdo.timeseries") + + if (COLORMAP.eq."0") then + gsn_define_colormap(wks,"ncl_default") + gsn_define_colormap(wks2,"cb_9step") + gsn_define_colormap(wks3,"ncl_default") + gsn_define_colormap(wks4,"MPL_BrBG") + end if + if (COLORMAP.eq."1") then + gsn_define_colormap(wks,"BlueDarkRed18") + gsn_define_colormap(wks2,"cb_9step") + gsn_define_colormap(wks3,"ncl_default") + gsn_define_colormap(wks4,"BrownBlue12") + end if + map = new(nsim,"graphic") + map_sst = new(nsim,"graphic") + map_tasreg = new(nsim,"graphic") + map_prreg = new(nsim,"graphic") + pspec = new(nsim,"graphic") + xyplot = new(nsim,"graphic") + xyplot2 = new(nsim,"graphic") + if (isfilepresent2("obs_ts")) then + pspec_obs = new(nsim,"graphic") + end if + + tasreg_frame = 1 ; *reg_frame = flag to create regressions .ps/.png files. Created/used instead of *reg_plot_flag + ; so that if {tas,pr} regressions are not created for the last simulation listed that .ps/png files are created + prreg_frame = 1 + do ee = 0,nsim-1 + sst = data_read_in(paths(ee),"TS",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(sst,"is_all_missing").or.nyr(ee).lt.15) then + delete(sst) + continue + end if + sst = where(sst.le.-1.8,-1.8,sst) ; set all values below -1.8 to -1.8 + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") ; mask out land (this is redundant for data that is already masked) + basemap = d->LSMASK + lsm = landsea_mask(basemap,sst&lat,sst&lon) + sst = mask(sst,conform(sst,lsm,(/1,2/)).ge.1,False) + delete([/lsm,basemap/]) + delete(d) + + if (OPT_CLIMO.eq."Full") then + sst = rmMonAnnCycTLL(sst) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sst + delete(temp_arr&time) + temp_arr&time = cd_calendar(sst&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sst = calcMonAnomTLL(sst,climo) + delete(climo) + end if + + coswgt=cos(rad*sst&lat) + coswgt!0 = "lat" + coswgt&lat= sst&lat + + do ff = 0,dimsizes(sst&time)-1 + sst(ff,:,:) = (/ sst(ff,:,:) - wgt_areaave(sst(ff,{-60:70},:),coswgt({-60.:70.}),1.0,0) /) + end do + delete(coswgt) + sst2 = sst(lat|:,lon|:,time|:) + delete(sst) + sst_CW= SqrtCosWeight(sst2(time|:,lat|:,lon|:)) + + evecv = eofunc(sst_CW({lat|20:70},{lon|110:260},time|:),2,75) + delete(sst_CW) + pcts = eofunc_ts(sst2({20:70},{110:260},:),evecv,False) + pctsS = dim_standardize(pcts(0,:),0) + delete([/pcts/]) + finarr = sst2(:,:,0) + finarr = finarr@_FillValue + + finarr = (/ regCoef(pctsS,sst2) /) + finarr@syear = syear(ee) + finarr@eyear = eyear(ee) + + pdo = finarr + pc1 = pctsS + pc1!0 = "time" + pc1&time = sst2&time + pc1@units = "1" + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(pc1),False) + if (sig_pcv(0)) then ; if True then significant + pdo@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + pdo@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete([/sig_pcv,evecv/]) + + if (.not.ismissing(pdo({37},{200}))) then + if (pdo({37},{200}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + pdo = pdo*-1. + pc1 = pc1*-1. + end if + end if + delete([/sst2,pctsS,finarr/]) +;---------TAS Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_tas(ee),eyear(ee),eyear_tas(ee)/)))) then + tasreg_plot_flag = 1 + else + if (syear(ee).eq.syear_tas(ee)) then ; check that the start and end years match for ts, tas, and psl + if (eyear(ee).eq.eyear_tas(ee)) then + tasreg_plot_flag = 0 + else + tasreg_plot_flag = 1 + end if + else + tasreg_plot_flag = 1 + end if + end if + + if (tasreg_plot_flag.eq.0) then + tas = data_read_in(paths_tas(ee),"TREFHT",syear_tas(ee),eyear_tas(ee)) + if (isatt(tas,"is_all_missing")) then + tasreg_plot_flag = 1 + delete(tas) + end if + + if (tasreg_plot_flag.eq.0) then ; only continue if both TAS/SST fields are present + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,tas&lat,tas&lon) + tas = mask(tas,conform(tas,lsm,(/1,2/)).eq.0,False) + delete(lsm) + + if (OPT_CLIMO.eq."Full") then + tas = rmMonAnnCycTLL(tas) + else + check_custom_climo(names_tas(ee),syear_tas(ee),eyear_tas(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = tas + delete(temp_arr&time) + temp_arr&time = cd_calendar(tas&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + tas = calcMonAnomTLL(tas,climo) + delete(climo) + end if + finreg_tas = tas(0,:,:) + finreg_tas = (/ regCoef(pc1,tas(lat|:,lon|:,time|:)) /) + delete(tas) + end if + end if +;---------PR Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_pr(ee),eyear(ee),eyear_pr(ee)/)))) then + prreg_plot_flag = 1 + else + if (syear(ee).eq.syear_pr(ee)) then ; check that the start and end years match for pr and psl + if (eyear(ee).eq.eyear_pr(ee)) then + prreg_plot_flag = 0 + else + prreg_plot_flag = 1 + end if + else + prreg_plot_flag = 1 + end if + end if + + if (prreg_plot_flag.eq.0) then + pr = data_read_in(paths_pr(ee),"PRECT",syear_pr(ee),eyear_pr(ee)) + if (isatt(pr,"is_all_missing")) then + prreg_plot_flag = 1 + delete(pr) + end if + + if (prreg_plot_flag.eq.0) then ; only continue if both SST/PR fields are present + if (OPT_CLIMO.eq."Full") then + pr = rmMonAnnCycTLL(pr) + else + check_custom_climo(names_pr(ee),syear_pr(ee),eyear_pr(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = pr + delete(temp_arr&time) + temp_arr&time = cd_calendar(pr&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + pr = calcMonAnomTLL(pr,climo) + delete(climo) + end if + finreg_pr = pr(0,:,:) + finreg_pr = (/ regCoef(pc1,pr(lat|:,lon|:,time|:)) /) + delete(pr) + end if + end if +;--------------------------------------------------------------------------------------------- + if (tasreg_frame.eq.1.and.tasreg_plot_flag.eq.0) then ; tasreg_frame = flag to create regressions .ps/.png files + tasreg_frame = 0 + end if + if (prreg_frame.eq.1.and.prreg_plot_flag.eq.0) then ; prreg_frame = flag to create regressions .ps/.png files + prreg_frame = 0 + end if +;--------------------------------------------------------------------------------------------- + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.pdo."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->pdo_pattern_mon = set_varAtts(pdo,"PDO spatial pattern (monthly)","","") + z->pdo_timeseries_mon = set_varAtts(pc1,"PDO normalized principal component timeseries (monthly)","1","") + delete([/modname,fn/]) + if (tasreg_plot_flag.eq.0) then + modname = str_sub_str(names_tas(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.pdo.tas."+syear_tas(ee)+"-"+eyear_tas(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z_tas = addfile(fn,"c") + z_tas@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z_tas@notes = "Data from "+names_tas(ee)+" from "+syear_tas(ee)+"-"+eyear_tas(ee) + if (OPT_CLIMO.eq."Full") then + z_tas@climatology = syear_tas(ee)+"-"+eyear_tas(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z_tas@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z_tas@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z_tas@Conventions = "CF-1.6" + else + z_tas = addfile(fn,"w") + end if + z_tas->pdo_tas_regression_mon = set_varAtts(finreg_tas,"tas regression onto PDO timeseries (monthly)","","") + delete([/modname,fn,z_tas/]) + end if + if (prreg_plot_flag.eq.0) then + modname = str_sub_str(names_pr(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.pdo.pr."+syear_pr(ee)+"-"+eyear_pr(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z_pr = addfile(fn,"c") + z_pr@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z_pr@notes = "Data from "+names_pr(ee)+" from "+syear_pr(ee)+"-"+eyear_pr(ee) + if (OPT_CLIMO.eq."Full") then + z_pr@climatology = syear_pr(ee)+"-"+eyear_pr(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z_pr@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z_pr@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z_pr@Conventions = "CF-1.6" + else + z_pr = addfile(fn,"w") + end if + z_pr->pdo_pr_regression_mon = set_varAtts(finreg_pr,"pr regression onto PDO timeseries (monthly)","","") + delete([/modname,fn,z_pr/]) + end if + end if +;------------------------------------------------------------------------ + iopt = 0 + jave = (7*nyr(ee))/100 + val1 = .95 + val2 = .99 + if (jave.eq.0) then + jave = 1 + end if + pct = 0.1 + spectra_mvf = False ; missing value flag + if (any(ismissing(pc1))) then ; check for missing data + print("Missing data detected for "+names(ee)+", not creating PDO spectra") + spectra_mvf = True + if (isfilepresent2("obs_ts").and.ee.eq.0) then + spectra_mvf_obs = True ; missing value flag + end if + else + if (isfilepresent2("obs_ts").and.ee.eq.0) then + spectra_mvf_obs = False ; missing value flag + end if + sdof = specx_anal(pc1,iopt,jave,pct) ; pc1 is standardized + splt1 = specx_ci(sdof,val1,val2) + if (OUTPUT_DATA.eq."True") then + splt1!0 = "ncurves" + splt1&ncurves = ispan(0,3,1) + splt1&ncurves@long_name = "power spectra curves" + splt1&ncurves@units = "1" + splt1!1 = "frequency" + splt1&frequency = sdof@frq + splt1&frequency@units = "1" + splt1@units_info = "df refers to frequency interval; data are standardized so there are no physical units" + splt1@units = "1/df" + splt1@info = "(0,:)=spectrum,(1,:)=Markov red noise spectrum, (2,:)="+val1+"% confidence bound for Markhov, (3,:)="+val2+"% confidence bound for Markhov" + z->pdo_spectra = set_varAtts(splt1,"PDO (monthly) power spectra, Markov spectrum and confidence curves","","") + end if + if (isfilepresent2("obs_ts").and.ee.eq.0) then + sdof_obs = sdof + end if + delete([/iopt,jave,pct/]) + end if + if (isvar("z")) then + delete(z) + end if +;======================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + res@vpYF = 0.95 + res@vpHeightF = 0.3 + res@vpXF = 0.2 + res@vpWidthF = 0.6 + +; res@cnFillMode = "RasterFill" + res@cnLevelSelectionMode = "ExplicitLevels" + + if (COLORMAP.eq."0") then + res@cnLevels = fspan(-.65,.65,27) + end if + if (COLORMAP.eq."1") then + res@cnLevels = fspan(-.8,.8,17) + end if + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnRightString = pdo@pcvar + res@gsnCenterString = names(ee) + + res4 = res ; res4 = pr regression resources + delete(res4@cnLevels) + if (COLORMAP.eq.0) then + res4@cnLevels = (/-5,-4,-3,-2,-1,-.75,-.5,-.25,-.1,0,.1,.25,.5,.75,1,2,3,4,5/) + else + res4@cnLevels = (/-3,-2,-1,-.5,-.1,0,.1,.5,1,2,3/) + end if + + res2 = True ; res2 = tas regression resources + res2@gsnDraw = False + res2@gsnFrame = False + res2@cnLevelSelectionMode = "ExplicitLevels" + res2@cnLevels = res@cnLevels + + res2@cnLineLabelsOn = False + res2@cnFillOn = True + res2@cnLinesOn = False + res2@cnFillMode = "AreaFill" + res2@lbLabelBarOn = False + res2@cnInfoLabelOn = False + res2@gsnRightString = "" + res2@gsnLeftString = "" + res2@gsnCenterString = "" + res2@gsnAddCyclic = True + + if (isfilepresent2("obs_ts").and.ee.eq.0) then ; for pattern correlation table + patcor = new((/nsim,dimsizes(pdo&lat),dimsizes(pdo&lon)/),typeof(pdo)) + patcor!1 = "lat" + patcor&lat = pdo&lat + patcor!2 = "lon" + patcor&lon = pdo&lon + patcor(ee,:,:) = (/ pdo /) + end if + if (isfilepresent2("obs_ts").and.ee.ge.1.and.isvar("patcor")) then + patcor(ee,:,:) = (/ totype(linint2(pdo&lon,pdo&lat,pdo,True,patcor&lon,patcor&lat,0),typeof(patcor)) /) + end if + + map(ee) = gsn_csm_contour_map(wks,pdo,res) + + if (tasreg_plot_flag.eq.0) then + if (names(ee).eq.names_tas(ee)) then + res@gsnCenterString = names(ee) + else + res@gsnCenterString = names(ee)+" / "+names_tas(ee) + end if + map_sst(ee) = gsn_csm_contour_map(wks,pdo,res) + map_tasreg(ee) = gsn_csm_contour(wks,finreg_tas,res2) + overlay(map_sst(ee),map_tasreg(ee)) + delete([/finreg_tas/]) + end if + delete([/pdo/]) + if (prreg_plot_flag.eq.0) then + res4@gsnCenterString = names_pr(ee) + map_prreg(ee) = gsn_csm_contour_map(wks4,finreg_pr,res4) + delete(finreg_pr) + end if + + pres = True + pres@vpXF = 0.07 + pres@trYMinF = 0. + pres@trXMinF = 0.0 +; pres@trYMaxF = 82. + pres@trXMaxF = 0.0832 + pres@tiYAxisString = "Power" ; yaxis + pres@xyLineColor = "black" + pres@gsnFrame = False + pres@gsnDraw = False + + pres@tmXBLabelDeltaF = -.8 + pres@tmXTLabelDeltaF = -.8 + pres@pmLegendDisplayMode = "Never" + pres@xyLineThicknesses = (/3.5,2.,1.,1./) + pres@xyDashPatterns = (/0,0,0,0/) + pres@xyLineColors = (/"foreground","red","blue","green"/) + pres@xyLabelMode = "custom" + pres@xyLineLabelFontColors = pres@xyLineColors + pres@xyExplicitLabels = (/"","",val1*100+"%",val2*100+"%"/) + pres@tmXTOn = True + pres@tmYROn = False + pres@tmXTLabelsOn = True + pres@tmXUseBottom = False + pres@tmXTMode = "Explicit" + pres@tmXBMode = "Explicit" + pres@tmXTValues = (/".00167",".00833",".01667",".02778",".0416",".0556",".0832"/) + pres@tmXTLabels = (/"50","10","5","3","2","1.5","1"/) + pres@tmXBValues = (/".0",".01",".02",".03",".042",".056",".083"/) + pres@tmXBLabels = pres@tmXBValues + pres@tmXTLabelFontHeightF = 0.018 + pres@tmXBLabelFontHeightF = 0.018 + pres@tmYLLabelFontHeightF = 0.018 + pres@tiYAxisString = "Variance" ;"Power (~S~o~N~C~S~2~N~ / cycles mo~S~-1~N~)" ; yaxis + pres@tiXAxisString = "Frequency (cycles mo~S~-1~N~)" + pres@tiMainString = "" + pres@txFontHeightF = 0.015 + pres@xyLineLabelFontHeightF = 0.022 + pres@tiXAxisFontHeightF = 0.025 + pres@tiYAxisFontHeightF = 0.025 + pres@tiMainFontHeightF = 0.03 + pres@gsnRightStringOrthogonalPosF = -0.115 + + pres@tiMainOn = False + pres@gsnCenterString = "Period (years)" + pres@gsnCenterStringFontHeightF = pres@tiYAxisFontHeightF + pres@gsnRightStringFontHeightF = pres@tiYAxisFontHeightF - 0.005 + pres@gsnRightString = syear(ee)+"-"+eyear(ee)+" " + pres@gsnLeftString = "" + if (wks_type.eq."png") then + pres@xyLineThicknessF = 3.5 + res@mpGeophysicalLineThicknessF = 2. + else + pres@xyLineThicknessF = 1.5 + res@mpGeophysicalLineThicknessF = 1. + end if + pres@gsnCenterString = names(ee) + if (spectra_mvf.eq.False) then + pspec(ee) = gsn_csm_xy(wks2,sdof@frq,splt1,pres) + + if (isfilepresent2("obs_ts").and.ee.ge.1.and.spectra_mvf_obs.eq.False) then + pres@xyLineColors = (/"gray70","black","black","black"/) + pres@xyCurveDrawOrder = "PreDraw" + pres@gsnCenterString = "" + pres@gsnRightString = "" + pspec_obs(ee) = gsn_csm_xy(wks2,sdof_obs@frq,sdof_obs@spcx,pres) + overlay(pspec(ee),pspec_obs(ee)) + delete(pres@xyCurveDrawOrder) + end if + delete([/sdof,splt1/]) + end if + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False +; xyres@trYMinF = -.65 +; xyres@trYMaxF = .65 +; xyres@tmYLFormat = "f" +; xyres@tmYLMode = "Explicit" +; xyres@tmYLValues = (/-0.5,-0.25,0,0.25,0.5/) +; xyres@tmYLLabels = (/"-0.5","-0.25","0","0.25","0.5"/) +; xyres@tmYLMinorValues = fspan(-1,1,41) + xyres@gsnRightString = "" + xyres@gsnLeftString = "" + xyres@gsnFrame = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + xyres@gsnXYBarChart = False + xyres@gsnAboveYRefLineColor = 185 + xyres@gsnBelowYRefLineColor = 35 + xyres@xyLineThicknessF = 0.1 +; xyres@xyLineColors = (/ xyres@gsnAboveYRefLineColor, xyres@gsnBelowYRefLineColor/) + xyres@xyLineColor = "gray70" + xyres@tiYAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnStringFontHeightF = 0.017 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnStringFontHeightF = 0.024 + end if + xyres@gsnCenterStringOrthogonalPosF = 0.025 + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnCenterString = "" + + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+1.5 + + + xyres2 = xyres + delete(xyres2@gsnXYBarChart) + delete(xyres2@gsnAboveYRefLineColor) + delete(xyres2@gsnBelowYRefLineColor) +; delete(xyres2@xyLineColors) + xyres2@xyLineColor = "black" + if (wks_type.eq."png") then + xyres2@xyLineThicknessF = 3.5 + else + xyres2@xyLineThicknessF = 2.5 + end if + + xyres@gsnCenterString = names(ee) + xyplot(ee) = gsn_csm_xy(wks3,fspan(syear(ee),eyear(ee)+.91667,dimsizes(pc1)),pc1,xyres) ; use standardized timeseries + xyplot2(ee) = gsn_csm_xy(wks3,fspan(syear(ee),eyear(ee)+.91667,dimsizes(pc1)),runave(pc1,61,0),xyres2) + overlay(xyplot(ee),xyplot2(ee)) + + delete([/val1,val2,pc1,res,pres,xyres,xyres2/]) + end do + + if (isvar("patcor")) then ; for pattern correlation table + clat = cos(0.01745329*patcor&lat) + finpr = "PDO (Monthly) " ; Must be 18 characters long + line3 = " " ; Must be 18 characters long + line4 = line3 + header = (/"","Pattern Correlations/RMS Differences Observations vs. Model(s)",""/) + do hh = 1,nsim-1 + dimY = dimsizes(tochar(names(hh))) + nchar = dimY + nchar = where(nchar.le.10,10,nchar) + if (dimY.lt.10) then + ntb = "" + do ii = 0,10-dimY-1 + ntb = ntb+" " + end do + ntb = ntb+names(hh) + else + ntb = names(hh) + end if + + ntc = "" + do ii = 0,nchar-1 + ntc = ntc+"-" + end do + format2 = "%"+(nchar-5+1)+".2f" + format3 = "%4.2f" + line3 = line3+" "+ntb + line4 = line4+" "+ntc + if (all(ismissing(patcor(hh,:,:)))) then + finpr = finpr+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr = finpr+sprintf(format2,(pattern_cor(patcor(0,:,:),patcor(hh,:,:),clat,0)))+"/"+sprintf(format3,(wgt_arearmse(patcor(0,:,:),patcor(hh,:,:),clat,1.0,0))) + end if + end do + if (dimsizes(tochar(line4)).ge.8190) then ; system or fortran compiler limit + print("Metrics table warning: Not creating metrics table as size of comparison results in a invalid ascii row size.") + else + write_table(getenv("OUTDIR")+"metrics.pdo.txt","w",[/header/],"%s") + write_table(getenv("OUTDIR")+"metrics.pdo.txt","a",[/line3/],"%s") + write_table(getenv("OUTDIR")+"metrics.pdo.txt","a",[/line4/],"%s") + write_table(getenv("OUTDIR")+"metrics.pdo.txt","a",[/finpr/],"%s") + end if + delete([/finpr,line3,line4,format2,format3,nchar,ntc,clat,patcor,dimY,ntb,header/]) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.55 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + panres@lbLabelFontHeightF = 0.013 + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@txString = "PDO (Monthly)" + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + gsn_panel2(wks,map,(/nrow,ncol/),panres) + + if (tasreg_frame.eq.0) then + panres@txString = "PDO SST/TAS Regressions (Monthly)" + gsn_panel2(wks,map_sst,(/nrow,ncol/),panres) + end if + delete(wks) + + if (prreg_frame.eq.0) then + panres@txString = "PDO PR Regressions (Monthly)" + gsn_panel2(wks4,map_prreg,(/nrow,ncol/),panres) + end if + delete(wks4) + + + delete(panres@gsnPanelLabelBar) + panres@txString = "PDO (Monthly)" + gsn_panel2(wks2,pspec,(/nrow,ncol/),panres) + delete(wks2) + + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) ;(/nsim/2+1,nsim/8+1/) + end if + panres@txString = "PDO (Monthly)" + gsn_panel2(wks3,xyplot,lp,panres) + delete(wks3) + delete([/map,pspec,syear,eyear,nyr,nyr_max,lp/]) +;-------------------------------------------------------------------------------------------------- + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + if (tasreg_frame.eq.0) then + system("mv "+OUTDIR+"pdo.000001.png "+OUTDIR+"pdo.png") + system("mv "+OUTDIR+"pdo.000002.png "+OUTDIR+"pdo.tasreg.png") + end if + else + if (tasreg_frame.eq.0) then + system("psplit "+OUTDIR+"pdo.ps "+OUTDIR+"pdo_nn") + system("mv "+OUTDIR+"pdo_nn0001.ps "+OUTDIR+"pdo.ps") + system("mv "+OUTDIR+"pdo_nn0002.ps "+OUTDIR+"pdo.tasreg.ps") + end if + end if + print("Finished: pdo.ncl") +end + diff --git a/lib/externals/CVDP/ncl_scripts/pr.mean_stddev.ncl b/lib/externals/CVDP/ncl_scripts/pr.mean_stddev.ncl new file mode 100644 index 000000000..55e5b8d00 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/pr.mean_stddev.ncl @@ -0,0 +1,573 @@ +; Calculates precipitation global means, zonal means, and standard deviations +; +; Variables used: pr +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: pr.mean_stddev.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_prect") + na = asciiread("namelist_byvar/namelist_prect",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_stddev_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.stddev.djf") + wks_stddev_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.stddev.mam") + wks_stddev_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.stddev.jja") + wks_stddev_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.stddev.son") + wks_stddev_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.stddev.ann") + wks_mean = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.mean") + wks_za_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.za.djf") + wks_za_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.za.mam") + wks_za_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.za.jja") + wks_za_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.za.son") + wks_za_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.za.ann") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_stddev_djf,"precip3_16lev") + gsn_define_colormap(wks_stddev_mam,"precip3_16lev") + gsn_define_colormap(wks_stddev_jja,"precip3_16lev") + gsn_define_colormap(wks_stddev_son,"precip3_16lev") + gsn_define_colormap(wks_stddev_ann,"precip3_16lev") + gsn_define_colormap(wks_mean,"precip3_16lev") + gsn_define_colormap(wks_za_djf,"cb_9step") + gsn_define_colormap(wks_za_mam,"cb_9step") + gsn_define_colormap(wks_za_jja,"cb_9step") + gsn_define_colormap(wks_za_son,"cb_9step") + gsn_define_colormap(wks_za_ann,"cb_9step") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_stddev_djf,"cb_rainbow") + gsn_define_colormap(wks_stddev_mam,"cb_rainbow") + gsn_define_colormap(wks_stddev_jja,"cb_rainbow") + gsn_define_colormap(wks_stddev_son,"cb_rainbow") + gsn_define_colormap(wks_stddev_ann,"cb_rainbow") + gsn_define_colormap(wks_mean,"BlueDarkRed18") + gsn_define_colormap(wks_za_djf,"cb_9step") + gsn_define_colormap(wks_za_mam,"cb_9step") + gsn_define_colormap(wks_za_jja,"cb_9step") + gsn_define_colormap(wks_za_son,"cb_9step") + gsn_define_colormap(wks_za_ann,"cb_9step") + end if + + plot_mean_djf = new(nsim,"graphic") + plot_mean_mam = new(nsim,"graphic") + plot_mean_jja = new(nsim,"graphic") + plot_mean_son = new(nsim,"graphic") + plot_mean_ann = new(nsim,"graphic") + plot_stddev_djf = new(nsim,"graphic") + plot_stddev_mam = new(nsim,"graphic") + plot_stddev_jja = new(nsim,"graphic") + plot_stddev_son = new(nsim,"graphic") + plot_stddev_ann = new(nsim,"graphic") + + plot_za_djf = new(nsim,"graphic") + plot_za_mam = new(nsim,"graphic") + plot_za_jja = new(nsim,"graphic") + plot_za_son = new(nsim,"graphic") + plot_za_ann = new(nsim,"graphic") + + if (isfilepresent2("obs_pr")) then + c1 = 1 + else + c1 = 76 + end if +; color = (/c1,2,6,11,5,3,7,15,23,31,39,47,55,63,71,79,c1,2,6,11,5,3,7,15,23,31,39,47,55,63,71,79,c1,2,6,11,5,3,7,15,23,31,39,47,55,63,71,79,c1,2/) +; dash = (/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3/) + + if (nsim.le.15) then + color = (/c1,2,6,11,5,3,7,15,23,31,39,47,55,63,71,79/) + dash = (/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/) + else + zt = (nsim/16)+1 + color = new((/zt*16/),integer) + dash = color + eind = 0 + do dd = 0,zt-1 + color(eind:eind+15) = (/c1,2,6,11,5,3,7,15,23,31,39,47,55,63,71,79/) + if (dd.le.16) then + dash(eind:eind+15) = dd + else + dash(eind:eind+15) = mod(dd,16) + end if + eind = eind+16 + end do + delete([/zt,eind/]) + end if + + do ee = 0,nsim-1 + ppt = data_read_in(paths(ee),"PRECT",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(ppt,"is_all_missing")) then + delete(ppt) + continue + end if + do ff = 0,1 + pptT = ppt + if (ff.eq.1) then + if (OPT_CLIMO.eq."Full") then + pptT = rmMonAnnCycTLL(pptT) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = pptT + delete(temp_arr&time) + temp_arr&time = cd_calendar(pptT&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + pptT = calcMonAnomTLL(pptT,climo) + delete(climo) + end if + end if + ppt_seas = runave_n_Wrap(pptT,3,0,0) + ppt_seas(0,:,:) = (/ dim_avg_n(pptT(:1,:,:),0) /) + ppt_seas(dimsizes(pptT&time)-1,:,:) = (/ dim_avg_n(pptT(dimsizes(pptT&time)-2:,:,:),0) /) + ppt_ann = runave_n_Wrap(pptT,12,0,0) + delete(pptT) + + if (ff.eq.0) then + ppt_mean_djf = dim_avg_n_Wrap(ppt_seas(0::12,:,:),0) + ppt_mean_mam = dim_avg_n_Wrap(ppt_seas(3::12,:,:),0) + ppt_mean_jja = dim_avg_n_Wrap(ppt_seas(6::12,:,:),0) + ppt_mean_son = dim_avg_n_Wrap(ppt_seas(9::12,:,:),0) + ppt_mean_ann = dim_avg_n_Wrap(ppt_ann(5::12,:,:),0) + + ppt_zamean_djf = dim_avg_n_Wrap(ppt_mean_djf,1) + ppt_zamean_mam = dim_avg_n_Wrap(ppt_mean_mam,1) + ppt_zamean_jja = dim_avg_n_Wrap(ppt_mean_jja,1) + ppt_zamean_son = dim_avg_n_Wrap(ppt_mean_son,1) + ppt_zamean_ann = dim_avg_n_Wrap(ppt_mean_ann,1) + end if + if (ff.eq.1) then + ppt_sd_djf = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),ppt_seas(0::12,:,:),False,False,0),0) + ppt_sd_mam = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),ppt_seas(3::12,:,:),False,False,0),0) + ppt_sd_jja = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),ppt_seas(6::12,:,:),False,False,0),0) + ppt_sd_son = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),ppt_seas(9::12,:,:),False,False,0),0) + ppt_sd_ann = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),ppt_ann(5::12,:,:),False,False,0),0) + end if + delete([/ppt_seas,ppt_ann/]) + end do + delete(ppt) + copy_VarMeta(ppt_mean_djf,ppt_sd_djf) + copy_VarMeta(ppt_mean_mam,ppt_sd_mam) + copy_VarMeta(ppt_mean_jja,ppt_sd_jja) + copy_VarMeta(ppt_mean_son,ppt_sd_son) + copy_VarMeta(ppt_mean_ann,ppt_sd_ann) + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.pr.mean_stddev."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + + z->pr_spatialmean_djf = set_varAtts(ppt_mean_djf,"pr mean (DJF)","","") + z->pr_spatialmean_mam = set_varAtts(ppt_mean_mam,"pr mean (MAM)","","") + z->pr_spatialmean_jja = set_varAtts(ppt_mean_jja,"pr mean (JJA)","","") + z->pr_spatialmean_son = set_varAtts(ppt_mean_son,"pr mean (SON)","","") + z->pr_spatialmean_ann = set_varAtts(ppt_mean_ann,"pr mean (annual)","","") + + z->pr_spatialstddev_djf = set_varAtts(ppt_sd_djf,"pr standard deviation (DJF)","","") + z->pr_spatialstddev_mam = set_varAtts(ppt_sd_mam,"pr standard deviation (MAM)","","") + z->pr_spatialstddev_jja = set_varAtts(ppt_sd_jja,"pr standard deviation (JJA)","","") + z->pr_spatialstddev_son = set_varAtts(ppt_sd_son,"pr standard deviation (SON)","","") + z->pr_spatialstddev_ann = set_varAtts(ppt_sd_ann,"pr standard deviation (annual)","","") + delete(z) + delete([/modname,fn/]) + end if +;========================================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@gsnDraw = False + res@gsnFrame = False + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@cnLevelSelectionMode = "ExplicitLevels" + + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + + sres = res + sres@cnLevels = (/0.5,1,2,3,4,5,6,7,8,9,10,12,14,16,18/) + res@cnLevels = (/.2,.4,.6,1.0,1.5,2.0,2.5,3.5/) + if (COLORMAP.eq.0) then + res@cnFillColors = (/2,4,6,8,10,12,14,16,18/) + end if + if (COLORMAP.eq.1) then + res@cnFillColors = (/35,47,63,79,95,111,124,155,175/) + end if + + + + if (isfilepresent2("obs_prect").and.ee.eq.0) then ; for pattern correlation table + patcor = new((/nsim,dimsizes(ppt_sd_ann&lat),dimsizes(ppt_sd_ann&lon)/),typeof(ppt_sd_ann)) + patcor!1 = "lat" + patcor&lat = ppt_sd_ann&lat + patcor!2 = "lon" + patcor&lon = ppt_sd_ann&lon + patcor(ee,:,:) = (/ ppt_sd_ann /) + end if + if (isfilepresent2("obs_prect").and.ee.ge.1.and.isvar("patcor")) then + patcor(ee,:,:) = (/ totype(linint2(ppt_sd_ann&lon,ppt_sd_ann&lat,ppt_sd_ann,True,patcor&lon,patcor&lat,0),typeof(patcor)) /) + end if + + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnRightString = ppt_mean_djf@units + res@gsnCenterString = names(ee) + plot_stddev_djf(ee) = gsn_csm_contour_map(wks_stddev_djf,ppt_sd_djf,res) + plot_stddev_mam(ee) = gsn_csm_contour_map(wks_stddev_mam,ppt_sd_mam,res) + plot_stddev_jja(ee) = gsn_csm_contour_map(wks_stddev_jja,ppt_sd_jja,res) + plot_stddev_son(ee) = gsn_csm_contour_map(wks_stddev_son,ppt_sd_son,res) + plot_stddev_ann(ee) = gsn_csm_contour_map(wks_stddev_ann,ppt_sd_ann,res) + + sres@gsnLeftString = syear(ee)+"-"+eyear(ee) + sres@gsnRightString = ppt_mean_djf@units + sres@gsnCenterString = names(ee) + plot_mean_djf(ee) = gsn_csm_contour_map(wks_mean,ppt_mean_djf,sres) + plot_mean_mam(ee) = gsn_csm_contour_map(wks_mean,ppt_mean_mam,sres) + plot_mean_jja(ee) = gsn_csm_contour_map(wks_mean,ppt_mean_jja,sres) + plot_mean_son(ee) = gsn_csm_contour_map(wks_mean,ppt_mean_son,sres) + plot_mean_ann(ee) = gsn_csm_contour_map(wks_mean,ppt_mean_ann,sres) + delete([/ppt_sd_djf,ppt_sd_mam,ppt_sd_jja,ppt_sd_son,ppt_sd_ann,ppt_mean_djf,ppt_mean_mam,ppt_mean_jja,ppt_mean_son,ppt_mean_ann,res,sres/]) + + zres = True + zres@vpYF = 0.8 + zres@vpXF = 0.14 + zres@vpWidthF = 0.55 + zres@vpHeightF = 0.55 + zres@trYMinF = 0. + zres@trYMaxF = 11.0 + zres@gsnDraw = False + zres@gsnFrame = False + + zres@tmXTLabelFontHeightF = 0.018 + zres@tmXBLabelFontHeightF = 0.018 + zres@tmYLLabelFontHeightF = 0.018 + zres@tiMainString = "" + zres@txFontHeightF = 0.015 + zres@xyLineLabelFontHeightF = 0.016 + zres@tiXAxisFontHeightF = 0.019 + zres@tiYAxisFontHeightF = 0.019 + zres@tiMainFontHeightF = 0.03 + + zres@pmLegendDisplayMode = "Never" + zres@tiYAxisString = "mm day~S~-1~N~" + + zres@xyLineColor = "black" + zres@xyDashPattern = 0 + if (wks_type.eq."png") then + zres@xyLineThicknessF = 3.5 + if (isfilepresent2("obs_prect").and.ee.eq.0) then + zres@xyLineThicknessF = 7. + end if + else + zres@xyLineThicknessF = 2. + if (isfilepresent2("obs_prect").and.ee.eq.0) then + zres@xyLineThicknessF = 4. + end if + end if + + zres@xyDashPattern = dash(ee) ;dash(mod(ee,50)) + zres@xyLineColor = color(ee) ;color(mod(ee,50)) + zres@tiMainFont = "helvetica" + + polyres = True + polyres@gsLineColor = color(mod(ee,50)) + polyres@gsLineThicknessF = zres@xyLineThicknessF + polyres@gsLineDashPattern = dash(mod(ee,50)) + + txres = True + if (nsim.le.15) then + txres@txFontHeightF = 0.012 + yeval = .02 + end if + if (nsim.ge.16.and.nsim.le.45) then + txres@txFontHeightF = 0.009 + yeval = .0175 + end if + if (nsim.ge.46.and.nsim.le.72) then + txres@txFontHeightF = 0.006 + yeval = .011 + end if + if (nsim.ge.73.and.nsim.le.106) then + txres@txFontHeightF = 0.004 + yeval = .0075 + end if + if (nsim.ge.107.and.nsim.le.228) then + txres@txFontHeightF = 0.002 + yeval = .0035 + end if + if (nsim.ge.229) then + txres@txFontHeightF = 0.001 + yeval = .002 + end if + + txres@txJust = "CenterLeft" + + zres@tiMainString = "PR Zonal Average (DJF)" + zres@gsnRightString = "mm/day" + + plot_za_djf(ee) = gsn_csm_xy(wks_za_djf,ppt_zamean_djf&lat,ppt_zamean_djf,zres) + if (ee.ne.0) then + overlay(plot_za_djf(0),plot_za_djf(ee)) + end if + gsn_text_ndc(wks_za_djf,names(ee),0.765,0.8-(ee*yeval),txres) + gsn_polyline_ndc(wks_za_djf,(/0.72,.75/),(/0.8-(ee*yeval),0.8-(ee*yeval)/),polyres) + + zres@tiMainString = "PR Zonal Average (MAM)" + plot_za_mam(ee) = gsn_csm_xy(wks_za_mam,ppt_zamean_mam&lat,ppt_zamean_mam,zres) + if (ee.ne.0) then + overlay(plot_za_mam(0),plot_za_mam(ee)) + end if + gsn_text_ndc(wks_za_mam,names(ee),0.765,0.8-(ee*yeval),txres) + gsn_polyline_ndc(wks_za_mam,(/0.72,.75/),(/0.8-(ee*yeval),0.8-(ee*yeval)/),polyres) + + zres@tiMainString = "PR Zonal Average (JJA)" + plot_za_jja(ee) = gsn_csm_xy(wks_za_jja,ppt_zamean_jja&lat,ppt_zamean_jja,zres) + if (ee.ne.0) then + overlay(plot_za_jja(0),plot_za_jja(ee)) + end if + gsn_text_ndc(wks_za_jja,names(ee),0.765,0.8-(ee*yeval),txres) + gsn_polyline_ndc(wks_za_jja,(/0.72,.75/),(/0.8-(ee*yeval),0.8-(ee*yeval)/),polyres) + + zres@tiMainString = "PR Zonal Average (SON)" + plot_za_son(ee) = gsn_csm_xy(wks_za_son,ppt_zamean_son&lat,ppt_zamean_son,zres) + if (ee.ne.0) then + overlay(plot_za_son(0),plot_za_son(ee)) + end if + gsn_text_ndc(wks_za_son,names(ee),0.765,0.8-(ee*yeval),txres) + gsn_polyline_ndc(wks_za_son,(/0.72,.75/),(/0.8-(ee*yeval),0.8-(ee*yeval)/),polyres) + + zres@tiMainString = "PR Zonal Average (ANN)" + plot_za_ann(ee) = gsn_csm_xy(wks_za_ann,ppt_zamean_ann&lat,ppt_zamean_ann,zres) + if (ee.ne.0) then + overlay(plot_za_ann(0),plot_za_ann(ee)) + end if + gsn_text_ndc(wks_za_ann,names(ee),0.765,0.8-(ee*yeval),txres) + gsn_polyline_ndc(wks_za_ann,(/0.72,.75/),(/0.8-(ee*yeval),0.8-(ee*yeval)/),polyres) + delete([/zres,polyres,txres,ppt_zamean_djf,ppt_zamean_mam,ppt_zamean_jja,ppt_zamean_son,ppt_zamean_ann/]) + end do + + if (isvar("patcor")) then ; for pattern correlation table + clat = cos(0.01745329*patcor&lat) + finpr = "pr Std Dev (Ann) " ; Must be 18 characters long + line3 = " " ; Must be 18 characters long + line4 = line3 + header = (/"","Pattern Correlations/RMS Differences Observations vs. Model(s)",""/) + do hh = 1,nsim-1 + dimY = dimsizes(tochar(names(hh))) + nchar = dimY + nchar = where(nchar.le.10,10,nchar) + if (dimY.lt.10) then + ntb = "" + do ii = 0,10-dimY-1 + ntb = ntb+" " + end do + ntb = ntb+names(hh) + else + ntb = names(hh) + end if + + ntc = "" + do ii = 0,nchar-1 + ntc = ntc+"-" + end do + format2 = "%"+(nchar-5+1)+".2f" + format3 = "%4.2f" + line3 = line3+" "+ntb + line4 = line4+" "+ntc + if (all(ismissing(patcor(hh,:,:)))) then + finpr = finpr+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr = finpr+sprintf(format2,(pattern_cor(patcor(0,:,:),patcor(hh,:,:),clat,0)))+"/"+sprintf(format3,(wgt_arearmse(patcor(0,:,:),patcor(hh,:,:),clat,1.0,0))) + end if + end do + if (dimsizes(tochar(line4)).ge.8190) then ; system or fortran compiler limit + print("Metrics table warning: Not creating metrics table as size of comparison results in a invalid ascii row size.") + else + write_table(getenv("OUTDIR")+"metrics.pr.mean_stddev.txt","w",[/header/],"%s") + write_table(getenv("OUTDIR")+"metrics.pr.mean_stddev.txt","a",[/line3/],"%s") + write_table(getenv("OUTDIR")+"metrics.pr.mean_stddev.txt","a",[/line4/],"%s") + write_table(getenv("OUTDIR")+"metrics.pr.mean_stddev.txt","a",[/finpr/],"%s") + end if + delete([/finpr,line3,line4,format2,format3,nchar,ntc,clat,patcor,dimY,ntb,header/]) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelFontHeightF = 0.013 + panres@lbLabelStride = 1 + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres@txString = "PR Standard Deviations (DJF)" + gsn_panel2(wks_stddev_djf,plot_stddev_djf,(/nrow,ncol/),panres) + delete(wks_stddev_djf) + + panres@txString = "PR Standard Deviations (MAM)" + gsn_panel2(wks_stddev_mam,plot_stddev_mam,(/nrow,ncol/),panres) + delete(wks_stddev_mam) + + panres@txString = "PR Standard Deviations (JJA)" + gsn_panel2(wks_stddev_jja,plot_stddev_jja,(/nrow,ncol/),panres) + delete(wks_stddev_jja) + + panres@txString = "PR Standard Deviations (SON)" + gsn_panel2(wks_stddev_son,plot_stddev_son,(/nrow,ncol/),panres) + delete(wks_stddev_son) + + panres@txString = "PR Standard Deviations (Annual)" + gsn_panel2(wks_stddev_ann,plot_stddev_ann,(/nrow,ncol/),panres) + delete(wks_stddev_ann) + + panres@txString = "PR Means (DJF)" + gsn_panel2(wks_mean,plot_mean_djf,(/nrow,ncol/),panres) + + panres@txString = "PR Means (MAM)" + gsn_panel2(wks_mean,plot_mean_mam,(/nrow,ncol/),panres) + + panres@txString = "PR Means (JJA)" + gsn_panel2(wks_mean,plot_mean_jja,(/nrow,ncol/),panres) + + panres@txString = "PR Means (SON)" + gsn_panel2(wks_mean,plot_mean_son,(/nrow,ncol/),panres) + + panres@txString = "PR Means (Annual)" + gsn_panel2(wks_mean,plot_mean_ann,(/nrow,ncol/),panres) + delete(wks_mean) + delete(panres) + + draw(plot_za_djf(0)) + frame(wks_za_djf) + delete(wks_za_djf) + + draw(plot_za_mam(0)) + frame(wks_za_mam) + delete(wks_za_mam) + + draw(plot_za_jja(0)) + frame(wks_za_jja) + delete(wks_za_jja) + + draw(plot_za_son(0)) + frame(wks_za_son) + delete(wks_za_son) + + draw(plot_za_ann(0)) + frame(wks_za_ann) + delete(wks_za_ann) +;-------------------------------------------------------------------------------------------------------------------------------------------- + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + system("mv "+OUTDIR+"pr.mean.000001.png "+OUTDIR+"pr.mean.djf.png") + system("mv "+OUTDIR+"pr.mean.000002.png "+OUTDIR+"pr.mean.mam.png") + system("mv "+OUTDIR+"pr.mean.000003.png "+OUTDIR+"pr.mean.jja.png") + system("mv "+OUTDIR+"pr.mean.000004.png "+OUTDIR+"pr.mean.son.png") + system("mv "+OUTDIR+"pr.mean.000005.png "+OUTDIR+"pr.mean.ann.png") + else + system("psplit "+OUTDIR+"pr.mean.ps "+OUTDIR+"pr_m") + system("mv "+OUTDIR+"pr_m0001.ps "+OUTDIR+"pr.mean.djf.ps") + system("mv "+OUTDIR+"pr_m0002.ps "+OUTDIR+"pr.mean.mam.ps") + system("mv "+OUTDIR+"pr_m0003.ps "+OUTDIR+"pr.mean.jja.ps") + system("mv "+OUTDIR+"pr_m0004.ps "+OUTDIR+"pr.mean.son.ps") + system("mv "+OUTDIR+"pr_m0005.ps "+OUTDIR+"pr.mean.ann.ps") + system("rm "+OUTDIR+"pr.mean.ps") + end if + print("Finished: pr.mean_stddev.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/pr.trends_timeseries.ncl b/lib/externals/CVDP/ncl_scripts/pr.trends_timeseries.ncl new file mode 100644 index 000000000..d537d4286 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/pr.trends_timeseries.ncl @@ -0,0 +1,550 @@ +; Calculates precipitation global trends and timeseries +; +; Variables used: pr +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: pr.trends_timeseries.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_prect") + na = asciiread("namelist_byvar/namelist_prect",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_trends_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.trends.djf") + wks_trends_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.trends.mam") + wks_trends_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.trends.jja") + wks_trends_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.trends.son") + wks_trends_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.trends.ann") + wks_trends_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.trends.mon") + + wks_aa_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.timeseries.djf") + wks_aa_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.timeseries.mam") + wks_aa_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.timeseries.jja") + wks_aa_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.timeseries.son") + wks_aa_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.timeseries.ann") + wks_aa_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.timeseries.mon") + + wks_rt_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"pr.runtrend.mon") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_trends_djf,"precip_diff_12lev") + gsn_define_colormap(wks_trends_mam,"precip_diff_12lev") + gsn_define_colormap(wks_trends_jja,"precip_diff_12lev") + gsn_define_colormap(wks_trends_son,"precip_diff_12lev") + gsn_define_colormap(wks_trends_ann,"precip_diff_12lev") + gsn_define_colormap(wks_trends_mon,"precip_diff_12lev") + gsn_define_colormap(wks_aa_djf,"ncl_default") + gsn_define_colormap(wks_aa_mam,"ncl_default") + gsn_define_colormap(wks_aa_jja,"ncl_default") + gsn_define_colormap(wks_aa_son,"ncl_default") + gsn_define_colormap(wks_aa_ann,"ncl_default") + gsn_define_colormap(wks_aa_mon,"ncl_default") + gsn_define_colormap(wks_rt_mon,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_trends_djf,"BrownBlue12") + gsn_define_colormap(wks_trends_mam,"BrownBlue12") + gsn_define_colormap(wks_trends_jja,"BrownBlue12") + gsn_define_colormap(wks_trends_son,"BrownBlue12") + gsn_define_colormap(wks_trends_ann,"BrownBlue12") + gsn_define_colormap(wks_trends_mon,"BrownBlue12") + gsn_define_colormap(wks_aa_djf,"ncl_default") + gsn_define_colormap(wks_aa_mam,"ncl_default") + gsn_define_colormap(wks_aa_jja,"ncl_default") + gsn_define_colormap(wks_aa_son,"ncl_default") + gsn_define_colormap(wks_aa_ann,"ncl_default") + gsn_define_colormap(wks_aa_mon,"ncl_default") + gsn_define_colormap(wks_rt_mon,"ncl_default") + end if + + map_djf = new(nsim,"graphic") + map_mam = new(nsim,"graphic") + map_jja = new(nsim,"graphic") + map_son = new(nsim,"graphic") + map_ann = new(nsim,"graphic") + map_mon = new(nsim,"graphic") + xy_djf = new(nsim,"graphic") + xy_mam = new(nsim,"graphic") + xy_jja = new(nsim,"graphic") + xy_son = new(nsim,"graphic") + xy_ann = new(nsim,"graphic") + xy_mon = new(nsim,"graphic") + + xy_rt_mon_8 = new(nsim,"graphic") + xy_rt_mon_10 = new(nsim,"graphic") + xy_rt_mon_12 = new(nsim,"graphic") + xy_rt_mon_14 = new(nsim,"graphic") + xy_rt_mon_16 = new(nsim,"graphic") + + if (isfilepresent2("obs_prect")) then + xy_obs_djf = new(nsim,"graphic") + xy_obs_mam = new(nsim,"graphic") + xy_obs_jja = new(nsim,"graphic") + xy_obs_son = new(nsim,"graphic") + xy_obs_ann = new(nsim,"graphic") + xy_obs_mon = new(nsim,"graphic") + end if + do ee = 0,nsim-1 + ppt = data_read_in(paths(ee),"PRECT",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(ppt,"is_all_missing")) then + delete(ppt) + continue + end if + + if (OPT_CLIMO.eq."Full") then + ppt = rmMonAnnCycTLL(ppt) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = ppt + delete(temp_arr&time) + temp_arr&time = cd_calendar(ppt&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + ppt = calcMonAnomTLL(ppt,climo) + delete(climo) + end if + + coswgt=cos(rad*ppt&lat) + coswgt!0 = "lat" + coswgt&lat= ppt&lat + + ppt_aa_mon = wgt_areaave_Wrap(ppt,coswgt,1.0,0) + tttt = dtrend_msg_n(ispan(0,dimsizes(ppt&time)-1,1),ppt,False,True,0) + ppt_trends_mon = ppt(0,:,:) + ppt_trends_mon = (/ onedtond(tttt@slope, (/dimsizes(ppt&lat),dimsizes(ppt&lon)/) ) /) + ppt_trends_mon = ppt_trends_mon*dimsizes(ppt&time) + ppt_trends_mon@units = ppt@units+" "+nyr(ee)+"yr~S~-1~N~" + delete(tttt) + + ppt_seas = runave_n_Wrap(ppt,3,0,0) + ppt_seas(0,:,:) = (/ dim_avg_n(ppt(:1,:,:),0) /) + ppt_seas(dimsizes(ppt&time)-1,:,:) = (/ dim_avg_n(ppt(dimsizes(ppt&time)-2:,:,:),0) /) + ppt_ann = runave_n_Wrap(ppt,12,0,0) + delete(ppt) + + ppt_trends_seas = ppt_seas(:3,:,:) + ppt_trends_seas = ppt_trends_seas@_FillValue + ppt_trends_ann = ppt_trends_seas(0,:,:) + ppt_aa_seas = new((/4,nyr(ee)/),typeof(ppt_seas)) + ppt_aa_seas!1 = "time" + ppt_aa_seas&time = ispan(syear(ee),eyear(ee),1) + ppt_aa_seas&time@units = "YYYY" + ppt_aa_seas&time@long_name = "time" + ppt_aa_ann = ppt_aa_seas(0,:) + do ff = 0,4 + if (ff.le.3) then + tarr = ppt_seas(ff*3::12,:,:) + end if + if (ff.eq.4) then + tarr = ppt_ann(5::12,:,:) + end if + tttt = dtrend_msg_n(ispan(0,dimsizes(tarr&time)-1,1),tarr,False,True,0) + if (ff.le.3) then + ppt_trends_seas(ff,:,:) = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + ppt_aa_seas(ff,:) = (/ wgt_areaave(tarr,coswgt,1.0,0) /) + end if + if (ff.eq.4) then + ppt_trends_ann = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + ppt_aa_ann = (/ wgt_areaave(tarr,coswgt,1.0,0) /) + end if + delete([/tarr,tttt/]) + end do + ppt_trends_seas = ppt_trends_seas*nyr(ee) + ppt_trends_seas@units = ppt_seas@units+" "+nyr(ee)+"yr~S~-1~N~" + ppt_trends_ann = ppt_trends_ann*nyr(ee) + ppt_trends_ann@units = ppt_ann@units+" "+nyr(ee)+"yr~S~-1~N~" + ppt_aa_seas@units = ppt_seas@units + ppt_aa_ann@units = ppt_ann@units + delete([/ppt_seas,ppt_ann,coswgt/]) + + if (isfilepresent2("obs_prect").and.ee.eq.0) then + ppt_aa_seas@syear = syear(ee) + ppt_aa_seas@eyear = eyear(ee) + ppt_aa_mon@syear = syear(ee) + ppt_aa_mon@eyear = eyear(ee) + ppt_aa_ann@syear = syear(ee) + ppt_aa_ann@eyear = eyear(ee) + ppt_aa_seas_obs = ppt_aa_seas + ppt_aa_mon_obs = ppt_aa_mon + ppt_aa_ann_obs = ppt_aa_ann + end if + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.pr.trends_timeseries."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + ppt_aa_seas2 = ppt_aa_seas + ppt_aa_seas2!1 = "TIME" + ppt_aa_seas2&TIME = ispan(syear(ee),eyear(ee),1) + ppt_aa_seas2&TIME@units = "YYYY" + ppt_aa_seas2&TIME@long_name = "time" + ppt_aa_ann2 = ppt_aa_ann + ppt_aa_ann2!0 = "TIME" + ppt_aa_ann2&TIME = ispan(syear(ee),eyear(ee),1) + ppt_aa_ann2&TIME@units = "YYYY" + ppt_aa_ann2&TIME@long_name = "time" + z->pr_global_avg_mon = set_varAtts(ppt_aa_mon,"pr global area-average (monthly)","","") + z->pr_global_avg_djf = set_varAtts(ppt_aa_seas2(0,:),"pr global area-average (DJF)","","") + z->pr_global_avg_mam = set_varAtts(ppt_aa_seas2(1,:),"pr global area-average (MAM)","","") + z->pr_global_avg_jja = set_varAtts(ppt_aa_seas2(2,:),"pr global area-average (JJA)","","") + z->pr_global_avg_son = set_varAtts(ppt_aa_seas2(3,:),"pr global area-average (SON)","","") + z->pr_global_avg_ann = set_varAtts(ppt_aa_ann2,"pr global area-average (annual)","","") + z->pr_trends_djf = set_varAtts(ppt_trends_seas(0,:,:),"pr linear trends (DJF)","","") + z->pr_trends_mam = set_varAtts(ppt_trends_seas(1,:,:),"pr linear trends (MAM)","","") + z->pr_trends_jja = set_varAtts(ppt_trends_seas(2,:,:),"pr linear trends (JJA)","","") + z->pr_trends_son = set_varAtts(ppt_trends_seas(3,:,:),"pr linear trends (SON)","","") + z->pr_trends_ann = set_varAtts(ppt_trends_ann,"pr linear trends (annual)","","") + z->pr_trends_mon = set_varAtts(ppt_trends_mon,"pr linear trends (monthly)","","") + delete(z) + delete(ppt_aa_seas2) + delete(ppt_aa_ann2) + delete([/modname,fn/]) + end if +;======================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + + res@cnLevelSelectionMode = "ExplicitLevels" + if (COLORMAP.eq.0) then + res@cnLevels = (/-6,-4,-2,-1,-0.5,-0.2,0,0.2,0.5,1,2,4,6/) + res@cnFillColors = (/2,3,4,5,6,7,8,8,9,10,11,12,13,14/) + end if + if (COLORMAP.eq.1) then + res@cnLevels = (/-4,-2,-1,-0.5,-0.2,0,0.2,0.5,1,2,4/) + end if + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.975 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + + res@gsnRightString = ppt_trends_seas@units + res@gsnCenterString = names(ee) + map_djf(ee) = gsn_csm_contour_map(wks_trends_djf,ppt_trends_seas(0,:,:),res) + map_mam(ee) = gsn_csm_contour_map(wks_trends_mam,ppt_trends_seas(1,:,:),res) + map_jja(ee) = gsn_csm_contour_map(wks_trends_jja,ppt_trends_seas(2,:,:),res) + map_son(ee) = gsn_csm_contour_map(wks_trends_son,ppt_trends_seas(3,:,:),res) + map_ann(ee) = gsn_csm_contour_map(wks_trends_ann,ppt_trends_ann,res) + map_mon(ee) = gsn_csm_contour_map(wks_trends_mon,ppt_trends_mon,res) + + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnFrame = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + + if (wks_type.eq."png") then + xyres@xyLineThicknessF = 4. + else + xyres@xyLineThicknessF = 2.0 + end if + if (isfilepresent2("obs_prect").and.ee.eq.0) then + xyres@xyLineColor = "black" + else + xyres@xyLineColor = "royalblue" + end if + xyres@tiYAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnLeftStringFontHeightF = 0.017 + xyres@gsnRightStringFontHeightF = 0.013 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnLeftStringFontHeightF = 0.024 + xyres@gsnRightStringFontHeightF = 0.020 + end if + xyres@gsnLeftStringOrthogonalPosF = 0.025 + xyres@gsnRightStringOrthogonalPosF = xyres@gsnLeftStringOrthogonalPosF + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnLeftString = "" + xyres@gsnCenterString = "" + xyres@gsnRightString = "" + + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+0.5 + + xyres2 = xyres + xyres2@xyLineColor = "gray60" + xyres2@xyCurveDrawOrder = "PreDraw" + + xyres@gsnLeftString = names(ee) + tttt = dtrend_msg(ispan(0,dimsizes(ppt_aa_seas&time)-1,1),ppt_aa_seas(0,:),False,True) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xyres@trYMinF = min((/min(ppt_aa_seas(0,:)),min(ppt_aa_seas_obs(0,:))/))-.005 + xyres@trYMaxF = max((/max(ppt_aa_seas(0,:)),max(ppt_aa_seas_obs(0,:))/))+.005 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+ppt_trends_seas@units + xy_djf(ee) = gsn_csm_xy(wks_aa_djf,ispan(syear(ee),eyear(ee),1),ppt_aa_seas(0,:),xyres) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xy_obs_djf(ee) = gsn_csm_xy(wks_aa_djf,ispan(ppt_aa_seas_obs@syear,ppt_aa_seas_obs@eyear,1),ppt_aa_seas_obs(0,:),xyres2) + overlay(xy_djf(ee),xy_obs_djf(ee)) + end if + + tttt = dtrend_msg(ispan(0,dimsizes(ppt_aa_seas&time)-1,1),ppt_aa_seas(1,:),False,True) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xyres@trYMinF = min((/min(ppt_aa_seas(1,:)),min(ppt_aa_seas_obs(1,:))/))-.005 + xyres@trYMaxF = max((/max(ppt_aa_seas(1,:)),max(ppt_aa_seas_obs(1,:))/))+.005 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+ppt_trends_seas@units + xy_mam(ee) = gsn_csm_xy(wks_aa_mam,ispan(syear(ee),eyear(ee),1),ppt_aa_seas(1,:),xyres) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xy_obs_mam(ee) = gsn_csm_xy(wks_aa_mam,ispan(ppt_aa_seas_obs@syear,ppt_aa_seas_obs@eyear,1),ppt_aa_seas_obs(1,:),xyres2) + overlay(xy_mam(ee),xy_obs_mam(ee)) + end if + + tttt = dtrend_msg(ispan(0,dimsizes(ppt_aa_seas&time)-1,1),ppt_aa_seas(2,:),False,True) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xyres@trYMinF = min((/min(ppt_aa_seas(2,:)),min(ppt_aa_seas_obs(2,:))/))-.005 + xyres@trYMaxF = max((/max(ppt_aa_seas(2,:)),max(ppt_aa_seas_obs(2,:))/))+.005 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+ppt_trends_seas@units + xy_jja(ee) = gsn_csm_xy(wks_aa_jja,ispan(syear(ee),eyear(ee),1),ppt_aa_seas(2,:),xyres) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xy_obs_jja(ee) = gsn_csm_xy(wks_aa_jja,ispan(ppt_aa_seas_obs@syear,ppt_aa_seas_obs@eyear,1),ppt_aa_seas_obs(2,:),xyres2) + overlay(xy_jja(ee),xy_obs_jja(ee)) + end if + + tttt = dtrend_msg(ispan(0,dimsizes(ppt_aa_seas&time)-1,1),ppt_aa_seas(3,:),False,True) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xyres@trYMinF = min((/min(ppt_aa_seas(3,:)),min(ppt_aa_seas_obs(3,:))/))-.005 + xyres@trYMaxF = max((/max(ppt_aa_seas(3,:)),max(ppt_aa_seas_obs(3,:))/))+.005 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+ppt_trends_seas@units + xy_son(ee) = gsn_csm_xy(wks_aa_son,ispan(syear(ee),eyear(ee),1),ppt_aa_seas(3,:),xyres) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xy_obs_son(ee) = gsn_csm_xy(wks_aa_son,ispan(ppt_aa_seas_obs@syear,ppt_aa_seas_obs@eyear,1),ppt_aa_seas_obs(3,:),xyres2) + overlay(xy_son(ee),xy_obs_son(ee)) + end if + delete(tttt) + + tttt = dtrend_msg(ispan(0,dimsizes(ppt_aa_ann&time)-1,1),ppt_aa_ann,False,True) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xyres@trYMinF = min((/min(ppt_aa_ann),min(ppt_aa_ann_obs)/))-.005 + xyres@trYMaxF = max((/max(ppt_aa_ann),max(ppt_aa_ann_obs)/))+.005 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+ppt_trends_ann@units + xy_ann(ee) = gsn_csm_xy(wks_aa_ann,ispan(syear(ee),eyear(ee),1),ppt_aa_ann,xyres) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xy_obs_ann(ee) = gsn_csm_xy(wks_aa_ann,ispan(ppt_aa_seas_obs@syear,ppt_aa_seas_obs@eyear,1),ppt_aa_ann_obs,xyres2) + overlay(xy_ann(ee),xy_obs_ann(ee)) + delete(xyres@trYMinF) + delete(xyres@trYMaxF) + end if + delete(tttt) + + xyres@trXMaxF = eyear(ee)+1.5 + xyres2@trXMaxF = eyear(ee)+1.5 + tttt = dtrend_msg(ispan(0,dimsizes(ppt_aa_mon&time)-1,1),ppt_aa_mon,False,True) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xyres@trYMinF = min((/min(ppt_aa_mon),min(ppt_aa_mon_obs)/))-.005 + xyres@trYMaxF = max((/max(ppt_aa_mon),max(ppt_aa_mon_obs)/))+.005 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(ppt_aa_mon&time),2,True)+ppt_trends_mon@units + xy_mon(ee) = gsn_csm_xy(wks_aa_mon,fspan(syear(ee),eyear(ee)+.91667,dimsizes(ppt_aa_mon)),ppt_aa_mon,xyres) + if (isfilepresent2("obs_prect").and.ee.ge.1) then + xy_obs_mon(ee) = gsn_csm_xy(wks_aa_mon,fspan(ppt_aa_seas_obs@syear,ppt_aa_seas_obs@eyear+.91667,dimsizes(ppt_aa_mon_obs)),ppt_aa_mon_obs,xyres2) + overlay(xy_mon(ee),xy_obs_mon(ee)) + end if + + delete([/ppt_trends_seas,ppt_trends_ann,ppt_trends_mon/]) + delete([/ppt_aa_seas,ppt_aa_mon,ppt_aa_ann,xyres,xyres2,res,tttt/]) + end do + if (isfilepresent2("obs_prect")) then + delete([/ppt_aa_seas_obs,ppt_aa_mon_obs,ppt_aa_ann_obs/]) + end if + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + panres@lbLabelFontHeightF = 0.013 + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelStride = 1 + + + panres@txString = "PPT Trends (DJF)" + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + gsn_panel2(wks_trends_djf,map_djf,(/nrow,ncol/),panres) + delete(wks_trends_djf) + + panres@txString = "PPT Trends (MAM)" + gsn_panel2(wks_trends_mam,map_mam,(/nrow,ncol/),panres) + delete(wks_trends_mam) + + panres@txString = "PPT Trends (JJA)" + gsn_panel2(wks_trends_jja,map_jja,(/nrow,ncol/),panres) + delete(wks_trends_jja) + + panres@txString = "PPT Trends (SON)" + gsn_panel2(wks_trends_son,map_son,(/nrow,ncol/),panres) + delete(wks_trends_son) + + panres@txString = "PPT Trends (Annual)" + gsn_panel2(wks_trends_ann,map_ann,(/nrow,ncol/),panres) + delete(wks_trends_ann) + + panres@txString = "PPT Trends (Monthly)" + gsn_panel2(wks_trends_mon,map_mon,(/nrow,ncol/),panres) + delete(wks_trends_mon) + + panres2 = True + panres2@gsnMaximize = True + panres2@gsnPaperOrientation = "portrait" + panres2@gsnPanelYWhiteSpacePercent = 3.0 + if (nsim.le.5) then + panres2@txFontHeightF = 0.024 + else + panres2@txFontHeightF = 0.016 + end if + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres2@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) ;(/nsim/2+1,nsim/8+1/) + end if + panres2@txString = "PR Global Average (DJF)" + gsn_panel2(wks_aa_djf,xy_djf,lp,panres2) + delete(wks_aa_djf) + + panres2@txString = "PR Global Average (MAM)" + gsn_panel2(wks_aa_mam,xy_mam,lp,panres2) + delete(wks_aa_mam) + + panres2@txString = "PR Global Average (JJA)" + gsn_panel2(wks_aa_jja,xy_jja,lp,panres2) + delete(wks_aa_jja) + + panres2@txString = "PR Global Average (SON)" + gsn_panel2(wks_aa_son,xy_son,lp,panres2) + delete(wks_aa_son) + + panres2@txString = "PR Global Average (Annual)" + gsn_panel2(wks_aa_ann,xy_ann,lp,panres2) + delete(wks_aa_ann) + + panres2@txString = "PR Global Average (Monthly)" + gsn_panel2(wks_aa_mon,xy_mon,lp,panres2) + delete(wks_aa_mon) + + delete([/nrow,ncol,lp,map_djf,map_mam,map_jja,map_son,map_ann,map_mon,xy_djf,xy_mam,xy_jja,xy_son,xy_ann,xy_mon/]) + delete(panres2) + if (isfilepresent2("obs_prect")) then + delete([/xy_obs_djf,xy_obs_mam,xy_obs_jja,xy_obs_son,xy_obs_ann,xy_obs_mon/]) + end if + print("Finished: pr.trends_timeseries.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/psl.mean_stddev.ncl b/lib/externals/CVDP/ncl_scripts/psl.mean_stddev.ncl new file mode 100644 index 000000000..1f4be5a41 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/psl.mean_stddev.ncl @@ -0,0 +1,382 @@ +; Calculates PSL global means and standard deviations +; +; Variables used: psl +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: psl.mean_stddev.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_psl") + na = asciiread("namelist_byvar/namelist_psl",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_stddev_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.stddev.djf") + wks_stddev_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.stddev.mam") + wks_stddev_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.stddev.jja") + wks_stddev_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.stddev.son") + wks_stddev_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.stddev.ann") + wks_mean_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.mean.djf") + wks_mean_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.mean.mam") + wks_mean_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.mean.jja") + wks_mean_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.mean.son") + wks_mean_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.mean.ann") + + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_stddev_djf,"precip3_16lev") + gsn_define_colormap(wks_stddev_mam,"precip3_16lev") + gsn_define_colormap(wks_stddev_jja,"precip3_16lev") + gsn_define_colormap(wks_stddev_son,"precip3_16lev") + gsn_define_colormap(wks_stddev_ann,"precip3_16lev") + gsn_define_colormap(wks_mean_djf,"ncl_default") + gsn_define_colormap(wks_mean_mam,"ncl_default") + gsn_define_colormap(wks_mean_jja,"ncl_default") + gsn_define_colormap(wks_mean_son,"ncl_default") + gsn_define_colormap(wks_mean_ann,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_stddev_djf,"cb_rainbow") + gsn_define_colormap(wks_stddev_mam,"cb_rainbow") + gsn_define_colormap(wks_stddev_jja,"cb_rainbow") + gsn_define_colormap(wks_stddev_son,"cb_rainbow") + gsn_define_colormap(wks_stddev_ann,"cb_rainbow") + gsn_define_colormap(wks_mean_djf,"BlueDarkRed18") + gsn_define_colormap(wks_mean_mam,"BlueDarkRed18") + gsn_define_colormap(wks_mean_jja,"BlueDarkRed18") + gsn_define_colormap(wks_mean_son,"BlueDarkRed18") + gsn_define_colormap(wks_mean_ann,"BlueDarkRed18") + end if + + plot_mean_djf = new(nsim,"graphic") + plot_mean_mam = new(nsim,"graphic") + plot_mean_jja = new(nsim,"graphic") + plot_mean_son = new(nsim,"graphic") + plot_mean_ann = new(nsim,"graphic") + plot_stddev_djf = new(nsim,"graphic") + plot_stddev_mam = new(nsim,"graphic") + plot_stddev_jja = new(nsim,"graphic") + plot_stddev_son = new(nsim,"graphic") + plot_stddev_ann = new(nsim,"graphic") + do ee = 0,nsim-1 + psl = data_read_in(paths(ee),"PSL",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(psl,"is_all_missing")) then + delete(psl) + continue + end if + do ff = 0,1 + pslT = psl + if (ff.eq.1) then + if (OPT_CLIMO.eq."Full") then + pslT = rmMonAnnCycTLL(pslT) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = pslT + delete(temp_arr&time) + temp_arr&time = cd_calendar(pslT&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + pslT = calcMonAnomTLL(pslT,climo) + delete(climo) + end if + end if + psl_seas = runave_n_Wrap(pslT,3,0,0) + psl_seas(0,:,:) = (/ dim_avg_n(pslT(:1,:,:),0) /) + psl_seas(dimsizes(pslT&time)-1,:,:) = (/ dim_avg_n(pslT(dimsizes(pslT&time)-2:,:,:),0) /) + psl_ann = runave_n_Wrap(pslT,12,0,0) + delete(pslT) + + if (ff.eq.0) then + psl_mean_djf = dim_avg_n_Wrap(psl_seas(0::12,:,:),0) + psl_mean_mam = dim_avg_n_Wrap(psl_seas(3::12,:,:),0) + psl_mean_jja = dim_avg_n_Wrap(psl_seas(6::12,:,:),0) + psl_mean_son = dim_avg_n_Wrap(psl_seas(9::12,:,:),0) + psl_mean_ann = dim_avg_n_Wrap(psl_ann(5::12,:,:),0) + end if + if (ff.eq.1) then + psl_sd_djf = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),psl_seas(0::12,:,:),False,False,0),0) + psl_sd_mam = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),psl_seas(3::12,:,:),False,False,0),0) + psl_sd_jja = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),psl_seas(6::12,:,:),False,False,0),0) + psl_sd_son = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),psl_seas(9::12,:,:),False,False,0),0) + psl_sd_ann = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),psl_ann(5::12,:,:),False,False,0),0) + end if + delete([/psl_seas,psl_ann/]) + end do + delete(psl) + copy_VarMeta(psl_mean_djf,psl_sd_djf) + copy_VarMeta(psl_mean_mam,psl_sd_mam) + copy_VarMeta(psl_mean_jja,psl_sd_jja) + copy_VarMeta(psl_mean_son,psl_sd_son) + copy_VarMeta(psl_mean_ann,psl_sd_ann) + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.mean_stddev."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + + z->psl_spatialmean_djf = set_varAtts(psl_mean_djf,"psl mean (DJF)","","") + z->psl_spatialmean_mam = set_varAtts(psl_mean_djf,"psl mean (MAM)","","") + z->psl_spatialmean_jja = set_varAtts(psl_mean_djf,"psl mean (JJA)","","") + z->psl_spatialmean_son = set_varAtts(psl_mean_djf,"psl mean (SON)","","") + z->psl_spatialmean_ann = set_varAtts(psl_mean_djf,"psl mean (annual)","","") + + z->psl_spatialstddev_djf = set_varAtts(psl_sd_djf,"psl standard deviation (DJF)","","") + z->psl_spatialstddev_mam = set_varAtts(psl_sd_mam,"psl standard deviation (MAM)","","") + z->psl_spatialstddev_jja = set_varAtts(psl_sd_jja,"psl standard deviation (JJA)","","") + z->psl_spatialstddev_son = set_varAtts(psl_sd_son,"psl standard deviation (SON)","","") + z->psl_spatialstddev_ann = set_varAtts(psl_sd_ann,"psl standard deviation (annual)","","") + delete(z) + delete([/modname,fn/]) + end if +;========================================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@gsnDraw = False + res@gsnFrame = False + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@cnLevelSelectionMode = "ExplicitLevels" + + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + + sres = res + + res@cnLevels = fspan(.4,6.0,8) + if (COLORMAP.eq.0) then + res@cnFillColors = (/2,4,6,8,10,12,14,16,18/) + sres@cnLevels = ispan(972,1044,4) + end if + if (COLORMAP.eq.1) then + res@cnFillColors = (/35,47,63,79,95,111,124,155,175/) + sres@cnLevels = ispan(980,1036,4) + end if + + + + if (isfilepresent2("obs_psl").and.ee.eq.0) then ; for pattern correlation table + patcor = new((/nsim,dimsizes(psl_sd_ann&lat),dimsizes(psl_sd_ann&lon)/),typeof(psl_sd_ann)) + patcor!1 = "lat" + patcor&lat = psl_sd_ann&lat + patcor!2 = "lon" + patcor&lon = psl_sd_ann&lon + patcor(ee,:,:) = (/ psl_sd_ann /) + end if + if (isfilepresent2("obs_psl").and.ee.ge.1.and.isvar("patcor")) then + patcor(ee,:,:) = (/ totype(linint2(psl_sd_ann&lon,psl_sd_ann&lat,psl_sd_ann,True,patcor&lon,patcor&lat,0),typeof(patcor)) /) + end if + + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnRightString = psl_mean_djf@units + res@gsnCenterString = names(ee) + plot_stddev_djf(ee) = gsn_csm_contour_map(wks_stddev_djf,psl_sd_djf,res) + plot_stddev_mam(ee) = gsn_csm_contour_map(wks_stddev_mam,psl_sd_mam,res) + plot_stddev_jja(ee) = gsn_csm_contour_map(wks_stddev_jja,psl_sd_jja,res) + plot_stddev_son(ee) = gsn_csm_contour_map(wks_stddev_son,psl_sd_son,res) + plot_stddev_ann(ee) = gsn_csm_contour_map(wks_stddev_ann,psl_sd_ann,res) + + sres@gsnLeftString = syear(ee)+"-"+eyear(ee) + sres@gsnRightString = psl_mean_djf@units + sres@gsnCenterString = names(ee) + plot_mean_djf(ee) = gsn_csm_contour_map(wks_mean_djf,psl_mean_djf,sres) + plot_mean_mam(ee) = gsn_csm_contour_map(wks_mean_mam,psl_mean_mam,sres) + plot_mean_jja(ee) = gsn_csm_contour_map(wks_mean_jja,psl_mean_jja,sres) + plot_mean_son(ee) = gsn_csm_contour_map(wks_mean_son,psl_mean_son,sres) + plot_mean_ann(ee) = gsn_csm_contour_map(wks_mean_ann,psl_mean_ann,sres) + delete([/psl_sd_djf,psl_sd_mam,psl_sd_jja,psl_sd_son,psl_sd_ann,psl_mean_djf,psl_mean_mam,psl_mean_jja,psl_mean_son,psl_mean_ann,res,sres/]) + end do + + if (isvar("patcor")) then ; for pattern correlation table + clat = cos(0.01745329*patcor&lat) + finpr = "psl Std Dev (Ann) " ; Must be 18 characters long + line3 = " " ; Must be 18 characters long + line4 = line3 + header = (/"","Pattern Correlations/RMS Differences Observations vs. Model(s)",""/) + do hh = 1,nsim-1 + dimY = dimsizes(tochar(names(hh))) + nchar = dimY + nchar = where(nchar.le.10,10,nchar) + if (dimY.lt.10) then + ntb = "" + do ii = 0,10-dimY-1 + ntb = ntb+" " + end do + ntb = ntb+names(hh) + else + ntb = names(hh) + end if + + ntc = "" + do ii = 0,nchar-1 + ntc = ntc+"-" + end do + format2 = "%"+(nchar-5+1)+".2f" + format3 = "%4.2f" + line3 = line3+" "+ntb + line4 = line4+" "+ntc + if (all(ismissing(patcor(hh,:,:)))) then + finpr = finpr+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr = finpr+sprintf(format2,(pattern_cor(patcor(0,:,:),patcor(hh,:,:),clat,0)))+"/"+sprintf(format3,(wgt_arearmse(patcor(0,:,:),patcor(hh,:,:),clat,1.0,0))) + end if + end do + if (dimsizes(tochar(line4)).ge.8190) then ; system or fortran compiler limit + print("Metrics table warning: Not creating metrics table as size of comparison results in a invalid ascii row size.") + else + write_table(getenv("OUTDIR")+"metrics.psl.mean_stddev.txt","w",[/header/],"%s") + write_table(getenv("OUTDIR")+"metrics.psl.mean_stddev.txt","a",[/line3/],"%s") + write_table(getenv("OUTDIR")+"metrics.psl.mean_stddev.txt","a",[/line4/],"%s") + write_table(getenv("OUTDIR")+"metrics.psl.mean_stddev.txt","a",[/finpr/],"%s") + end if + delete([/finpr,line3,line4,format2,format3,nchar,ntc,clat,patcor,dimY,ntb,header/]) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelFontHeightF = 0.013 + panres@lbLabelStride = 1 + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres@txString = "PSL Standard Deviations (DJF)" + gsn_panel2(wks_stddev_djf,plot_stddev_djf,(/nrow,ncol/),panres) + delete(wks_stddev_djf) + + panres@txString = "PSL Standard Deviations (MAM)" + gsn_panel2(wks_stddev_mam,plot_stddev_mam,(/nrow,ncol/),panres) + delete(wks_stddev_mam) + + panres@txString = "PSL Standard Deviations (JJA)" + gsn_panel2(wks_stddev_jja,plot_stddev_jja,(/nrow,ncol/),panres) + delete(wks_stddev_jja) + + panres@txString = "PSL Standard Deviations (SON)" + gsn_panel2(wks_stddev_son,plot_stddev_son,(/nrow,ncol/),panres) + delete(wks_stddev_son) + + panres@txString = "PSL Standard Deviations (Annual)" + gsn_panel2(wks_stddev_ann,plot_stddev_ann,(/nrow,ncol/),panres) + delete(wks_stddev_ann) + + panres@txString = "PSL Means (DJF)" + gsn_panel2(wks_mean_djf,plot_mean_djf,(/nrow,ncol/),panres) + delete(wks_mean_djf) + + panres@txString = "PSL Means (MAM)" + gsn_panel2(wks_mean_mam,plot_mean_mam,(/nrow,ncol/),panres) + delete(wks_mean_mam) + + panres@txString = "PSL Means (JJA)" + gsn_panel2(wks_mean_jja,plot_mean_jja,(/nrow,ncol/),panres) + delete(wks_mean_jja) + + panres@txString = "PSL Means (SON)" + gsn_panel2(wks_mean_son,plot_mean_son,(/nrow,ncol/),panres) + delete(wks_mean_son) + + panres@txString = "PSL Means (Annual)" + gsn_panel2(wks_mean_ann,plot_mean_ann,(/nrow,ncol/),panres) + delete(wks_mean_ann) + delete(panres) + print("Finished: psl.mean_stddev.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/psl.nam_nao.ncl b/lib/externals/CVDP/ncl_scripts/psl.nam_nao.ncl new file mode 100644 index 000000000..f7be5c014 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/psl.nam_nao.ncl @@ -0,0 +1,1942 @@ +; Calculates NAM and NAO (patterns and PC timeseries), as well as +; regressions of those PC timeseries onto ts, tas, and pr. +; +; Variables used: psl, ts, tas, and pr +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: psl.nam_nao.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COMPUTE_MODES_MON = getenv("COMPUTE_MODES_MON") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_psl") + na = asciiread("namelist_byvar/namelist_psl",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) + +;---------SST Regressions coding------------------------------------------------- + nsim_ts = numAsciiRow("namelist_byvar/namelist_ts") + na_ts = asciiread("namelist_byvar/namelist_ts",(/nsim_ts/),"string") + names_ts = new(nsim_ts,"string") + paths_ts = new(nsim_ts,"string") + syear_ts = new(nsim_ts,"integer",-999) + eyear_ts = new(nsim_ts,"integer",-999) + + do gg = 0,nsim_ts-1 + names_ts(gg) = str_strip(str_get_field(na_ts(gg),1,delim)) + paths_ts(gg) = str_strip(str_get_field(na_ts(gg),2,delim)) + syear_ts(gg) = stringtointeger(str_strip(str_get_field(na_ts(gg),3,delim))) + eyear_ts(gg) = stringtointeger(str_strip(str_get_field(na_ts(gg),4,delim))) + end do + delete(na_ts) + nyr_ts = eyear_ts-syear_ts+1 +;---------TAS Regressions coding------------------------------------------------- + nsim_tas = numAsciiRow("namelist_byvar/namelist_trefht") + na_tas = asciiread("namelist_byvar/namelist_trefht",(/nsim_tas/),"string") + names_tas = new(nsim_tas,"string") + paths_tas = new(nsim_tas,"string") + syear_tas = new(nsim_tas,"integer",-999) + eyear_tas = new(nsim_tas,"integer",-999) + + do gg = 0,nsim_tas-1 + names_tas(gg) = str_strip(str_get_field(na_tas(gg),1,delim)) + paths_tas(gg) = str_strip(str_get_field(na_tas(gg),2,delim)) + syear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),3,delim))) + eyear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),4,delim))) + end do + delete(na_tas) + nyr_tas = eyear_tas-syear_tas+1 +;---------PR Regressions coding------------------------------------------------- + nsim_pr = numAsciiRow("namelist_byvar/namelist_prect") + na_pr = asciiread("namelist_byvar/namelist_prect",(/nsim_pr/),"string") + names_pr = new(nsim_pr,"string") + paths_pr = new(nsim_pr,"string") + syear_pr = new(nsim_pr,"integer",-999) + eyear_pr = new(nsim_pr,"integer",-999) + + do gg = 0,nsim_pr-1 + names_pr(gg) = str_strip(str_get_field(na_pr(gg),1,delim)) + paths_pr(gg) = str_strip(str_get_field(na_pr(gg),2,delim)) + syear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),3,delim))) + eyear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),4,delim))) + end do + delete(na_pr) + nyr_pr = eyear_pr-syear_pr+1 +;------------------------------------------------------------------------------------------------- + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_nam = gsn_open_wks(wks_type,getenv("OUTDIR")+"nam") + wks_nam_pr = gsn_open_wks(wks_type,getenv("OUTDIR")+"nam.prreg") + wks_nam_ts = gsn_open_wks(wks_type,getenv("OUTDIR")+"nam.timeseries") + + wks_nao = gsn_open_wks(wks_type,getenv("OUTDIR")+"nao") + wks_nao_pr = gsn_open_wks(wks_type,getenv("OUTDIR")+"nao.prreg") + wks_nao_ts = gsn_open_wks(wks_type,getenv("OUTDIR")+"nao.timeseries") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_nam,"ncl_default") + gsn_define_colormap(wks_nam_ts,"ncl_default") + gsn_define_colormap(wks_nao,"ncl_default") + gsn_define_colormap(wks_nao_ts,"ncl_default") + gsn_define_colormap(wks_nam_pr,"MPL_BrBG") + gsn_define_colormap(wks_nao_pr,"MPL_BrBG") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_nam,"BlueDarkRed18") + gsn_define_colormap(wks_nam_ts,"ncl_default") + gsn_define_colormap(wks_nao,"BlueDarkRed18") + gsn_define_colormap(wks_nao_ts,"ncl_default") + gsn_define_colormap(wks_nam_pr,"BrownBlue12") + gsn_define_colormap(wks_nao_pr,"BrownBlue12") + end if + + map_nam_djf = new(nsim,"graphic") + map_nam_mam = new(nsim,"graphic") + map_nam_jja = new(nsim,"graphic") + map_nam_son = new(nsim,"graphic") + map_nam_ann = new(nsim,"graphic") + map_nam_mon = new(nsim,"graphic") + xy_nam_djf = new(nsim,"graphic") + xy_nam_mam = new(nsim,"graphic") + xy_nam_jja = new(nsim,"graphic") + xy_nam_son = new(nsim,"graphic") + xy_nam_ann = new(nsim,"graphic") + xy_nam_mon = new(nsim,"graphic") + reg_nam_djf = new(nsim,"graphic") + reg_nam_mam = new(nsim,"graphic") + reg_nam_jja = new(nsim,"graphic") + reg_nam_son = new(nsim,"graphic") + reg_nam_ann = new(nsim,"graphic") + reg_nam_mon = new(nsim,"graphic") + reg_nam_pr_djf = new(nsim,"graphic") + reg_nam_pr_mam = new(nsim,"graphic") + reg_nam_pr_jja = new(nsim,"graphic") + reg_nam_pr_son = new(nsim,"graphic") + reg_nam_pr_ann = new(nsim,"graphic") + reg_nam_pr_mon = new(nsim,"graphic") + + map_nao_djf = new(nsim,"graphic") + map_nao_mam = new(nsim,"graphic") + map_nao_jja = new(nsim,"graphic") + map_nao_son = new(nsim,"graphic") + map_nao_ann = new(nsim,"graphic") + map_nao_mon = new(nsim,"graphic") + xy_nao_djf = new(nsim,"graphic") + xy_nao_mam = new(nsim,"graphic") + xy_nao_jja = new(nsim,"graphic") + xy_nao_son = new(nsim,"graphic") + xy_nao_ann = new(nsim,"graphic") + xy_nao_mon = new(nsim,"graphic") + reg_nao_djf = new(nsim,"graphic") + reg_nao_mam = new(nsim,"graphic") + reg_nao_jja = new(nsim,"graphic") + reg_nao_son = new(nsim,"graphic") + reg_nao_ann = new(nsim,"graphic") + reg_nao_mon = new(nsim,"graphic") + reg_nao_pr_djf = new(nsim,"graphic") + reg_nao_pr_mam = new(nsim,"graphic") + reg_nao_pr_jja = new(nsim,"graphic") + reg_nao_pr_son = new(nsim,"graphic") + reg_nao_pr_ann = new(nsim,"graphic") + reg_nao_pr_mon = new(nsim,"graphic") + + xy_npi = new(nsim,"graphic") + sstreg_frame = 1 ; *reg_frame = flag to create regressions .ps/.png files. Created/used instead of *reg_plot_flag + ; so that if {sst,tas,pr} regressions are not created for the last simulation listed that .ps/png files are created + tasreg_frame = 1 + prreg_frame = 1 + + do ee = 0,nsim-1 +; print(paths(ee)+" "+syear(ee)+" "+eyear(ee)) + arr = data_read_in(paths(ee),"PSL",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(arr,"is_all_missing")) then + delete(arr) + continue + end if + + if (OPT_CLIMO.eq."Full") then + arr = rmMonAnnCycTLL(arr) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = arr + delete(temp_arr&time) + temp_arr&time = cd_calendar(arr&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + arr = calcMonAnomTLL(arr,climo) + delete(climo) + end if + + arrT = runave_n_Wrap(arr,3,0,0) ; form DJF averages + arrT(0,:,:) = (/ dim_avg_n(arr(:1,:,:),0) /) + arr_djf = arrT(0::12,:,:) + arr_mam = arrT(3::12,:,:) + arr_jja = arrT(6::12,:,:) ; form JJA averages + arr_son = arrT(9::12,:,:) + delete(arrT) + + arrV = runave_n_Wrap(arr,12,0,0) + arr_ann = arrV(5::12,:,:) + delete(arrV) +; +; arr_djf = (/ dtrend_msg_n(ispan(0,dimsizes(arr_djf&time)-1,1),arr_djf,True,False,0) /) +; arr_mam = (/ dtrend_msg_n(ispan(0,dimsizes(arr_mam&time)-1,1),arr_mam,True,False,0) /) +; arr_jja = (/ dtrend_msg_n(ispan(0,dimsizes(arr_jja&time)-1,1),arr_jja,True,False,0) /) +; arr_son = (/ dtrend_msg_n(ispan(0,dimsizes(arr_son&time)-1,1),arr_son,True,False,0) /) +; +; arr_ann = (/ dtrend_msg_n(ispan(0,dimsizes(arr_ann&time)-1,1),arr_ann,True,False,0) /) +; +; arr_ndjfm = (/ dtrend_msg_n(ispan(0,dimsizes(arr_ndjfm&time)-1,1),arr_ndjfm,True,False,0) /) +; +; arr = (/ dtrend_msg_n(ispan(0,dimsizes(arr&time)-1,1),arr,True,False,0) /) +;---------SST Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_ts(ee),eyear(ee),eyear_ts(ee)/)))) then + sstreg_plot_flag = 1 + else + if (syear(ee).eq.syear_ts(ee)) then ; check that the start and end years match for ts, tas, and psl + if (eyear(ee).eq.eyear_ts(ee)) then + sstreg_plot_flag = 0 + else + sstreg_plot_flag = 1 + end if + else + sstreg_plot_flag = 1 + end if + end if + + if (sstreg_plot_flag.eq.0) then + ; print("Data to be read in: "+paths_ts(ee)+" from "+syear_ts(ee)+":"+eyear_ts(ee)) + sst = data_read_in(paths_ts(ee),"TS",syear_ts(ee),eyear_ts(ee)) + if (isatt(sst,"is_all_missing")) then + sstreg_plot_flag = 1 + delete(sst) + end if + + if (sstreg_plot_flag.eq.0) then ; only continue if both PSL/TS fields are present + sst = where(sst.le.-1.8,-1.8,sst) + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,sst&lat,sst&lon) + sst = mask(sst,conform(sst,lsm,(/1,2/)).ge.1,False) + delete(lsm) + + if (OPT_CLIMO.eq."Full") then + sst = rmMonAnnCycTLL(sst) + else + check_custom_climo(names_ts(ee),syear_ts(ee),eyear_ts(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sst + delete(temp_arr&time) + temp_arr&time = cd_calendar(sst&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sst = calcMonAnomTLL(sst,climo) + delete(climo) + end if +; sst = (/ dtrend_msg_n(ispan(0,dimsizes(sst&time)-1,1),sst,False,False,0) /) + + sstT = runave_n_Wrap(sst,3,0,0) ; form DJF averages + sstT(0,:,:) = (/ dim_avg_n(sst(:1,:,:),0) /) + sst_djf = sstT(0::12,:,:) + sst_mam = sstT(3::12,:,:) + sst_jja = sstT(6::12,:,:) ; form JJA averages + sst_son = sstT(9::12,:,:) + delete(sstT) + + sstV = runave_n_Wrap(sst,12,0,0) + sst_ann = sstV(5::12,:,:) + delete([/sstV/]) + end if + end if +;---------TAS Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_tas(ee),eyear(ee),eyear_tas(ee)/)))) then + tasreg_plot_flag = 1 + else + if (syear(ee).eq.syear_tas(ee)) then ; check that the start and end years match for ts, tas, and psl + if (eyear(ee).eq.eyear_tas(ee)) then + tasreg_plot_flag = 0 + else + tasreg_plot_flag = 1 + end if + else + tasreg_plot_flag = 1 + end if + if (sstreg_plot_flag.eq.1) then ; if the ts dataset is missing but the tas is not, do not + tasreg_plot_flag = 1 ; run through the tas calculations as both currently required + end if + end if + + if (tasreg_plot_flag.eq.0) then + tas = data_read_in(paths_tas(ee),"TREFHT",syear_tas(ee),eyear_tas(ee)) + if (isatt(tas,"is_all_missing")) then + tasreg_plot_flag = 1 + delete(tas) + end if + + if (tasreg_plot_flag.eq.0) then ; only continue if both PSL/TS fields are present + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,tas&lat,tas&lon) + tas = mask(tas,conform(tas,lsm,(/1,2/)).eq.0,False) + delete(lsm) + + if (OPT_CLIMO.eq."Full") then + tas = rmMonAnnCycTLL(tas) + else + check_custom_climo(names_tas(ee),syear_tas(ee),eyear_tas(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = tas + delete(temp_arr&time) + temp_arr&time = cd_calendar(tas&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + tas = calcMonAnomTLL(tas,climo) + delete(climo) + end if +; tas = (/ dtrend_msg_n(ispan(0,dimsizes(tas&time)-1,1),tas,False,False,0) /) + + tasT = runave_n_Wrap(tas,3,0,0) ; form DJF averages + tasT(0,:,:) = (/ dim_avg_n(tas(:1,:,:),0) /) + tas_djf = tasT(0::12,:,:) + tas_mam = tasT(3::12,:,:) + tas_jja = tasT(6::12,:,:) ; form JJA averages + tas_son = tasT(9::12,:,:) + delete(tasT) + + tasV = runave_n_Wrap(tas,12,0,0) + tas_ann = tasV(5::12,:,:) + delete([/tasV/]) + end if + end if +;---------PR Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_pr(ee),eyear(ee),eyear_pr(ee)/)))) then + prreg_plot_flag = 1 + else + if (syear(ee).eq.syear_pr(ee)) then ; check that the start and end years match for pr and psl + if (eyear(ee).eq.eyear_pr(ee)) then + prreg_plot_flag = 0 + else + prreg_plot_flag = 1 + end if + else + prreg_plot_flag = 1 + end if + end if + + if (prreg_plot_flag.eq.0) then + pr = data_read_in(paths_pr(ee),"PRECT",syear_pr(ee),eyear_pr(ee)) + if (isatt(pr,"is_all_missing")) then + prreg_plot_flag = 1 + delete(pr) + end if + + if (prreg_plot_flag.eq.0) then ; only continue if both PSL/PR fields are present + if (OPT_CLIMO.eq."Full") then + pr = rmMonAnnCycTLL(pr) + else + check_custom_climo(names_pr(ee),syear_pr(ee),eyear_pr(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = pr + delete(temp_arr&time) + temp_arr&time = cd_calendar(pr&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + pr = calcMonAnomTLL(pr,climo) + delete(climo) + end if +; pr = (/ dtrend_msg_n(ispan(0,dimsizes(pr&time)-1,1),pr,False,False,0) /) + + prT = runave_n_Wrap(pr,3,0,0) ; form DJF averages + prT(0,:,:) = (/ dim_avg_n(pr(:1,:,:),0) /) + pr_djf = prT(0::12,:,:) + pr_mam = prT(3::12,:,:) + pr_jja = prT(6::12,:,:) ; form JJA averages + pr_son = prT(9::12,:,:) + delete(prT) + + prV = runave_n_Wrap(pr,12,0,0) + pr_ann = prV(5::12,:,:) + delete([/prV/]) + end if + end if + +;------------------------------------------------------------------- + arr_djf_CW = SqrtCosWeight(arr_djf) + arr_mam_CW = SqrtCosWeight(arr_mam) + arr_jja_CW = SqrtCosWeight(arr_jja) + arr_son_CW = SqrtCosWeight(arr_son) + arr_ann_CW = SqrtCosWeight(arr_ann) + if (COMPUTE_MODES_MON.eq."True") then + arr_mon_CW = SqrtCosWeight(arr) + else + if (isvar("arr")) then + delete(arr) + end if + if (isvar("sst")) then + delete(sst) + end if + if (isvar("tas")) then + delete(tas) + end if + if (isvar("pr")) then + delete(pr) + end if + end if +;---------NAM calculations---------------------------------------------------------- + evecv = eofunc(arr_djf_CW({lat|20:},lon|:,time|:),2,75) + pcts = eofunc_ts(arr_djf_CW({lat|20:},lon|:,time|:),evecv,False) + nam_pc_djf = dim_standardize(pcts(0,:),0) + nam_djf = arr_djf(0,:,:) + nam_djf = (/ regCoef(nam_pc_djf,arr_djf(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nam_sst_djf = sst_djf(0,:,:) + nam_sst_djf = (/ regCoef(nam_pc_djf,sst_djf(lat|:,lon|:,time|:)) /) + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_djf = tas_djf(0,:,:) + nam_tas_djf = (/ regCoef(nam_pc_djf,tas_djf(lat|:,lon|:,time|:)) /) + end if + if (prreg_plot_flag.eq.0) then + nam_pr_djf = pr_djf(0,:,:) + nam_pr_djf = (/ regCoef(nam_pc_djf,pr_djf(lat|:,lon|:,time|:)) /) + end if + if (.not.ismissing(nam_djf({85},{5}))) then + if (nam_djf({85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nam_djf = nam_djf*-1. + nam_pc_djf = nam_pc_djf*-1. + if (sstreg_plot_flag.eq.0) then + nam_sst_djf = nam_sst_djf*-1. + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_djf = nam_tas_djf*-1. + end if + if (prreg_plot_flag.eq.0) then + nam_pr_djf = nam_pr_djf*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nam_pc_djf),False) + if (sig_pcv(0)) then ; if True then significant + nam_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nam_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + nam_pc_djf!0 = "TIME" + nam_pc_djf&TIME = ispan(syear(ee),eyear(ee),1) + nam_pc_djf&TIME@units = "YYYY" + nam_pc_djf&TIME@long_name = "time" + delete([/evecv,pcts/]) + + evecv = eofunc(arr_mam_CW({lat|20:},lon|:,time|:),2,75) + pcts = eofunc_ts(arr_mam_CW({lat|20:},lon|:,time|:),evecv,False) + nam_pc_mam = dim_standardize(pcts(0,:),0) + nam_mam = arr_mam(0,:,:) + nam_mam = (/ regCoef(nam_pc_mam,arr_mam(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nam_sst_mam = sst_mam(0,:,:) + nam_sst_mam = (/ regCoef(nam_pc_mam,sst_mam(lat|:,lon|:,time|:)) /) + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_mam = tas_mam(0,:,:) + nam_tas_mam = (/ regCoef(nam_pc_mam,tas_mam(lat|:,lon|:,time|:)) /) + end if + if (prreg_plot_flag.eq.0) then + nam_pr_mam = pr_mam(0,:,:) + nam_pr_mam = (/ regCoef(nam_pc_mam,pr_mam(lat|:,lon|:,time|:)) /) + end if + if (.not.ismissing(nam_mam({85},{5}))) then + if (nam_mam({85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nam_mam = nam_mam*-1. + nam_pc_mam = nam_pc_mam*-1. + if (sstreg_plot_flag.eq.0) then + nam_sst_mam = nam_sst_mam*-1. + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_mam = nam_tas_mam*-1. + end if + if (prreg_plot_flag.eq.0) then + nam_pr_mam = nam_pr_mam*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nam_pc_mam),False) + if (sig_pcv(0)) then ; if True then significant + nam_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nam_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(nam_pc_djf,nam_pc_mam) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_jja_CW({lat|20:},lon|:,time|:),2,75) + pcts = eofunc_ts(arr_jja_CW({lat|20:},lon|:,time|:),evecv,False) + nam_pc_jja = dim_standardize(pcts(0,:),0) + nam_jja = arr_jja(0,:,:) + nam_jja = (/ regCoef(nam_pc_jja,arr_jja(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nam_sst_jja = sst_jja(0,:,:) + nam_sst_jja = (/ regCoef(nam_pc_jja,sst_jja(lat|:,lon|:,time|:)) /) + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_jja = tas_jja(0,:,:) + nam_tas_jja = (/ regCoef(nam_pc_jja,tas_jja(lat|:,lon|:,time|:)) /) + end if + if (prreg_plot_flag.eq.0) then + nam_pr_jja = pr_jja(0,:,:) + nam_pr_jja = (/ regCoef(nam_pc_jja,pr_jja(lat|:,lon|:,time|:)) /) + end if + if (.not.ismissing(nam_jja({85},{5}))) then + if (nam_jja({85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nam_jja = nam_jja*-1. + nam_pc_jja = nam_pc_jja*-1. + if (sstreg_plot_flag.eq.0) then + nam_sst_jja = nam_sst_jja*-1. + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_jja = nam_tas_jja*-1. + end if + if (prreg_plot_flag.eq.0) then + nam_pr_jja = nam_pr_jja*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nam_pc_jja),False) + if (sig_pcv(0)) then ; if True then significant + nam_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nam_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(nam_pc_djf,nam_pc_jja) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_son_CW({lat|20:},lon|:,time|:),2,75) + pcts = eofunc_ts(arr_son_CW({lat|20:},lon|:,time|:),evecv,False) + nam_pc_son = dim_standardize(pcts(0,:),0) + nam_son = arr_son(0,:,:) + nam_son = (/ regCoef(nam_pc_son,arr_son(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nam_sst_son = sst_son(0,:,:) + nam_sst_son = (/ regCoef(nam_pc_son,sst_son(lat|:,lon|:,time|:)) /) + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_son = tas_son(0,:,:) + nam_tas_son = (/ regCoef(nam_pc_son,tas_son(lat|:,lon|:,time|:)) /) + end if + if (prreg_plot_flag.eq.0) then + nam_pr_son = pr_son(0,:,:) + nam_pr_son = (/ regCoef(nam_pc_son,pr_son(lat|:,lon|:,time|:)) /) + end if + if (.not.ismissing(nam_son({85},{5}))) then + if (nam_son({85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nam_son = nam_son*-1. + nam_pc_son = nam_pc_son*-1. + if (sstreg_plot_flag.eq.0) then + nam_sst_son = nam_sst_son*-1. + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_son = nam_tas_son*-1. + end if + if (prreg_plot_flag.eq.0) then + nam_pr_son = nam_pr_son*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nam_pc_son),False) + if (sig_pcv(0)) then ; if True then significant + nam_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nam_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(nam_pc_djf,nam_pc_son) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_ann_CW({lat|20:},lon|:,time|:),2,75) + pcts = eofunc_ts(arr_ann_CW({lat|20:},lon|:,time|:),evecv,False) + nam_pc_ann = dim_standardize(pcts(0,:),0) + nam_ann = arr_ann(0,:,:) + nam_ann = (/ regCoef(nam_pc_ann,arr_ann(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nam_sst_ann = sst_ann(0,:,:) + nam_sst_ann = (/ regCoef(nam_pc_ann,sst_ann(lat|:,lon|:,time|:)) /) + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_ann = tas_ann(0,:,:) + nam_tas_ann = (/ regCoef(nam_pc_ann,tas_ann(lat|:,lon|:,time|:)) /) + end if + if (prreg_plot_flag.eq.0) then + nam_pr_ann = pr_ann(0,:,:) + nam_pr_ann = (/ regCoef(nam_pc_ann,pr_ann(lat|:,lon|:,time|:)) /) + end if + if (.not.ismissing(nam_ann({85},{5}))) then + if (nam_ann({85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nam_ann = nam_ann*-1. + nam_pc_ann = nam_pc_ann*-1. + if (sstreg_plot_flag.eq.0) then + nam_sst_ann = nam_sst_ann*-1. + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_ann = nam_tas_ann*-1. + end if + if (prreg_plot_flag.eq.0) then + nam_pr_ann = nam_pr_ann*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nam_pc_ann),False) + if (sig_pcv(0)) then ; if True then significant + nam_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nam_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(nam_pc_djf,nam_pc_ann) + delete([/evecv,pcts/]) + + if (COMPUTE_MODES_MON.eq."True") then + evecv = eofunc(arr_mon_CW({lat|20:},lon|:,time|:),2,75) + pcts = eofunc_ts(arr_mon_CW({lat|20:},lon|:,time|:),evecv,False) + nam_pc_mon = dim_standardize(pcts(0,:),0) + nam_mon = arr(0,:,:) + nam_mon = (/ regCoef(nam_pc_mon,arr(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nam_sst_mon = sst(0,:,:) + nam_sst_mon = (/ regCoef(nam_pc_mon,sst(lat|:,lon|:,time|:)) /) + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_mon = tas(0,:,:) + nam_tas_mon = (/ regCoef(nam_pc_mon,tas(lat|:,lon|:,time|:)) /) + end if + if (prreg_plot_flag.eq.0) then + nam_pr_mon = pr(0,:,:) + nam_pr_mon = (/ regCoef(nam_pc_mon,pr(lat|:,lon|:,time|:)) /) + end if + if (.not.ismissing(nam_mon({85},{5}))) then + if (nam_mon({85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nam_mon = nam_mon*-1. + nam_pc_mon = nam_pc_mon*-1. + if (sstreg_plot_flag.eq.0) then + nam_sst_mon = nam_sst_mon*-1. + end if + if (tasreg_plot_flag.eq.0) then + nam_tas_mon = nam_tas_mon*-1. + end if + if (prreg_plot_flag.eq.0) then + nam_pr_mon = nam_pr_mon*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nam_pc_mon),False) + if (sig_pcv(0)) then ; if True then significant + nam_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nam_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + nam_pc_mon!0 = "time" + nam_pc_mon&time = arr&time + delete([/evecv,pcts/]) + end if +;----------NAO calculations-------------------------------------------------------------------------------- + arr_djf_CW_LF = lonFlip(arr_djf_CW) + arr_mam_CW_LF = lonFlip(arr_mam_CW) + arr_jja_CW_LF = lonFlip(arr_jja_CW) + arr_son_CW_LF = lonFlip(arr_son_CW) + arr_ann_CW_LF = lonFlip(arr_ann_CW) + if (COMPUTE_MODES_MON.eq."True") then + arr_mon_CW_LF = lonFlip(arr_mon_CW) + delete(arr_mon_CW) + end if + delete([/arr_djf_CW,arr_mam_CW,arr_jja_CW,arr_son_CW,arr_ann_CW/]) + + evecv = eofunc(arr_djf_CW_LF({lat|20:80},{lon|-90.:40},time|:),2,75) + pcts = eofunc_ts(arr_djf_CW_LF({lat|20:80},{lon|-90.:40},time|:),evecv,False) + nao_pc_djf = dim_standardize(pcts(0,:),0) + nao_djf = arr_djf(0,:,:) + nao_djf = (/ regCoef(nao_pc_djf,arr_djf(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nao_sst_djf = sst_djf(0,:,:) + nao_sst_djf = (/ regCoef(nao_pc_djf,sst_djf(lat|:,lon|:,time|:)) /) + delete(sst_djf) + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_djf = tas_djf(0,:,:) + nao_tas_djf = (/ regCoef(nao_pc_djf,tas_djf(lat|:,lon|:,time|:)) /) + delete(tas_djf) + end if + if (prreg_plot_flag.eq.0) then + nao_pr_djf = pr_djf(0,:,:) + nao_pr_djf = (/ regCoef(nao_pc_djf,pr_djf(lat|:,lon|:,time|:)) /) + delete(pr_djf) + end if + if (.not.ismissing(nao_djf({70},{350}))) then + if (nao_djf({70},{350}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nao_djf = nao_djf*-1. + nao_pc_djf = nao_pc_djf*-1. + if (sstreg_plot_flag.eq.0) then + nao_sst_djf = nao_sst_djf*-1. + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_djf = nao_tas_djf*-1. + end if + if (prreg_plot_flag.eq.0) then + nao_pr_djf = nao_pr_djf*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nao_pc_djf),False) + if (sig_pcv(0)) then ; if True then significant + nao_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nao_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(nam_pc_djf,nao_pc_djf) + delete([/evecv,pcts,arr_djf,arr_djf_CW_LF/]) + + evecv = eofunc(arr_mam_CW_LF({lat|20:80},{lon|-90.:40},time|:),2,75) + pcts = eofunc_ts(arr_mam_CW_LF({lat|20:80},{lon|-90.:40},time|:),evecv,False) + nao_pc_mam = dim_standardize(pcts(0,:),0) + nao_mam = arr_mam(0,:,:) + nao_mam = (/ regCoef(nao_pc_mam,arr_mam(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nao_sst_mam = sst_mam(0,:,:) + nao_sst_mam = (/ regCoef(nao_pc_mam,sst_mam(lat|:,lon|:,time|:)) /) + delete(sst_mam) + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_mam = tas_mam(0,:,:) + nao_tas_mam = (/ regCoef(nao_pc_mam,tas_mam(lat|:,lon|:,time|:)) /) + delete(tas_mam) + end if + if (prreg_plot_flag.eq.0) then + nao_pr_mam = pr_mam(0,:,:) + nao_pr_mam = (/ regCoef(nao_pc_mam,pr_mam(lat|:,lon|:,time|:)) /) + delete(pr_mam) + end if + if (.not.ismissing(nao_mam({70},{350}))) then + if (nao_mam({70},{350}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nao_mam = nao_mam*-1. + nao_pc_mam = nao_pc_mam*-1. + if (sstreg_plot_flag.eq.0) then + nao_sst_mam = nao_sst_mam*-1. + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_mam = nao_tas_mam*-1. + end if + if (prreg_plot_flag.eq.0) then + nao_pr_mam = nao_pr_mam*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nao_pc_mam),False) + if (sig_pcv(0)) then ; if True then significant + nao_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nao_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(nam_pc_djf,nao_pc_mam) + delete([/evecv,pcts,arr_mam,arr_mam_CW_LF/]) + + evecv = eofunc(arr_jja_CW_LF({lat|20:80},{lon|-90.:40},time|:),2,75) + pcts = eofunc_ts(arr_jja_CW_LF({lat|20:80},{lon|-90.:40},time|:),evecv,False) + nao_pc_jja = dim_standardize(pcts(0,:),0) + nao_jja = arr_jja(0,:,:) + nao_jja = (/ regCoef(nao_pc_jja,arr_jja(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nao_sst_jja = sst_jja(0,:,:) + nao_sst_jja = (/ regCoef(nao_pc_jja,sst_jja(lat|:,lon|:,time|:)) /) + delete(sst_jja) + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_jja = tas_jja(0,:,:) + nao_tas_jja = (/ regCoef(nao_pc_jja,tas_jja(lat|:,lon|:,time|:)) /) + delete(tas_jja) + end if + if (prreg_plot_flag.eq.0) then + nao_pr_jja = pr_jja(0,:,:) + nao_pr_jja = (/ regCoef(nao_pc_jja,pr_jja(lat|:,lon|:,time|:)) /) + delete(pr_jja) + end if + if (.not.ismissing(nao_jja({70},{350}))) then + if (nao_jja({70},{350}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nao_jja = nao_jja*-1. + nao_pc_jja = nao_pc_jja*-1. + if (sstreg_plot_flag.eq.0) then + nao_sst_jja = nao_sst_jja*-1. + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_jja = nao_tas_jja*-1. + end if + if (prreg_plot_flag.eq.0) then + nao_pr_jja = nao_pr_jja*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nao_pc_jja),False) + if (sig_pcv(0)) then ; if True then significant + nao_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nao_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(nam_pc_djf,nao_pc_jja) + delete([/evecv,pcts,arr_jja,arr_jja_CW_LF/]) + + evecv = eofunc(arr_son_CW_LF({lat|20:80},{lon|-90.:40},time|:),2,75) + pcts = eofunc_ts(arr_son_CW_LF({lat|20:80},{lon|-90.:40},time|:),evecv,False) + nao_pc_son = dim_standardize(pcts(0,:),0) + nao_son = arr_son(0,:,:) + nao_son = (/ regCoef(nao_pc_son,arr_son(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nao_sst_son = sst_son(0,:,:) + nao_sst_son = (/ regCoef(nao_pc_son,sst_son(lat|:,lon|:,time|:)) /) + delete(sst_son) + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_son = tas_son(0,:,:) + nao_tas_son = (/ regCoef(nao_pc_son,tas_son(lat|:,lon|:,time|:)) /) + delete(tas_son) + end if + if (prreg_plot_flag.eq.0) then + nao_pr_son = pr_son(0,:,:) + nao_pr_son = (/ regCoef(nao_pc_son,pr_son(lat|:,lon|:,time|:)) /) + delete(pr_son) + end if + if (.not.ismissing(nao_son({70},{350}))) then + if (nao_son({70},{350}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nao_son = nao_son*-1. + nao_pc_son = nao_pc_son*-1. + if (sstreg_plot_flag.eq.0) then + nao_sst_son = nao_sst_son*-1. + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_son = nao_tas_son*-1. + end if + if (prreg_plot_flag.eq.0) then + nao_pr_son = nao_pr_son*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nao_pc_son),False) + if (sig_pcv(0)) then ; if True then significant + nao_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nao_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(nam_pc_djf,nao_pc_son) + delete([/evecv,pcts,arr_son,arr_son_CW_LF/]) + + evecv = eofunc(arr_ann_CW_LF({lat|20:80},{lon|-90.:40},time|:),2,75) + pcts = eofunc_ts(arr_ann_CW_LF({lat|20:80},{lon|-90.:40},time|:),evecv,False) + nao_pc_ann = dim_standardize(pcts(0,:),0) + nao_ann = arr_ann(0,:,:) + nao_ann = (/ regCoef(nao_pc_ann,arr_ann(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nao_sst_ann = sst_ann(0,:,:) + nao_sst_ann = (/ regCoef(nao_pc_ann,sst_ann(lat|:,lon|:,time|:)) /) + delete(sst_ann) + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_ann = tas_ann(0,:,:) + nao_tas_ann = (/ regCoef(nao_pc_ann,tas_ann(lat|:,lon|:,time|:)) /) + delete(tas_ann) + end if + if (prreg_plot_flag.eq.0) then + nao_pr_ann = pr_ann(0,:,:) + nao_pr_ann = (/ regCoef(nao_pc_ann,pr_ann(lat|:,lon|:,time|:)) /) + delete(pr_ann) + end if + if (.not.ismissing(nao_ann({70},{350}))) then + if (nao_ann({70},{350}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nao_ann = nao_ann*-1. + nao_pc_ann = nao_pc_ann*-1. + if (sstreg_plot_flag.eq.0) then + nao_sst_ann = nao_sst_ann*-1. + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_ann = nao_tas_ann*-1. + end if + if (prreg_plot_flag.eq.0) then + nao_pr_ann = nao_pr_ann*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nao_pc_ann),False) + if (sig_pcv(0)) then ; if True then significant + nao_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nao_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(nam_pc_djf,nao_pc_ann) + delete([/evecv,pcts,arr_ann,arr_ann_CW_LF/]) + + if (COMPUTE_MODES_MON.eq."True") then + evecv = eofunc(arr_mon_CW_LF({lat|20:80},{lon|-90.:40},time|:),2,75) + pcts = eofunc_ts(arr_mon_CW_LF({lat|20:80},{lon|-90.:40},time|:),evecv,False) + nao_pc_mon = dim_standardize(pcts(0,:),0) + nao_mon = arr(0,:,:) + nao_mon = (/ regCoef(nao_pc_mon,arr(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + nao_sst_mon = sst(0,:,:) + nao_sst_mon = (/ regCoef(nao_pc_mon,sst(lat|:,lon|:,time|:)) /) + delete(sst) + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_mon = tas(0,:,:) + nao_tas_mon = (/ regCoef(nao_pc_mon,tas(lat|:,lon|:,time|:)) /) + delete(tas) + end if + if (prreg_plot_flag.eq.0) then + nao_pr_mon = pr(0,:,:) + nao_pr_mon = (/ regCoef(nao_pc_mon,pr(lat|:,lon|:,time|:)) /) + delete(pr) + end if + if (.not.ismissing(nao_mon({70},{350}))) then + if (nao_mon({70},{350}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + nao_mon = nao_mon*-1. + nao_pc_mon = nao_pc_mon*-1. + if (sstreg_plot_flag.eq.0) then + nao_sst_mon = nao_sst_mon*-1. + end if + if (tasreg_plot_flag.eq.0) then + nao_tas_mon = nao_tas_mon*-1. + end if + if (prreg_plot_flag.eq.0) then + nao_pr_mon = nao_pr_mon*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(nao_pc_mon),False) + if (sig_pcv(0)) then ; if True then significant + nao_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + nao_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + delete(sig_pcv) + nao_pc_mon!0 = "time" + nao_pc_mon&time = arr&time + delete([/evecv,pcts,arr,arr_mon_CW_LF/]) + end if +;------------------------------------------------------------------------------------------------------ + if (sstreg_frame.eq.1.and.sstreg_plot_flag.eq.0) then ; sstreg_frame = flag to create regressions .ps/.png files + sstreg_frame = 0 + end if + if (tasreg_frame.eq.1.and.tasreg_plot_flag.eq.0) then ; tasreg_frame = flag to create regressions .ps/.png files + tasreg_frame = 0 + end if + if (prreg_frame.eq.1.and.prreg_plot_flag.eq.0) then ; prreg_frame = flag to create regressions .ps/.png files + prreg_frame = 0 + end if +;------------------------------------------------------------------------------------------------------ + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.nam_nao."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + + z->nao_timeseries_djf = set_varAtts(nao_pc_djf,"NAO normalized principal component timeseries (DJF)","1","") + z->nao_timeseries_mam = set_varAtts(nao_pc_mam,"NAO normalized principal component timeseries (MAM)","1","") + z->nao_timeseries_jja = set_varAtts(nao_pc_jja,"NAO normalized principal component timeseries (JJA)","1","") + z->nao_timeseries_son = set_varAtts(nao_pc_son,"NAO normalized principal component timeseries (SON)","1","") + z->nao_timeseries_ann = set_varAtts(nao_pc_ann,"NAO normalized principal component timeseries (ANN)","1","") + + z->nam_timeseries_djf = set_varAtts(nam_pc_djf,"NAM normalized principal component timeseries (DJF)","1","") + z->nam_timeseries_mam = set_varAtts(nam_pc_mam,"NAM normalized principal component timeseries (MAM)","1","") + z->nam_timeseries_jja = set_varAtts(nam_pc_jja,"NAM normalized principal component timeseries (JJA)","1","") + z->nam_timeseries_son = set_varAtts(nam_pc_son,"NAM normalized principal component timeseries (SON)","1","") + z->nam_timeseries_ann = set_varAtts(nam_pc_ann,"NAM normalized principal component timeseries (ANN)","1","") + + z->nao_pattern_djf = set_varAtts(nao_djf,"NAO spatial pattern (DJF)","","") + z->nao_pattern_mam = set_varAtts(nao_mam,"NAO spatial pattern (MAM)","","") + z->nao_pattern_jja = set_varAtts(nao_jja,"NAO spatial pattern (JJA)","","") + z->nao_pattern_son = set_varAtts(nao_son,"NAO spatial pattern (SON)","","") + z->nao_pattern_ann = set_varAtts(nao_ann,"NAO spatial pattern (annual)","","") + + z->nam_pattern_djf = set_varAtts(nam_djf,"NAM spatial pattern (DJF)","","") + z->nam_pattern_mam = set_varAtts(nam_mam,"NAM spatial pattern (MAM)","","") + z->nam_pattern_jja = set_varAtts(nam_jja,"NAM spatial pattern (JJA)","","") + z->nam_pattern_son = set_varAtts(nam_son,"NAM spatial pattern (SON)","","") + z->nam_pattern_ann = set_varAtts(nam_ann,"NAM spatial pattern (annual)","","") + + if (COMPUTE_MODES_MON.eq."True") then + z->nao_timeseries_mon = set_varAtts(nao_pc_mon,"NAO principal component timeseries (monthly)","","") + z->nam_timeseries_mon = set_varAtts(nam_pc_mon,"NAM principal component timeseries (monthly)","","") + z->nao_pattern_mon = set_varAtts(nao_mon,"NAO spatial pattern (monthly)","","") + z->nam_pattern_mon = set_varAtts(nam_mon,"NAM spatial pattern (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + + if (sstreg_plot_flag.eq.0) then + modname = str_sub_str(names_ts(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.nam_nao.ts."+syear_ts(ee)+"-"+eyear_ts(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_ts(ee)+" from "+syear_ts(ee)+"-"+eyear_ts(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_ts(ee)+"-"+eyear_ts(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->nao_sst_regression_djf = set_varAtts(nao_sst_djf,"sst regression onto NAO principal component timeseries (DJF)","","") + z->nao_sst_regression_mam = set_varAtts(nao_sst_mam,"sst regression onto NAO principal component timeseries (MAM)","","") + z->nao_sst_regression_jja = set_varAtts(nao_sst_jja,"sst regression onto NAO principal component timeseries (JJA)","","") + z->nao_sst_regression_son = set_varAtts(nao_sst_son,"sst regression onto NAO principal component timeseries (SON)","","") + z->nao_sst_regression_ann = set_varAtts(nao_sst_ann,"sst regression onto NAO principal component timeseries (annual)","","") + + z->nam_sst_regression_djf = set_varAtts(nam_sst_djf,"sst regression onto NAM principal component timeseries (DJF)","","") + z->nam_sst_regression_mam = set_varAtts(nam_sst_mam,"sst regression onto NAM principal component timeseries (MAM)","","") + z->nam_sst_regression_jja = set_varAtts(nam_sst_jja,"sst regression onto NAM principal component timeseries (JJA)","","") + z->nam_sst_regression_son = set_varAtts(nam_sst_son,"sst regression onto NAM principal component timeseries (SON)","","") + z->nam_sst_regression_ann = set_varAtts(nam_sst_ann,"sst regression onto NAM principal component timeseries (annual)","","") + if (COMPUTE_MODES_MON.eq."True") then + z->nao_sst_regression_mon = set_varAtts(nao_sst_mon,"sst regression onto NAO principal component timeseries (monthly)","","") + z->nam_sst_regression_mon = set_varAtts(nam_sst_mon,"sst regression onto NAM principal component timeseries (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + end if + if (tasreg_plot_flag.eq.0) then + modname = str_sub_str(names_tas(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.nam_nao.tas."+syear_tas(ee)+"-"+eyear_tas(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_tas(ee)+" from "+syear_tas(ee)+"-"+eyear_tas(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_tas(ee)+"-"+eyear_tas(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->nao_tas_regression_djf = set_varAtts(nao_tas_djf,"tas regression onto NAO principal component timeseries (DJF)","","") + z->nao_tas_regression_mam = set_varAtts(nao_tas_mam,"tas regression onto NAO principal component timeseries (MAM)","","") + z->nao_tas_regression_jja = set_varAtts(nao_tas_jja,"tas regression onto NAO principal component timeseries (JJA)","","") + z->nao_tas_regression_son = set_varAtts(nao_tas_son,"tas regression onto NAO principal component timeseries (SON)","","") + z->nao_tas_regression_ann = set_varAtts(nao_tas_ann,"tas regression onto NAO principal component timeseries (annual)","","") + + z->nam_tas_regression_djf = set_varAtts(nam_tas_djf,"tas regression onto NAM principal component timeseries (DJF)","","") + z->nam_tas_regression_mam = set_varAtts(nam_tas_mam,"tas regression onto NAM principal component timeseries (MAM)","","") + z->nam_tas_regression_jja = set_varAtts(nam_tas_jja,"tas regression onto NAM principal component timeseries (JJA)","","") + z->nam_tas_regression_son = set_varAtts(nam_tas_son,"tas regression onto NAM principal component timeseries (SON)","","") + z->nam_tas_regression_ann = set_varAtts(nam_tas_ann,"tas regression onto NAM principal component timeseries (annual)","","") + if (COMPUTE_MODES_MON.eq."True") then + z->nao_tas_regression_mon = set_varAtts(nao_tas_mon,"tas regression onto NAO principal component timeseries (monthly)","","") + z->nam_tas_regression_mon = set_varAtts(nam_tas_mon,"tas regression onto NAM principal component timeseries (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + end if + if (prreg_plot_flag.eq.0) then + modname = str_sub_str(names_pr(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.nam_nao.pr."+syear_pr(ee)+"-"+eyear_pr(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_pr(ee)+" from "+syear_pr(ee)+"-"+eyear_pr(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_pr(ee)+"-"+eyear_pr(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->nao_pr_regression_djf = set_varAtts(nao_pr_djf,"pr regression onto NAO principal component timeseries (DJF)","","") + z->nao_pr_regression_mam = set_varAtts(nao_pr_mam,"pr regression onto NAO principal component timeseries (MAM)","","") + z->nao_pr_regression_jja = set_varAtts(nao_pr_jja,"pr regression onto NAO principal component timeseries (JJA)","","") + z->nao_pr_regression_son = set_varAtts(nao_pr_son,"pr regression onto NAO principal component timeseries (SON)","","") + z->nao_pr_regression_ann = set_varAtts(nao_pr_ann,"pr regression onto NAO principal component timeseries (annual)","","") + + z->nam_pr_regression_djf = set_varAtts(nam_pr_djf,"pr regression onto NAM principal component timeseries (DJF)","","") + z->nam_pr_regression_mam = set_varAtts(nam_pr_mam,"pr regression onto NAM principal component timeseries (MAM)","","") + z->nam_pr_regression_jja = set_varAtts(nam_pr_jja,"pr regression onto NAM principal component timeseries (JJA)","","") + z->nam_pr_regression_son = set_varAtts(nam_pr_son,"pr regression onto NAM principal component timeseries (SON)","","") + z->nam_pr_regression_ann = set_varAtts(nam_pr_ann,"pr regression onto NAM principal component timeseries (annual)","","") + if (COMPUTE_MODES_MON.eq."True") then + z->nao_pr_regression_mon = set_varAtts(nao_pr_mon,"pr regression onto NAO principal component timeseries (monthly)","","") + z->nam_pr_regression_mon = set_varAtts(nam_pr_mon,"pr regression onto NAM principal component timeseries (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + end if + end if +;======================================================================== + res = True + res@mpGeophysicalLineColor = "gray42" + res@mpGeophysicalLineThicknessF = 2. + res@mpGridAndLimbOn = False + res@mpFillOn = False + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + res@cnLevelSelectionMode = "ExplicitLevels" + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.03 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.03 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + if (nsim.le.5) then + res@gsnLeftStringFontHeightF = 0.018 + res@gsnCenterStringFontHeightF = 0.022 + res@gsnRightStringFontHeightF = 0.018 + else + res@gsnLeftStringFontHeightF = 0.024 + res@gsnCenterStringFontHeightF = 0.028 + res@gsnRightStringFontHeightF = 0.024 + end if + res@gsnPolar = "NH" + res@mpMinLatF = 20. + res@mpCenterLonF = 0. + res@cnLevels = (/-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7./) + + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnCenterString = names(ee) + + res4 = res ; res4 = pr regression resources + if (COLORMAP.eq.0) then + res4@cnLevels := fspan(-.7,.7,15) + else + res4@cnLevels := fspan(-.5,.5,11) + end if + + res2 = True + res2@gsnDraw = False + res2@gsnFrame = False + res2@cnLevelSelectionMode = "ExplicitLevels" + res2@cnLevels = res@cnLevels + + res2@cnLineLabelsOn = False + res2@cnFillOn = True + res2@cnLinesOn = False + res2@cnFillMode = "AreaFill" + res2@lbLabelBarOn = False + res2@cnInfoLabelOn = False + res2@gsnRightString = "" + res2@gsnLeftString = "" + res2@gsnCenterString = "" + res2@gsnAddCyclic = True + + + if (isfilepresent2("obs_psl").and.ee.eq.0) then ; for pattern correlation table. Save entire lat/lon array + patcor_nam_djf = new((/nsim,dimsizes(nam_djf&lat),dimsizes(nam_djf&lon)/),typeof(nam_djf)) + patcor_nam_djf!1 = "lat" + patcor_nam_djf&lat = nam_djf&lat + patcor_nam_djf!2 = "lon" + patcor_nam_djf&lon = nam_djf&lon + patcor_nam_jja = patcor_nam_djf + patcor_nam_ann = patcor_nam_djf + patcor_nao_djf = patcor_nam_djf + patcor_nao_jja = patcor_nam_djf + patcor_nao_ann = patcor_nam_djf + patcor_nam_djf(ee,:,:) = (/ nam_djf /) + patcor_nam_jja(ee,:,:) = (/ nam_jja /) + patcor_nam_ann(ee,:,:) = (/ nam_ann /) + patcor_nao_djf(ee,:,:) = (/ nao_djf /) + patcor_nao_jja(ee,:,:) = (/ nao_jja /) + patcor_nao_ann(ee,:,:) = (/ nao_ann /) + end if + if (isfilepresent2("obs_psl").and.ee.ge.1.and.isvar("patcor_nam_djf")) then + patcor_nam_djf(ee,:,:) = (/ totype(linint2(nam_djf&lon,nam_djf&lat,nam_djf,True,patcor_nam_djf&lon,patcor_nam_djf&lat,0),typeof(patcor_nam_djf)) /) + patcor_nam_jja(ee,:,:) = (/ totype(linint2(nam_jja&lon,nam_jja&lat,nam_jja,True,patcor_nam_jja&lon,patcor_nam_jja&lat,0),typeof(patcor_nam_jja)) /) + patcor_nam_ann(ee,:,:) = (/ totype(linint2(nam_ann&lon,nam_ann&lat,nam_ann,True,patcor_nam_ann&lon,patcor_nam_ann&lat,0),typeof(patcor_nam_ann)) /) + + patcor_nao_djf(ee,:,:) = (/ totype(linint2(nao_djf&lon,nao_djf&lat,nao_djf,True,patcor_nao_djf&lon,patcor_nao_djf&lat,0),typeof(patcor_nao_djf)) /) + patcor_nao_jja(ee,:,:) = (/ totype(linint2(nao_jja&lon,nao_jja&lat,nao_jja,True,patcor_nao_jja&lon,patcor_nao_jja&lat,0),typeof(patcor_nao_jja)) /) + patcor_nao_ann(ee,:,:) = (/ totype(linint2(nao_ann&lon,nao_ann&lat,nao_ann,True,patcor_nao_ann&lon,patcor_nao_ann&lat,0),typeof(patcor_nao_ann)) /) + end if + + res@gsnRightString = nam_djf@pcvar + map_nam_djf(ee) = gsn_csm_contour_map_polar(wks_nam,nam_djf,res) + res@gsnRightString = nam_mam@pcvar + map_nam_mam(ee) = gsn_csm_contour_map_polar(wks_nam,nam_mam,res) + res@gsnRightString = nam_jja@pcvar + map_nam_jja(ee) = gsn_csm_contour_map_polar(wks_nam,nam_jja,res) + res@gsnRightString = nam_son@pcvar + map_nam_son(ee) = gsn_csm_contour_map_polar(wks_nam,nam_son,res) + res@gsnRightString = nam_ann@pcvar + map_nam_ann(ee) = gsn_csm_contour_map_polar(wks_nam,nam_ann,res) + delete([/nam_djf,nam_mam,nam_jja,nam_son,nam_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + res@gsnRightString = nam_mon@pcvar + map_nam_mon(ee) = gsn_csm_contour_map_polar(wks_nam,nam_mon,res) + delete([/nam_mon/]) + end if + + res@gsnRightString = nao_djf@pcvar + map_nao_djf(ee) = gsn_csm_contour_map_polar(wks_nao,nao_djf,res) + res@gsnRightString = nao_mam@pcvar + map_nao_mam(ee) = gsn_csm_contour_map_polar(wks_nao,nao_mam,res) + res@gsnRightString = nao_jja@pcvar + map_nao_jja(ee) = gsn_csm_contour_map_polar(wks_nao,nao_jja,res) + res@gsnRightString = nao_son@pcvar + map_nao_son(ee) = gsn_csm_contour_map_polar(wks_nao,nao_son,res) + res@gsnRightString = nao_ann@pcvar + map_nao_ann(ee) = gsn_csm_contour_map_polar(wks_nao,nao_ann,res) + delete([/nao_djf,nao_mam,nao_jja,nao_son,nao_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + res@gsnRightString = nao_mon@pcvar + map_nao_mon(ee) = gsn_csm_contour_map_polar(wks_nao,nao_mon,res) + delete([/nao_mon/]) + end if + + if (sstreg_plot_flag.eq.0) then ; SSTs have to be present for regressions. TASs are optional + res@cnLevels := fspan(-.7,.7,15) + if (tasreg_plot_flag.eq.0) then + if (names_ts(ee).eq.names_tas(ee)) then + res@gsnCenterString = names_ts(ee) + else + res@gsnCenterString = names_ts(ee)+" / "+names_tas(ee) + end if + else + res@gsnCenterString = names_ts(ee) + end if + res@gsnRightString = "" + reg_nam_djf(ee) = gsn_csm_contour_map_polar(wks_nam,nam_sst_djf,res) + reg_nam_mam(ee) = gsn_csm_contour_map_polar(wks_nam,nam_sst_mam,res) + reg_nam_jja(ee) = gsn_csm_contour_map_polar(wks_nam,nam_sst_jja,res) + reg_nam_son(ee) = gsn_csm_contour_map_polar(wks_nam,nam_sst_son,res) + reg_nam_ann(ee) = gsn_csm_contour_map_polar(wks_nam,nam_sst_ann,res) + delete([/nam_sst_djf,nam_sst_mam,nam_sst_jja,nam_sst_son,nam_sst_ann/]) + if (tasreg_plot_flag.eq.0) then + o_djf = gsn_csm_contour(wks_nam,nam_tas_djf,res2) + o_mam = gsn_csm_contour(wks_nam,nam_tas_mam,res2) + o_jja = gsn_csm_contour(wks_nam,nam_tas_jja,res2) + o_son = gsn_csm_contour(wks_nam,nam_tas_son,res2) + o_ann = gsn_csm_contour(wks_nam,nam_tas_ann,res2) + delete([/nam_tas_djf,nam_tas_mam,nam_tas_jja,nam_tas_son,nam_tas_ann/]) + overlay(reg_nam_djf(ee),o_djf) + overlay(reg_nam_mam(ee),o_mam) + overlay(reg_nam_jja(ee),o_jja) + overlay(reg_nam_son(ee),o_son) + overlay(reg_nam_ann(ee),o_ann) + delete([/o_djf,o_mam,o_jja,o_son,o_ann/]) + end if + if (COMPUTE_MODES_MON.eq."True") then + reg_nam_mon(ee) = gsn_csm_contour_map_polar(wks_nam,nam_sst_mon,res) + delete([/nam_sst_mon/]) + if (tasreg_plot_flag.eq.0) then + o_mon = gsn_csm_contour(wks_nam,nam_tas_mon,res2) + overlay(reg_nam_mon(ee),o_mon) + delete([/o_mon,nam_tas_mon/]) + end if + end if + + reg_nao_djf(ee) = gsn_csm_contour_map_polar(wks_nao,nao_sst_djf,res) + reg_nao_mam(ee) = gsn_csm_contour_map_polar(wks_nao,nao_sst_mam,res) + reg_nao_jja(ee) = gsn_csm_contour_map_polar(wks_nao,nao_sst_jja,res) + reg_nao_son(ee) = gsn_csm_contour_map_polar(wks_nao,nao_sst_son,res) + reg_nao_ann(ee) = gsn_csm_contour_map_polar(wks_nao,nao_sst_ann,res) + delete([/nao_sst_djf,nao_sst_mam,nao_sst_jja,nao_sst_son,nao_sst_ann/]) + if (tasreg_plot_flag.eq.0) then + o_djf = gsn_csm_contour(wks_nao,nao_tas_djf,res2) + o_mam = gsn_csm_contour(wks_nao,nao_tas_mam,res2) + o_jja = gsn_csm_contour(wks_nao,nao_tas_jja,res2) + o_son = gsn_csm_contour(wks_nao,nao_tas_son,res2) + o_ann = gsn_csm_contour(wks_nao,nao_tas_ann,res2) + delete([/nao_tas_djf,nao_tas_mam,nao_tas_jja,nao_tas_son,nao_tas_ann/]) + overlay(reg_nao_djf(ee),o_djf) + overlay(reg_nao_mam(ee),o_mam) + overlay(reg_nao_jja(ee),o_jja) + overlay(reg_nao_son(ee),o_son) + overlay(reg_nao_ann(ee),o_ann) + delete([/o_djf,o_mam,o_jja,o_son,o_ann/]) + end if + if (COMPUTE_MODES_MON.eq."True") then + reg_nao_mon(ee) = gsn_csm_contour_map_polar(wks_nao,nao_sst_mon,res) + delete([/nao_sst_mon/]) + if (tasreg_plot_flag.eq.0) then + o_mon = gsn_csm_contour(wks_nao,nao_tas_mon,res2) + overlay(reg_nao_mon(ee),o_mon) + delete([/o_mon,nao_tas_mon/]) + end if + end if + end if + + if (prreg_plot_flag.eq.0) then ; PR regressions + res4@gsnRightString = "" + res4@gsnCenterString = names_pr(ee) + reg_nam_pr_djf(ee) = gsn_csm_contour_map_polar(wks_nam_pr,nam_pr_djf,res4) + reg_nam_pr_mam(ee) = gsn_csm_contour_map_polar(wks_nam_pr,nam_pr_mam,res4) + reg_nam_pr_jja(ee) = gsn_csm_contour_map_polar(wks_nam_pr,nam_pr_jja,res4) + reg_nam_pr_son(ee) = gsn_csm_contour_map_polar(wks_nam_pr,nam_pr_son,res4) + reg_nam_pr_ann(ee) = gsn_csm_contour_map_polar(wks_nam_pr,nam_pr_ann,res4) + delete([/nam_pr_djf,nam_pr_mam,nam_pr_jja,nam_pr_son,nam_pr_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + reg_nam_pr_mon(ee) = gsn_csm_contour_map_polar(wks_nam_pr,nam_pr_mon,res4) + delete([/nam_pr_mon/]) + end if + + reg_nao_pr_djf(ee) = gsn_csm_contour_map_polar(wks_nao_pr,nao_pr_djf,res4) + reg_nao_pr_mam(ee) = gsn_csm_contour_map_polar(wks_nao_pr,nao_pr_mam,res4) + reg_nao_pr_jja(ee) = gsn_csm_contour_map_polar(wks_nao_pr,nao_pr_jja,res4) + reg_nao_pr_son(ee) = gsn_csm_contour_map_polar(wks_nao_pr,nao_pr_son,res4) + reg_nao_pr_ann(ee) = gsn_csm_contour_map_polar(wks_nao_pr,nao_pr_ann,res4) + delete([/nao_pr_djf,nao_pr_mam,nao_pr_jja,nao_pr_son,nao_pr_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + reg_nao_pr_mon(ee) = gsn_csm_contour_map_polar(wks_nao_pr,nao_pr_mon,res4) + delete([/nao_pr_mon/]) + end if + end if + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnXYBarChart = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + xyres@gsnAboveYRefLineColor = 185 + xyres@gsnBelowYRefLineColor = 35 + if (wks_type.eq."png") then + xyres@xyLineThicknessF = .5 + else + xyres@xyLineThicknessF = .2 + end if + xyres@xyLineColor = "gray52" + xyres@tiYAxisString = "" + xyres@tiXAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnStringFontHeightF = 0.017 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnStringFontHeightF = 0.024 + end if + xyres@gsnCenterStringOrthogonalPosF = 0.025 + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnLeftString = "" + xyres@gsnRightString = "" + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+1.5 + + xyres@gsnCenterString = names(ee) + + xyresmon = xyres + xyresmon@gsnXYBarChart = False + xyresmon@xyLineThicknessF = .1 + + xy_nam_djf(ee) = gsn_csm_xy(wks_nam_ts,fspan(syear(ee),eyear(ee),dimsizes(nam_pc_djf)),nam_pc_djf,xyres) ; use standardized timeseries + xy_nam_mam(ee) = gsn_csm_xy(wks_nam_ts,fspan(syear(ee),eyear(ee),dimsizes(nam_pc_mam)),nam_pc_mam,xyres) ; use standardized timeseries + xy_nam_jja(ee) = gsn_csm_xy(wks_nam_ts,fspan(syear(ee),eyear(ee),dimsizes(nam_pc_jja)),nam_pc_jja,xyres) ; use standardized timeseries + xy_nam_son(ee) = gsn_csm_xy(wks_nam_ts,fspan(syear(ee),eyear(ee),dimsizes(nam_pc_son)),nam_pc_son,xyres) ; use standardized timeseries + xy_nam_ann(ee) = gsn_csm_xy(wks_nam_ts,fspan(syear(ee),eyear(ee),dimsizes(nam_pc_ann)),nam_pc_ann,xyres) ; use standardized timeseries + delete([/nam_pc_djf,nam_pc_mam,nam_pc_jja,nam_pc_son,nam_pc_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + xy_nam_mon(ee) = gsn_csm_xy(wks_nam_ts,fspan(syear(ee),eyear(ee)+.91667,dimsizes(nam_pc_mon)),nam_pc_mon,xyresmon) ; use standardized timeseries + delete([/nam_pc_mon/]) + end if + + xy_nao_djf(ee) = gsn_csm_xy(wks_nao_ts,fspan(syear(ee),eyear(ee),dimsizes(nao_pc_djf)),nao_pc_djf,xyres) ; use standardized timeseries + xy_nao_mam(ee) = gsn_csm_xy(wks_nao_ts,fspan(syear(ee),eyear(ee),dimsizes(nao_pc_mam)),nao_pc_mam,xyres) ; use standardized timeseries + xy_nao_jja(ee) = gsn_csm_xy(wks_nao_ts,fspan(syear(ee),eyear(ee),dimsizes(nao_pc_jja)),nao_pc_jja,xyres) ; use standardized timeseries + xy_nao_son(ee) = gsn_csm_xy(wks_nao_ts,fspan(syear(ee),eyear(ee),dimsizes(nao_pc_son)),nao_pc_son,xyres) ; use standardized timeseries + xy_nao_ann(ee) = gsn_csm_xy(wks_nao_ts,fspan(syear(ee),eyear(ee),dimsizes(nao_pc_ann)),nao_pc_ann,xyres) ; use standardized timeseries + delete([/nao_pc_djf,nao_pc_mam,nao_pc_jja,nao_pc_son,nao_pc_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + xy_nao_mon(ee) = gsn_csm_xy(wks_nao_ts,fspan(syear(ee),eyear(ee)+.91667,dimsizes(nao_pc_mon)),nao_pc_mon,xyresmon) ; use standardized timeseries + delete([/nao_pc_mon/]) + end if + delete(sstreg_plot_flag) + end do + + if (isvar("clim_syear")) then + delete(clim_syear) + end if + if (isvar("clim_eyear")) then + delete(clim_eyear) + end if + + if (isvar("patcor_nam_djf")) then ; for pattern correlation table + clat = cos(0.01745329*patcor_nam_djf&lat) + clat!0 = "lat" + clat&lat = patcor_nam_djf&lat + line3 = " " ; Must be 18 characters long + line4 = line3 + header = (/"","Pattern Correlations Observations vs. Model(s)",""/) + finpr_nam_djf = "NAM (DJF) " ; Must be 18 characters long + do hh = 1,nsim-1 + dimY = dimsizes(tochar(names(hh))) + nchar = dimY + nchar = where(nchar.le.10,10,nchar) + if (dimY.lt.10) then + ntb = "" + do ii = 0,10-dimY-1 + ntb = ntb+" " + end do + ntb = ntb+names(hh) + else + ntb = names(hh) + end if + + ntc = "" + do ii = 0,nchar-1 + ntc = ntc+"-" + end do + format2 = "%"+(nchar-5+1)+".2f" + format3 = "%4.2f" + line3 = line3+" "+ntb + line4 = line4+" "+ntc + if (all(ismissing(patcor_nam_djf(hh,{20:},:)))) then + finpr_nam_djf = finpr_nam_djf+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr_nam_djf = finpr_nam_djf+sprintf(format2,(pattern_cor(patcor_nam_djf(0,{20:},:),patcor_nam_djf(hh,{20:},:),clat({20:}),0)))+"/"+sprintf(format3,(wgt_arearmse(patcor_nam_djf(0,{20:},:),patcor_nam_djf(hh,{20:},:),clat({20:}),1.0,0))) + end if + end do +; + if (dimsizes(tochar(line4)).ge.8190) then ; system or fortran compiler limit + print("Metrics table warning: Not creating metrics table as size of comparison results in a invalid ascii row size.") + else + write_table(getenv("OUTDIR")+"metrics.psl.nam_nao.txt","w",[/header/],"%s") + write_table(getenv("OUTDIR")+"metrics.psl.nam_nao.txt","a",[/line3/],"%s") + write_table(getenv("OUTDIR")+"metrics.psl.nam_nao.txt","a",[/line4/],"%s") + write_table(getenv("OUTDIR")+"metrics.psl.nam_nao.txt","a",[/finpr_nam_djf/],"%s") + end if + delete([/line3,line4,format2,format3,nchar,ntc,clat,patcor_nam_djf,patcor_nam_jja,patcor_nam_ann/]) + delete([/patcor_nao_djf,patcor_nao_jja,patcor_nao_ann/]) + delete([/dimY,ntb,header/]) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.55 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres@txString = "NAM (DJF)" + gsn_panel2(wks_nam,map_nam_djf,(/nrow,ncol/),panres) + delete(map_nam_djf) + panres@txString = "NAM (MAM)" + gsn_panel2(wks_nam,map_nam_mam,(/nrow,ncol/),panres) + delete(map_nam_mam) + panres@txString = "NAM (JJA)" + gsn_panel2(wks_nam,map_nam_jja,(/nrow,ncol/),panres) + delete(map_nam_jja) + panres@txString = "NAM (SON)" + gsn_panel2(wks_nam,map_nam_son,(/nrow,ncol/),panres) + delete(map_nam_son) + panres@txString = "NAM (Annual)" + gsn_panel2(wks_nam,map_nam_ann,(/nrow,ncol/),panres) + delete(map_nam_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "NAM (Monthly)" + gsn_panel2(wks_nam,map_nam_mon,(/nrow,ncol/),panres) + delete(map_nam_mon) + end if + + if (sstreg_frame.eq.0) then + if (tasreg_frame.eq.0) then + txt0 = "SST/TAS" + else + txt0 = "SST" + end if + panres@txString = "NAM "+txt0+" Regressions (DJF)" + gsn_panel2(wks_nam,reg_nam_djf,(/nrow,ncol/),panres) + delete(reg_nam_djf) + panres@txString = "NAM "+txt0+" Regressions (MAM)" + gsn_panel2(wks_nam,reg_nam_mam,(/nrow,ncol/),panres) + delete(reg_nam_mam) + panres@txString = "NAM "+txt0+" Regressions (JJA)" + gsn_panel2(wks_nam,reg_nam_jja,(/nrow,ncol/),panres) + delete(reg_nam_jja) + panres@txString = "NAM "+txt0+" Regressions (SON)" + gsn_panel2(wks_nam,reg_nam_son,(/nrow,ncol/),panres) + delete(reg_nam_son) + panres@txString = "NAM "+txt0+" Regressions (Annual)" + gsn_panel2(wks_nam,reg_nam_ann,(/nrow,ncol/),panres) + delete(reg_nam_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "NAM "+txt0+" Regressions (Monthly)" + gsn_panel2(wks_nam,reg_nam_mon,(/nrow,ncol/),panres) + delete(reg_nam_mon) + end if + delete(wks_nam) + end if + if (prreg_frame.eq.0) then + panres@txString = "NAM PR Regressions (DJF)" + gsn_panel2(wks_nam_pr,reg_nam_pr_djf,(/nrow,ncol/),panres) + delete(reg_nam_pr_djf) + panres@txString = "NAM PR Regressions (MAM)" + gsn_panel2(wks_nam_pr,reg_nam_pr_mam,(/nrow,ncol/),panres) + delete(reg_nam_pr_mam) + panres@txString = "NAM PR Regressions (JJA)" + gsn_panel2(wks_nam_pr,reg_nam_pr_jja,(/nrow,ncol/),panres) + delete(reg_nam_pr_jja) + panres@txString = "NAM PR Regressions (SON)" + gsn_panel2(wks_nam_pr,reg_nam_pr_son,(/nrow,ncol/),panres) + delete(reg_nam_pr_son) + panres@txString = "NAM PR Regressions (Annual)" + gsn_panel2(wks_nam_pr,reg_nam_pr_ann,(/nrow,ncol/),panres) + delete(reg_nam_pr_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "NAM PR Regressions (Monthly)" + gsn_panel2(wks_nam_pr,reg_nam_pr_mon,(/nrow,ncol/),panres) + delete(reg_nam_pr_mon) + end if + delete(wks_nam_pr) + end if + + panres@txString = "NAO (DJF)" + gsn_panel2(wks_nao,map_nao_djf,(/nrow,ncol/),panres) + delete(map_nao_djf) + panres@txString = "NAO (MAM)" + gsn_panel2(wks_nao,map_nao_mam,(/nrow,ncol/),panres) + delete(map_nao_mam) + panres@txString = "NAO (JJA)" + gsn_panel2(wks_nao,map_nao_jja,(/nrow,ncol/),panres) + delete(map_nao_jja) + panres@txString = "NAO (SON)" + gsn_panel2(wks_nao,map_nao_son,(/nrow,ncol/),panres) + delete(map_nao_son) + panres@txString = "NAO (Annual)" + gsn_panel2(wks_nao,map_nao_ann,(/nrow,ncol/),panres) + delete(map_nao_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "NAO (Monthly)" + gsn_panel2(wks_nao,map_nao_mon,(/nrow,ncol/),panres) + delete(map_nao_mon) + end if + + if (sstreg_frame.eq.0) then + if (tasreg_frame.eq.0) then + txt0 = "SST/TAS" + else + txt0 = "SST" + end if + panres@txString = "NAO "+txt0+" Regressions (DJF)" + gsn_panel2(wks_nao,reg_nao_djf,(/nrow,ncol/),panres) + delete(reg_nao_djf) + panres@txString = "NAO "+txt0+" Regressions (MAM)" + gsn_panel2(wks_nao,reg_nao_mam,(/nrow,ncol/),panres) + delete(reg_nao_mam) + panres@txString = "NAO "+txt0+" Regressions (JJA)" + gsn_panel2(wks_nao,reg_nao_jja,(/nrow,ncol/),panres) + delete(reg_nao_jja) + panres@txString = "NAO "+txt0+" Regressions (SON)" + gsn_panel2(wks_nao,reg_nao_son,(/nrow,ncol/),panres) + delete(reg_nao_son) + panres@txString = "NAO "+txt0+" Regressions (Annual)" + gsn_panel2(wks_nao,reg_nao_ann,(/nrow,ncol/),panres) + delete(reg_nao_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "NAO "+txt0+" Regressions (Monthly)" + gsn_panel2(wks_nao,reg_nao_mon,(/nrow,ncol/),panres) + delete(reg_nao_mon) + end if + delete(wks_nao) + end if + if (prreg_frame.eq.0) then + panres@txString = "NAO PR Regressions (DJF)" + gsn_panel2(wks_nao_pr,reg_nao_pr_djf,(/nrow,ncol/),panres) + delete(reg_nao_pr_djf) + panres@txString = "NAO PR Regressions (MAM)" + gsn_panel2(wks_nao_pr,reg_nao_pr_mam,(/nrow,ncol/),panres) + delete(reg_nao_pr_mam) + panres@txString = "NAO PR Regressions (JJA)" + gsn_panel2(wks_nao_pr,reg_nao_pr_jja,(/nrow,ncol/),panres) + delete(reg_nao_pr_jja) + panres@txString = "NAO PR Regressions (SON)" + gsn_panel2(wks_nao_pr,reg_nao_pr_son,(/nrow,ncol/),panres) + delete(reg_nao_pr_son) + panres@txString = "NAO PR Regressions (Annual)" + gsn_panel2(wks_nao_pr,reg_nao_pr_ann,(/nrow,ncol/),panres) + delete(reg_nao_pr_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "NAO PR Regressions (Monthly)" + gsn_panel2(wks_nao_pr,reg_nao_pr_mon,(/nrow,ncol/),panres) + delete(reg_nao_pr_mon) + end if + delete(wks_nao_pr) + end if + + panres2 = True + if (nsim.le.5) then + panres2@txFontHeightF = 0.024 + else + panres2@txFontHeightF = 0.016 + end if + panres2@gsnMaximize = True + panres2@gsnPaperOrientation = "portrait" + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres2@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) + end if + + panres2@txString = "NAM (DJF)" + gsn_panel2(wks_nam_ts,xy_nam_djf,lp,panres2) + delete(xy_nam_djf) + panres2@txString = "NAM (MAM)" + gsn_panel2(wks_nam_ts,xy_nam_mam,lp,panres2) + delete(xy_nam_mam) + panres2@txString = "NAM (JJA)" + gsn_panel2(wks_nam_ts,xy_nam_jja,lp,panres2) + delete(xy_nam_jja) + panres2@txString = "NAM (SON)" + gsn_panel2(wks_nam_ts,xy_nam_son,lp,panres2) + delete(xy_nam_son) + panres2@txString = "NAM (Annual)" + gsn_panel2(wks_nam_ts,xy_nam_ann,lp,panres2) + delete(xy_nam_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres2@txString = "NAM (Monthly)" + gsn_panel2(wks_nam_ts,xy_nam_mon,lp,panres2) + delete(xy_nam_mon) + end if + delete(wks_nam_ts) + + panres2@txString = "NAO (DJF)" + gsn_panel2(wks_nao_ts,xy_nao_djf,lp,panres2) + delete(xy_nao_djf) + panres2@txString = "NAO (MAM)" + gsn_panel2(wks_nao_ts,xy_nao_mam,lp,panres2) + delete(xy_nao_mam) + panres2@txString = "NAO (JJA)" + gsn_panel2(wks_nao_ts,xy_nao_jja,lp,panres2) + delete(xy_nao_jja) + panres2@txString = "NAO (SON)" + gsn_panel2(wks_nao_ts,xy_nao_son,lp,panres2) + delete(xy_nao_son) + panres2@txString = "NAO (Annual)" + gsn_panel2(wks_nao_ts,xy_nao_ann,lp,panres2) + delete(xy_nao_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres2@txString = "NAO (Monthly)" + gsn_panel2(wks_nao_ts,xy_nao_mon,lp,panres2) + delete(xy_nao_mon) + end if + delete(wks_nao_ts) +;-------------------------------------------------------------------------------------------------- + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + system("mv "+OUTDIR+"nam.000001.png "+OUTDIR+"nam.djf.png") + system("mv "+OUTDIR+"nam.000002.png "+OUTDIR+"nam.mam.png") + system("mv "+OUTDIR+"nam.000003.png "+OUTDIR+"nam.jja.png") + system("mv "+OUTDIR+"nam.000004.png "+OUTDIR+"nam.son.png") + system("mv "+OUTDIR+"nam.000005.png "+OUTDIR+"nam.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"nam.000006.png "+OUTDIR+"nam.mon.png") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"nam.000007.png "+OUTDIR+"nam.tempreg.djf.png") + system("mv "+OUTDIR+"nam.000008.png "+OUTDIR+"nam.tempreg.mam.png") + system("mv "+OUTDIR+"nam.000009.png "+OUTDIR+"nam.tempreg.jja.png") + system("mv "+OUTDIR+"nam.000010.png "+OUTDIR+"nam.tempreg.son.png") + system("mv "+OUTDIR+"nam.000011.png "+OUTDIR+"nam.tempreg.ann.png") + system("mv "+OUTDIR+"nam.000012.png "+OUTDIR+"nam.tempreg.mon.png") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"nam.000006.png "+OUTDIR+"nam.tempreg.djf.png") + system("mv "+OUTDIR+"nam.000007.png "+OUTDIR+"nam.tempreg.mam.png") + system("mv "+OUTDIR+"nam.000008.png "+OUTDIR+"nam.tempreg.jja.png") + system("mv "+OUTDIR+"nam.000009.png "+OUTDIR+"nam.tempreg.son.png") + system("mv "+OUTDIR+"nam.000010.png "+OUTDIR+"nam.tempreg.ann.png") + end if + end if + + if (prreg_frame.eq.0) then + system("mv "+OUTDIR+"nam.prreg.000001.png "+OUTDIR+"nam.prreg.djf.png") + system("mv "+OUTDIR+"nam.prreg.000002.png "+OUTDIR+"nam.prreg.mam.png") + system("mv "+OUTDIR+"nam.prreg.000003.png "+OUTDIR+"nam.prreg.jja.png") + system("mv "+OUTDIR+"nam.prreg.000004.png "+OUTDIR+"nam.prreg.son.png") + system("mv "+OUTDIR+"nam.prreg.000005.png "+OUTDIR+"nam.prreg.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"nam.prreg.000006.png "+OUTDIR+"nam.prreg.mon.png") + end if + end if + + system("mv "+OUTDIR+"nao.000001.png "+OUTDIR+"nao.djf.png") + system("mv "+OUTDIR+"nao.000002.png "+OUTDIR+"nao.mam.png") + system("mv "+OUTDIR+"nao.000003.png "+OUTDIR+"nao.jja.png") + system("mv "+OUTDIR+"nao.000004.png "+OUTDIR+"nao.son.png") + system("mv "+OUTDIR+"nao.000005.png "+OUTDIR+"nao.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"nao.000006.png "+OUTDIR+"nao.mon.png") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"nao.000007.png "+OUTDIR+"nao.tempreg.djf.png") + system("mv "+OUTDIR+"nao.000008.png "+OUTDIR+"nao.tempreg.mam.png") + system("mv "+OUTDIR+"nao.000009.png "+OUTDIR+"nao.tempreg.jja.png") + system("mv "+OUTDIR+"nao.000010.png "+OUTDIR+"nao.tempreg.son.png") + system("mv "+OUTDIR+"nao.000011.png "+OUTDIR+"nao.tempreg.ann.png") + system("mv "+OUTDIR+"nao.000012.png "+OUTDIR+"nao.tempreg.mon.png") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"nao.000006.png "+OUTDIR+"nao.tempreg.djf.png") + system("mv "+OUTDIR+"nao.000007.png "+OUTDIR+"nao.tempreg.mam.png") + system("mv "+OUTDIR+"nao.000008.png "+OUTDIR+"nao.tempreg.jja.png") + system("mv "+OUTDIR+"nao.000009.png "+OUTDIR+"nao.tempreg.son.png") + system("mv "+OUTDIR+"nao.000010.png "+OUTDIR+"nao.tempreg.ann.png") + end if + end if + + if (prreg_frame.eq.0) then + system("mv "+OUTDIR+"nao.prreg.000001.png "+OUTDIR+"nao.prreg.djf.png") + system("mv "+OUTDIR+"nao.prreg.000002.png "+OUTDIR+"nao.prreg.mam.png") + system("mv "+OUTDIR+"nao.prreg.000003.png "+OUTDIR+"nao.prreg.jja.png") + system("mv "+OUTDIR+"nao.prreg.000004.png "+OUTDIR+"nao.prreg.son.png") + system("mv "+OUTDIR+"nao.prreg.000005.png "+OUTDIR+"nao.prreg.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"nao.prreg.000006.png "+OUTDIR+"nao.prreg.mon.png") + end if + end if + + system("mv "+OUTDIR+"nam.timeseries.000001.png "+OUTDIR+"nam.timeseries.djf.png") + system("mv "+OUTDIR+"nam.timeseries.000002.png "+OUTDIR+"nam.timeseries.mam.png") + system("mv "+OUTDIR+"nam.timeseries.000003.png "+OUTDIR+"nam.timeseries.jja.png") + system("mv "+OUTDIR+"nam.timeseries.000004.png "+OUTDIR+"nam.timeseries.son.png") + system("mv "+OUTDIR+"nam.timeseries.000005.png "+OUTDIR+"nam.timeseries.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"nam.timeseries.000006.png "+OUTDIR+"nam.timeseries.mon.png") + end if + + system("mv "+OUTDIR+"nao.timeseries.000001.png "+OUTDIR+"nao.timeseries.djf.png") + system("mv "+OUTDIR+"nao.timeseries.000002.png "+OUTDIR+"nao.timeseries.mam.png") + system("mv "+OUTDIR+"nao.timeseries.000003.png "+OUTDIR+"nao.timeseries.jja.png") + system("mv "+OUTDIR+"nao.timeseries.000004.png "+OUTDIR+"nao.timeseries.son.png") + system("mv "+OUTDIR+"nao.timeseries.000005.png "+OUTDIR+"nao.timeseries.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"nao.timeseries.000006.png "+OUTDIR+"nao.timeseries.mon.png") + end if + + + else + system("psplit "+OUTDIR+"nam.ps "+OUTDIR+"psl_nn") + system("mv "+OUTDIR+"psl_nn0001.ps "+OUTDIR+"nam.djf.ps") + system("mv "+OUTDIR+"psl_nn0002.ps "+OUTDIR+"nam.mam.ps") + system("mv "+OUTDIR+"psl_nn0003.ps "+OUTDIR+"nam.jja.ps") + system("mv "+OUTDIR+"psl_nn0004.ps "+OUTDIR+"nam.son.ps") + system("mv "+OUTDIR+"psl_nn0005.ps "+OUTDIR+"nam.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_nn0006.ps "+OUTDIR+"nam.mon.ps") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_nn0007.ps "+OUTDIR+"nam.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_nn0008.ps "+OUTDIR+"nam.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_nn0009.ps "+OUTDIR+"nam.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_nn0010.ps "+OUTDIR+"nam.tempreg.son.ps") + system("mv "+OUTDIR+"psl_nn0011.ps "+OUTDIR+"nam.tempreg.ann.ps") + system("mv "+OUTDIR+"psl_nn0012.ps "+OUTDIR+"nam.tempreg.mon.ps") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_nn0006.ps "+OUTDIR+"nam.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_nn0007.ps "+OUTDIR+"nam.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_nn0008.ps "+OUTDIR+"nam.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_nn0009.ps "+OUTDIR+"nam.tempreg.son.ps") + system("mv "+OUTDIR+"psl_nn0010.ps "+OUTDIR+"nam.tempreg.ann.ps") + end if + end if + + if (prreg_frame.eq.0) then + system("psplit "+OUTDIR+"nam.prreg.ps "+OUTDIR+"pr_nn") + system("mv "+OUTDIR+"pr_nn0001.ps "+OUTDIR+"nam.prreg.djf.ps") + system("mv "+OUTDIR+"pr_nn0002.ps "+OUTDIR+"nam.prreg.mam.ps") + system("mv "+OUTDIR+"pr_nn0003.ps "+OUTDIR+"nam.prreg.jja.ps") + system("mv "+OUTDIR+"pr_nn0004.ps "+OUTDIR+"nam.prreg.son.ps") + system("mv "+OUTDIR+"pr_nn0005.ps "+OUTDIR+"nam.prreg.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pr_nn0006.ps "+OUTDIR+"nam.prreg.mon.ps") + end if + end if + + system("psplit "+OUTDIR+"nao.ps "+OUTDIR+"psl_nn") + system("mv "+OUTDIR+"psl_nn0001.ps "+OUTDIR+"nao.djf.ps") + system("mv "+OUTDIR+"psl_nn0002.ps "+OUTDIR+"nao.mam.ps") + system("mv "+OUTDIR+"psl_nn0003.ps "+OUTDIR+"nao.jja.ps") + system("mv "+OUTDIR+"psl_nn0004.ps "+OUTDIR+"nao.son.ps") + system("mv "+OUTDIR+"psl_nn0005.ps "+OUTDIR+"nao.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_nn0006.ps "+OUTDIR+"nao.mon.ps") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_nn0007.ps "+OUTDIR+"nao.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_nn0008.ps "+OUTDIR+"nao.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_nn0009.ps "+OUTDIR+"nao.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_nn0010.ps "+OUTDIR+"nao.tempreg.son.ps") + system("mv "+OUTDIR+"psl_nn0011.ps "+OUTDIR+"nao.tempreg.ann.ps") + system("mv "+OUTDIR+"psl_nn0012.ps "+OUTDIR+"nao.tempreg.mon.ps") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_nn0006.ps "+OUTDIR+"nao.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_nn0007.ps "+OUTDIR+"nao.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_nn0008.ps "+OUTDIR+"nao.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_nn0009.ps "+OUTDIR+"nao.tempreg.son.ps") + system("mv "+OUTDIR+"psl_nn0010.ps "+OUTDIR+"nao.tempreg.ann.ps") + end if + end if + + if (prreg_frame.eq.0) then + system("psplit "+OUTDIR+"nao.prreg.ps "+OUTDIR+"pr_nn") + system("mv "+OUTDIR+"pr_nn0001.ps "+OUTDIR+"nao.prreg.djf.ps") + system("mv "+OUTDIR+"pr_nn0002.ps "+OUTDIR+"nao.prreg.mam.ps") + system("mv "+OUTDIR+"pr_nn0003.ps "+OUTDIR+"nao.prreg.jja.ps") + system("mv "+OUTDIR+"pr_nn0004.ps "+OUTDIR+"nao.prreg.son.ps") + system("mv "+OUTDIR+"pr_nn0005.ps "+OUTDIR+"nao.prreg.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pr_nn0006.ps "+OUTDIR+"nao.prreg.mon.ps") + end if + system("rm "+OUTDIR+"nam.prreg.ps "+OUTDIR+"nao.prreg.ps") + end if + + system("psplit "+OUTDIR+"nam.timeseries.ps "+OUTDIR+"psl_nn") + system("mv "+OUTDIR+"psl_nn0001.ps "+OUTDIR+"nam.timeseries.djf.ps") + system("mv "+OUTDIR+"psl_nn0002.ps "+OUTDIR+"nam.timeseries.mam.ps") + system("mv "+OUTDIR+"psl_nn0003.ps "+OUTDIR+"nam.timeseries.jja.ps") + system("mv "+OUTDIR+"psl_nn0004.ps "+OUTDIR+"nam.timeseries.son.ps") + system("mv "+OUTDIR+"psl_nn0005.ps "+OUTDIR+"nam.timeseries.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_nn0006.ps "+OUTDIR+"nam.timeseries.mon.ps") + end if + + system("psplit "+OUTDIR+"nao.timeseries.ps "+OUTDIR+"psl_nn") + system("mv "+OUTDIR+"psl_nn0001.ps "+OUTDIR+"nao.timeseries.djf.ps") + system("mv "+OUTDIR+"psl_nn0002.ps "+OUTDIR+"nao.timeseries.mam.ps") + system("mv "+OUTDIR+"psl_nn0003.ps "+OUTDIR+"nao.timeseries.jja.ps") + system("mv "+OUTDIR+"psl_nn0004.ps "+OUTDIR+"nao.timeseries.son.ps") + system("mv "+OUTDIR+"psl_nn0005.ps "+OUTDIR+"nao.timeseries.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_nn0006.ps "+OUTDIR+"nao.timeseries.mon.ps") + end if + system("rm "+OUTDIR+"nao.timeseries.ps "+OUTDIR+"nam.timeseries.ps "+OUTDIR+"nao.ps "+OUTDIR+"nam.ps") + end if + print("Finished: psl.nam_nao.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/psl.pna_npo.ncl b/lib/externals/CVDP/ncl_scripts/psl.pna_npo.ncl new file mode 100644 index 000000000..c945ef6d6 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/psl.pna_npo.ncl @@ -0,0 +1,1812 @@ +; Calculates PNA and NPO (patterns and PC timeseries), as well as regressions +; of those PC timeseries onto ts, tas, and pr. Also calculates the NPI. +; +; Variables used: psl, ts, tas, and pr +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: psl.pna_npo.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COMPUTE_MODES_MON = getenv("COMPUTE_MODES_MON") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_psl") + na = asciiread("namelist_byvar/namelist_psl",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) + +;---------SST Regressions coding------------------------------------------------- + nsim_ts = numAsciiRow("namelist_byvar/namelist_ts") + na_ts = asciiread("namelist_byvar/namelist_ts",(/nsim_ts/),"string") + names_ts = new(nsim_ts,"string") + paths_ts = new(nsim_ts,"string") + syear_ts = new(nsim_ts,"integer",-999) + eyear_ts = new(nsim_ts,"integer",-999) + + do gg = 0,nsim_ts-1 + names_ts(gg) = str_strip(str_get_field(na_ts(gg),1,delim)) + paths_ts(gg) = str_strip(str_get_field(na_ts(gg),2,delim)) + syear_ts(gg) = stringtointeger(str_strip(str_get_field(na_ts(gg),3,delim))) + eyear_ts(gg) = stringtointeger(str_strip(str_get_field(na_ts(gg),4,delim))) + end do + delete(na_ts) + nyr_ts = eyear_ts-syear_ts+1 +;---------TAS Regressions coding------------------------------------------------- + nsim_tas = numAsciiRow("namelist_byvar/namelist_trefht") + na_tas = asciiread("namelist_byvar/namelist_trefht",(/nsim_tas/),"string") + names_tas = new(nsim_tas,"string") + paths_tas = new(nsim_tas,"string") + syear_tas = new(nsim_tas,"integer",-999) + eyear_tas = new(nsim_tas,"integer",-999) + + do gg = 0,nsim_tas-1 + names_tas(gg) = str_strip(str_get_field(na_tas(gg),1,delim)) + paths_tas(gg) = str_strip(str_get_field(na_tas(gg),2,delim)) + syear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),3,delim))) + eyear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),4,delim))) + end do + delete(na_tas) + nyr_tas = eyear_tas-syear_tas+1 +;---------PR Regressions coding------------------------------------------------- + nsim_pr = numAsciiRow("namelist_byvar/namelist_prect") + na_pr = asciiread("namelist_byvar/namelist_prect",(/nsim_pr/),"string") + names_pr = new(nsim_pr,"string") + paths_pr = new(nsim_pr,"string") + syear_pr = new(nsim_pr,"integer",-999) + eyear_pr = new(nsim_pr,"integer",-999) + + do gg = 0,nsim_pr-1 + names_pr(gg) = str_strip(str_get_field(na_pr(gg),1,delim)) + paths_pr(gg) = str_strip(str_get_field(na_pr(gg),2,delim)) + syear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),3,delim))) + eyear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),4,delim))) + end do + delete(na_pr) + nyr_pr = eyear_pr-syear_pr+1 +;------------------------------------------------------------------------------------------------- + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + + wks_pna = gsn_open_wks(wks_type,getenv("OUTDIR")+"pna") + wks_pna_pr = gsn_open_wks(wks_type,getenv("OUTDIR")+"pna.prreg") + wks_pna_ts = gsn_open_wks(wks_type,getenv("OUTDIR")+"pna.timeseries") + + wks_npo = gsn_open_wks(wks_type,getenv("OUTDIR")+"npo") + wks_npo_pr = gsn_open_wks(wks_type,getenv("OUTDIR")+"npo.prreg") + wks_npo_ts = gsn_open_wks(wks_type,getenv("OUTDIR")+"npo.timeseries") + + wks_npi_ts = gsn_open_wks(wks_type,getenv("OUTDIR")+"npi.timeseries.ndjfm") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_pna,"ncl_default") + gsn_define_colormap(wks_pna_ts,"ncl_default") + gsn_define_colormap(wks_npo,"ncl_default") + gsn_define_colormap(wks_npo_ts,"ncl_default") + gsn_define_colormap(wks_npi_ts,"ncl_default") + gsn_define_colormap(wks_pna_pr,"MPL_BrBG") + gsn_define_colormap(wks_npo_pr,"MPL_BrBG") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_pna,"BlueDarkRed18") + gsn_define_colormap(wks_pna_ts,"ncl_default") + gsn_define_colormap(wks_npo,"BlueDarkRed18") + gsn_define_colormap(wks_npo_ts,"ncl_default") + gsn_define_colormap(wks_npi_ts,"ncl_default") + gsn_define_colormap(wks_pna_pr,"MPL_BrBG") + gsn_define_colormap(wks_npo_pr,"MPL_BrBG") + end if + + map_pna_djf = new(nsim,"graphic") + map_pna_mam = new(nsim,"graphic") + map_pna_jja = new(nsim,"graphic") + map_pna_son = new(nsim,"graphic") + map_pna_ann = new(nsim,"graphic") + map_pna_mon = new(nsim,"graphic") + xy_pna_djf = new(nsim,"graphic") + xy_pna_mam = new(nsim,"graphic") + xy_pna_jja = new(nsim,"graphic") + xy_pna_son = new(nsim,"graphic") + xy_pna_ann = new(nsim,"graphic") + xy_pna_mon = new(nsim,"graphic") + reg_pna_djf = new(nsim,"graphic") + reg_pna_mam = new(nsim,"graphic") + reg_pna_jja = new(nsim,"graphic") + reg_pna_son = new(nsim,"graphic") + reg_pna_ann = new(nsim,"graphic") + reg_pna_mon = new(nsim,"graphic") + reg_pna_pr_djf = new(nsim,"graphic") + reg_pna_pr_mam = new(nsim,"graphic") + reg_pna_pr_jja = new(nsim,"graphic") + reg_pna_pr_son = new(nsim,"graphic") + reg_pna_pr_ann = new(nsim,"graphic") + reg_pna_pr_mon = new(nsim,"graphic") + + map_npo_djf = new(nsim,"graphic") + map_npo_mam = new(nsim,"graphic") + map_npo_jja = new(nsim,"graphic") + map_npo_son = new(nsim,"graphic") + map_npo_ann = new(nsim,"graphic") + map_npo_mon = new(nsim,"graphic") + xy_npo_djf = new(nsim,"graphic") + xy_npo_mam = new(nsim,"graphic") + xy_npo_jja = new(nsim,"graphic") + xy_npo_son = new(nsim,"graphic") + xy_npo_ann = new(nsim,"graphic") + xy_npo_mon = new(nsim,"graphic") + reg_npo_djf = new(nsim,"graphic") + reg_npo_mam = new(nsim,"graphic") + reg_npo_jja = new(nsim,"graphic") + reg_npo_son = new(nsim,"graphic") + reg_npo_ann = new(nsim,"graphic") + reg_npo_mon = new(nsim,"graphic") + reg_npo_pr_djf = new(nsim,"graphic") + reg_npo_pr_mam = new(nsim,"graphic") + reg_npo_pr_jja = new(nsim,"graphic") + reg_npo_pr_son = new(nsim,"graphic") + reg_npo_pr_ann = new(nsim,"graphic") + reg_npo_pr_mon = new(nsim,"graphic") + + xy_npi = new(nsim,"graphic") + + sstreg_frame = 1 ; sstreg_frame = flag to create regressions .ps/.png files. Created/used instead of sstreg_plot_flag + ; so that if sst regressions are not created for the last simulation listed that .ps/png files are created + tasreg_frame = 1 + prreg_frame = 1 + + do ee = 0,nsim-1 +; print(paths(ee)+" "+syear(ee)+" "+eyear(ee)) + arr = data_read_in(paths(ee),"PSL",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(arr,"is_all_missing")) then + delete(arr) + continue + end if + + if (OPT_CLIMO.eq."Full") then + arr = rmMonAnnCycTLL(arr) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = arr + delete(temp_arr&time) + temp_arr&time = cd_calendar(arr&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + arr = calcMonAnomTLL(arr,climo) + delete(climo) + end if + + arrT = runave_n_Wrap(arr,3,0,0) ; form DJF averages + arrT(0,:,:) = (/ dim_avg_n(arr(:1,:,:),0) /) + arr_djf = arrT(0::12,:,:) + arr_mam = arrT(3::12,:,:) + arr_jja = arrT(6::12,:,:) ; form JJA averages + arr_son = arrT(9::12,:,:) + delete(arrT) + + arrU = runave_n_Wrap(arr,5,0,0) + arrU(0,:,:) = (/ dim_avg_n(arr(:2,:,:),0) /) + arr_ndjfm = arrU(0::12,:,:) + delete(arrU) + + arrV = runave_n_Wrap(arr,12,0,0) + arr_ann = arrV(5::12,:,:) + delete(arrV) +; +; arr_djf = (/ dtrend_msg_n(ispan(0,dimsizes(arr_djf&time)-1,1),arr_djf,True,False,0) /) +; arr_mam = (/ dtrend_msg_n(ispan(0,dimsizes(arr_mam&time)-1,1),arr_mam,True,False,0) /) +; arr_jja = (/ dtrend_msg_n(ispan(0,dimsizes(arr_jja&time)-1,1),arr_jja,True,False,0) /) +; arr_son = (/ dtrend_msg_n(ispan(0,dimsizes(arr_son&time)-1,1),arr_son,True,False,0) /) +; +; arr_ann = (/ dtrend_msg_n(ispan(0,dimsizes(arr_ann&time)-1,1),arr_ann,True,False,0) /) +; +; arr_ndjfm = (/ dtrend_msg_n(ispan(0,dimsizes(arr_ndjfm&time)-1,1),arr_ndjfm,True,False,0) /) +; +; arr = (/ dtrend_msg_n(ispan(0,dimsizes(arr&time)-1,1),arr,True,False,0) /) +;---------SST Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_ts(ee),eyear(ee),eyear_ts(ee)/)))) then + sstreg_plot_flag = 1 + else + if (syear(ee).eq.syear_ts(ee)) then ; check that the start and end years match for ts, trefht, and psl + if (eyear(ee).eq.eyear_ts(ee)) then + sstreg_plot_flag = 0 + else + sstreg_plot_flag = 1 + end if + else + sstreg_plot_flag = 1 + end if + end if + + if (sstreg_plot_flag.eq.0) then + ; print("Data to be read in: "+paths_ts(ee)+" from "+syear_ts(ee)+":"+eyear_ts(ee)) + sst = data_read_in(paths_ts(ee),"TS",syear_ts(ee),eyear_ts(ee)) + if (isatt(sst,"is_all_missing")) then + sstreg_plot_flag = 1 + delete(sst) + end if + + if (sstreg_plot_flag.eq.0) then ; only continue if both PSL/TS fields are present + sst = where(sst.le.-1.8,-1.8,sst) + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,sst&lat,sst&lon) + sst = mask(sst,conform(sst,lsm,(/1,2/)).ge.1,False) + delete(lsm) + + if (OPT_CLIMO.eq."Full") then + sst = rmMonAnnCycTLL(sst) + else + check_custom_climo(names_ts(ee),syear_ts(ee),eyear_ts(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sst + delete(temp_arr&time) + temp_arr&time = cd_calendar(sst&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sst = calcMonAnomTLL(sst,climo) + delete(climo) + end if +; sst = (/ dtrend_msg_n(ispan(0,dimsizes(sst&time)-1,1),sst,False,False,0) /) + + sstT = runave_n_Wrap(sst,3,0,0) ; form DJF averages + sstT(0,:,:) = (/ dim_avg_n(sst(:1,:,:),0) /) + sst_djf = sstT(0::12,:,:) + sst_mam = sstT(3::12,:,:) + sst_jja = sstT(6::12,:,:) ; form JJA averages + sst_son = sstT(9::12,:,:) + delete(sstT) + + sstV = runave_n_Wrap(sst,12,0,0) + sst_ann = sstV(5::12,:,:) + delete(sstV) + end if + end if +;---------TAS Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_tas(ee),eyear(ee),eyear_tas(ee)/)))) then + tasreg_plot_flag = 1 + else + if (syear(ee).eq.syear_tas(ee)) then ; check that the start and end years match for ts, tas, and psl + if (eyear(ee).eq.eyear_tas(ee)) then + tasreg_plot_flag = 0 + else + tasreg_plot_flag = 1 + end if + else + tasreg_plot_flag = 1 + end if + if (sstreg_plot_flag.eq.1) then ; if the ts dataset is missing but the tas is not, do not + tasreg_plot_flag = 1 ; run through the tas calculations as both currently required + end if + end if + + if (tasreg_plot_flag.eq.0) then + tas = data_read_in(paths_tas(ee),"TREFHT",syear_tas(ee),eyear_tas(ee)) + if (isatt(tas,"is_all_missing")) then + tasreg_plot_flag = 1 + delete(tas) + end if + + if (tasreg_plot_flag.eq.0) then ; only continue if both PSL/TS fields are present + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,tas&lat,tas&lon) + tas = mask(tas,conform(tas,lsm,(/1,2/)).eq.0,False) + delete(lsm) + + if (OPT_CLIMO.eq."Full") then + tas = rmMonAnnCycTLL(tas) + else + check_custom_climo(names_tas(ee),syear_tas(ee),eyear_tas(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = tas + delete(temp_arr&time) + temp_arr&time = cd_calendar(tas&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + tas = calcMonAnomTLL(tas,climo) + delete(climo) + end if +; tas = (/ dtrend_msg_n(ispan(0,dimsizes(tas&time)-1,1),tas,False,False,0) /) + + tasT = runave_n_Wrap(tas,3,0,0) ; form DJF averages + tasT(0,:,:) = (/ dim_avg_n(tas(:1,:,:),0) /) + tas_djf = tasT(0::12,:,:) + tas_mam = tasT(3::12,:,:) + tas_jja = tasT(6::12,:,:) ; form JJA averages + tas_son = tasT(9::12,:,:) + delete(tasT) + + tasV = runave_n_Wrap(tas,12,0,0) + tas_ann = tasV(5::12,:,:) + delete([/tasV/]) + end if + end if +;---------PR Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_pr(ee),eyear(ee),eyear_pr(ee)/)))) then + prreg_plot_flag = 1 + else + if (syear(ee).eq.syear_pr(ee)) then ; check that the start and end years match for ts, tas, and psl + if (eyear(ee).eq.eyear_pr(ee)) then + prreg_plot_flag = 0 + else + prreg_plot_flag = 1 + end if + else + prreg_plot_flag = 1 + end if + end if + + if (prreg_plot_flag.eq.0) then + pr = data_read_in(paths_pr(ee),"PRECT",syear_pr(ee),eyear_pr(ee)) + if (isatt(pr,"is_all_missing")) then + prreg_plot_flag = 1 + delete(pr) + end if + + if (prreg_plot_flag.eq.0) then ; only continue if both PSL/TS fields are present + if (OPT_CLIMO.eq."Full") then + pr = rmMonAnnCycTLL(pr) + else + check_custom_climo(names_pr(ee),syear_pr(ee),eyear_pr(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = pr + delete(temp_arr&time) + temp_arr&time = cd_calendar(pr&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + pr = calcMonAnomTLL(pr,climo) + delete(climo) + end if +; pr = (/ dtrend_msg_n(ispan(0,dimsizes(pr&time)-1,1),pr,False,False,0) /) + + prT = runave_n_Wrap(pr,3,0,0) ; form DJF averages + prT(0,:,:) = (/ dim_avg_n(pr(:1,:,:),0) /) + pr_djf = prT(0::12,:,:) + pr_mam = prT(3::12,:,:) + pr_jja = prT(6::12,:,:) ; form JJA averages + pr_son = prT(9::12,:,:) + delete(prT) + + prV = runave_n_Wrap(pr,12,0,0) + pr_ann = prV(5::12,:,:) + delete([/prV/]) + end if + end if +;----------------NPI calculation----------------------------------- + coswgt=cos(rad*arr_djf&lat) + coswgt!0 = "lat" + coswgt&lat = arr_djf&lat + npi_ndjfm = wgt_areaave(arr_ndjfm(:,{30:65},{160:220}),coswgt({30.:65.}),1.0,0) + npi_ndjfm!0 = "TIME" + npi_ndjfm&TIME = ispan(syear(ee),eyear(ee),1) + npi_ndjfm&TIME@units = "YYYY" + npi_ndjfm&TIME@long_name = "time" + + npi_ndjfm@area = "30:65N, 160:220E" + npi_ndjfm@units = arr_ndjfm@units + npi_ndjfm@long_name = "North Pacific Index" + delete([/coswgt,arr_ndjfm/]) + +;------------------------------------------------------------------ + arr_djf_CW = SqrtCosWeight(arr_djf) + arr_mam_CW = SqrtCosWeight(arr_mam) + arr_jja_CW = SqrtCosWeight(arr_jja) + arr_son_CW = SqrtCosWeight(arr_son) + arr_ann_CW = SqrtCosWeight(arr_ann) + if (COMPUTE_MODES_MON.eq."True") then + arr_mon_CW = SqrtCosWeight(arr) + else + if (isvar("arr")) then + delete(arr) + end if + if (isvar("sst")) then + delete(sst) + end if + if (isvar("tas")) then + delete(tas) + end if + if (isvar("pr")) then + delete(pr) + end if + end if +;----------PNA/NPO calculations (EOF1/2 of NP PSL)---------------------------------------------------------- + evecv = eofunc(arr_djf_CW({lat|20:85},{lon|120:240},time|:),3,75) + pcts = eofunc_ts(arr_djf_CW({lat|20:85},{lon|120:240},time|:),evecv,False) + pna_pc_djf = dim_standardize(pcts(0,:),0) + npo_pc_djf = dim_standardize(pcts(1,:),0) + pna_djf = arr_djf(0,:,:) + pna_djf = (/ regCoef(pna_pc_djf,arr_djf(lat|:,lon|:,time|:)) /) + npo_djf = arr_djf(0,:,:) + npo_djf = (/ regCoef(npo_pc_djf,arr_djf(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + pna_sst_djf = sst_djf(0,:,:) + pna_sst_djf = (/ regCoef(pna_pc_djf,sst_djf(lat|:,lon|:,time|:)) /) + npo_sst_djf = sst_djf(0,:,:) + npo_sst_djf = (/ regCoef(npo_pc_djf,sst_djf(lat|:,lon|:,time|:)) /) + delete(sst_djf) + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_djf = tas_djf(0,:,:) + pna_tas_djf = (/ regCoef(pna_pc_djf,tas_djf(lat|:,lon|:,time|:)) /) + npo_tas_djf = tas_djf(0,:,:) + npo_tas_djf = (/ regCoef(npo_pc_djf,tas_djf(lat|:,lon|:,time|:)) /) + delete(tas_djf) + end if + if (prreg_plot_flag.eq.0) then + pna_pr_djf = pr_djf(0,:,:) + pna_pr_djf = (/ regCoef(pna_pc_djf,pr_djf(lat|:,lon|:,time|:)) /) + npo_pr_djf = pr_djf(0,:,:) + npo_pr_djf = (/ regCoef(npo_pc_djf,pr_djf(lat|:,lon|:,time|:)) /) + delete(pr_djf) + end if + + if (.not.ismissing(pna_djf({50},{185}))) then + if (pna_djf({50},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + pna_djf = pna_djf*-1. + pna_pc_djf = pna_pc_djf*-1. + if (sstreg_plot_flag.eq.0) then + pna_sst_djf = pna_sst_djf*-1. + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_djf = pna_tas_djf*-1. + end if + if (prreg_plot_flag.eq.0) then + pna_pr_djf = pna_pr_djf*-1. + end if + end if + end if + if (.not.ismissing(npo_djf({65},{185}))) then + if (npo_djf({65},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + npo_djf = npo_djf*-1. + npo_pc_djf = npo_pc_djf*-1. + if (sstreg_plot_flag.eq.0) then + npo_sst_djf = npo_sst_djf*-1. + end if + if (tasreg_plot_flag.eq.0) then + npo_tas_djf = npo_tas_djf*-1. + end if + if (prreg_plot_flag.eq.0) then + npo_pr_djf = npo_pr_djf*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(pna_pc_djf),False) + if (sig_pcv(0)) then ; if True then significant + pna_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + pna_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + npo_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + npo_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(npi_ndjfm,pna_pc_djf) + copy_VarCoords(npi_ndjfm,npo_pc_djf) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_mam_CW({lat|20:85},{lon|120:240},time|:),3,75) + pcts = eofunc_ts(arr_mam_CW({lat|20:85},{lon|120:240},time|:),evecv,False) + pna_pc_mam = dim_standardize(pcts(0,:),0) + npo_pc_mam = dim_standardize(pcts(1,:),0) + pna_mam = arr_mam(0,:,:) + pna_mam = (/ regCoef(pna_pc_mam,arr_mam(lat|:,lon|:,time|:)) /) + npo_mam = arr_mam(0,:,:) + npo_mam = (/ regCoef(npo_pc_mam,arr_mam(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + pna_sst_mam = sst_mam(0,:,:) + pna_sst_mam = (/ regCoef(pna_pc_mam,sst_mam(lat|:,lon|:,time|:)) /) + npo_sst_mam = sst_mam(0,:,:) + npo_sst_mam = (/ regCoef(npo_pc_mam,sst_mam(lat|:,lon|:,time|:)) /) + delete(sst_mam) + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_mam = tas_mam(0,:,:) + pna_tas_mam = (/ regCoef(pna_pc_mam,tas_mam(lat|:,lon|:,time|:)) /) + npo_tas_mam = tas_mam(0,:,:) + npo_tas_mam = (/ regCoef(npo_pc_mam,tas_mam(lat|:,lon|:,time|:)) /) + delete(tas_mam) + end if + if (prreg_plot_flag.eq.0) then + pna_pr_mam = pr_mam(0,:,:) + pna_pr_mam = (/ regCoef(pna_pc_mam,pr_mam(lat|:,lon|:,time|:)) /) + npo_pr_mam = pr_mam(0,:,:) + npo_pr_mam = (/ regCoef(npo_pc_mam,pr_mam(lat|:,lon|:,time|:)) /) + delete(pr_mam) + end if + + if (.not.ismissing(pna_mam({50},{185}))) then + if (pna_mam({50},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + pna_mam = pna_mam*-1. + pna_pc_mam = pna_pc_mam*-1. + if (sstreg_plot_flag.eq.0) then + pna_sst_mam = pna_sst_mam*-1. + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_mam = pna_tas_mam*-1. + end if + if (prreg_plot_flag.eq.0) then + pna_pr_mam = pna_pr_mam*-1. + end if + end if + end if + if (.not.ismissing(npo_mam({65},{185}))) then + if (npo_mam({65},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + npo_mam = npo_mam*-1. + npo_pc_mam = npo_pc_mam*-1. + if (sstreg_plot_flag.eq.0) then + npo_sst_mam = npo_sst_mam*-1. + end if + if (tasreg_plot_flag.eq.0) then + npo_tas_mam = npo_tas_mam*-1. + end if + if (prreg_plot_flag.eq.0) then + npo_pr_mam = npo_pr_mam*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(pna_pc_mam),False) + if (sig_pcv(0)) then ; if True then significant + pna_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + pna_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + npo_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + npo_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(npi_ndjfm,pna_pc_mam) + copy_VarCoords(npi_ndjfm,npo_pc_mam) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_jja_CW({lat|20:85},{lon|120:240},time|:),3,75) + pcts = eofunc_ts(arr_jja_CW({lat|20:85},{lon|120:240},time|:),evecv,False) + pna_pc_jja = dim_standardize(pcts(0,:),0) + npo_pc_jja = dim_standardize(pcts(1,:),0) + pna_jja = arr_jja(0,:,:) + pna_jja = (/ regCoef(pna_pc_jja,arr_jja(lat|:,lon|:,time|:)) /) + npo_jja = arr_jja(0,:,:) + npo_jja = (/ regCoef(npo_pc_jja,arr_jja(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + pna_sst_jja = sst_jja(0,:,:) + pna_sst_jja = (/ regCoef(pna_pc_jja,sst_jja(lat|:,lon|:,time|:)) /) + npo_sst_jja = sst_jja(0,:,:) + npo_sst_jja = (/ regCoef(npo_pc_jja,sst_jja(lat|:,lon|:,time|:)) /) + delete(sst_jja) + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_jja = tas_jja(0,:,:) + pna_tas_jja = (/ regCoef(pna_pc_jja,tas_jja(lat|:,lon|:,time|:)) /) + npo_tas_jja = tas_jja(0,:,:) + npo_tas_jja = (/ regCoef(npo_pc_jja,tas_jja(lat|:,lon|:,time|:)) /) + delete(tas_jja) + end if + if (prreg_plot_flag.eq.0) then + pna_pr_jja = pr_jja(0,:,:) + pna_pr_jja = (/ regCoef(pna_pc_jja,pr_jja(lat|:,lon|:,time|:)) /) + npo_pr_jja = pr_jja(0,:,:) + npo_pr_jja = (/ regCoef(npo_pc_jja,pr_jja(lat|:,lon|:,time|:)) /) + delete(pr_jja) + end if + + if (.not.ismissing(pna_jja({50},{185}))) then + if (pna_jja({50},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + pna_jja = pna_jja*-1. + pna_pc_jja = pna_pc_jja*-1. + if (sstreg_plot_flag.eq.0) then + pna_sst_jja = pna_sst_jja*-1. + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_jja = pna_tas_jja*-1. + end if + if (prreg_plot_flag.eq.0) then + pna_pr_jja = pna_pr_jja*-1. + end if + end if + end if + if (.not.ismissing(npo_jja({65},{185}))) then + if (npo_jja({65},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + npo_jja = npo_jja*-1. + npo_pc_jja = npo_pc_jja*-1. + if (sstreg_plot_flag.eq.0) then + npo_sst_jja = npo_sst_jja*-1. + end if + if (tasreg_plot_flag.eq.0) then + npo_tas_jja = npo_tas_jja*-1. + end if + if (prreg_plot_flag.eq.0) then + npo_pr_jja = npo_pr_jja*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(pna_pc_jja),False) + if (sig_pcv(0)) then ; if True then significant + pna_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + pna_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + npo_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + npo_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(npi_ndjfm,pna_pc_jja) + copy_VarCoords(npi_ndjfm,npo_pc_jja) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_son_CW({lat|20:85},{lon|120:240},time|:),3,75) + pcts = eofunc_ts(arr_son_CW({lat|20:85},{lon|120:240},time|:),evecv,False) + pna_pc_son = dim_standardize(pcts(0,:),0) + npo_pc_son = dim_standardize(pcts(1,:),0) + pna_son = arr_son(0,:,:) + pna_son = (/ regCoef(pna_pc_son,arr_son(lat|:,lon|:,time|:)) /) + npo_son = arr_son(0,:,:) + npo_son = (/ regCoef(npo_pc_son,arr_son(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + pna_sst_son = sst_son(0,:,:) + pna_sst_son = (/ regCoef(pna_pc_son,sst_son(lat|:,lon|:,time|:)) /) + npo_sst_son = sst_son(0,:,:) + npo_sst_son = (/ regCoef(npo_pc_son,sst_son(lat|:,lon|:,time|:)) /) + delete(sst_son) + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_son = tas_son(0,:,:) + pna_tas_son = (/ regCoef(pna_pc_son,tas_son(lat|:,lon|:,time|:)) /) + npo_tas_son = tas_son(0,:,:) + npo_tas_son = (/ regCoef(npo_pc_son,tas_son(lat|:,lon|:,time|:)) /) + delete(tas_son) + end if + if (prreg_plot_flag.eq.0) then + pna_pr_son = pr_son(0,:,:) + pna_pr_son = (/ regCoef(pna_pc_son,pr_son(lat|:,lon|:,time|:)) /) + npo_pr_son = pr_son(0,:,:) + npo_pr_son = (/ regCoef(npo_pc_son,pr_son(lat|:,lon|:,time|:)) /) + delete(pr_son) + end if + + if (.not.ismissing(pna_son({50},{185}))) then + if (pna_son({50},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + pna_son = pna_son*-1. + pna_pc_son = pna_pc_son*-1. + if (sstreg_plot_flag.eq.0) then + pna_sst_son = pna_sst_son*-1. + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_son = pna_tas_son*-1. + end if + if (prreg_plot_flag.eq.0) then + pna_pr_son = pna_pr_son*-1. + end if + end if + end if + if (.not.ismissing(npo_son({65},{185}))) then + if (npo_son({65},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + npo_son = npo_son*-1. + npo_pc_son = npo_pc_son*-1. + if (sstreg_plot_flag.eq.0) then + npo_sst_son = npo_sst_son*-1. + end if + if (tasreg_plot_flag.eq.0) then + npo_tas_son = npo_tas_son*-1. + end if + if (prreg_plot_flag.eq.0) then + npo_pr_son = npo_pr_son*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(pna_pc_son),False) + if (sig_pcv(0)) then ; if True then significant + pna_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + pna_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + npo_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + npo_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(npi_ndjfm,pna_pc_son) + copy_VarCoords(npi_ndjfm,npo_pc_son) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_ann_CW({lat|20:85},{lon|120:240},time|:),3,75) + pcts = eofunc_ts(arr_ann_CW({lat|20:85},{lon|120:240},time|:),evecv,False) + pna_pc_ann = dim_standardize(pcts(0,:),0) + npo_pc_ann = dim_standardize(pcts(1,:),0) + pna_ann = arr_ann(0,:,:) + pna_ann = (/ regCoef(pna_pc_ann,arr_ann(lat|:,lon|:,time|:)) /) + npo_ann = arr_ann(0,:,:) + npo_ann = (/ regCoef(npo_pc_ann,arr_ann(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + pna_sst_ann = sst_ann(0,:,:) + pna_sst_ann = (/ regCoef(pna_pc_ann,sst_ann(lat|:,lon|:,time|:)) /) + npo_sst_ann = sst_ann(0,:,:) + npo_sst_ann = (/ regCoef(npo_pc_ann,sst_ann(lat|:,lon|:,time|:)) /) + delete(sst_ann) + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_ann = tas_ann(0,:,:) + pna_tas_ann = (/ regCoef(pna_pc_ann,tas_ann(lat|:,lon|:,time|:)) /) + npo_tas_ann = tas_ann(0,:,:) + npo_tas_ann = (/ regCoef(npo_pc_ann,tas_ann(lat|:,lon|:,time|:)) /) + delete(tas_ann) + end if + if (prreg_plot_flag.eq.0) then + pna_pr_ann = pr_ann(0,:,:) + pna_pr_ann = (/ regCoef(pna_pc_ann,pr_ann(lat|:,lon|:,time|:)) /) + npo_pr_ann = pr_ann(0,:,:) + npo_pr_ann = (/ regCoef(npo_pc_ann,pr_ann(lat|:,lon|:,time|:)) /) + delete(pr_ann) + end if + + if (.not.ismissing(pna_ann({50},{185}))) then + if (pna_ann({50},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + pna_ann = pna_ann*-1. + pna_pc_ann = pna_pc_ann*-1. + if (sstreg_plot_flag.eq.0) then + pna_sst_ann = pna_sst_ann*-1. + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_ann = pna_tas_ann*-1. + end if + if (prreg_plot_flag.eq.0) then + pna_pr_ann = pna_pr_ann*-1. + end if + end if + end if + if (.not.ismissing(npo_ann({65},{185}))) then + if (npo_ann({65},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + npo_ann = npo_ann*-1. + npo_pc_ann = npo_pc_ann*-1. + if (sstreg_plot_flag.eq.0) then + npo_sst_ann = npo_sst_ann*-1. + end if + if (tasreg_plot_flag.eq.0) then + npo_tas_ann = npo_tas_ann*-1. + end if + if (prreg_plot_flag.eq.0) then + npo_pr_ann = npo_pr_ann*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(pna_pc_ann),False) + if (sig_pcv(0)) then ; if True then significant + pna_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + pna_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + npo_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + npo_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(npi_ndjfm,pna_pc_ann) + copy_VarCoords(npi_ndjfm,npo_pc_ann) + delete([/evecv,pcts/]) + + if (COMPUTE_MODES_MON.eq."True") then + evecv = eofunc(arr_mon_CW({lat|20:85},{lon|120:240},time|:),3,75) + pcts = eofunc_ts(arr_mon_CW({lat|20:85},{lon|120:240},time|:),evecv,False) + pna_pc_mon = dim_standardize(pcts(0,:),0) + npo_pc_mon = dim_standardize(pcts(1,:),0) + pna_mon = arr(0,:,:) + pna_mon = (/ regCoef(pna_pc_mon,arr(lat|:,lon|:,time|:)) /) + npo_mon = arr(0,:,:) + npo_mon = (/ regCoef(npo_pc_mon,arr(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + pna_sst_mon = sst(0,:,:) + pna_sst_mon = (/ regCoef(pna_pc_mon,sst(lat|:,lon|:,time|:)) /) + npo_sst_mon = sst(0,:,:) + npo_sst_mon = (/ regCoef(npo_pc_mon,sst(lat|:,lon|:,time|:)) /) + delete(sst) + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_mon = tas(0,:,:) + pna_tas_mon = (/ regCoef(pna_pc_mon,tas(lat|:,lon|:,time|:)) /) + npo_tas_mon = tas(0,:,:) + npo_tas_mon = (/ regCoef(npo_pc_mon,tas(lat|:,lon|:,time|:)) /) + delete(tas) + end if + if (prreg_plot_flag.eq.0) then + pna_pr_mon = pr(0,:,:) + pna_pr_mon = (/ regCoef(pna_pc_mon,pr(lat|:,lon|:,time|:)) /) + npo_pr_mon = pr(0,:,:) + npo_pr_mon = (/ regCoef(npo_pc_mon,pr(lat|:,lon|:,time|:)) /) + delete(pr) + end if + if (.not.ismissing(pna_mon({50},{185}))) then + if (pna_mon({50},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + pna_mon = pna_mon*-1. + pna_pc_mon = pna_pc_mon*-1. + if (sstreg_plot_flag.eq.0) then + pna_sst_mon = pna_sst_mon*-1. + end if + if (tasreg_plot_flag.eq.0) then + pna_tas_mon = pna_tas_mon*-1. + end if + if (prreg_plot_flag.eq.0) then + pna_pr_mon = pna_pr_mon*-1. + end if + end if + end if + if (.not.ismissing(npo_mon({65},{185}))) then + if (npo_mon({65},{185}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + npo_mon = npo_mon*-1. + npo_pc_mon = npo_pc_mon*-1. + if (sstreg_plot_flag.eq.0) then + npo_sst_mon = npo_sst_mon*-1. + end if + if (tasreg_plot_flag.eq.0) then + npo_tas_mon = npo_tas_mon*-1. + end if + if (prreg_plot_flag.eq.0) then + npo_pr_mon = npo_pr_mon*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(pna_pc_mon),False) + if (sig_pcv(0)) then ; if True then significant + pna_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + pna_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + npo_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + npo_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + delete(sig_pcv) + pna_pc_mon!0 = "time" + pna_pc_mon&time = arr&time + npo_pc_mon!0 = "time" + npo_pc_mon&time = arr&time + delete([/evecv,pcts,arr,arr_mon_CW/]) + end if + delete([/arr_djf_CW,arr_mam_CW,arr_jja_CW,arr_son_CW,arr_ann_CW/]) + delete([/arr_djf,arr_mam,arr_jja,arr_son,arr_ann/]) +;------------------------------------------------------------------------------------------------------ + if (sstreg_frame.eq.1.and.sstreg_plot_flag.eq.0) then ; sstreg_frame = flag to create regressions .ps/.png files + sstreg_frame = 0 + end if + if (tasreg_frame.eq.1.and.tasreg_plot_flag.eq.0) then ; tasreg_frame = flag to create regressions .ps/.png files + tasreg_frame = 0 + end if + if (prreg_frame.eq.1.and.prreg_plot_flag.eq.0) then ; prreg_frame = flag to create regressions .ps/.png files + prreg_frame = 0 + end if +;------------------------------------------------------------------------------------------------------ + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.pna_npo."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->npi_ndjfm = npi_ndjfm + + z->pna_timeseries_djf = set_varAtts(pna_pc_djf,"PNA normalized principal component timeseries (DJF)","1","") + z->pna_timeseries_mam = set_varAtts(pna_pc_mam,"PNA normalized principal component timeseries (MAM)","1","") + z->pna_timeseries_jja = set_varAtts(pna_pc_jja,"PNA normalized principal component timeseries (JJA)","1","") + z->pna_timeseries_son = set_varAtts(pna_pc_son,"PNA normalized principal component timeseries (SON)","1","") + z->pna_timeseries_ann = set_varAtts(pna_pc_ann,"PNA normalized principal component timeseries (annual)","1","") + + z->npo_timeseries_djf = set_varAtts(npo_pc_djf,"NPO normalized principal component timeseries (DJF)","1","") + z->npo_timeseries_mam = set_varAtts(npo_pc_mam,"NPO normalized principal component timeseries (MAM)","1","") + z->npo_timeseries_jja = set_varAtts(npo_pc_jja,"NPO normalized principal component timeseries (JJA)","1","") + z->npo_timeseries_son = set_varAtts(npo_pc_son,"NPO normalized principal component timeseries (SON)","1","") + z->npo_timeseries_ann = set_varAtts(npo_pc_ann,"NPO normalized principal component timeseries (annual)","1","") + + z->pna_pattern_djf = set_varAtts(pna_djf,"PNA spatial pattern (DJF)","","") + z->pna_pattern_mam = set_varAtts(pna_mam,"PNA spatial pattern (MAM)","","") + z->pna_pattern_jja = set_varAtts(pna_jja,"PNA spatial pattern (JJA)","","") + z->pna_pattern_son = set_varAtts(pna_son,"PNA spatial pattern (SON)","","") + z->pna_pattern_ann = set_varAtts(pna_ann,"PNA spatial pattern (annual)","","") + + z->npo_pattern_djf = set_varAtts(npo_djf,"NPO spatial pattern (DJF)","","") + z->npo_pattern_mam = set_varAtts(npo_mam,"NPO spatial pattern (MAM)","","") + z->npo_pattern_jja = set_varAtts(npo_jja,"NPO spatial pattern (JJA)","","") + z->npo_pattern_son = set_varAtts(npo_son,"NPO spatial pattern (SON)","","") + z->npo_pattern_ann = set_varAtts(npo_ann,"NPO spatial pattern (annual)","","") + + if (COMPUTE_MODES_MON.eq."True") then + z->pna_timeseries_mon = set_varAtts(pna_pc_mon,"PNA principal component timeseries (monthly)","","") + z->npo_timeseries_mon = set_varAtts(npo_pc_mon,"NPO principal component timeseries (monthly)","","") + z->pna_pattern_mon = set_varAtts(pna_mon,"PNA spatial pattern (monthly)","","") + z->npo_pattern_mon = set_varAtts(npo_mon,"NPO spatial pattern (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + + if (sstreg_plot_flag.eq.0) then + modname = str_sub_str(names_ts(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.pna_npo.ts."+syear_ts(ee)+"-"+eyear_ts(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_ts(ee)+" from "+syear_ts(ee)+"-"+eyear_ts(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_ts(ee)+"-"+eyear_ts(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->pna_sst_regression_djf = set_varAtts(pna_sst_djf,"sst regression onto PNA principal component timeseries (DJF)","","") + z->pna_sst_regression_mam = set_varAtts(pna_sst_mam,"sst regression onto PNA principal component timeseries (MAM)","","") + z->pna_sst_regression_jja = set_varAtts(pna_sst_jja,"sst regression onto PNA principal component timeseries (JJA)","","") + z->pna_sst_regression_son = set_varAtts(pna_sst_son,"sst regression onto PNA principal component timeseries (SON)","","") + z->pna_sst_regression_ann = set_varAtts(pna_sst_ann,"sst regression onto PNA principal component timeseries (annual)","","") + + z->npo_sst_regression_djf = set_varAtts(npo_sst_djf,"sst regression onto NPO principal component timeseries (DJF)","","") + z->npo_sst_regression_mam = set_varAtts(npo_sst_mam,"sst regression onto NPO principal component timeseries (MAM)","","") + z->npo_sst_regression_jja = set_varAtts(npo_sst_jja,"sst regression onto NPO principal component timeseries (JJA)","","") + z->npo_sst_regression_son = set_varAtts(npo_sst_son,"sst regression onto NPO principal component timeseries (SON)","","") + z->npo_sst_regression_ann = set_varAtts(npo_sst_ann,"sst regression onto NPO principal component timeseries (annual)","","") + if (COMPUTE_MODES_MON.eq."True") then + z->pna_sst_regression_mon = set_varAtts(pna_sst_mon,"sst regression onto PNA principal component timeseries (monthly)","","") + z->npo_sst_regression_mon = set_varAtts(npo_sst_mon,"sst regression onto NPO principal component timeseries (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + end if + if (tasreg_plot_flag.eq.0) then + modname = str_sub_str(names_tas(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.pna_npo.tas."+syear_tas(ee)+"-"+eyear_tas(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_tas(ee)+" from "+syear_tas(ee)+"-"+eyear_tas(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_tas(ee)+"-"+eyear_tas(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->pna_tas_regression_djf = set_varAtts(pna_tas_djf,"tas regression onto PNA principal component timeseries (DJF)","","") + z->pna_tas_regression_mam = set_varAtts(pna_tas_mam,"tas regression onto PNA principal component timeseries (MAM)","","") + z->pna_tas_regression_jja = set_varAtts(pna_tas_jja,"tas regression onto PNA principal component timeseries (JJA)","","") + z->pna_tas_regression_son = set_varAtts(pna_tas_son,"tas regression onto PNA principal component timeseries (SON)","","") + z->pna_tas_regression_ann = set_varAtts(pna_tas_ann,"tas regression onto PNA principal component timeseries (annual)","","") + + z->npo_tas_regression_djf = set_varAtts(npo_tas_djf,"tas regression onto NPO principal component timeseries (DJF)","","") + z->npo_tas_regression_mam = set_varAtts(npo_tas_mam,"tas regression onto NPO principal component timeseries (MAM)","","") + z->npo_tas_regression_jja = set_varAtts(npo_tas_jja,"tas regression onto NPO principal component timeseries (JJA)","","") + z->npo_tas_regression_son = set_varAtts(npo_tas_son,"tas regression onto NPO principal component timeseries (SON)","","") + z->npo_tas_regression_ann = set_varAtts(npo_tas_ann,"tas regression onto NPO principal component timeseries (annual)","","") + if (COMPUTE_MODES_MON.eq."True") then + z->pna_tas_regression_mon = set_varAtts(pna_tas_mon,"tas regression onto PNA principal component timeseries (monthly)","","") + z->npo_tas_regression_mon = set_varAtts(npo_tas_mon,"tas regression onto NPO principal component timeseries (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + end if + if (prreg_plot_flag.eq.0) then + modname = str_sub_str(names_pr(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.pna_npo.pr."+syear_pr(ee)+"-"+eyear_pr(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_pr(ee)+" from "+syear_pr(ee)+"-"+eyear_pr(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_pr(ee)+"-"+eyear_pr(ee)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->pna_pr_regression_djf = set_varAtts(pna_pr_djf,"pr regression onto PNA principal component timeseries (DJF)","","") + z->pna_pr_regression_mam = set_varAtts(pna_pr_mam,"pr regression onto PNA principal component timeseries (MAM)","","") + z->pna_pr_regression_jja = set_varAtts(pna_pr_jja,"pr regression onto PNA principal component timeseries (JJA)","","") + z->pna_pr_regression_son = set_varAtts(pna_pr_son,"pr regression onto PNA principal component timeseries (SON)","","") + z->pna_pr_regression_ann = set_varAtts(pna_pr_ann,"pr regression onto PNA principal component timeseries (annual)","","") + + z->npo_pr_regression_djf = set_varAtts(npo_pr_djf,"pr regression onto NPO principal component timeseries (DJF)","","") + z->npo_pr_regression_mam = set_varAtts(npo_pr_mam,"pr regression onto NPO principal component timeseries (MAM)","","") + z->npo_pr_regression_jja = set_varAtts(npo_pr_jja,"pr regression onto NPO principal component timeseries (JJA)","","") + z->npo_pr_regression_son = set_varAtts(npo_pr_son,"pr regression onto NPO principal component timeseries (SON)","","") + z->npo_pr_regression_ann = set_varAtts(npo_pr_ann,"pr regression onto NPO principal component timeseries (annual)","","") + if (COMPUTE_MODES_MON.eq."True") then + z->pna_pr_regression_mon = set_varAtts(pna_pr_mon,"pr regression onto PNA principal component timeseries (monthly)","","") + z->npo_pr_regression_mon = set_varAtts(npo_pr_mon,"pr regression onto NPO principal component timeseries (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + end if + end if +;======================================================================== + res = True + res@mpGeophysicalLineColor = "gray42" + res@mpGeophysicalLineThicknessF = 2. + res@mpGridAndLimbOn = False + res@mpFillOn = False + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + res@cnLevelSelectionMode = "ExplicitLevels" + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.03 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.03 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + if (nsim.le.5) then + res@gsnLeftStringFontHeightF = 0.018 + res@gsnCenterStringFontHeightF = 0.022 + res@gsnRightStringFontHeightF = 0.018 + else + res@gsnLeftStringFontHeightF = 0.024 + res@gsnCenterStringFontHeightF = 0.028 + res@gsnRightStringFontHeightF = 0.024 + end if + res@gsnPolar = "NH" + res@mpMinLatF = 20. + res@mpCenterLonF = 0. + + res@cnLevels = (/-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7./) + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnCenterString = names(ee) + + res4 = res ; res4 = pr regression resources + if (COLORMAP.eq.0) then + res4@cnLevels := fspan(-.7,.7,15) + else + res4@cnLevels := fspan(-.5,.5,11) + end if + + res2 = True + res2@gsnDraw = False + res2@gsnFrame = False + res2@cnLevelSelectionMode = "ExplicitLevels" + res2@cnLevels = res@cnLevels + + res2@cnLineLabelsOn = False + res2@cnFillOn = True + res2@cnLinesOn = False + res2@cnFillMode = "AreaFill" + res2@lbLabelBarOn = False + res2@cnInfoLabelOn = False + res2@gsnRightString = "" + res2@gsnLeftString = "" + res2@gsnCenterString = "" + res2@gsnAddCyclic = True + + res@gsnRightString = pna_djf@pcvar + map_pna_djf(ee) = gsn_csm_contour_map_polar(wks_pna,pna_djf,res) + res@gsnRightString = pna_mam@pcvar + map_pna_mam(ee) = gsn_csm_contour_map_polar(wks_pna,pna_mam,res) + res@gsnRightString = pna_jja@pcvar + map_pna_jja(ee) = gsn_csm_contour_map_polar(wks_pna,pna_jja,res) + res@gsnRightString = pna_son@pcvar + map_pna_son(ee) = gsn_csm_contour_map_polar(wks_pna,pna_son,res) + res@gsnRightString = pna_ann@pcvar + map_pna_ann(ee) = gsn_csm_contour_map_polar(wks_pna,pna_ann,res) + delete([/pna_djf,pna_mam,pna_jja,pna_son,pna_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + res@gsnRightString = pna_mon@pcvar + map_pna_mon(ee) = gsn_csm_contour_map_polar(wks_pna,pna_mon,res) + delete([/pna_mon/]) + end if + + res@cnLevels = (/-4,-3,-2.5,-2,-1.5,-1,-0.5,0,0.5,1,1.5,2,2.5,3,4/) + res@gsnRightString = npo_djf@pcvar + map_npo_djf(ee) = gsn_csm_contour_map_polar(wks_npo,npo_djf,res) + res@gsnRightString = npo_mam@pcvar + map_npo_mam(ee) = gsn_csm_contour_map_polar(wks_npo,npo_mam,res) + res@gsnRightString = npo_jja@pcvar + map_npo_jja(ee) = gsn_csm_contour_map_polar(wks_npo,npo_jja,res) + res@gsnRightString = npo_son@pcvar + map_npo_son(ee) = gsn_csm_contour_map_polar(wks_npo,npo_son,res) + res@gsnRightString = npo_ann@pcvar + map_npo_ann(ee) = gsn_csm_contour_map_polar(wks_npo,npo_ann,res) + delete([/npo_djf,npo_mam,npo_jja,npo_son,npo_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + res@gsnRightString = npo_mon@pcvar + map_npo_mon(ee) = gsn_csm_contour_map_polar(wks_npo,npo_mon,res) + delete([/npo_mon/]) + end if + + if (sstreg_plot_flag.eq.0) then + res@cnLevels := fspan(-.7,.7,15) + if (tasreg_plot_flag.eq.0) then + if (names_ts(ee).eq.names_tas(ee)) then + res@gsnCenterString = names_ts(ee) + else + res@gsnCenterString = names_ts(ee)+" / "+names_tas(ee) + end if + else + res@gsnCenterString = names_ts(ee) + end if + res@gsnRightString = "" + reg_pna_djf(ee) = gsn_csm_contour_map_polar(wks_pna,pna_sst_djf,res) + reg_pna_mam(ee) = gsn_csm_contour_map_polar(wks_pna,pna_sst_mam,res) + reg_pna_jja(ee) = gsn_csm_contour_map_polar(wks_pna,pna_sst_jja,res) + reg_pna_son(ee) = gsn_csm_contour_map_polar(wks_pna,pna_sst_son,res) + reg_pna_ann(ee) = gsn_csm_contour_map_polar(wks_pna,pna_sst_ann,res) + delete([/pna_sst_djf,pna_sst_mam,pna_sst_jja,pna_sst_son,pna_sst_ann/]) + if (tasreg_plot_flag.eq.0) then + o_djf = gsn_csm_contour(wks_pna,pna_tas_djf,res2) + o_mam = gsn_csm_contour(wks_pna,pna_tas_mam,res2) + o_jja = gsn_csm_contour(wks_pna,pna_tas_jja,res2) + o_son = gsn_csm_contour(wks_pna,pna_tas_son,res2) + o_ann = gsn_csm_contour(wks_pna,pna_tas_ann,res2) + delete([/pna_tas_djf,pna_tas_mam,pna_tas_jja,pna_tas_son,pna_tas_ann/]) + overlay(reg_pna_djf(ee),o_djf) + overlay(reg_pna_mam(ee),o_mam) + overlay(reg_pna_jja(ee),o_jja) + overlay(reg_pna_son(ee),o_son) + overlay(reg_pna_ann(ee),o_ann) + delete([/o_djf,o_mam,o_jja,o_son,o_ann/]) + end if + if (COMPUTE_MODES_MON.eq."True") then + reg_pna_mon(ee) = gsn_csm_contour_map_polar(wks_pna,pna_sst_mon,res) + delete([/pna_sst_mon/]) + if (tasreg_plot_flag.eq.0) then + o_mon = gsn_csm_contour(wks_pna,pna_tas_mon,res2) + overlay(reg_pna_mon(ee),o_mon) + delete([/o_mon,pna_tas_mon/]) + end if + end if + + reg_npo_djf(ee) = gsn_csm_contour_map_polar(wks_npo,npo_sst_djf,res) + reg_npo_mam(ee) = gsn_csm_contour_map_polar(wks_npo,npo_sst_mam,res) + reg_npo_jja(ee) = gsn_csm_contour_map_polar(wks_npo,npo_sst_jja,res) + reg_npo_son(ee) = gsn_csm_contour_map_polar(wks_npo,npo_sst_son,res) + reg_npo_ann(ee) = gsn_csm_contour_map_polar(wks_npo,npo_sst_ann,res) + delete([/npo_sst_djf,npo_sst_mam,npo_sst_jja,npo_sst_son,npo_sst_ann/]) + if (tasreg_plot_flag.eq.0) then + o_djf = gsn_csm_contour(wks_npo,npo_tas_djf,res2) + o_mam = gsn_csm_contour(wks_npo,npo_tas_mam,res2) + o_jja = gsn_csm_contour(wks_npo,npo_tas_jja,res2) + o_son = gsn_csm_contour(wks_npo,npo_tas_son,res2) + o_ann = gsn_csm_contour(wks_npo,npo_tas_ann,res2) + delete([/npo_tas_djf,npo_tas_mam,npo_tas_jja,npo_tas_son,npo_tas_ann/]) + overlay(reg_npo_djf(ee),o_djf) + overlay(reg_npo_mam(ee),o_mam) + overlay(reg_npo_jja(ee),o_jja) + overlay(reg_npo_son(ee),o_son) + overlay(reg_npo_ann(ee),o_ann) + delete([/o_djf,o_mam,o_jja,o_son,o_ann/]) + end if + if (COMPUTE_MODES_MON.eq."True") then + reg_npo_mon(ee) = gsn_csm_contour_map_polar(wks_npo,npo_sst_mon,res) + delete([/npo_sst_mon/]) + if (tasreg_plot_flag.eq.0) then + o_mon = gsn_csm_contour(wks_npo,npo_tas_mon,res2) + overlay(reg_npo_mon(ee),o_mon) + delete([/o_mon,npo_tas_mon/]) + end if + end if + end if + + if (prreg_plot_flag.eq.0) then ; PR regressions + res4@gsnRightString = "" + res4@gsnCenterString = names_pr(ee) + reg_pna_pr_djf(ee) = gsn_csm_contour_map_polar(wks_pna_pr,pna_pr_djf,res4) + reg_pna_pr_mam(ee) = gsn_csm_contour_map_polar(wks_pna_pr,pna_pr_mam,res4) + reg_pna_pr_jja(ee) = gsn_csm_contour_map_polar(wks_pna_pr,pna_pr_jja,res4) + reg_pna_pr_son(ee) = gsn_csm_contour_map_polar(wks_pna_pr,pna_pr_son,res4) + reg_pna_pr_ann(ee) = gsn_csm_contour_map_polar(wks_pna_pr,pna_pr_ann,res4) + delete([/pna_pr_djf,pna_pr_mam,pna_pr_jja,pna_pr_son,pna_pr_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + reg_pna_pr_mon(ee) = gsn_csm_contour_map_polar(wks_pna_pr,pna_pr_mon,res4) + delete([/pna_pr_mon/]) + end if + + reg_npo_pr_djf(ee) = gsn_csm_contour_map_polar(wks_npo_pr,npo_pr_djf,res4) + reg_npo_pr_mam(ee) = gsn_csm_contour_map_polar(wks_npo_pr,npo_pr_mam,res4) + reg_npo_pr_jja(ee) = gsn_csm_contour_map_polar(wks_npo_pr,npo_pr_jja,res4) + reg_npo_pr_son(ee) = gsn_csm_contour_map_polar(wks_npo_pr,npo_pr_son,res4) + reg_npo_pr_ann(ee) = gsn_csm_contour_map_polar(wks_npo_pr,npo_pr_ann,res4) + delete([/npo_pr_djf,npo_pr_mam,npo_pr_jja,npo_pr_son,npo_pr_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + reg_npo_pr_mon(ee) = gsn_csm_contour_map_polar(wks_npo_pr,npo_pr_mon,res4) + delete([/npo_pr_mon/]) + end if + end if + + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnXYBarChart = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + xyres@gsnAboveYRefLineColor = 185 + xyres@gsnBelowYRefLineColor = 35 + if (wks_type.eq."png") then + xyres@xyLineThicknessF = .5 + else + xyres@xyLineThicknessF = .2 + end if + xyres@xyLineColor = "gray52" + xyres@tiYAxisString = "" + xyres@tiXAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnStringFontHeightF = 0.017 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnStringFontHeightF = 0.024 + end if + xyres@gsnCenterStringOrthogonalPosF = 0.025 + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnLeftString = "" + xyres@gsnRightString = "" + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+1.5 + xyres@gsnCenterStringOrthogonalPosF = 0.025 + + xyres@gsnCenterString = names(ee) + + xyresmon = xyres + xyresmon@gsnXYBarChart = False + xyresmon@xyLineThicknessF = .1 + + xy_pna_djf(ee) = gsn_csm_xy(wks_pna_ts,fspan(syear(ee),eyear(ee),dimsizes(pna_pc_djf)),pna_pc_djf,xyres) ; use standardized timeseries + xy_pna_mam(ee) = gsn_csm_xy(wks_pna_ts,fspan(syear(ee),eyear(ee),dimsizes(pna_pc_mam)),pna_pc_mam,xyres) ; use standardized timeseries + xy_pna_jja(ee) = gsn_csm_xy(wks_pna_ts,fspan(syear(ee),eyear(ee),dimsizes(pna_pc_jja)),pna_pc_jja,xyres) ; use standardized timeseries + xy_pna_son(ee) = gsn_csm_xy(wks_pna_ts,fspan(syear(ee),eyear(ee),dimsizes(pna_pc_son)),pna_pc_son,xyres) ; use standardized timeseries + xy_pna_ann(ee) = gsn_csm_xy(wks_pna_ts,fspan(syear(ee),eyear(ee),dimsizes(pna_pc_ann)),pna_pc_ann,xyres) ; use standardized timeseries + delete([/pna_pc_djf,pna_pc_mam,pna_pc_jja,pna_pc_son,pna_pc_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + xy_pna_mon(ee) = gsn_csm_xy(wks_pna_ts,fspan(syear(ee),eyear(ee)+.91667,dimsizes(pna_pc_mon)),pna_pc_mon,xyresmon) ; use standardized timeseries + delete([/pna_pc_mon/]) + end if + + xy_npo_djf(ee) = gsn_csm_xy(wks_npo_ts,fspan(syear(ee),eyear(ee),dimsizes(npo_pc_djf)),npo_pc_djf,xyres) ; use standardized timeseries + xy_npo_mam(ee) = gsn_csm_xy(wks_npo_ts,fspan(syear(ee),eyear(ee),dimsizes(npo_pc_mam)),npo_pc_mam,xyres) ; use standardized timeseries + xy_npo_jja(ee) = gsn_csm_xy(wks_npo_ts,fspan(syear(ee),eyear(ee),dimsizes(npo_pc_jja)),npo_pc_jja,xyres) ; use standardized timeseries + xy_npo_son(ee) = gsn_csm_xy(wks_npo_ts,fspan(syear(ee),eyear(ee),dimsizes(npo_pc_son)),npo_pc_son,xyres) ; use standardized timeseries + xy_npo_ann(ee) = gsn_csm_xy(wks_npo_ts,fspan(syear(ee),eyear(ee),dimsizes(npo_pc_ann)),npo_pc_ann,xyres) ; use standardized timeseries + delete([/npo_pc_djf,npo_pc_mam,npo_pc_jja,npo_pc_son,npo_pc_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + xy_npo_mon(ee) = gsn_csm_xy(wks_npo_ts,fspan(syear(ee),eyear(ee)+.91667,dimsizes(npo_pc_mon)),npo_pc_mon,xyresmon) ; use standardized timeseries + delete([/npo_pc_mon/]) + end if + + xy_npi(ee) = gsn_csm_xy(wks_npi_ts,fspan(syear(ee),eyear(ee),dimsizes(npi_ndjfm)),npi_ndjfm,xyres) ; throw NPI into wks_psa2_ts workstation + delete(npi_ndjfm) + delete(sstreg_plot_flag) + end do + + if (isvar("clim_syear")) then + delete(clim_syear) + end if + if (isvar("clim_eyear")) then + delete(clim_eyear) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.55 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres@txString = "PNA (DJF)" + gsn_panel2(wks_pna,map_pna_djf,(/nrow,ncol/),panres) + delete(map_pna_djf) + panres@txString = "PNA (MAM)" + gsn_panel2(wks_pna,map_pna_mam,(/nrow,ncol/),panres) + delete(map_pna_mam) + panres@txString = "PNA (JJA)" + gsn_panel2(wks_pna,map_pna_jja,(/nrow,ncol/),panres) + delete(map_pna_jja) + panres@txString = "PNA (SON)" + gsn_panel2(wks_pna,map_pna_son,(/nrow,ncol/),panres) + delete(map_pna_son) + panres@txString = "PNA (Annual)" + gsn_panel2(wks_pna,map_pna_ann,(/nrow,ncol/),panres) + delete(map_pna_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "PNA (Monthly)" + gsn_panel2(wks_pna,map_pna_mon,(/nrow,ncol/),panres) + delete(map_pna_mon) + end if + + if (sstreg_frame.eq.0) then + if (tasreg_frame.eq.0) then + txt0 = "SST/TAS" + else + txt0 = "SST" + end if + panres@txString = "PNA "+txt0+" Regressions (DJF)" + gsn_panel2(wks_pna,reg_pna_djf,(/nrow,ncol/),panres) + delete(reg_pna_djf) + panres@txString = "PNA "+txt0+" Regressions (MAM)" + gsn_panel2(wks_pna,reg_pna_mam,(/nrow,ncol/),panres) + delete(reg_pna_mam) + panres@txString = "PNA "+txt0+" Regressions (JJA)" + gsn_panel2(wks_pna,reg_pna_jja,(/nrow,ncol/),panres) + delete(reg_pna_jja) + panres@txString = "PNA "+txt0+" Regressions (SON)" + gsn_panel2(wks_pna,reg_pna_son,(/nrow,ncol/),panres) + delete(reg_pna_son) + panres@txString = "PNA "+txt0+" Regressions (Annual)" + gsn_panel2(wks_pna,reg_pna_ann,(/nrow,ncol/),panres) + delete(reg_pna_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "PNA "+txt0+" Regressions (Monthly)" + gsn_panel2(wks_pna,reg_pna_mon,(/nrow,ncol/),panres) + delete(reg_pna_mon) + end if + delete(wks_pna) + end if + if (prreg_frame.eq.0) then + panres@txString = "PNA PR Regressions (DJF)" + gsn_panel2(wks_pna_pr,reg_pna_pr_djf,(/nrow,ncol/),panres) + delete(reg_pna_pr_djf) + panres@txString = "PNA PR Regressions (MAM)" + gsn_panel2(wks_pna_pr,reg_pna_pr_mam,(/nrow,ncol/),panres) + delete(reg_pna_pr_mam) + panres@txString = "PNA PR Regressions (JJA)" + gsn_panel2(wks_pna_pr,reg_pna_pr_jja,(/nrow,ncol/),panres) + delete(reg_pna_pr_jja) + panres@txString = "PNA PR Regressions (SON)" + gsn_panel2(wks_pna_pr,reg_pna_pr_son,(/nrow,ncol/),panres) + delete(reg_pna_pr_son) + panres@txString = "PNA PR Regressions (Annual)" + gsn_panel2(wks_pna_pr,reg_pna_pr_ann,(/nrow,ncol/),panres) + delete(reg_pna_pr_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "PNA PR Regressions (Monthly)" + gsn_panel2(wks_pna_pr,reg_pna_pr_mon,(/nrow,ncol/),panres) + delete(reg_pna_pr_mon) + end if + delete(wks_pna_pr) + end if + + panres@txString = "NPO (DJF)" + gsn_panel2(wks_npo,map_npo_djf,(/nrow,ncol/),panres) + delete(map_npo_djf) + panres@txString = "NPO (MAM)" + gsn_panel2(wks_npo,map_npo_mam,(/nrow,ncol/),panres) + delete(map_npo_mam) + panres@txString = "NPO (JJA)" + gsn_panel2(wks_npo,map_npo_jja,(/nrow,ncol/),panres) + delete(map_npo_jja) + panres@txString = "NPO (SON)" + gsn_panel2(wks_npo,map_npo_son,(/nrow,ncol/),panres) + delete(map_npo_son) + panres@txString = "NPO (Annual)" + gsn_panel2(wks_npo,map_npo_ann,(/nrow,ncol/),panres) + delete(map_npo_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "NPO (Monthly)" + gsn_panel2(wks_npo,map_npo_mon,(/nrow,ncol/),panres) + delete(map_npo_mon) + end if + + if (sstreg_frame.eq.0) then + if (tasreg_frame.eq.0) then + txt0 = "SST/TAS" + else + txt0 = "SST" + end if + panres@txString = "NPO "+txt0+" Regressions (DJF)" + gsn_panel2(wks_npo,reg_npo_djf,(/nrow,ncol/),panres) + delete(reg_npo_djf) + panres@txString = "NPO "+txt0+" Regressions (MAM)" + gsn_panel2(wks_npo,reg_npo_mam,(/nrow,ncol/),panres) + delete(reg_npo_mam) + panres@txString = "NPO "+txt0+" Regressions (JJA)" + gsn_panel2(wks_npo,reg_npo_jja,(/nrow,ncol/),panres) + delete(reg_npo_jja) + panres@txString = "NPO "+txt0+" Regressions (SON)" + gsn_panel2(wks_npo,reg_npo_son,(/nrow,ncol/),panres) + delete(reg_npo_son) + panres@txString = "NPO "+txt0+" Regressions (Annual)" + gsn_panel2(wks_npo,reg_npo_ann,(/nrow,ncol/),panres) + delete(reg_npo_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "NPO "+txt0+" Regressions (Monthly)" + gsn_panel2(wks_npo,reg_npo_mon,(/nrow,ncol/),panres) + delete(reg_npo_mon) + end if + delete(wks_npo) + end if + if (prreg_frame.eq.0) then + panres@txString = "NPO PR Regressions (DJF)" + gsn_panel2(wks_npo_pr,reg_npo_pr_djf,(/nrow,ncol/),panres) + delete(reg_npo_pr_djf) + panres@txString = "NPO PR Regressions (MAM)" + gsn_panel2(wks_npo_pr,reg_npo_pr_mam,(/nrow,ncol/),panres) + delete(reg_npo_pr_mam) + panres@txString = "NPO PR Regressions (JJA)" + gsn_panel2(wks_npo_pr,reg_npo_pr_jja,(/nrow,ncol/),panres) + delete(reg_npo_pr_jja) + panres@txString = "NPO PR Regressions (SON)" + gsn_panel2(wks_npo_pr,reg_npo_pr_son,(/nrow,ncol/),panres) + delete(reg_npo_pr_son) + panres@txString = "NPO PR Regressions (Annual)" + gsn_panel2(wks_npo_pr,reg_npo_pr_ann,(/nrow,ncol/),panres) + delete(reg_npo_pr_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "NPO PR Regressions (Monthly)" + gsn_panel2(wks_npo_pr,reg_npo_pr_mon,(/nrow,ncol/),panres) + delete(reg_npo_pr_mon) + end if + delete(wks_npo_pr) + end if + + panres2 = True + if (nsim.le.5) then + panres2@txFontHeightF = 0.024 + else + panres2@txFontHeightF = 0.016 + end if + panres2@gsnMaximize = True + panres2@gsnPaperOrientation = "portrait" + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres2@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) + end if + + panres2@txString = "PNA (DJF)" + gsn_panel2(wks_pna_ts,xy_pna_djf,lp,panres2) + delete(xy_pna_djf) + panres2@txString = "PNA (MAM)" + gsn_panel2(wks_pna_ts,xy_pna_mam,lp,panres2) + delete(xy_pna_mam) + panres2@txString = "PNA (JJA)" + gsn_panel2(wks_pna_ts,xy_pna_jja,lp,panres2) + delete(xy_pna_jja) + panres2@txString = "PNA (SON)" + gsn_panel2(wks_pna_ts,xy_pna_son,lp,panres2) + delete(xy_pna_son) + panres2@txString = "PNA (Annual)" + gsn_panel2(wks_pna_ts,xy_pna_ann,lp,panres2) + delete(xy_pna_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres2@txString = "PNA (Monthly)" + gsn_panel2(wks_pna_ts,xy_pna_mon,lp,panres2) + delete(xy_pna_mon) + end if + delete(wks_pna_ts) + + panres2@txString = "NPO (DJF)" + gsn_panel2(wks_npo_ts,xy_npo_djf,lp,panres2) + delete(xy_npo_djf) + panres2@txString = "NPO (MAM)" + gsn_panel2(wks_npo_ts,xy_npo_mam,lp,panres2) + delete(xy_npo_mam) + panres2@txString = "NPO (JJA)" + gsn_panel2(wks_npo_ts,xy_npo_jja,lp,panres2) + delete(xy_npo_jja) + panres2@txString = "NPO (SON)" + gsn_panel2(wks_npo_ts,xy_npo_son,lp,panres2) + delete(xy_npo_son) + panres2@txString = "NPO (Annual)" + gsn_panel2(wks_npo_ts,xy_npo_ann,lp,panres2) + delete(xy_npo_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres2@txString = "NPO (Monthly)" + gsn_panel2(wks_npo_ts,xy_npo_mon,lp,panres2) + delete(xy_npo_mon) + end if + delete(wks_npo_ts) + + panres2@txString = "NPI (NDJFM)" + gsn_panel2(wks_npi_ts,xy_npi,lp,panres2) + delete(xy_npi) + delete(wks_npi_ts) +;-------------------------------------------------------------------------------------------------- + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + system("mv "+OUTDIR+"pna.000001.png "+OUTDIR+"pna.djf.png") + system("mv "+OUTDIR+"pna.000002.png "+OUTDIR+"pna.mam.png") + system("mv "+OUTDIR+"pna.000003.png "+OUTDIR+"pna.jja.png") + system("mv "+OUTDIR+"pna.000004.png "+OUTDIR+"pna.son.png") + system("mv "+OUTDIR+"pna.000005.png "+OUTDIR+"pna.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pna.000006.png "+OUTDIR+"pna.mon.png") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"pna.000007.png "+OUTDIR+"pna.tempreg.djf.png") + system("mv "+OUTDIR+"pna.000008.png "+OUTDIR+"pna.tempreg.mam.png") + system("mv "+OUTDIR+"pna.000009.png "+OUTDIR+"pna.tempreg.jja.png") + system("mv "+OUTDIR+"pna.000010.png "+OUTDIR+"pna.tempreg.son.png") + system("mv "+OUTDIR+"pna.000011.png "+OUTDIR+"pna.tempreg.ann.png") + system("mv "+OUTDIR+"pna.000012.png "+OUTDIR+"pna.tempreg.mon.png") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"pna.000006.png "+OUTDIR+"pna.tempreg.djf.png") + system("mv "+OUTDIR+"pna.000007.png "+OUTDIR+"pna.tempreg.mam.png") + system("mv "+OUTDIR+"pna.000008.png "+OUTDIR+"pna.tempreg.jja.png") + system("mv "+OUTDIR+"pna.000009.png "+OUTDIR+"pna.tempreg.son.png") + system("mv "+OUTDIR+"pna.000010.png "+OUTDIR+"pna.tempreg.ann.png") + end if + end if + + if (prreg_frame.eq.0) then + system("mv "+OUTDIR+"pna.prreg.000001.png "+OUTDIR+"pna.prreg.djf.png") + system("mv "+OUTDIR+"pna.prreg.000002.png "+OUTDIR+"pna.prreg.mam.png") + system("mv "+OUTDIR+"pna.prreg.000003.png "+OUTDIR+"pna.prreg.jja.png") + system("mv "+OUTDIR+"pna.prreg.000004.png "+OUTDIR+"pna.prreg.son.png") + system("mv "+OUTDIR+"pna.prreg.000005.png "+OUTDIR+"pna.prreg.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pna.prreg.000006.png "+OUTDIR+"pna.prreg.mon.png") + end if + end if + + system("mv "+OUTDIR+"npo.000001.png "+OUTDIR+"npo.djf.png") + system("mv "+OUTDIR+"npo.000002.png "+OUTDIR+"npo.mam.png") + system("mv "+OUTDIR+"npo.000003.png "+OUTDIR+"npo.jja.png") + system("mv "+OUTDIR+"npo.000004.png "+OUTDIR+"npo.son.png") + system("mv "+OUTDIR+"npo.000005.png "+OUTDIR+"npo.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"npo.000006.png "+OUTDIR+"npo.mon.png") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"npo.000007.png "+OUTDIR+"npo.tempreg.djf.png") + system("mv "+OUTDIR+"npo.000008.png "+OUTDIR+"npo.tempreg.mam.png") + system("mv "+OUTDIR+"npo.000009.png "+OUTDIR+"npo.tempreg.jja.png") + system("mv "+OUTDIR+"npo.000010.png "+OUTDIR+"npo.tempreg.son.png") + system("mv "+OUTDIR+"npo.000011.png "+OUTDIR+"npo.tempreg.ann.png") + system("mv "+OUTDIR+"npo.000012.png "+OUTDIR+"npo.tempreg.mon.png") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"npo.000006.png "+OUTDIR+"npo.tempreg.djf.png") + system("mv "+OUTDIR+"npo.000007.png "+OUTDIR+"npo.tempreg.mam.png") + system("mv "+OUTDIR+"npo.000008.png "+OUTDIR+"npo.tempreg.jja.png") + system("mv "+OUTDIR+"npo.000009.png "+OUTDIR+"npo.tempreg.son.png") + system("mv "+OUTDIR+"npo.000010.png "+OUTDIR+"npo.tempreg.ann.png") + end if + end if + + if (prreg_frame.eq.0) then + system("mv "+OUTDIR+"npo.prreg.000001.png "+OUTDIR+"npo.prreg.djf.png") + system("mv "+OUTDIR+"npo.prreg.000002.png "+OUTDIR+"npo.prreg.mam.png") + system("mv "+OUTDIR+"npo.prreg.000003.png "+OUTDIR+"npo.prreg.jja.png") + system("mv "+OUTDIR+"npo.prreg.000004.png "+OUTDIR+"npo.prreg.son.png") + system("mv "+OUTDIR+"npo.prreg.000005.png "+OUTDIR+"npo.prreg.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"npo.prreg.000006.png "+OUTDIR+"npo.prreg.mon.png") + end if + end if + + system("mv "+OUTDIR+"pna.timeseries.000001.png "+OUTDIR+"pna.timeseries.djf.png") + system("mv "+OUTDIR+"pna.timeseries.000002.png "+OUTDIR+"pna.timeseries.mam.png") + system("mv "+OUTDIR+"pna.timeseries.000003.png "+OUTDIR+"pna.timeseries.jja.png") + system("mv "+OUTDIR+"pna.timeseries.000004.png "+OUTDIR+"pna.timeseries.son.png") + system("mv "+OUTDIR+"pna.timeseries.000005.png "+OUTDIR+"pna.timeseries.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pna.timeseries.000006.png "+OUTDIR+"pna.timeseries.mon.png") + end if + + system("mv "+OUTDIR+"npo.timeseries.000001.png "+OUTDIR+"npo.timeseries.djf.png") + system("mv "+OUTDIR+"npo.timeseries.000002.png "+OUTDIR+"npo.timeseries.mam.png") + system("mv "+OUTDIR+"npo.timeseries.000003.png "+OUTDIR+"npo.timeseries.jja.png") + system("mv "+OUTDIR+"npo.timeseries.000004.png "+OUTDIR+"npo.timeseries.son.png") + system("mv "+OUTDIR+"npo.timeseries.000005.png "+OUTDIR+"npo.timeseries.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"npo.timeseries.000006.png "+OUTDIR+"npo.timeseries.mon.png") + end if + else + system("psplit "+OUTDIR+"pna.ps "+OUTDIR+"psl_pn") + system("mv "+OUTDIR+"psl_pn0001.ps "+OUTDIR+"pna.djf.ps") + system("mv "+OUTDIR+"psl_pn0002.ps "+OUTDIR+"pna.mam.ps") + system("mv "+OUTDIR+"psl_pn0003.ps "+OUTDIR+"pna.jja.ps") + system("mv "+OUTDIR+"psl_pn0004.ps "+OUTDIR+"pna.son.ps") + system("mv "+OUTDIR+"psl_pn0005.ps "+OUTDIR+"pna.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_pn0006.ps "+OUTDIR+"pna.mon.ps") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_pn0007.ps "+OUTDIR+"pna.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_pn0008.ps "+OUTDIR+"pna.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_pn0009.ps "+OUTDIR+"pna.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_pn0010.ps "+OUTDIR+"pna.tempreg.son.ps") + system("mv "+OUTDIR+"psl_pn0011.ps "+OUTDIR+"pna.tempreg.ann.ps") + system("mv "+OUTDIR+"psl_pn0012.ps "+OUTDIR+"pna.tempreg.mon.ps") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_pn0006.ps "+OUTDIR+"pna.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_pn0007.ps "+OUTDIR+"pna.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_pn0008.ps "+OUTDIR+"pna.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_pn0009.ps "+OUTDIR+"pna.tempreg.son.ps") + system("mv "+OUTDIR+"psl_pn0010.ps "+OUTDIR+"pna.tempreg.ann.ps") + end if + end if + + if (prreg_frame.eq.0) then + system("psplit "+OUTDIR+"pna.prreg.ps "+OUTDIR+"pr_nn") + system("mv "+OUTDIR+"pr_nn0001.ps "+OUTDIR+"pna.prreg.djf.ps") + system("mv "+OUTDIR+"pr_nn0002.ps "+OUTDIR+"pna.prreg.mam.ps") + system("mv "+OUTDIR+"pr_nn0003.ps "+OUTDIR+"pna.prreg.jja.ps") + system("mv "+OUTDIR+"pr_nn0004.ps "+OUTDIR+"pna.prreg.son.ps") + system("mv "+OUTDIR+"pr_nn0005.ps "+OUTDIR+"pna.prreg.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pr_nn0006.ps "+OUTDIR+"pna.prreg.mon.ps") + end if + end if + + system("psplit "+OUTDIR+"npo.ps "+OUTDIR+"psl_pn") + system("mv "+OUTDIR+"psl_pn0001.ps "+OUTDIR+"npo.djf.ps") + system("mv "+OUTDIR+"psl_pn0002.ps "+OUTDIR+"npo.mam.ps") + system("mv "+OUTDIR+"psl_pn0003.ps "+OUTDIR+"npo.jja.ps") + system("mv "+OUTDIR+"psl_pn0004.ps "+OUTDIR+"npo.son.ps") + system("mv "+OUTDIR+"psl_pn0005.ps "+OUTDIR+"npo.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_pn0006.ps "+OUTDIR+"npo.mon.ps") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_pn0007.ps "+OUTDIR+"npo.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_pn0008.ps "+OUTDIR+"npo.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_pn0009.ps "+OUTDIR+"npo.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_pn0010.ps "+OUTDIR+"npo.tempreg.son.ps") + system("mv "+OUTDIR+"psl_pn0011.ps "+OUTDIR+"npo.tempreg.ann.ps") + system("mv "+OUTDIR+"psl_pn0012.ps "+OUTDIR+"npo.tempreg.mon.ps") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_pn0006.ps "+OUTDIR+"npo.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_pn0007.ps "+OUTDIR+"npo.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_pn0008.ps "+OUTDIR+"npo.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_pn0009.ps "+OUTDIR+"npo.tempreg.son.ps") + system("mv "+OUTDIR+"psl_pn0010.ps "+OUTDIR+"npo.tempreg.ann.ps") + end if + end if + if (prreg_frame.eq.0) then + system("psplit "+OUTDIR+"npo.prreg.ps "+OUTDIR+"pr_nn") + system("mv "+OUTDIR+"pr_nn0001.ps "+OUTDIR+"npo.prreg.djf.ps") + system("mv "+OUTDIR+"pr_nn0002.ps "+OUTDIR+"npo.prreg.mam.ps") + system("mv "+OUTDIR+"pr_nn0003.ps "+OUTDIR+"npo.prreg.jja.ps") + system("mv "+OUTDIR+"pr_nn0004.ps "+OUTDIR+"npo.prreg.son.ps") + system("mv "+OUTDIR+"pr_nn0005.ps "+OUTDIR+"npo.prreg.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pr_nn0006.ps "+OUTDIR+"npo.prreg.mon.ps") + end if + system("rm "+OUTDIR+"pna.prreg.ps "+OUTDIR+"npo.prreg.ps") + end if + + system("psplit "+OUTDIR+"pna.timeseries.ps "+OUTDIR+"psl_pn") + system("mv "+OUTDIR+"psl_pn0001.ps "+OUTDIR+"pna.timeseries.djf.ps") + system("mv "+OUTDIR+"psl_pn0002.ps "+OUTDIR+"pna.timeseries.mam.ps") + system("mv "+OUTDIR+"psl_pn0003.ps "+OUTDIR+"pna.timeseries.jja.ps") + system("mv "+OUTDIR+"psl_pn0004.ps "+OUTDIR+"pna.timeseries.son.ps") + system("mv "+OUTDIR+"psl_pn0005.ps "+OUTDIR+"pna.timeseries.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_pn0006.ps "+OUTDIR+"pna.timeseries.mon.ps") + end if + + system("psplit "+OUTDIR+"npo.timeseries.ps "+OUTDIR+"psl_pn") + system("mv "+OUTDIR+"psl_pn0001.ps "+OUTDIR+"npo.timeseries.djf.ps") + system("mv "+OUTDIR+"psl_pn0002.ps "+OUTDIR+"npo.timeseries.mam.ps") + system("mv "+OUTDIR+"psl_pn0003.ps "+OUTDIR+"npo.timeseries.jja.ps") + system("mv "+OUTDIR+"psl_pn0004.ps "+OUTDIR+"npo.timeseries.son.ps") + system("mv "+OUTDIR+"psl_pn0005.ps "+OUTDIR+"npo.timeseries.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_pn0006.ps "+OUTDIR+"npo.timeseries.mon.ps") + end if + system("rm "+OUTDIR+"npo.timeseries.ps "+OUTDIR+"pna.timeseries.ps "+OUTDIR+"npo.ps "+OUTDIR+"pna.ps") + end if + print("Finished: psl.pna_npo.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/psl.sam_psa.ncl b/lib/externals/CVDP/ncl_scripts/psl.sam_psa.ncl new file mode 100644 index 000000000..784a6c9cc --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/psl.sam_psa.ncl @@ -0,0 +1,2383 @@ +; Calculates SAM, PSA1 and PSA2 (patterns and PC timeseries), as well as +; regressions of those PC timeseries onto ts, tas, and pr. +; +; Variables used: psl, ts, tas, and pr +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: psl.sam_psa.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COMPUTE_MODES_MON = getenv("COMPUTE_MODES_MON") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_psl") + na = asciiread("namelist_byvar/namelist_psl",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) + +;---------SST Regressions coding------------------------------------------------- + nsim_ts = numAsciiRow("namelist_byvar/namelist_ts") + na_ts = asciiread("namelist_byvar/namelist_ts",(/nsim_ts/),"string") + names_ts = new(nsim_ts,"string") + paths_ts = new(nsim_ts,"string") + syear_ts = new(nsim_ts,"integer",-999) + eyear_ts = new(nsim_ts,"integer",-999) + + do gg = 0,nsim_ts-1 + names_ts(gg) = str_strip(str_get_field(na_ts(gg),1,delim)) + paths_ts(gg) = str_strip(str_get_field(na_ts(gg),2,delim)) + syear_ts(gg) = stringtointeger(str_strip(str_get_field(na_ts(gg),3,delim))) + eyear_ts(gg) = stringtointeger(str_strip(str_get_field(na_ts(gg),4,delim))) + end do + delete(na_ts) + nyr_ts = eyear_ts-syear_ts+1 +;---------TAS Regressions coding------------------------------------------------- + nsim_tas = numAsciiRow("namelist_byvar/namelist_trefht") + na_tas = asciiread("namelist_byvar/namelist_trefht",(/nsim_tas/),"string") + names_tas = new(nsim_tas,"string") + paths_tas = new(nsim_tas,"string") + syear_tas = new(nsim_tas,"integer",-999) + eyear_tas = new(nsim_tas,"integer",-999) + + do gg = 0,nsim_tas-1 + names_tas(gg) = str_strip(str_get_field(na_tas(gg),1,delim)) + paths_tas(gg) = str_strip(str_get_field(na_tas(gg),2,delim)) + syear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),3,delim))) + eyear_tas(gg) = stringtointeger(str_strip(str_get_field(na_tas(gg),4,delim))) + end do + delete(na_tas) + nyr_tas = eyear_tas-syear_tas+1 +;---------PR Regressions coding------------------------------------------------- + nsim_pr = numAsciiRow("namelist_byvar/namelist_prect") + na_pr = asciiread("namelist_byvar/namelist_prect",(/nsim_pr/),"string") + names_pr = new(nsim_pr,"string") + paths_pr = new(nsim_pr,"string") + syear_pr = new(nsim_pr,"integer",-999) + eyear_pr = new(nsim_pr,"integer",-999) + + do gg = 0,nsim_pr-1 + names_pr(gg) = str_strip(str_get_field(na_pr(gg),1,delim)) + paths_pr(gg) = str_strip(str_get_field(na_pr(gg),2,delim)) + syear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),3,delim))) + eyear_pr(gg) = stringtointeger(str_strip(str_get_field(na_pr(gg),4,delim))) + end do + delete(na_pr) + nyr_pr = eyear_pr-syear_pr+1 +;------------------------------------------------------------------------------------------------- + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + + wks_sam = gsn_open_wks(wks_type,getenv("OUTDIR")+"sam") + wks_sam_pr = gsn_open_wks(wks_type,getenv("OUTDIR")+"sam.prreg") + wks_sam_ts = gsn_open_wks(wks_type,getenv("OUTDIR")+"sam.timeseries") + + wks_psa1 = gsn_open_wks(wks_type,getenv("OUTDIR")+"psa1") + wks_psa1_pr = gsn_open_wks(wks_type,getenv("OUTDIR")+"psa1.prreg") + wks_psa1_ts = gsn_open_wks(wks_type,getenv("OUTDIR")+"psa1.timeseries") + + wks_psa2 = gsn_open_wks(wks_type,getenv("OUTDIR")+"psa2") + wks_psa2_pr = gsn_open_wks(wks_type,getenv("OUTDIR")+"psa2.prreg") + wks_psa2_ts = gsn_open_wks(wks_type,getenv("OUTDIR")+"psa2.timeseries") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_sam,"ncl_default") + gsn_define_colormap(wks_sam_ts,"ncl_default") + gsn_define_colormap(wks_psa1,"ncl_default") + gsn_define_colormap(wks_psa1_ts,"ncl_default") + gsn_define_colormap(wks_psa2,"ncl_default") + gsn_define_colormap(wks_psa2_ts,"ncl_default") + gsn_define_colormap(wks_sam_pr,"MPL_BrBG") + gsn_define_colormap(wks_psa1_pr,"MPL_BrBG") + gsn_define_colormap(wks_psa2_pr,"MPL_BrBG") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_sam,"BlueDarkRed18") + gsn_define_colormap(wks_sam_ts,"ncl_default") + gsn_define_colormap(wks_psa1,"BlueDarkRed18") + gsn_define_colormap(wks_psa1_ts,"ncl_default") + gsn_define_colormap(wks_psa2,"BlueDarkRed18") + gsn_define_colormap(wks_psa2_ts,"ncl_default") + gsn_define_colormap(wks_sam_pr,"MPL_BrBG") + gsn_define_colormap(wks_psa1_pr,"MPL_BrBG") + gsn_define_colormap(wks_psa2_pr,"MPL_BrBG") + end if + + map_sam_djf = new(nsim,"graphic") + map_sam_mam = new(nsim,"graphic") + map_sam_jja = new(nsim,"graphic") + map_sam_son = new(nsim,"graphic") + map_sam_ann = new(nsim,"graphic") + map_sam_mon = new(nsim,"graphic") + xy_sam_djf = new(nsim,"graphic") + xy_sam_mam = new(nsim,"graphic") + xy_sam_jja = new(nsim,"graphic") + xy_sam_son = new(nsim,"graphic") + xy_sam_ann = new(nsim,"graphic") + xy_sam_mon = new(nsim,"graphic") + reg_sam_djf = new(nsim,"graphic") + reg_sam_mam = new(nsim,"graphic") + reg_sam_jja = new(nsim,"graphic") + reg_sam_son = new(nsim,"graphic") + reg_sam_ann = new(nsim,"graphic") + reg_sam_mon = new(nsim,"graphic") + reg_sam_pr_djf = new(nsim,"graphic") + reg_sam_pr_mam = new(nsim,"graphic") + reg_sam_pr_jja = new(nsim,"graphic") + reg_sam_pr_son = new(nsim,"graphic") + reg_sam_pr_ann = new(nsim,"graphic") + reg_sam_pr_mon = new(nsim,"graphic") + + map_psa1_djf = new(nsim,"graphic") + map_psa1_mam = new(nsim,"graphic") + map_psa1_jja = new(nsim,"graphic") + map_psa1_son = new(nsim,"graphic") + map_psa1_ann = new(nsim,"graphic") + map_psa1_mon = new(nsim,"graphic") + xy_psa1_djf = new(nsim,"graphic") + xy_psa1_mam = new(nsim,"graphic") + xy_psa1_jja = new(nsim,"graphic") + xy_psa1_son = new(nsim,"graphic") + xy_psa1_ann = new(nsim,"graphic") + xy_psa1_mon = new(nsim,"graphic") + reg_psa1_djf = new(nsim,"graphic") + reg_psa1_mam = new(nsim,"graphic") + reg_psa1_jja = new(nsim,"graphic") + reg_psa1_son = new(nsim,"graphic") + reg_psa1_ann = new(nsim,"graphic") + reg_psa1_mon = new(nsim,"graphic") + reg_psa1_pr_djf = new(nsim,"graphic") + reg_psa1_pr_mam = new(nsim,"graphic") + reg_psa1_pr_jja = new(nsim,"graphic") + reg_psa1_pr_son = new(nsim,"graphic") + reg_psa1_pr_ann = new(nsim,"graphic") + reg_psa1_pr_mon = new(nsim,"graphic") + + map_psa2_djf = new(nsim,"graphic") + map_psa2_mam = new(nsim,"graphic") + map_psa2_jja = new(nsim,"graphic") + map_psa2_son = new(nsim,"graphic") + map_psa2_ann = new(nsim,"graphic") + map_psa2_mon = new(nsim,"graphic") + xy_psa2_djf = new(nsim,"graphic") + xy_psa2_mam = new(nsim,"graphic") + xy_psa2_jja = new(nsim,"graphic") + xy_psa2_son = new(nsim,"graphic") + xy_psa2_ann = new(nsim,"graphic") + xy_psa2_mon = new(nsim,"graphic") + reg_psa2_djf = new(nsim,"graphic") + reg_psa2_mam = new(nsim,"graphic") + reg_psa2_jja = new(nsim,"graphic") + reg_psa2_son = new(nsim,"graphic") + reg_psa2_ann = new(nsim,"graphic") + reg_psa2_mon = new(nsim,"graphic") + reg_psa2_pr_djf = new(nsim,"graphic") + reg_psa2_pr_mam = new(nsim,"graphic") + reg_psa2_pr_jja = new(nsim,"graphic") + reg_psa2_pr_son = new(nsim,"graphic") + reg_psa2_pr_ann = new(nsim,"graphic") + reg_psa2_pr_mon = new(nsim,"graphic") + + sstreg_frame = 1 ; sstreg_frame = flag to create regressions .ps/.png files. Created/used instead of sstreg_plot_flag + ; so that if sst regressions are not created for the last simulation listed that .ps/png files are created + tasreg_frame = 1 + prreg_frame = 1 + + do ee = 0,nsim-1 +; print(paths(ee)+" "+syear(ee)+" "+eyear(ee)) + arr = data_read_in(paths(ee),"PSL",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(arr,"is_all_missing")) then + delete(arr) + continue + end if + + if (OPT_CLIMO.eq."Full") then + arr = rmMonAnnCycTLL(arr) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = arr + delete(temp_arr&time) + temp_arr&time = cd_calendar(arr&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + arr = calcMonAnomTLL(arr,climo) + delete(climo) + end if + + arrT = runave_n_Wrap(arr,3,0,0) ; form DJF averages + arrT(0,:,:) = (/ dim_avg_n(arr(:1,:,:),0) /) + arr_djf = arrT(0::12,:,:) + arr_mam = arrT(3::12,:,:) + arr_jja = arrT(6::12,:,:) ; form JJA averages + arr_son = arrT(9::12,:,:) + delete(arrT) + + arrV = runave_n_Wrap(arr,12,0,0) + arr_ann = arrV(5::12,:,:) + delete(arrV) +; +; arr_djf = (/ dtrend_msg_n(ispan(0,dimsizes(arr_djf&time)-1,1),arr_djf,True,False,0) /) +; arr_mam = (/ dtrend_msg_n(ispan(0,dimsizes(arr_mam&time)-1,1),arr_mam,True,False,0) /) +; arr_jja = (/ dtrend_msg_n(ispan(0,dimsizes(arr_jja&time)-1,1),arr_jja,True,False,0) /) +; arr_son = (/ dtrend_msg_n(ispan(0,dimsizes(arr_son&time)-1,1),arr_son,True,False,0) /) +; +; arr_ann = (/ dtrend_msg_n(ispan(0,dimsizes(arr_ann&time)-1,1),arr_ann,True,False,0) /) +; +; arr_ndjfm = (/ dtrend_msg_n(ispan(0,dimsizes(arr_ndjfm&time)-1,1),arr_ndjfm,True,False,0) /) +; +; arr = (/ dtrend_msg_n(ispan(0,dimsizes(arr&time)-1,1),arr,True,False,0) /) +;---------SST Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_ts(ee),eyear(ee),eyear_ts(ee)/)))) then + sstreg_plot_flag = 1 + else + if (syear(ee).eq.syear_ts(ee)) then ; check that the start and end years match for ts, trefht, and psl + if (eyear(ee).eq.eyear_ts(ee)) then + sstreg_plot_flag = 0 + else + sstreg_plot_flag = 1 + end if + else + sstreg_plot_flag = 1 + end if + end if + + if (sstreg_plot_flag.eq.0) then + ; print("Data to be read in: "+paths_ts(ee)+" from "+syear_ts(ee)+":"+eyear_ts(ee)) + sst = data_read_in(paths_ts(ee),"TS",syear_ts(ee),eyear_ts(ee)) + if (isatt(sst,"is_all_missing")) then + sstreg_plot_flag = 1 + delete(sst) + end if + + if (sstreg_plot_flag.eq.0) then ; only continue if both PSL/TS fields are present + sst = where(sst.le.-1.8,-1.8,sst) + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,sst&lat,sst&lon) + sst = mask(sst,conform(sst,lsm,(/1,2/)).ge.1,False) + delete(lsm) + + if (OPT_CLIMO.eq."Full") then + sst = rmMonAnnCycTLL(sst) + else + check_custom_climo(names_ts(ee),syear_ts(ee),eyear_ts(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sst + delete(temp_arr&time) + temp_arr&time = cd_calendar(sst&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sst = calcMonAnomTLL(sst,climo) + delete(climo) + end if +; sst = (/ dtrend_msg_n(ispan(0,dimsizes(sst&time)-1,1),sst,False,False,0) /) + + sstT = runave_n_Wrap(sst,3,0,0) ; form DJF averages + sstT(0,:,:) = (/ dim_avg_n(sst(:1,:,:),0) /) + sst_djf = sstT(0::12,:,:) + sst_mam = sstT(3::12,:,:) + sst_jja = sstT(6::12,:,:) ; form JJA averages + sst_son = sstT(9::12,:,:) + delete(sstT) + + sstV = runave_n_Wrap(sst,12,0,0) + sst_ann = sstV(5::12,:,:) + delete(sstV) + end if + end if +;---------TAS Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_tas(ee),eyear(ee),eyear_tas(ee)/)))) then + tasreg_plot_flag = 1 + else + if (syear(ee).eq.syear_tas(ee)) then ; check that the start and end years match for ts, tas, and psl + if (eyear(ee).eq.eyear_tas(ee)) then + tasreg_plot_flag = 0 + else + tasreg_plot_flag = 1 + end if + else + tasreg_plot_flag = 1 + end if + if (sstreg_plot_flag.eq.1) then ; if the ts dataset is missing but the tas is not, do not + tasreg_plot_flag = 1 ; run through the tas calculations as both currently required + end if + end if + + if (tasreg_plot_flag.eq.0) then + tas = data_read_in(paths_tas(ee),"TREFHT",syear_tas(ee),eyear_tas(ee)) + if (isatt(tas,"is_all_missing")) then + tasreg_plot_flag = 1 + delete(tas) + end if + + if (tasreg_plot_flag.eq.0) then ; only continue if both PSL/TS fields are present + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") + basemap = d->LSMASK + lsm = landsea_mask(basemap,tas&lat,tas&lon) + tas = mask(tas,conform(tas,lsm,(/1,2/)).eq.0,False) + delete(lsm) + + if (OPT_CLIMO.eq."Full") then + tas = rmMonAnnCycTLL(tas) + else + check_custom_climo(names_tas(ee),syear_tas(ee),eyear_tas(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = tas + delete(temp_arr&time) + temp_arr&time = cd_calendar(tas&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + tas = calcMonAnomTLL(tas,climo) + delete(climo) + end if +; tas = (/ dtrend_msg_n(ispan(0,dimsizes(tas&time)-1,1),tas,False,False,0) /) + + tasT = runave_n_Wrap(tas,3,0,0) ; form DJF averages + tasT(0,:,:) = (/ dim_avg_n(tas(:1,:,:),0) /) + tas_djf = tasT(0::12,:,:) + tas_mam = tasT(3::12,:,:) + tas_jja = tasT(6::12,:,:) ; form JJA averages + tas_son = tasT(9::12,:,:) + delete(tasT) + + tasV = runave_n_Wrap(tas,12,0,0) + tas_ann = tasV(5::12,:,:) + delete([/tasV/]) + end if + end if +;---------PR Regressions coding------------------------------------------------- + if (any(ismissing((/syear(ee),syear_pr(ee),eyear(ee),eyear_pr(ee)/)))) then + prreg_plot_flag = 1 + else + if (syear(ee).eq.syear_pr(ee)) then ; check that the start and end years match for ts, tas, and psl + if (eyear(ee).eq.eyear_pr(ee)) then + prreg_plot_flag = 0 + else + prreg_plot_flag = 1 + end if + else + prreg_plot_flag = 1 + end if + end if + + if (prreg_plot_flag.eq.0) then + pr = data_read_in(paths_pr(ee),"PRECT",syear_pr(ee),eyear_pr(ee)) + if (isatt(pr,"is_all_missing")) then + prreg_plot_flag = 1 + delete(pr) + end if + + if (prreg_plot_flag.eq.0) then ; only continue if both PSL/TS fields are present + if (OPT_CLIMO.eq."Full") then + pr = rmMonAnnCycTLL(pr) + else + check_custom_climo(names_pr(ee),syear_pr(ee),eyear_pr(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = pr + delete(temp_arr&time) + temp_arr&time = cd_calendar(pr&time,1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + pr = calcMonAnomTLL(pr,climo) + delete(climo) + end if +; pr = (/ dtrend_msg_n(ispan(0,dimsizes(pr&time)-1,1),pr,False,False,0) /) + + prT = runave_n_Wrap(pr,3,0,0) ; form DJF averages + prT(0,:,:) = (/ dim_avg_n(pr(:1,:,:),0) /) + pr_djf = prT(0::12,:,:) + pr_mam = prT(3::12,:,:) + pr_jja = prT(6::12,:,:) ; form JJA averages + pr_son = prT(9::12,:,:) + delete(prT) + + prV = runave_n_Wrap(pr,12,0,0) + pr_ann = prV(5::12,:,:) + delete([/prV/]) + end if + end if +;------------------------------------------------------------------ + arr_djf_CW = SqrtCosWeight(arr_djf) + arr_mam_CW = SqrtCosWeight(arr_mam) + arr_jja_CW = SqrtCosWeight(arr_jja) + arr_son_CW = SqrtCosWeight(arr_son) + arr_ann_CW = SqrtCosWeight(arr_ann) + if (COMPUTE_MODES_MON.eq."True") then + arr_mon_CW = SqrtCosWeight(arr) + else + if (isvar("arr")) then + delete(arr) + end if + if (isvar("sst")) then + delete(sst) + end if + if (isvar("tas")) then + delete(tas) + end if + if (isvar("pr")) then + delete(pr) + end if + end if +;----------SAM/PSA1/PSA2 calculations---------------------------------------------------------------------- + evecv = eofunc(arr_djf_CW({lat|:-20},lon|:,time|:),4,75) + pcts = eofunc_ts(arr_djf_CW({lat|:-20},lon|:,time|:),evecv,False) + sam_pc_djf = dim_standardize(pcts(0,:),0) + psa1_pc_djf = dim_standardize(pcts(1,:),0) + psa2_pc_djf = dim_standardize(pcts(2,:),0) + sam_djf = arr_djf(0,:,:) + sam_djf = (/ regCoef(sam_pc_djf,arr_djf(lat|:,lon|:,time|:)) /) + psa1_djf = arr_djf(0,:,:) + psa1_djf = (/ regCoef(psa1_pc_djf,arr_djf(lat|:,lon|:,time|:)) /) + psa2_djf = arr_djf(0,:,:) + psa2_djf = (/ regCoef(psa2_pc_djf,arr_djf(lat|:,lon|:,time|:)) /) + + if (sstreg_plot_flag.eq.0) then + sam_sst_djf = sst_djf(0,:,:) + sam_sst_djf = (/ regCoef(sam_pc_djf,sst_djf(lat|:,lon|:,time|:)) /) + psa1_sst_djf = sst_djf(0,:,:) + psa1_sst_djf = (/ regCoef(psa1_pc_djf,sst_djf(lat|:,lon|:,time|:)) /) + psa2_sst_djf = sst_djf(0,:,:) + psa2_sst_djf = (/ regCoef(psa2_pc_djf,sst_djf(lat|:,lon|:,time|:)) /) + delete(sst_djf) + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_djf = tas_djf(0,:,:) + sam_tas_djf = (/ regCoef(sam_pc_djf,tas_djf(lat|:,lon|:,time|:)) /) + psa1_tas_djf = tas_djf(0,:,:) + psa1_tas_djf = (/ regCoef(psa1_pc_djf,tas_djf(lat|:,lon|:,time|:)) /) + psa2_tas_djf = tas_djf(0,:,:) + psa2_tas_djf = (/ regCoef(psa2_pc_djf,tas_djf(lat|:,lon|:,time|:)) /) + delete(tas_djf) + end if + if (prreg_plot_flag.eq.0) then + sam_pr_djf = pr_djf(0,:,:) + sam_pr_djf = (/ regCoef(sam_pc_djf,pr_djf(lat|:,lon|:,time|:)) /) + psa1_pr_djf = pr_djf(0,:,:) + psa1_pr_djf = (/ regCoef(psa1_pc_djf,pr_djf(lat|:,lon|:,time|:)) /) + psa2_pr_djf = pr_djf(0,:,:) + psa2_pr_djf = (/ regCoef(psa2_pc_djf,pr_djf(lat|:,lon|:,time|:)) /) + delete(pr_djf) + end if + + if (.not.ismissing(sam_djf({-85},{5}))) then + if (sam_djf({-85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + sam_djf = sam_djf*-1. + sam_pc_djf = sam_pc_djf*-1. + if (sstreg_plot_flag.eq.0) then + sam_sst_djf = sam_sst_djf*-1. + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_djf = sam_tas_djf*-1. + end if + if (prreg_plot_flag.eq.0) then + sam_pr_djf = sam_pr_djf*-1. + end if + end if + end if + if (.not.ismissing(psa1_djf({-62},{210}))) then + if (psa1_djf({-62},{210}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa1_djf = psa1_djf*-1. + psa1_pc_djf = psa1_pc_djf*-1. + if (sstreg_plot_flag.eq.0) then + psa1_sst_djf = psa1_sst_djf*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa1_tas_djf = psa1_tas_djf*-1. + end if + if (prreg_plot_flag.eq.0) then + psa1_pr_djf = psa1_pr_djf*-1. + end if + end if + end if + if (.not.ismissing(psa2_djf({-60},{280}))) then + if (psa2_djf({-60},{280}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa2_djf = psa2_djf*-1. + psa2_pc_djf = psa2_pc_djf*-1. + if (sstreg_plot_flag.eq.0) then + psa2_sst_djf = psa2_sst_djf*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa2_tas_djf = psa2_tas_djf*-1. + end if + if (prreg_plot_flag.eq.0) then + psa2_pr_djf = psa2_pr_djf*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(sam_pc_djf),False) + if (sig_pcv(0)) then ; if True then significant + sam_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + sam_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + psa1_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + psa1_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + if (sig_pcv(2)) then ; if True then significant + psa2_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%*" + else + psa2_djf@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%" + end if + delete(sig_pcv) + sam_pc_djf!0 = "TIME" + sam_pc_djf&TIME = ispan(syear(ee),eyear(ee),1) + sam_pc_djf&TIME@units = "YYYY" + sam_pc_djf&TIME@long_name = "time" + + copy_VarCoords(sam_pc_djf,psa1_pc_djf) + copy_VarCoords(sam_pc_djf,psa2_pc_djf) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_mam_CW({lat|:-20},lon|:,time|:),4,75) + pcts = eofunc_ts(arr_mam_CW({lat|:-20},lon|:,time|:),evecv,False) + sam_pc_mam = dim_standardize(pcts(0,:),0) + psa1_pc_mam = dim_standardize(pcts(1,:),0) + psa2_pc_mam = dim_standardize(pcts(2,:),0) + sam_mam = arr_mam(0,:,:) + sam_mam = (/ regCoef(sam_pc_mam,arr_mam(lat|:,lon|:,time|:)) /) + psa1_mam = arr_mam(0,:,:) + psa1_mam = (/ regCoef(psa1_pc_mam,arr_mam(lat|:,lon|:,time|:)) /) + psa2_mam = arr_mam(0,:,:) + psa2_mam = (/ regCoef(psa2_pc_mam,arr_mam(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + sam_sst_mam = sst_mam(0,:,:) + sam_sst_mam = (/ regCoef(sam_pc_mam,sst_mam(lat|:,lon|:,time|:)) /) + psa1_sst_mam = sst_mam(0,:,:) + psa1_sst_mam = (/ regCoef(psa1_pc_mam,sst_mam(lat|:,lon|:,time|:)) /) + psa2_sst_mam = sst_mam(0,:,:) + psa2_sst_mam = (/ regCoef(psa2_pc_mam,sst_mam(lat|:,lon|:,time|:)) /) + delete(sst_mam) + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_mam = tas_mam(0,:,:) + sam_tas_mam = (/ regCoef(sam_pc_mam,tas_mam(lat|:,lon|:,time|:)) /) + psa1_tas_mam = tas_mam(0,:,:) + psa1_tas_mam = (/ regCoef(psa1_pc_mam,tas_mam(lat|:,lon|:,time|:)) /) + psa2_tas_mam = tas_mam(0,:,:) + psa2_tas_mam = (/ regCoef(psa2_pc_mam,tas_mam(lat|:,lon|:,time|:)) /) + delete(tas_mam) + end if + if (prreg_plot_flag.eq.0) then + sam_pr_mam = pr_mam(0,:,:) + sam_pr_mam = (/ regCoef(sam_pc_mam,pr_mam(lat|:,lon|:,time|:)) /) + psa1_pr_mam = pr_mam(0,:,:) + psa1_pr_mam = (/ regCoef(psa1_pc_mam,pr_mam(lat|:,lon|:,time|:)) /) + psa2_pr_mam = pr_mam(0,:,:) + psa2_pr_mam = (/ regCoef(psa2_pc_mam,pr_mam(lat|:,lon|:,time|:)) /) + delete(pr_mam) + end if + + if (.not.ismissing(sam_mam({-85},{5}))) then + if (sam_mam({-85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + sam_mam = sam_mam*-1. + sam_pc_mam = sam_pc_mam*-1. + if (sstreg_plot_flag.eq.0) then + sam_sst_mam = sam_sst_mam*-1. + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_mam = sam_tas_mam*-1. + end if + if (prreg_plot_flag.eq.0) then + sam_pr_mam = sam_pr_mam*-1. + end if + end if + end if + if (.not.ismissing(psa1_mam({-62},{210}))) then + if (psa1_mam({-62},{210}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa1_mam = psa1_mam*-1. + psa1_pc_mam = psa1_pc_mam*-1. + if (sstreg_plot_flag.eq.0) then + psa1_sst_mam = psa1_sst_mam*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa1_tas_mam = psa1_tas_mam*-1. + end if + if (prreg_plot_flag.eq.0) then + psa1_pr_mam = psa1_pr_mam*-1. + end if + end if + end if + if (.not.ismissing(psa2_mam({-60},{280}))) then + if (psa2_mam({-60},{280}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa2_mam = psa2_mam*-1. + psa2_pc_mam = psa2_pc_mam*-1. + if (sstreg_plot_flag.eq.0) then + psa2_sst_mam = psa2_sst_mam*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa2_tas_mam = psa2_tas_mam*-1. + end if + if (prreg_plot_flag.eq.0) then + psa2_pr_mam = psa2_pr_mam*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(sam_pc_mam),False) + if (sig_pcv(0)) then ; if True then significant + sam_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + sam_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + psa1_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + psa1_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + if (sig_pcv(2)) then ; if True then significant + psa2_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%*" + else + psa2_mam@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(sam_pc_djf,sam_pc_mam) + copy_VarCoords(sam_pc_djf,psa1_pc_mam) + copy_VarCoords(sam_pc_djf,psa2_pc_mam) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_jja_CW({lat|:-20},lon|:,time|:),4,75) + pcts = eofunc_ts(arr_jja_CW({lat|:-20},lon|:,time|:),evecv,False) + sam_pc_jja = dim_standardize(pcts(0,:),0) + psa1_pc_jja = dim_standardize(pcts(1,:),0) + psa2_pc_jja = dim_standardize(pcts(2,:),0) + sam_jja = arr_jja(0,:,:) + sam_jja = (/ regCoef(sam_pc_jja,arr_jja(lat|:,lon|:,time|:)) /) + psa1_jja = arr_jja(0,:,:) + psa1_jja = (/ regCoef(psa1_pc_jja,arr_jja(lat|:,lon|:,time|:)) /) + psa2_jja = arr_jja(0,:,:) + psa2_jja = (/ regCoef(psa2_pc_jja,arr_jja(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + sam_sst_jja = sst_jja(0,:,:) + sam_sst_jja = (/ regCoef(sam_pc_jja,sst_jja(lat|:,lon|:,time|:)) /) + psa1_sst_jja = sst_jja(0,:,:) + psa1_sst_jja = (/ regCoef(psa1_pc_jja,sst_jja(lat|:,lon|:,time|:)) /) + psa2_sst_jja = sst_jja(0,:,:) + psa2_sst_jja = (/ regCoef(psa2_pc_jja,sst_jja(lat|:,lon|:,time|:)) /) + delete(sst_jja) + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_jja = tas_jja(0,:,:) + sam_tas_jja = (/ regCoef(sam_pc_jja,tas_jja(lat|:,lon|:,time|:)) /) + psa1_tas_jja = tas_jja(0,:,:) + psa1_tas_jja = (/ regCoef(psa1_pc_jja,tas_jja(lat|:,lon|:,time|:)) /) + psa2_tas_jja = tas_jja(0,:,:) + psa2_tas_jja = (/ regCoef(psa2_pc_jja,tas_jja(lat|:,lon|:,time|:)) /) + delete(tas_jja) + end if + if (prreg_plot_flag.eq.0) then + sam_pr_jja = pr_jja(0,:,:) + sam_pr_jja = (/ regCoef(sam_pc_jja,pr_jja(lat|:,lon|:,time|:)) /) + psa1_pr_jja = pr_jja(0,:,:) + psa1_pr_jja = (/ regCoef(psa1_pc_jja,pr_jja(lat|:,lon|:,time|:)) /) + psa2_pr_jja = pr_jja(0,:,:) + psa2_pr_jja = (/ regCoef(psa2_pc_jja,pr_jja(lat|:,lon|:,time|:)) /) + delete(pr_jja) + end if + + if (.not.ismissing(sam_jja({-85},{5}))) then + if (sam_jja({-85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + sam_jja = sam_jja*-1. + sam_pc_jja = sam_pc_jja*-1. + if (sstreg_plot_flag.eq.0) then + sam_sst_jja = sam_sst_jja*-1. + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_jja = sam_tas_jja*-1. + end if + if (prreg_plot_flag.eq.0) then + sam_pr_jja = sam_pr_jja*-1. + end if + end if + end if + if (.not.ismissing(psa1_jja({-62},{210}))) then + if (psa1_jja({-62},{210}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa1_jja = psa1_jja*-1. + psa1_pc_jja = psa1_pc_jja*-1. + if (sstreg_plot_flag.eq.0) then + psa1_sst_jja = psa1_sst_jja*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa1_tas_jja = psa1_tas_jja*-1. + end if + if (prreg_plot_flag.eq.0) then + psa1_pr_jja = psa1_pr_jja*-1. + end if + end if + end if + if (.not.ismissing(psa2_jja({-60},{280}))) then + if (psa2_jja({-60},{280}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa2_jja = psa2_jja*-1. + psa2_pc_jja = psa2_pc_jja*-1. + if (sstreg_plot_flag.eq.0) then + psa2_sst_jja = psa2_sst_jja*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa2_tas_jja = psa2_tas_jja*-1. + end if + if (prreg_plot_flag.eq.0) then + psa2_pr_jja = psa2_pr_jja*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(sam_pc_jja),False) + if (sig_pcv(0)) then ; if True then significant + sam_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + sam_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + psa1_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + psa1_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + if (sig_pcv(2)) then ; if True then significant + psa2_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%*" + else + psa2_jja@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(sam_pc_djf,sam_pc_jja) + copy_VarCoords(sam_pc_djf,psa1_pc_jja) + copy_VarCoords(sam_pc_djf,psa2_pc_jja) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_son_CW({lat|:-20},lon|:,time|:),4,75) + pcts = eofunc_ts(arr_son_CW({lat|:-20},lon|:,time|:),evecv,False) + sam_pc_son = dim_standardize(pcts(0,:),0) + psa1_pc_son = dim_standardize(pcts(1,:),0) + psa2_pc_son = dim_standardize(pcts(2,:),0) + sam_son = arr_son(0,:,:) + sam_son = (/ regCoef(sam_pc_son,arr_son(lat|:,lon|:,time|:)) /) + psa1_son = arr_son(0,:,:) + psa1_son = (/ regCoef(psa1_pc_son,arr_son(lat|:,lon|:,time|:)) /) + psa2_son = arr_son(0,:,:) + psa2_son = (/ regCoef(psa2_pc_son,arr_son(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + sam_sst_son = sst_son(0,:,:) + sam_sst_son = (/ regCoef(sam_pc_son,sst_son(lat|:,lon|:,time|:)) /) + psa1_sst_son = sst_son(0,:,:) + psa1_sst_son = (/ regCoef(psa1_pc_son,sst_son(lat|:,lon|:,time|:)) /) + psa2_sst_son = sst_son(0,:,:) + psa2_sst_son = (/ regCoef(psa2_pc_son,sst_son(lat|:,lon|:,time|:)) /) + delete(sst_son) + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_son = tas_son(0,:,:) + sam_tas_son = (/ regCoef(sam_pc_son,tas_son(lat|:,lon|:,time|:)) /) + psa1_tas_son = tas_son(0,:,:) + psa1_tas_son = (/ regCoef(psa1_pc_son,tas_son(lat|:,lon|:,time|:)) /) + psa2_tas_son = tas_son(0,:,:) + psa2_tas_son = (/ regCoef(psa2_pc_son,tas_son(lat|:,lon|:,time|:)) /) + delete(tas_son) + end if + if (prreg_plot_flag.eq.0) then + sam_pr_son = pr_son(0,:,:) + sam_pr_son = (/ regCoef(sam_pc_son,pr_son(lat|:,lon|:,time|:)) /) + psa1_pr_son = pr_son(0,:,:) + psa1_pr_son = (/ regCoef(psa1_pc_son,pr_son(lat|:,lon|:,time|:)) /) + psa2_pr_son = pr_son(0,:,:) + psa2_pr_son = (/ regCoef(psa2_pc_son,pr_son(lat|:,lon|:,time|:)) /) + delete(pr_son) + end if + + if (.not.ismissing(sam_son({-85},{5}))) then + if (sam_son({-85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + sam_son = sam_son*-1. + sam_pc_son = sam_pc_son*-1. + if (sstreg_plot_flag.eq.0) then + sam_sst_son = sam_sst_son*-1. + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_son = sam_tas_son*-1. + end if + if (prreg_plot_flag.eq.0) then + sam_pr_son = sam_pr_son*-1. + end if + end if + end if + if (.not.ismissing(psa1_son({-62},{210}))) then + if (psa1_son({-62},{210}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa1_son = psa1_son*-1. + psa1_pc_son = psa1_pc_son*-1. + if (sstreg_plot_flag.eq.0) then + psa1_sst_son = psa1_sst_son*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa1_tas_son = psa1_tas_son*-1. + end if + if (prreg_plot_flag.eq.0) then + psa1_pr_son = psa1_pr_son*-1. + end if + end if + end if + if (.not.ismissing(psa2_son({-60},{280}))) then + if (psa2_son({-60},{280}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa2_son = psa2_son*-1. + psa2_pc_son = psa2_pc_son*-1. + if (sstreg_plot_flag.eq.0) then + psa2_sst_son = psa2_sst_son*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa2_tas_son = psa2_tas_son*-1. + end if + if (prreg_plot_flag.eq.0) then + psa2_pr_son = psa2_pr_son*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(sam_pc_son),False) + if (sig_pcv(0)) then ; if True then significant + sam_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + sam_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + psa1_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + psa1_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + if (sig_pcv(2)) then ; if True then significant + psa2_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%*" + else + psa2_son@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(sam_pc_djf,sam_pc_son) + copy_VarCoords(sam_pc_djf,psa1_pc_son) + copy_VarCoords(sam_pc_djf,psa2_pc_son) + delete([/evecv,pcts/]) + + evecv = eofunc(arr_ann_CW({lat|:-20},lon|:,time|:),4,75) + pcts = eofunc_ts(arr_ann_CW({lat|:-20},lon|:,time|:),evecv,False) + sam_pc_ann = dim_standardize(pcts(0,:),0) + psa1_pc_ann = dim_standardize(pcts(1,:),0) + psa2_pc_ann = dim_standardize(pcts(2,:),0) + sam_ann = arr_ann(0,:,:) + sam_ann = (/ regCoef(sam_pc_ann,arr_ann(lat|:,lon|:,time|:)) /) + psa1_ann = arr_ann(0,:,:) + psa1_ann = (/ regCoef(psa1_pc_ann,arr_ann(lat|:,lon|:,time|:)) /) + psa2_ann = arr_ann(0,:,:) + psa2_ann = (/ regCoef(psa2_pc_ann,arr_ann(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + sam_sst_ann = sst_ann(0,:,:) + sam_sst_ann = (/ regCoef(sam_pc_ann,sst_ann(lat|:,lon|:,time|:)) /) + psa1_sst_ann = sst_ann(0,:,:) + psa1_sst_ann = (/ regCoef(psa1_pc_ann,sst_ann(lat|:,lon|:,time|:)) /) + psa2_sst_ann = sst_ann(0,:,:) + psa2_sst_ann = (/ regCoef(psa2_pc_ann,sst_ann(lat|:,lon|:,time|:)) /) + delete(sst_ann) + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_ann = tas_ann(0,:,:) + sam_tas_ann = (/ regCoef(sam_pc_ann,tas_ann(lat|:,lon|:,time|:)) /) + psa1_tas_ann = tas_ann(0,:,:) + psa1_tas_ann = (/ regCoef(psa1_pc_ann,tas_ann(lat|:,lon|:,time|:)) /) + psa2_tas_ann = tas_ann(0,:,:) + psa2_tas_ann = (/ regCoef(psa2_pc_ann,tas_ann(lat|:,lon|:,time|:)) /) + delete(tas_ann) + end if + if (prreg_plot_flag.eq.0) then + sam_pr_ann = pr_ann(0,:,:) + sam_pr_ann = (/ regCoef(sam_pc_ann,pr_ann(lat|:,lon|:,time|:)) /) + psa1_pr_ann = pr_ann(0,:,:) + psa1_pr_ann = (/ regCoef(psa1_pc_ann,pr_ann(lat|:,lon|:,time|:)) /) + psa2_pr_ann = pr_ann(0,:,:) + psa2_pr_ann = (/ regCoef(psa2_pc_ann,pr_ann(lat|:,lon|:,time|:)) /) + delete(pr_ann) + end if + + if (.not.ismissing(sam_ann({-85},{5}))) then + if (sam_ann({-85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + sam_ann = sam_ann*-1. + sam_pc_ann = sam_pc_ann*-1. + if (sstreg_plot_flag.eq.0) then + sam_sst_ann = sam_sst_ann*-1. + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_ann = sam_tas_ann*-1. + end if + if (prreg_plot_flag.eq.0) then + sam_pr_ann = sam_pr_ann*-1. + end if + end if + end if + if (.not.ismissing(psa1_ann({-62},{210}))) then + if (psa1_ann({-62},{210}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa1_ann = psa1_ann*-1. + psa1_pc_ann = psa1_pc_ann*-1. + if (sstreg_plot_flag.eq.0) then + psa1_sst_ann = psa1_sst_ann*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa1_tas_ann = psa1_tas_ann*-1. + end if + if (prreg_plot_flag.eq.0) then + psa1_pr_ann = psa1_pr_ann*-1. + end if + end if + end if + if (.not.ismissing(psa2_ann({-60},{280}))) then + if (psa2_ann({-60},{280}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa2_ann = psa2_ann*-1. + psa2_pc_ann = psa2_pc_ann*-1. + if (sstreg_plot_flag.eq.0) then + psa2_sst_ann = psa2_sst_ann*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa2_tas_ann = psa2_tas_ann*-1. + end if + if (prreg_plot_flag.eq.0) then + psa2_pr_ann = psa2_pr_ann*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(sam_pc_ann),False) + if (sig_pcv(0)) then ; if True then significant + sam_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + sam_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + psa1_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + psa1_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + if (sig_pcv(2)) then ; if True then significant + psa2_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%*" + else + psa2_ann@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%" + end if + delete(sig_pcv) + copy_VarCoords(sam_pc_djf,sam_pc_ann) + copy_VarCoords(sam_pc_djf,psa1_pc_ann) + copy_VarCoords(sam_pc_djf,psa2_pc_ann) + delete([/evecv,pcts/]) + + if (COMPUTE_MODES_MON.eq."True") then + evecv = eofunc(arr_mon_CW({lat|:-20},lon|:,time|:),4,75) + pcts = eofunc_ts(arr_mon_CW({lat|:-20},lon|:,time|:),evecv,False) + sam_pc_mon = dim_standardize(pcts(0,:),0) + psa1_pc_mon = dim_standardize(pcts(1,:),0) + psa2_pc_mon = dim_standardize(pcts(2,:),0) + sam_mon = arr(0,:,:) + sam_mon = (/ regCoef(sam_pc_mon,arr(lat|:,lon|:,time|:)) /) + psa1_mon = arr(0,:,:) + psa1_mon = (/ regCoef(psa1_pc_mon,arr(lat|:,lon|:,time|:)) /) + psa2_mon = arr(0,:,:) + psa2_mon = (/ regCoef(psa2_pc_mon,arr(lat|:,lon|:,time|:)) /) + if (sstreg_plot_flag.eq.0) then + sam_sst_mon = sst(0,:,:) + sam_sst_mon = (/ regCoef(sam_pc_mon,sst(lat|:,lon|:,time|:)) /) + psa1_sst_mon = sst(0,:,:) + psa1_sst_mon = (/ regCoef(psa1_pc_mon,sst(lat|:,lon|:,time|:)) /) + psa2_sst_mon = sst(0,:,:) + psa2_sst_mon = (/ regCoef(psa2_pc_mon,sst(lat|:,lon|:,time|:)) /) + delete(sst) + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_mon = tas(0,:,:) + sam_tas_mon = (/ regCoef(sam_pc_mon,tas(lat|:,lon|:,time|:)) /) + psa1_tas_mon = tas(0,:,:) + psa1_tas_mon = (/ regCoef(psa1_pc_mon,tas(lat|:,lon|:,time|:)) /) + psa2_tas_mon = tas(0,:,:) + psa2_tas_mon = (/ regCoef(psa2_pc_mon,tas(lat|:,lon|:,time|:)) /) + delete(tas) + end if + if (prreg_plot_flag.eq.0) then + sam_pr_mon = pr(0,:,:) + sam_pr_mon = (/ regCoef(sam_pc_mon,pr(lat|:,lon|:,time|:)) /) + psa1_pr_mon = pr(0,:,:) + psa1_pr_mon = (/ regCoef(psa1_pc_mon,pr(lat|:,lon|:,time|:)) /) + psa2_pr_mon = pr(0,:,:) + psa2_pr_mon = (/ regCoef(psa2_pc_mon,pr(lat|:,lon|:,time|:)) /) + delete(pr) + end if + + if (.not.ismissing(sam_mon({-85},{5}))) then + if (sam_mon({-85},{5}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + sam_mon = sam_mon*-1. + sam_pc_mon = sam_pc_mon*-1. + if (sstreg_plot_flag.eq.0) then + sam_sst_mon = sam_sst_mon*-1. + end if + if (tasreg_plot_flag.eq.0) then + sam_tas_mon = sam_tas_mon*-1. + end if + if (prreg_plot_flag.eq.0) then + sam_pr_mon = sam_pr_mon*-1. + end if + end if + end if + if (.not.ismissing(psa1_mon({-62},{210}))) then + if (psa1_mon({-62},{210}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa1_mon = psa1_mon*-1. + psa1_pc_mon = psa1_pc_mon*-1. + if (sstreg_plot_flag.eq.0) then + psa1_sst_mon = psa1_sst_mon*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa1_tas_mon = psa1_tas_mon*-1. + end if + if (prreg_plot_flag.eq.0) then + psa1_pr_mon = psa1_pr_mon*-1. + end if + end if + end if + if (.not.ismissing(psa2_mon({-60},{280}))) then + if (psa2_mon({-60},{280}).ge.0) then ; arbitrary attempt to make all plots have the same sign.. + psa2_mon = psa2_mon*-1. + psa2_pc_mon = psa2_pc_mon*-1. + if (sstreg_plot_flag.eq.0) then + psa2_sst_mon = psa2_sst_mon*-1. + end if + if (tasreg_plot_flag.eq.0) then + psa2_tas_mon = psa2_tas_mon*-1. + end if + if (prreg_plot_flag.eq.0) then + psa2_pr_mon = psa2_pr_mon*-1. + end if + end if + end if + sig_pcv = eofunc_north2(evecv@pcvar,dimsizes(sam_pc_mon),False) + if (sig_pcv(0)) then ; if True then significant + sam_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%*" + else + sam_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(0)))+"%" + end if + if (sig_pcv(1)) then ; if True then significant + psa1_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%*" + else + psa1_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(1)))+"%" + end if + if (sig_pcv(2)) then ; if True then significant + psa2_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%*" + else + psa2_mon@pcvar = tofloat(sprintf("%4.1f", evecv@pcvar(2)))+"%" + end if + delete(sig_pcv) + sam_pc_mon!0 = "time" + sam_pc_mon&time = arr&time + psa1_pc_mon!0 = "time" + psa1_pc_mon&time = arr&time + psa2_pc_mon!0 = "time" + psa2_pc_mon&time = arr&time + delete([/evecv,pcts,arr_mon_CW,arr/]) + end if + delete([/arr_djf_CW,arr_mam_CW,arr_jja_CW,arr_son_CW,arr_ann_CW/]) + delete([/arr_djf,arr_mam,arr_jja,arr_son,arr_ann/]) +;------------------------------------------------------------------------------------------------------ + if (sstreg_frame.eq.1.and.sstreg_plot_flag.eq.0) then ; sstreg_frame = flag to create regressions .ps/.png files + sstreg_frame = 0 + end if + if (tasreg_frame.eq.1.and.tasreg_plot_flag.eq.0) then ; tasreg_frame = flag to create regressions .ps/.png files + tasreg_frame = 0 + end if + if (prreg_frame.eq.1.and.prreg_plot_flag.eq.0) then ; prreg_frame = flag to create regressions .ps/.png files + prreg_frame = 0 + end if +;------------------------------------------------------------------------------------------------------ + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.sam_psa."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->sam_timeseries_djf = set_varAtts(sam_pc_djf,"SAM normalized principal component timeseries (DJF)","1","") + z->sam_timeseries_mam = set_varAtts(sam_pc_mam,"SAM normalized principal component timeseries (MAM)","1","") + z->sam_timeseries_jja = set_varAtts(sam_pc_jja,"SAM normalized principal component timeseries (JJA)","1","") + z->sam_timeseries_son = set_varAtts(sam_pc_son,"SAM normalized principal component timeseries (SON)","1","") + z->sam_timeseries_ann = set_varAtts(sam_pc_ann,"SAM normalized principal component timeseries (annual)","1","") + + z->psa1_timeseries_djf = set_varAtts(psa1_pc_djf,"PSA1 normalized principal component timeseries (DJF)","1","") + z->psa1_timeseries_mam = set_varAtts(psa1_pc_mam,"PSA1 normalized principal component timeseries (MAM)","1","") + z->psa1_timeseries_jja = set_varAtts(psa1_pc_jja,"PSA1 normalized principal component timeseries (JJA)","1","") + z->psa1_timeseries_son = set_varAtts(psa1_pc_son,"PSA1 normalized principal component timeseries (SON)","1","") + z->psa1_timeseries_ann = set_varAtts(psa1_pc_ann,"PSA1 normalized principal component timeseries (annual)","1","") + + z->psa2_timeseries_djf = set_varAtts(psa2_pc_djf,"PSA2 normalized principal component timeseries (DJF)","1","") + z->psa2_timeseries_mam = set_varAtts(psa2_pc_mam,"PSA2 normalized principal component timeseries (MAM)","1","") + z->psa2_timeseries_jja = set_varAtts(psa2_pc_jja,"PSA2 normalized principal component timeseries (JJA)","1","") + z->psa2_timeseries_son = set_varAtts(psa2_pc_son,"PSA2 normalized principal component timeseries (SON)","1","") + z->psa2_timeseries_ann = set_varAtts(psa2_pc_ann,"PSA2 normalized principal component timeseries (annual)","1","") + + z->sam_pattern_djf = set_varAtts(sam_djf,"SAM spatial pattern (DJF)","","") + z->sam_pattern_mam = set_varAtts(sam_mam,"SAM spatial pattern (MAM)","","") + z->sam_pattern_jja = set_varAtts(sam_jja,"SAM spatial pattern (JJA)","","") + z->sam_pattern_son = set_varAtts(sam_son,"SAM spatial pattern (SON)","","") + z->sam_pattern_ann = set_varAtts(sam_ann,"SAM spatial pattern (annual)","","") + + z->psa1_pattern_djf = set_varAtts(psa1_djf,"PSA1 spatial pattern (DJF)","","") + z->psa1_pattern_mam = set_varAtts(psa1_mam,"PSA1 spatial pattern (MAM)","","") + z->psa1_pattern_jja = set_varAtts(psa1_jja,"PSA1 spatial pattern (JJA)","","") + z->psa1_pattern_son = set_varAtts(psa1_son,"PSA1 spatial pattern (SON)","","") + z->psa1_pattern_ann = set_varAtts(psa1_ann,"PSA1 spatial pattern (annual)","","") + + z->psa2_pattern_djf = set_varAtts(psa2_djf,"PSA2 spatial pattern (DJF)","","") + z->psa2_pattern_mam = set_varAtts(psa2_mam,"PSA2 spatial pattern (MAM)","","") + z->psa2_pattern_jja = set_varAtts(psa2_jja,"PSA2 spatial pattern (JJA)","","") + z->psa2_pattern_son = set_varAtts(psa2_son,"PSA2 spatial pattern (SON)","","") + z->psa2_pattern_ann = set_varAtts(psa2_ann,"PSA2 spatial pattern (annual)","","") + + if (COMPUTE_MODES_MON.eq."True") then + z->sam_timeseries_mon = set_varAtts(sam_pc_mon,"SAM principal component timeseries (monthly)","","") + z->psa1_timeseries_mon = set_varAtts(psa1_pc_mon,"PSA1 principal component timeseries (monthly)","","") + z->psa2_timeseries_mon = set_varAtts(psa2_pc_mon,"PSA2 principal component timeseries (monthly)","","") + z->sam_pattern_mon = set_varAtts(sam_mon,"SAM spatial pattern (monthly)","","") + z->psa1_pattern_mon = set_varAtts(psa1_mon,"PSA1 spatial pattern (monthly)","","") + z->psa2_pattern_mon = set_varAtts(psa2_mon,"PSA2 spatial pattern (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + + if (sstreg_plot_flag.eq.0) then + modname = str_sub_str(names_ts(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.sam_psa.ts."+syear_ts(ee)+"-"+eyear_ts(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_ts(ee)+" from "+syear_ts(ee)+"-"+eyear_ts(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_ts(ee)+"-"+eyear_ts(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->sam_sst_regression_djf = set_varAtts(sam_sst_djf,"sst regression onto SAM principal component timeseries (DJF)","","") + z->sam_sst_regression_mam = set_varAtts(sam_sst_mam,"sst regression onto SAM principal component timeseries (MAM)","","") + z->sam_sst_regression_jja = set_varAtts(sam_sst_jja,"sst regression onto SAM principal component timeseries (JJA)","","") + z->sam_sst_regression_son = set_varAtts(sam_sst_son,"sst regression onto SAM principal component timeseries (SON)","","") + z->sam_sst_regression_ann = set_varAtts(sam_sst_ann,"sst regression onto SAM principal component timeseries (annual)","","") + + z->psa1_sst_regression_djf = set_varAtts(psa1_sst_djf,"sst regression onto PSA1 principal component timeseries (DJF)","","") + z->psa1_sst_regression_mam = set_varAtts(psa1_sst_mam,"sst regression onto PSA1 principal component timeseries (MAM)","","") + z->psa1_sst_regression_jja = set_varAtts(psa1_sst_jja,"sst regression onto PSA1 principal component timeseries (JJA)","","") + z->psa1_sst_regression_son = set_varAtts(psa1_sst_son,"sst regression onto PSA1 principal component timeseries (SON)","","") + z->psa1_sst_regression_ann = set_varAtts(psa1_sst_ann,"sst regression onto PSA1 principal component timeseries (annual)","","") + + z->psa2_sst_regression_djf = set_varAtts(psa2_sst_djf,"sst regression onto PSA2 principal component timeseries (DJF)","","") + z->psa2_sst_regression_mam = set_varAtts(psa2_sst_mam,"sst regression onto PSA2 principal component timeseries (MAM)","","") + z->psa2_sst_regression_jja = set_varAtts(psa2_sst_jja,"sst regression onto PSA2 principal component timeseries (JJA)","","") + z->psa2_sst_regression_son = set_varAtts(psa2_sst_son,"sst regression onto PSA2 principal component timeseries (SON)","","") + z->psa2_sst_regression_ann = set_varAtts(psa2_sst_ann,"sst regression onto PSA2 principal component timeseries (annual)","","") + if (COMPUTE_MODES_MON.eq."True") then + z->sam_sst_regression_mon = set_varAtts(sam_sst_mon,"sst regression onto SAM principal component timeseries (monthly)","","") + z->psa1_sst_regression_mon = set_varAtts(psa1_sst_mon,"sst regression onto PSA1 principal component timeseries (monthly)","","") + z->psa2_sst_regression_mon = set_varAtts(psa2_sst_mon,"sst regression onto PSA2 principal component timeseries (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + end if + if (tasreg_plot_flag.eq.0) then + modname = str_sub_str(names_tas(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.sam_psa.tas."+syear_tas(ee)+"-"+eyear_tas(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_tas(ee)+" from "+syear_tas(ee)+"-"+eyear_tas(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_tas(ee)+"-"+eyear_tas(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->sam_tas_regression_djf = set_varAtts(sam_tas_djf,"tas regression onto SAM principal component timeseries (DJF)","","") + z->sam_tas_regression_mam = set_varAtts(sam_tas_mam,"tas regression onto SAM principal component timeseries (MAM)","","") + z->sam_tas_regression_jja = set_varAtts(sam_tas_jja,"tas regression onto SAM principal component timeseries (JJA)","","") + z->sam_tas_regression_son = set_varAtts(sam_tas_son,"tas regression onto SAM principal component timeseries (SON)","","") + z->sam_tas_regression_ann = set_varAtts(sam_tas_ann,"tas regression onto SAM principal component timeseries (annual)","","") + + z->psa1_tas_regression_djf = set_varAtts(psa1_tas_djf,"tas regression onto PSA1 principal component timeseries (DJF)","","") + z->psa1_tas_regression_mam = set_varAtts(psa1_tas_mam,"tas regression onto PSA1 principal component timeseries (MAM)","","") + z->psa1_tas_regression_jja = set_varAtts(psa1_tas_jja,"tas regression onto PSA1 principal component timeseries (JJA)","","") + z->psa1_tas_regression_son = set_varAtts(psa1_tas_son,"tas regression onto PSA1 principal component timeseries (SON)","","") + z->psa1_tas_regression_ann = set_varAtts(psa1_tas_ann,"tas regression onto PSA1 principal component timeseries (annual)","","") + + z->psa2_tas_regression_djf = set_varAtts(psa2_tas_djf,"tas regression onto PSA2 principal component timeseries (DJF)","","") + z->psa2_tas_regression_mam = set_varAtts(psa2_tas_mam,"tas regression onto PSA2 principal component timeseries (MAM)","","") + z->psa2_tas_regression_jja = set_varAtts(psa2_tas_jja,"tas regression onto PSA2 principal component timeseries (JJA)","","") + z->psa2_tas_regression_son = set_varAtts(psa2_tas_son,"tas regression onto PSA2 principal component timeseries (SON)","","") + z->psa2_tas_regression_ann = set_varAtts(psa2_tas_ann,"tas regression onto PSA2 principal component timeseries (annual)","","") + if (COMPUTE_MODES_MON.eq."True") then + z->sam_tas_regression_mon = set_varAtts(sam_tas_mon,"tas regression onto SAM principal component timeseries (monthly)","","") + z->psa1_tas_regression_mon = set_varAtts(psa1_tas_mon,"tas regression onto PSA1 principal component timeseries (monthly)","","") + z->psa2_tas_regression_mon = set_varAtts(psa2_tas_mon,"tas regression onto PSA2 principal component timeseries (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + end if + if (prreg_plot_flag.eq.0) then + modname = str_sub_str(names_pr(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.sam_psa.pr."+syear_pr(ee)+"-"+eyear_pr(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names_pr(ee)+" from "+syear_pr(ee)+"-"+eyear_pr(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear_pr(ee)+"-"+eyear_pr(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->sam_pr_regression_djf = set_varAtts(sam_pr_djf,"pr regression onto SAM principal component timeseries (DJF)","","") + z->sam_pr_regression_mam = set_varAtts(sam_pr_mam,"pr regression onto SAM principal component timeseries (MAM)","","") + z->sam_pr_regression_jja = set_varAtts(sam_pr_jja,"pr regression onto SAM principal component timeseries (JJA)","","") + z->sam_pr_regression_son = set_varAtts(sam_pr_son,"pr regression onto SAM principal component timeseries (SON)","","") + z->sam_pr_regression_ann = set_varAtts(sam_pr_ann,"pr regression onto SAM principal component timeseries (annual)","","") + + z->psa1_pr_regression_djf = set_varAtts(psa1_pr_djf,"pr regression onto PSA1 principal component timeseries (DJF)","","") + z->psa1_pr_regression_mam = set_varAtts(psa1_pr_mam,"pr regression onto PSA1 principal component timeseries (MAM)","","") + z->psa1_pr_regression_jja = set_varAtts(psa1_pr_jja,"pr regression onto PSA1 principal component timeseries (JJA)","","") + z->psa1_pr_regression_son = set_varAtts(psa1_pr_son,"pr regression onto PSA1 principal component timeseries (SON)","","") + z->psa1_pr_regression_ann = set_varAtts(psa1_pr_ann,"pr regression onto PSA1 principal component timeseries (annual)","","") + + z->psa2_pr_regression_djf = set_varAtts(psa2_pr_djf,"pr regression onto PSA2 principal component timeseries (DJF)","","") + z->psa2_pr_regression_mam = set_varAtts(psa2_pr_mam,"pr regression onto PSA2 principal component timeseries (MAM)","","") + z->psa2_pr_regression_jja = set_varAtts(psa2_pr_jja,"pr regression onto PSA2 principal component timeseries (JJA)","","") + z->psa2_pr_regression_son = set_varAtts(psa2_pr_son,"pr regression onto PSA2 principal component timeseries (SON)","","") + z->psa2_pr_regression_ann = set_varAtts(psa2_pr_ann,"pr regression onto PSA2 principal component timeseries (annual)","","") + if (COMPUTE_MODES_MON.eq."True") then + z->sam_pr_regression_mon = set_varAtts(sam_pr_mon,"pr regression onto SAM principal component timeseries (monthly)","","") + z->psa1_pr_regression_mon = set_varAtts(psa1_pr_mon,"pr regression onto PSA1 principal component timeseries (monthly)","","") + z->psa2_pr_regression_mon = set_varAtts(psa2_pr_mon,"pr regression onto PSA2 principal component timeseries (monthly)","","") + end if + delete(z) + delete([/modname,fn/]) + end if + end if +;======================================================================== + res = True + res@mpGeophysicalLineColor = "gray42" + res@mpGeophysicalLineThicknessF = 2. + res@mpGridAndLimbOn = False + res@mpFillOn = False + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + res@cnLevelSelectionMode = "ExplicitLevels" + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.03 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.03 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + if (nsim.le.5) then + res@gsnLeftStringFontHeightF = 0.018 + res@gsnCenterStringFontHeightF = 0.022 + res@gsnRightStringFontHeightF = 0.018 + else + res@gsnLeftStringFontHeightF = 0.024 + res@gsnCenterStringFontHeightF = 0.028 + res@gsnRightStringFontHeightF = 0.024 + end if + res@gsnPolar = "SH" + res@mpMaxLatF = -20. + res@mpCenterLonF = 0. + + res@cnLevels = (/-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7./) + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnCenterString = names(ee) + + res4 = res ; res4 = pr regression resources + if (COLORMAP.eq.0) then + res4@cnLevels := fspan(-.7,.7,15) + else + res4@cnLevels := fspan(-.5,.5,11) + end if + + res2 = True + res2@gsnDraw = False + res2@gsnFrame = False + res2@cnLevelSelectionMode = "ExplicitLevels" + res2@cnLevels = res@cnLevels + + res2@cnLineLabelsOn = False + res2@cnFillOn = True + res2@cnLinesOn = False + res2@cnFillMode = "AreaFill" + res2@lbLabelBarOn = False + res2@cnInfoLabelOn = False + res2@gsnRightString = "" + res2@gsnLeftString = "" + res2@gsnCenterString = "" + res2@gsnAddCyclic = True + + if (isfilepresent2("obs_psl").and.ee.eq.0) then ; for pattern correlation table. Save entire lat/lon array + patcor_sam_djf = new((/nsim,dimsizes(sam_djf&lat),dimsizes(sam_djf&lon)/),typeof(sam_djf)) + patcor_sam_djf!1 = "lat" + patcor_sam_djf&lat = sam_djf&lat + patcor_sam_djf!2 = "lon" + patcor_sam_djf&lon = sam_djf&lon + patcor_sam_jja = patcor_sam_djf + patcor_sam_ann = patcor_sam_djf + patcor_psa1_djf = patcor_sam_djf + patcor_psa1_jja = patcor_sam_djf + patcor_psa1_ann = patcor_sam_djf + patcor_psa2_djf = patcor_sam_djf + patcor_psa2_jja = patcor_sam_djf + patcor_psa2_ann = patcor_sam_djf + patcor_sam_djf(ee,:,:) = (/ sam_djf /) + patcor_sam_jja(ee,:,:) = (/ sam_jja /) + patcor_sam_ann(ee,:,:) = (/ sam_ann /) + patcor_psa1_djf(ee,:,:) = (/ psa1_djf /) + patcor_psa1_jja(ee,:,:) = (/ psa1_jja /) + patcor_psa1_ann(ee,:,:) = (/ psa1_ann /) + patcor_psa2_djf(ee,:,:) = (/ psa2_djf /) + patcor_psa2_jja(ee,:,:) = (/ psa2_jja /) + patcor_psa2_ann(ee,:,:) = (/ psa2_ann /) + end if + if (isfilepresent2("obs_psl").and.ee.ge.1.and.isvar("patcor_sam_djf")) then + patcor_sam_djf(ee,:,:) = (/ totype(linint2(sam_djf&lon,sam_djf&lat,sam_djf,True,patcor_sam_djf&lon,patcor_sam_djf&lat,0),typeof(patcor_sam_djf)) /) + patcor_sam_jja(ee,:,:) = (/ totype(linint2(sam_jja&lon,sam_jja&lat,sam_jja,True,patcor_sam_jja&lon,patcor_sam_jja&lat,0),typeof(patcor_sam_jja)) /) + patcor_sam_ann(ee,:,:) = (/ totype(linint2(sam_ann&lon,sam_ann&lat,sam_ann,True,patcor_sam_ann&lon,patcor_sam_ann&lat,0),typeof(patcor_sam_ann)) /) + + patcor_psa1_djf(ee,:,:) = (/ totype(linint2(psa1_djf&lon,psa1_djf&lat,psa1_djf,True,patcor_psa1_djf&lon,patcor_psa1_djf&lat,0),typeof(patcor_psa1_djf)) /) + patcor_psa1_jja(ee,:,:) = (/ totype(linint2(psa1_jja&lon,psa1_jja&lat,psa1_jja,True,patcor_psa1_jja&lon,patcor_psa1_jja&lat,0),typeof(patcor_psa1_jja)) /) + patcor_psa1_ann(ee,:,:) = (/ totype(linint2(psa1_ann&lon,psa1_ann&lat,psa1_ann,True,patcor_psa1_ann&lon,patcor_psa1_ann&lat,0),typeof(patcor_psa1_ann)) /) + + patcor_psa2_djf(ee,:,:) = (/ totype(linint2(psa2_djf&lon,psa2_djf&lat,psa2_djf,True,patcor_psa2_djf&lon,patcor_psa2_djf&lat,0),typeof(patcor_psa2_djf)) /) + patcor_psa2_jja(ee,:,:) = (/ totype(linint2(psa2_jja&lon,psa2_jja&lat,psa2_jja,True,patcor_psa2_jja&lon,patcor_psa2_jja&lat,0),typeof(patcor_psa2_jja)) /) + patcor_psa2_ann(ee,:,:) = (/ totype(linint2(psa2_ann&lon,psa2_ann&lat,psa2_ann,True,patcor_psa2_ann&lon,patcor_psa2_ann&lat,0),typeof(patcor_psa2_ann)) /) + end if + + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnCenterString = names(ee) + res@gsnRightString = sam_djf@pcvar + map_sam_djf(ee) = gsn_csm_contour_map_polar(wks_sam,sam_djf,res) + res@gsnRightString = sam_mam@pcvar + map_sam_mam(ee) = gsn_csm_contour_map_polar(wks_sam,sam_mam,res) + res@gsnRightString = sam_jja@pcvar + map_sam_jja(ee) = gsn_csm_contour_map_polar(wks_sam,sam_jja,res) + res@gsnRightString = sam_son@pcvar + map_sam_son(ee) = gsn_csm_contour_map_polar(wks_sam,sam_son,res) + res@gsnRightString = sam_ann@pcvar + map_sam_ann(ee) = gsn_csm_contour_map_polar(wks_sam,sam_ann,res) + delete([/sam_djf,sam_mam,sam_jja,sam_son,sam_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + res@gsnRightString = sam_mon@pcvar + map_sam_mon(ee) = gsn_csm_contour_map_polar(wks_sam,sam_mon,res) + delete([/sam_mon/]) + end if + + res@cnLevels = (/-4,-3,-2.5,-2,-1.5,-1,-0.5,0,0.5,1,1.5,2,2.5,3,4/) + res@gsnRightString = psa1_djf@pcvar + map_psa1_djf(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_djf,res) + res@gsnRightString = psa1_mam@pcvar + map_psa1_mam(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_mam,res) + res@gsnRightString = psa1_jja@pcvar + map_psa1_jja(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_jja,res) + res@gsnRightString = psa1_son@pcvar + map_psa1_son(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_son,res) + res@gsnRightString = psa1_ann@pcvar + map_psa1_ann(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_ann,res) + delete([/psa1_djf,psa1_mam,psa1_jja,psa1_son,psa1_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + res@gsnRightString = psa1_mon@pcvar + map_psa1_mon(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_mon,res) + delete([/psa1_mon/]) + end if + + res@gsnRightString = psa2_djf@pcvar + map_psa2_djf(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_djf,res) + res@gsnRightString = psa2_mam@pcvar + map_psa2_mam(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_mam,res) + res@gsnRightString = psa2_jja@pcvar + map_psa2_jja(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_jja,res) + res@gsnRightString = psa2_son@pcvar + map_psa2_son(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_son,res) + res@gsnRightString = psa2_ann@pcvar + map_psa2_ann(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_ann,res) + delete([/psa2_djf,psa2_mam,psa2_jja,psa2_son,psa2_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + res@gsnRightString = psa2_mon@pcvar + map_psa2_mon(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_mon,res) + delete([/psa2_mon/]) + end if + + if (sstreg_plot_flag.eq.0) then + res@cnLevels := fspan(-.7,.7,15) + if (tasreg_plot_flag.eq.0) then + if (names_ts(ee).eq.names_tas(ee)) then + res@gsnCenterString = names_ts(ee) + else + res@gsnCenterString = names_ts(ee)+" / "+names_tas(ee) + end if + else + res@gsnCenterString = names_ts(ee) + end if + res@gsnRightString = "" + reg_sam_djf(ee) = gsn_csm_contour_map_polar(wks_sam,sam_sst_djf,res) + reg_sam_mam(ee) = gsn_csm_contour_map_polar(wks_sam,sam_sst_mam,res) + reg_sam_jja(ee) = gsn_csm_contour_map_polar(wks_sam,sam_sst_jja,res) + reg_sam_son(ee) = gsn_csm_contour_map_polar(wks_sam,sam_sst_son,res) + reg_sam_ann(ee) = gsn_csm_contour_map_polar(wks_sam,sam_sst_ann,res) + delete([/sam_sst_djf,sam_sst_mam,sam_sst_jja,sam_sst_son,sam_sst_ann/]) + if (tasreg_plot_flag.eq.0) then + o_djf = gsn_csm_contour(wks_sam,sam_tas_djf,res2) + o_mam = gsn_csm_contour(wks_sam,sam_tas_mam,res2) + o_jja = gsn_csm_contour(wks_sam,sam_tas_jja,res2) + o_son = gsn_csm_contour(wks_sam,sam_tas_son,res2) + o_ann = gsn_csm_contour(wks_sam,sam_tas_ann,res2) + delete([/sam_tas_djf,sam_tas_mam,sam_tas_jja,sam_tas_son,sam_tas_ann/]) + overlay(reg_sam_djf(ee),o_djf) + overlay(reg_sam_mam(ee),o_mam) + overlay(reg_sam_jja(ee),o_jja) + overlay(reg_sam_son(ee),o_son) + overlay(reg_sam_ann(ee),o_ann) + delete([/o_djf,o_mam,o_jja,o_son,o_ann/]) + end if + if (COMPUTE_MODES_MON.eq."True") then + reg_sam_mon(ee) = gsn_csm_contour_map_polar(wks_sam,sam_sst_mon,res) + delete([/sam_sst_mon/]) + if (tasreg_plot_flag.eq.0) then + o_mon = gsn_csm_contour(wks_sam,sam_tas_mon,res2) + overlay(reg_sam_mon(ee),o_mon) + delete([/o_mon,sam_tas_mon/]) + end if + end if + + reg_psa1_djf(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_sst_djf,res) + reg_psa1_mam(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_sst_mam,res) + reg_psa1_jja(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_sst_jja,res) + reg_psa1_son(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_sst_son,res) + reg_psa1_ann(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_sst_ann,res) + delete([/psa1_sst_djf,psa1_sst_mam,psa1_sst_jja,psa1_sst_son,psa1_sst_ann/]) + if (tasreg_plot_flag.eq.0) then + o_djf = gsn_csm_contour(wks_psa1,psa1_tas_djf,res2) + o_mam = gsn_csm_contour(wks_psa1,psa1_tas_mam,res2) + o_jja = gsn_csm_contour(wks_psa1,psa1_tas_jja,res2) + o_son = gsn_csm_contour(wks_psa1,psa1_tas_son,res2) + o_ann = gsn_csm_contour(wks_psa1,psa1_tas_ann,res2) + delete([/psa1_tas_djf,psa1_tas_mam,psa1_tas_jja,psa1_tas_son,psa1_tas_ann/]) + overlay(reg_psa1_djf(ee),o_djf) + overlay(reg_psa1_mam(ee),o_mam) + overlay(reg_psa1_jja(ee),o_jja) + overlay(reg_psa1_son(ee),o_son) + overlay(reg_psa1_ann(ee),o_ann) + delete([/o_djf,o_mam,o_jja,o_son,o_ann/]) + end if + if (COMPUTE_MODES_MON.eq."True") then + reg_psa1_mon(ee) = gsn_csm_contour_map_polar(wks_psa1,psa1_sst_mon,res) + delete([/psa1_sst_mon/]) + if (tasreg_plot_flag.eq.0) then + o_mon = gsn_csm_contour(wks_psa1,psa1_tas_mon,res2) + overlay(reg_psa1_mon(ee),o_mon) + delete([/o_mon,psa1_tas_mon/]) + end if + end if + + reg_psa2_djf(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_sst_djf,res) + reg_psa2_mam(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_sst_mam,res) + reg_psa2_jja(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_sst_jja,res) + reg_psa2_son(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_sst_son,res) + reg_psa2_ann(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_sst_ann,res) + delete([/psa2_sst_djf,psa2_sst_mam,psa2_sst_jja,psa2_sst_son,psa2_sst_ann/]) + if (tasreg_plot_flag.eq.0) then + o_djf = gsn_csm_contour(wks_psa2,psa2_tas_djf,res2) + o_mam = gsn_csm_contour(wks_psa2,psa2_tas_mam,res2) + o_jja = gsn_csm_contour(wks_psa2,psa2_tas_jja,res2) + o_son = gsn_csm_contour(wks_psa2,psa2_tas_son,res2) + o_ann = gsn_csm_contour(wks_psa2,psa2_tas_ann,res2) + delete([/psa2_tas_djf,psa2_tas_mam,psa2_tas_jja,psa2_tas_son,psa2_tas_ann/]) + overlay(reg_psa2_djf(ee),o_djf) + overlay(reg_psa2_mam(ee),o_mam) + overlay(reg_psa2_jja(ee),o_jja) + overlay(reg_psa2_son(ee),o_son) + overlay(reg_psa2_ann(ee),o_ann) + delete([/o_djf,o_mam,o_jja,o_son,o_ann/]) + end if + if (COMPUTE_MODES_MON.eq."True") then + reg_psa2_mon(ee) = gsn_csm_contour_map_polar(wks_psa2,psa2_sst_mon,res) + delete([/psa2_sst_mon/]) + if (tasreg_plot_flag.eq.0) then + o_mon = gsn_csm_contour(wks_psa2,psa2_tas_mon,res2) + overlay(reg_psa2_mon(ee),o_mon) + delete([/o_mon,psa2_tas_mon/]) + end if + end if + end if + + if (prreg_plot_flag.eq.0) then ; PR regressions + res4@gsnRightString = "" + res4@gsnCenterString = names_pr(ee) + reg_sam_pr_djf(ee) = gsn_csm_contour_map_polar(wks_sam_pr,sam_pr_djf,res4) + reg_sam_pr_mam(ee) = gsn_csm_contour_map_polar(wks_sam_pr,sam_pr_mam,res4) + reg_sam_pr_jja(ee) = gsn_csm_contour_map_polar(wks_sam_pr,sam_pr_jja,res4) + reg_sam_pr_son(ee) = gsn_csm_contour_map_polar(wks_sam_pr,sam_pr_son,res4) + reg_sam_pr_ann(ee) = gsn_csm_contour_map_polar(wks_sam_pr,sam_pr_ann,res4) + delete([/sam_pr_djf,sam_pr_mam,sam_pr_jja,sam_pr_son,sam_pr_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + reg_sam_pr_mon(ee) = gsn_csm_contour_map_polar(wks_sam_pr,sam_pr_mon,res4) + delete([/sam_pr_mon/]) + end if + + reg_psa1_pr_djf(ee) = gsn_csm_contour_map_polar(wks_psa1_pr,psa1_pr_djf,res4) + reg_psa1_pr_mam(ee) = gsn_csm_contour_map_polar(wks_psa1_pr,psa1_pr_mam,res4) + reg_psa1_pr_jja(ee) = gsn_csm_contour_map_polar(wks_psa1_pr,psa1_pr_jja,res4) + reg_psa1_pr_son(ee) = gsn_csm_contour_map_polar(wks_psa1_pr,psa1_pr_son,res4) + reg_psa1_pr_ann(ee) = gsn_csm_contour_map_polar(wks_psa1_pr,psa1_pr_ann,res4) + delete([/psa1_pr_djf,psa1_pr_mam,psa1_pr_jja,psa1_pr_son,psa1_pr_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + reg_psa1_pr_mon(ee) = gsn_csm_contour_map_polar(wks_psa1_pr,psa1_pr_mon,res4) + delete([/psa1_pr_mon/]) + end if + + reg_psa2_pr_djf(ee) = gsn_csm_contour_map_polar(wks_psa2_pr,psa2_pr_djf,res4) + reg_psa2_pr_mam(ee) = gsn_csm_contour_map_polar(wks_psa2_pr,psa2_pr_mam,res4) + reg_psa2_pr_jja(ee) = gsn_csm_contour_map_polar(wks_psa2_pr,psa2_pr_jja,res4) + reg_psa2_pr_son(ee) = gsn_csm_contour_map_polar(wks_psa2_pr,psa2_pr_son,res4) + reg_psa2_pr_ann(ee) = gsn_csm_contour_map_polar(wks_psa2_pr,psa2_pr_ann,res4) + delete([/psa2_pr_djf,psa2_pr_mam,psa2_pr_jja,psa2_pr_son,psa2_pr_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + reg_psa2_pr_mon(ee) = gsn_csm_contour_map_polar(wks_psa2_pr,psa2_pr_mon,res4) + delete([/psa2_pr_mon/]) + end if + end if + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnXYBarChart = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + xyres@gsnAboveYRefLineColor = 185 + xyres@gsnBelowYRefLineColor = 35 + if (wks_type.eq."png") then + xyres@xyLineThicknessF = .5 + else + xyres@xyLineThicknessF = .2 + end if + xyres@xyLineColor = "gray52" + xyres@tiYAxisString = "" + xyres@tiXAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnStringFontHeightF = 0.017 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnStringFontHeightF = 0.024 + end if + xyres@gsnCenterStringOrthogonalPosF = 0.025 + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnLeftString = "" + xyres@gsnRightString = "" + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+1.5 + + xyres@gsnCenterString = names(ee) + + xyresmon = xyres + xyresmon@gsnXYBarChart = False + xyresmon@xyLineThicknessF = .1 + + xy_sam_djf(ee) = gsn_csm_xy(wks_sam_ts,fspan(syear(ee),eyear(ee),dimsizes(sam_pc_djf)),sam_pc_djf,xyres) ; use standardized timeseries + xy_sam_mam(ee) = gsn_csm_xy(wks_sam_ts,fspan(syear(ee),eyear(ee),dimsizes(sam_pc_mam)),sam_pc_mam,xyres) ; use standardized timeseries + xy_sam_jja(ee) = gsn_csm_xy(wks_sam_ts,fspan(syear(ee),eyear(ee),dimsizes(sam_pc_jja)),sam_pc_jja,xyres) ; use standardized timeseries + xy_sam_son(ee) = gsn_csm_xy(wks_sam_ts,fspan(syear(ee),eyear(ee),dimsizes(sam_pc_son)),sam_pc_son,xyres) ; use standardized timeseries + xy_sam_ann(ee) = gsn_csm_xy(wks_sam_ts,fspan(syear(ee),eyear(ee),dimsizes(sam_pc_ann)),sam_pc_ann,xyres) ; use standardized timeseries + delete([/sam_pc_djf,sam_pc_mam,sam_pc_jja,sam_pc_son,sam_pc_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + xy_sam_mon(ee) = gsn_csm_xy(wks_sam_ts,fspan(syear(ee),eyear(ee)+.91667,dimsizes(sam_pc_mon)),sam_pc_mon,xyresmon) ; use standardized timeseries + delete([/sam_pc_mon/]) + end if + + xy_psa1_djf(ee) = gsn_csm_xy(wks_psa1_ts,fspan(syear(ee),eyear(ee),dimsizes(psa1_pc_djf)),psa1_pc_djf,xyres) ; use standardized timeseries + xy_psa1_mam(ee) = gsn_csm_xy(wks_psa1_ts,fspan(syear(ee),eyear(ee),dimsizes(psa1_pc_mam)),psa1_pc_mam,xyres) ; use standardized timeseries + xy_psa1_jja(ee) = gsn_csm_xy(wks_psa1_ts,fspan(syear(ee),eyear(ee),dimsizes(psa1_pc_jja)),psa1_pc_jja,xyres) ; use standardized timeseries + xy_psa1_son(ee) = gsn_csm_xy(wks_psa1_ts,fspan(syear(ee),eyear(ee),dimsizes(psa1_pc_son)),psa1_pc_son,xyres) ; use standardized timeseries + xy_psa1_ann(ee) = gsn_csm_xy(wks_psa1_ts,fspan(syear(ee),eyear(ee),dimsizes(psa1_pc_ann)),psa1_pc_ann,xyres) ; use standardized timeseries + delete([/psa1_pc_djf,psa1_pc_mam,psa1_pc_jja,psa1_pc_son,psa1_pc_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + xy_psa1_mon(ee) = gsn_csm_xy(wks_psa1_ts,fspan(syear(ee),eyear(ee)+.91667,dimsizes(psa1_pc_mon)),psa1_pc_mon,xyresmon) ; use standardized timeseries + delete([/psa1_pc_mon/]) + end if + + xy_psa2_djf(ee) = gsn_csm_xy(wks_psa2_ts,fspan(syear(ee),eyear(ee),dimsizes(psa2_pc_djf)),psa2_pc_djf,xyres) ; use standardized timeseries + xy_psa2_mam(ee) = gsn_csm_xy(wks_psa2_ts,fspan(syear(ee),eyear(ee),dimsizes(psa2_pc_mam)),psa2_pc_mam,xyres) ; use standardized timeseries + xy_psa2_jja(ee) = gsn_csm_xy(wks_psa2_ts,fspan(syear(ee),eyear(ee),dimsizes(psa2_pc_jja)),psa2_pc_jja,xyres) ; use standardized timeseries + xy_psa2_son(ee) = gsn_csm_xy(wks_psa2_ts,fspan(syear(ee),eyear(ee),dimsizes(psa2_pc_son)),psa2_pc_son,xyres) ; use standardized timeseries + xy_psa2_ann(ee) = gsn_csm_xy(wks_psa2_ts,fspan(syear(ee),eyear(ee),dimsizes(psa2_pc_ann)),psa2_pc_ann,xyres) ; use standardized timeseries + delete([/psa2_pc_djf,psa2_pc_mam,psa2_pc_jja,psa2_pc_son,psa2_pc_ann/]) + if (COMPUTE_MODES_MON.eq."True") then + xy_psa2_mon(ee) = gsn_csm_xy(wks_psa2_ts,fspan(syear(ee),eyear(ee)+.91667,dimsizes(psa2_pc_mon)),psa2_pc_mon,xyresmon) ; use standardized timeseries + delete([/psa2_pc_mon/]) + end if + + delete(sstreg_plot_flag) + end do + + if (isvar("clim_syear")) then + delete(clim_syear) + end if + if (isvar("clim_eyear")) then + delete(clim_eyear) + end if + + if (isvar("patcor_sam_djf")) then ; for pattern correlation table + clat = cos(0.01745329*patcor_sam_djf&lat) + clat!0 = "lat" + clat&lat = patcor_sam_djf&lat + line3 = " " ; Must be 18 characters long + line4 = line3 + header = (/"","Pattern Correlations Observations vs. Model(s)",""/) + finpr_sam_djf = "SAM (DJF) " + do hh = 1,nsim-1 + dimY = dimsizes(tochar(names(hh))) + nchar = dimY + nchar = where(nchar.le.10,10,nchar) + if (dimY.lt.10) then + ntb = "" + do ii = 0,10-dimY-1 + ntb = ntb+" " + end do + ntb = ntb+names(hh) + else + ntb = names(hh) + end if + + ntc = "" + do ii = 0,nchar-1 + ntc = ntc+"-" + end do + format2 = "%"+(nchar-5+1)+".2f" + format3 = "%4.2f" + line3 = line3+" "+ntb + line4 = line4+" "+ntc + if (all(ismissing(patcor_sam_djf(hh,{:-20},:)))) then + finpr_sam_djf = finpr_sam_djf+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr_sam_djf = finpr_sam_djf+sprintf(format2,(pattern_cor(patcor_sam_djf(0,{:-20},:),patcor_sam_djf(hh,{:-20},:),clat({:-20}),0)))+"/"+sprintf(format3,(wgt_arearmse(patcor_sam_djf(0,{:-20},:),patcor_sam_djf(hh,{:-20},:),clat({:-20}),1.0,0))) + end if + end do +; + if (dimsizes(tochar(line4)).ge.8190) then ; system or fortran compiler limit + print("Metrics table warning: Not creating metrics table as size of comparison results in a invalid ascii row size.") + else + write_table(getenv("OUTDIR")+"metrics.psl.sam_psa.txt","w",[/header/],"%s") + write_table(getenv("OUTDIR")+"metrics.psl.sam_psa.txt","a",[/line3/],"%s") + write_table(getenv("OUTDIR")+"metrics.psl.sam_psa.txt","a",[/line4/],"%s") + write_table(getenv("OUTDIR")+"metrics.psl.sam_psa.txt","a",[/finpr_sam_djf/],"%s") + end if + delete([/line3,line4,format2,format3,nchar,ntc,clat,patcor_sam_djf,patcor_sam_jja,patcor_sam_ann/]) + delete([/patcor_psa1_djf,patcor_psa1_jja,patcor_psa1_ann,patcor_psa2_djf,patcor_psa2_jja,patcor_psa2_ann,dimY,ntb,header/]) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.55 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres@txString = "SAM (DJF)" + gsn_panel2(wks_sam,map_sam_djf,(/nrow,ncol/),panres) + delete(map_sam_djf) + panres@txString = "SAM (MAM)" + gsn_panel2(wks_sam,map_sam_mam,(/nrow,ncol/),panres) + delete(map_sam_mam) + panres@txString = "SAM (JJA)" + gsn_panel2(wks_sam,map_sam_jja,(/nrow,ncol/),panres) + delete(map_sam_jja) + panres@txString = "SAM (SON)" + gsn_panel2(wks_sam,map_sam_son,(/nrow,ncol/),panres) + delete(map_sam_son) + panres@txString = "SAM (Annual)" + gsn_panel2(wks_sam,map_sam_ann,(/nrow,ncol/),panres) + delete(map_sam_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "SAM (Monthly)" + gsn_panel2(wks_sam,map_sam_mon,(/nrow,ncol/),panres) + delete(map_sam_mon) + end if + + if (sstreg_frame.eq.0) then + if (tasreg_frame.eq.0) then + txt0 = "SST/TAS" + else + txt0 = "SST" + end if + panres@txString = "SAM "+txt0+" Regressions (DJF)" + gsn_panel2(wks_sam,reg_sam_djf,(/nrow,ncol/),panres) + delete(reg_sam_djf) + panres@txString = "SAM "+txt0+" Regressions (MAM)" + gsn_panel2(wks_sam,reg_sam_mam,(/nrow,ncol/),panres) + delete(reg_sam_mam) + panres@txString = "SAM "+txt0+" Regressions (JJA)" + gsn_panel2(wks_sam,reg_sam_jja,(/nrow,ncol/),panres) + delete(reg_sam_jja) + panres@txString = "SAM "+txt0+" Regressions (SON)" + gsn_panel2(wks_sam,reg_sam_son,(/nrow,ncol/),panres) + delete(reg_sam_son) + panres@txString = "SAM "+txt0+" Regressions (Annual)" + gsn_panel2(wks_sam,reg_sam_ann,(/nrow,ncol/),panres) + delete(reg_sam_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "SAM "+txt0+" Regressions (Monthly)" + gsn_panel2(wks_sam,reg_sam_mon,(/nrow,ncol/),panres) + delete(reg_sam_mon) + end if + delete(wks_sam) + end if + if (prreg_frame.eq.0) then + panres@txString = "SAM PR Regressions (DJF)" + gsn_panel2(wks_sam_pr,reg_sam_pr_djf,(/nrow,ncol/),panres) + delete(reg_sam_pr_djf) + panres@txString = "SAM PR Regressions (MAM)" + gsn_panel2(wks_sam_pr,reg_sam_pr_mam,(/nrow,ncol/),panres) + delete(reg_sam_pr_mam) + panres@txString = "SAM PR Regressions (JJA)" + gsn_panel2(wks_sam_pr,reg_sam_pr_jja,(/nrow,ncol/),panres) + delete(reg_sam_pr_jja) + panres@txString = "SAM PR Regressions (SON)" + gsn_panel2(wks_sam_pr,reg_sam_pr_son,(/nrow,ncol/),panres) + delete(reg_sam_pr_son) + panres@txString = "SAM PR Regressions (Annual)" + gsn_panel2(wks_sam_pr,reg_sam_pr_ann,(/nrow,ncol/),panres) + delete(reg_sam_pr_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "SAM PR Regressions (Monthly)" + gsn_panel2(wks_sam_pr,reg_sam_pr_mon,(/nrow,ncol/),panres) + delete(reg_sam_pr_mon) + end if + delete(wks_sam_pr) + end if + + panres@txString = "PSA1 (DJF)" + gsn_panel2(wks_psa1,map_psa1_djf,(/nrow,ncol/),panres) + delete(map_psa1_djf) + panres@txString = "PSA1 (MAM)" + gsn_panel2(wks_psa1,map_psa1_mam,(/nrow,ncol/),panres) + delete(map_psa1_mam) + panres@txString = "PSA1 (JJA)" + gsn_panel2(wks_psa1,map_psa1_jja,(/nrow,ncol/),panres) + delete(map_psa1_jja) + panres@txString = "PSA1 (SON)" + gsn_panel2(wks_psa1,map_psa1_son,(/nrow,ncol/),panres) + delete(map_psa1_son) + panres@txString = "PSA1 (Annual)" + gsn_panel2(wks_psa1,map_psa1_ann,(/nrow,ncol/),panres) + delete(map_psa1_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "PSA1 (Monthly)" + gsn_panel2(wks_psa1,map_psa1_mon,(/nrow,ncol/),panres) + delete(map_psa1_mon) + end if + + if (sstreg_frame.eq.0) then + if (tasreg_frame.eq.0) then + txt0 = "SST/TAS" + else + txt0 = "SST" + end if + panres@txString = "PSA1 "+txt0+" Regressions (DJF)" + gsn_panel2(wks_psa1,reg_psa1_djf,(/nrow,ncol/),panres) + delete(reg_psa1_djf) + panres@txString = "PSA1 "+txt0+" Regressions (MAM)" + gsn_panel2(wks_psa1,reg_psa1_mam,(/nrow,ncol/),panres) + delete(reg_psa1_mam) + panres@txString = "PSA1 "+txt0+" Regressions (JJA)" + gsn_panel2(wks_psa1,reg_psa1_jja,(/nrow,ncol/),panres) + delete(reg_psa1_jja) + panres@txString = "PSA1 "+txt0+" Regressions (SON)" + gsn_panel2(wks_psa1,reg_psa1_son,(/nrow,ncol/),panres) + delete(reg_psa1_son) + panres@txString = "PSA1 "+txt0+" Regressions (Annual)" + gsn_panel2(wks_psa1,reg_psa1_ann,(/nrow,ncol/),panres) + delete(reg_psa1_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "PSA1 "+txt0+" Regressions (Monthly)" + gsn_panel2(wks_psa1,reg_psa1_mon,(/nrow,ncol/),panres) + delete(reg_psa1_mon) + end if + delete(wks_psa1) + end if + if (prreg_frame.eq.0) then + panres@txString = "PSA1 PR Regressions (DJF)" + gsn_panel2(wks_psa1_pr,reg_psa1_pr_djf,(/nrow,ncol/),panres) + delete(reg_psa1_pr_djf) + panres@txString = "PSA1 PR Regressions (MAM)" + gsn_panel2(wks_psa1_pr,reg_psa1_pr_mam,(/nrow,ncol/),panres) + delete(reg_psa1_pr_mam) + panres@txString = "PSA1 PR Regressions (JJA)" + gsn_panel2(wks_psa1_pr,reg_psa1_pr_jja,(/nrow,ncol/),panres) + delete(reg_psa1_pr_jja) + panres@txString = "PSA1 PR Regressions (SON)" + gsn_panel2(wks_psa1_pr,reg_psa1_pr_son,(/nrow,ncol/),panres) + delete(reg_psa1_pr_son) + panres@txString = "PSA1 PR Regressions (Annual)" + gsn_panel2(wks_psa1_pr,reg_psa1_pr_ann,(/nrow,ncol/),panres) + delete(reg_psa1_pr_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "PSA1 PR Regressions (Monthly)" + gsn_panel2(wks_psa1_pr,reg_psa1_pr_mon,(/nrow,ncol/),panres) + delete(reg_psa1_pr_mon) + end if + delete(wks_psa1_pr) + end if + + panres@txString = "PSA2 (DJF)" + gsn_panel2(wks_psa2,map_psa2_djf,(/nrow,ncol/),panres) + delete(map_psa2_djf) + panres@txString = "PSA2 (MAM)" + gsn_panel2(wks_psa2,map_psa2_mam,(/nrow,ncol/),panres) + delete(map_psa2_mam) + panres@txString = "PSA2 (JJA)" + gsn_panel2(wks_psa2,map_psa2_jja,(/nrow,ncol/),panres) + delete(map_psa2_jja) + panres@txString = "PSA2 (SON)" + gsn_panel2(wks_psa2,map_psa2_son,(/nrow,ncol/),panres) + delete(map_psa2_son) + panres@txString = "PSA2 (Annual)" + gsn_panel2(wks_psa2,map_psa2_ann,(/nrow,ncol/),panres) + delete(map_psa2_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "PSA2 (Monthly)" + gsn_panel2(wks_psa2,map_psa2_mon,(/nrow,ncol/),panres) + delete(map_psa2_mon) + end if + + if (sstreg_frame.eq.0) then + if (tasreg_frame.eq.0) then + txt0 = "SST/TAS" + else + txt0 = "SST" + end if + panres@txString = "PSA2 "+txt0+" Regressions (DJF)" + gsn_panel2(wks_psa2,reg_psa2_djf,(/nrow,ncol/),panres) + delete(reg_psa2_djf) + panres@txString = "PSA2 "+txt0+" Regressions (MAM)" + gsn_panel2(wks_psa2,reg_psa2_mam,(/nrow,ncol/),panres) + delete(reg_psa2_mam) + panres@txString = "PSA2 "+txt0+" Regressions (JJA)" + gsn_panel2(wks_psa2,reg_psa2_jja,(/nrow,ncol/),panres) + delete(reg_psa2_jja) + panres@txString = "PSA2 "+txt0+" Regressions (SON)" + gsn_panel2(wks_psa2,reg_psa2_son,(/nrow,ncol/),panres) + delete(reg_psa2_son) + panres@txString = "PSA2 "+txt0+" Regressions (Annual)" + gsn_panel2(wks_psa2,reg_psa2_ann,(/nrow,ncol/),panres) + delete(reg_psa2_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "PSA2 "+txt0+" Regressions (Monthly)" + gsn_panel2(wks_psa2,reg_psa2_mon,(/nrow,ncol/),panres) + delete(reg_psa2_mon) + end if + delete(wks_psa2) + end if + if (prreg_frame.eq.0) then + panres@txString = "PSA2 PR Regressions (DJF)" + gsn_panel2(wks_psa2_pr,reg_psa2_pr_djf,(/nrow,ncol/),panres) + delete(reg_psa2_pr_djf) + panres@txString = "PSA2 PR Regressions (MAM)" + gsn_panel2(wks_psa2_pr,reg_psa2_pr_mam,(/nrow,ncol/),panres) + delete(reg_psa2_pr_mam) + panres@txString = "PSA2 PR Regressions (JJA)" + gsn_panel2(wks_psa2_pr,reg_psa2_pr_jja,(/nrow,ncol/),panres) + delete(reg_psa2_pr_jja) + panres@txString = "PSA2 PR Regressions (SON)" + gsn_panel2(wks_psa2_pr,reg_psa2_pr_son,(/nrow,ncol/),panres) + delete(reg_psa2_pr_son) + panres@txString = "PSA2 PR Regressions (Annual)" + gsn_panel2(wks_psa2_pr,reg_psa2_pr_ann,(/nrow,ncol/),panres) + delete(reg_psa2_pr_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres@txString = "PSA2 PR Regressions (Monthly)" + gsn_panel2(wks_psa2_pr,reg_psa2_pr_mon,(/nrow,ncol/),panres) + delete(reg_psa2_pr_mon) + end if + delete(wks_psa2_pr) + end if + + panres2 = True + if (nsim.le.5) then + panres2@txFontHeightF = 0.024 + else + panres2@txFontHeightF = 0.016 + end if + panres2@gsnMaximize = True + panres2@gsnPaperOrientation = "portrait" + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres2@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) + end if + panres2@txString = "SAM (DJF)" + gsn_panel2(wks_sam_ts,xy_sam_djf,lp,panres2) + delete(xy_sam_djf) + panres2@txString = "SAM (MAM)" + gsn_panel2(wks_sam_ts,xy_sam_mam,lp,panres2) + delete(xy_sam_mam) + panres2@txString = "SAM (JJA)" + gsn_panel2(wks_sam_ts,xy_sam_jja,lp,panres2) + delete(xy_sam_jja) + panres2@txString = "SAM (SON)" + gsn_panel2(wks_sam_ts,xy_sam_son,lp,panres2) + delete(xy_sam_son) + panres2@txString = "SAM (Annual)" + gsn_panel2(wks_sam_ts,xy_sam_ann,lp,panres2) + delete(xy_sam_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres2@txString = "SAM (Monthly)" + gsn_panel2(wks_sam_ts,xy_sam_mon,lp,panres2) + delete(xy_sam_mon) + end if + delete(wks_sam_ts) + + panres2@txString = "PSA1 (DJF)" + gsn_panel2(wks_psa1_ts,xy_psa1_djf,lp,panres2) + delete(xy_psa1_djf) + panres2@txString = "PSA1 (MAM)" + gsn_panel2(wks_psa1_ts,xy_psa1_mam,lp,panres2) + delete(xy_psa1_mam) + panres2@txString = "PSA1 (JJA)" + gsn_panel2(wks_psa1_ts,xy_psa1_jja,lp,panres2) + delete(xy_psa1_jja) + panres2@txString = "PSA1 (SON)" + gsn_panel2(wks_psa1_ts,xy_psa1_son,lp,panres2) + delete(xy_psa1_son) + panres2@txString = "PSA1 (Annual)" + gsn_panel2(wks_psa1_ts,xy_psa1_ann,lp,panres2) + delete(xy_psa1_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres2@txString = "PSA1 (Monthly)" + gsn_panel2(wks_psa1_ts,xy_psa1_mon,lp,panres2) + delete(xy_psa1_mon) + end if + delete(wks_psa1_ts) + + panres2@txString = "PSA2 (DJF)" + gsn_panel2(wks_psa2_ts,xy_psa2_djf,lp,panres2) + delete(xy_psa2_djf) + panres2@txString = "PSA2 (MAM)" + gsn_panel2(wks_psa2_ts,xy_psa2_mam,lp,panres2) + delete(xy_psa2_mam) + panres2@txString = "PSA2 (JJA)" + gsn_panel2(wks_psa2_ts,xy_psa2_jja,lp,panres2) + delete(xy_psa2_jja) + panres2@txString = "PSA2 (SON)" + gsn_panel2(wks_psa2_ts,xy_psa2_son,lp,panres2) + delete(xy_psa2_son) + panres2@txString = "PSA2 (Annual)" + gsn_panel2(wks_psa2_ts,xy_psa2_ann,lp,panres2) + delete(xy_psa2_ann) + if (COMPUTE_MODES_MON.eq."True") then + panres2@txString = "PSA2 (Monthly)" + gsn_panel2(wks_psa2_ts,xy_psa2_mon,lp,panres2) + delete(xy_psa2_mon) + end if + delete(wks_psa2_ts) +;-------------------------------------------------------------------------------------------------- + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + system("mv "+OUTDIR+"sam.000001.png "+OUTDIR+"sam.djf.png") + system("mv "+OUTDIR+"sam.000002.png "+OUTDIR+"sam.mam.png") + system("mv "+OUTDIR+"sam.000003.png "+OUTDIR+"sam.jja.png") + system("mv "+OUTDIR+"sam.000004.png "+OUTDIR+"sam.son.png") + system("mv "+OUTDIR+"sam.000005.png "+OUTDIR+"sam.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"sam.000006.png "+OUTDIR+"sam.mon.png") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"sam.000007.png "+OUTDIR+"sam.tempreg.djf.png") + system("mv "+OUTDIR+"sam.000008.png "+OUTDIR+"sam.tempreg.mam.png") + system("mv "+OUTDIR+"sam.000009.png "+OUTDIR+"sam.tempreg.jja.png") + system("mv "+OUTDIR+"sam.000010.png "+OUTDIR+"sam.tempreg.son.png") + system("mv "+OUTDIR+"sam.000011.png "+OUTDIR+"sam.tempreg.ann.png") + system("mv "+OUTDIR+"sam.000012.png "+OUTDIR+"sam.tempreg.mon.png") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"sam.000006.png "+OUTDIR+"sam.tempreg.djf.png") + system("mv "+OUTDIR+"sam.000007.png "+OUTDIR+"sam.tempreg.mam.png") + system("mv "+OUTDIR+"sam.000008.png "+OUTDIR+"sam.tempreg.jja.png") + system("mv "+OUTDIR+"sam.000009.png "+OUTDIR+"sam.tempreg.son.png") + system("mv "+OUTDIR+"sam.000010.png "+OUTDIR+"sam.tempreg.ann.png") + end if + end if + + if (prreg_frame.eq.0) then + system("mv "+OUTDIR+"sam.prreg.000001.png "+OUTDIR+"sam.prreg.djf.png") + system("mv "+OUTDIR+"sam.prreg.000002.png "+OUTDIR+"sam.prreg.mam.png") + system("mv "+OUTDIR+"sam.prreg.000003.png "+OUTDIR+"sam.prreg.jja.png") + system("mv "+OUTDIR+"sam.prreg.000004.png "+OUTDIR+"sam.prreg.son.png") + system("mv "+OUTDIR+"sam.prreg.000005.png "+OUTDIR+"sam.prreg.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"sam.prreg.000006.png "+OUTDIR+"sam.prreg.mon.png") + end if + end if + + system("mv "+OUTDIR+"psa1.000001.png "+OUTDIR+"psa1.djf.png") + system("mv "+OUTDIR+"psa1.000002.png "+OUTDIR+"psa1.mam.png") + system("mv "+OUTDIR+"psa1.000003.png "+OUTDIR+"psa1.jja.png") + system("mv "+OUTDIR+"psa1.000004.png "+OUTDIR+"psa1.son.png") + system("mv "+OUTDIR+"psa1.000005.png "+OUTDIR+"psa1.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psa1.000006.png "+OUTDIR+"psa1.mon.png") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psa1.000007.png "+OUTDIR+"psa1.tempreg.djf.png") + system("mv "+OUTDIR+"psa1.000008.png "+OUTDIR+"psa1.tempreg.mam.png") + system("mv "+OUTDIR+"psa1.000009.png "+OUTDIR+"psa1.tempreg.jja.png") + system("mv "+OUTDIR+"psa1.000010.png "+OUTDIR+"psa1.tempreg.son.png") + system("mv "+OUTDIR+"psa1.000011.png "+OUTDIR+"psa1.tempreg.ann.png") + system("mv "+OUTDIR+"psa1.000012.png "+OUTDIR+"psa1.tempreg.mon.png") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psa1.000006.png "+OUTDIR+"psa1.tempreg.djf.png") + system("mv "+OUTDIR+"psa1.000007.png "+OUTDIR+"psa1.tempreg.mam.png") + system("mv "+OUTDIR+"psa1.000008.png "+OUTDIR+"psa1.tempreg.jja.png") + system("mv "+OUTDIR+"psa1.000009.png "+OUTDIR+"psa1.tempreg.son.png") + system("mv "+OUTDIR+"psa1.000010.png "+OUTDIR+"psa1.tempreg.ann.png") + end if + end if + + if (prreg_frame.eq.0) then + system("mv "+OUTDIR+"psa1.prreg.000001.png "+OUTDIR+"psa1.prreg.djf.png") + system("mv "+OUTDIR+"psa1.prreg.000002.png "+OUTDIR+"psa1.prreg.mam.png") + system("mv "+OUTDIR+"psa1.prreg.000003.png "+OUTDIR+"psa1.prreg.jja.png") + system("mv "+OUTDIR+"psa1.prreg.000004.png "+OUTDIR+"psa1.prreg.son.png") + system("mv "+OUTDIR+"psa1.prreg.000005.png "+OUTDIR+"psa1.prreg.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psa1.prreg.000006.png "+OUTDIR+"psa1.prreg.mon.png") + end if + end if + + system("mv "+OUTDIR+"psa2.000001.png "+OUTDIR+"psa2.djf.png") + system("mv "+OUTDIR+"psa2.000002.png "+OUTDIR+"psa2.mam.png") + system("mv "+OUTDIR+"psa2.000003.png "+OUTDIR+"psa2.jja.png") + system("mv "+OUTDIR+"psa2.000004.png "+OUTDIR+"psa2.son.png") + system("mv "+OUTDIR+"psa2.000005.png "+OUTDIR+"psa2.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psa2.000006.png "+OUTDIR+"psa2.mon.png") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psa2.000007.png "+OUTDIR+"psa2.tempreg.djf.png") + system("mv "+OUTDIR+"psa2.000008.png "+OUTDIR+"psa2.tempreg.mam.png") + system("mv "+OUTDIR+"psa2.000009.png "+OUTDIR+"psa2.tempreg.jja.png") + system("mv "+OUTDIR+"psa2.000010.png "+OUTDIR+"psa2.tempreg.son.png") + system("mv "+OUTDIR+"psa2.000011.png "+OUTDIR+"psa2.tempreg.ann.png") + system("mv "+OUTDIR+"psa2.000012.png "+OUTDIR+"psa2.tempreg.mon.png") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psa2.000006.png "+OUTDIR+"psa2.tempreg.djf.png") + system("mv "+OUTDIR+"psa2.000007.png "+OUTDIR+"psa2.tempreg.mam.png") + system("mv "+OUTDIR+"psa2.000008.png "+OUTDIR+"psa2.tempreg.jja.png") + system("mv "+OUTDIR+"psa2.000009.png "+OUTDIR+"psa2.tempreg.son.png") + system("mv "+OUTDIR+"psa2.000010.png "+OUTDIR+"psa2.tempreg.ann.png") + end if + end if + + if (prreg_frame.eq.0) then + system("mv "+OUTDIR+"psa2.prreg.000001.png "+OUTDIR+"psa2.prreg.djf.png") + system("mv "+OUTDIR+"psa2.prreg.000002.png "+OUTDIR+"psa2.prreg.mam.png") + system("mv "+OUTDIR+"psa2.prreg.000003.png "+OUTDIR+"psa2.prreg.jja.png") + system("mv "+OUTDIR+"psa2.prreg.000004.png "+OUTDIR+"psa2.prreg.son.png") + system("mv "+OUTDIR+"psa2.prreg.000005.png "+OUTDIR+"psa2.prreg.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psa2.prreg.000006.png "+OUTDIR+"psa2.prreg.mon.png") + end if + end if + + system("mv "+OUTDIR+"sam.timeseries.000001.png "+OUTDIR+"sam.timeseries.djf.png") + system("mv "+OUTDIR+"sam.timeseries.000002.png "+OUTDIR+"sam.timeseries.mam.png") + system("mv "+OUTDIR+"sam.timeseries.000003.png "+OUTDIR+"sam.timeseries.jja.png") + system("mv "+OUTDIR+"sam.timeseries.000004.png "+OUTDIR+"sam.timeseries.son.png") + system("mv "+OUTDIR+"sam.timeseries.000005.png "+OUTDIR+"sam.timeseries.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"sam.timeseries.000006.png "+OUTDIR+"sam.timeseries.mon.png") + end if + + system("mv "+OUTDIR+"psa1.timeseries.000001.png "+OUTDIR+"psa1.timeseries.djf.png") + system("mv "+OUTDIR+"psa1.timeseries.000002.png "+OUTDIR+"psa1.timeseries.mam.png") + system("mv "+OUTDIR+"psa1.timeseries.000003.png "+OUTDIR+"psa1.timeseries.jja.png") + system("mv "+OUTDIR+"psa1.timeseries.000004.png "+OUTDIR+"psa1.timeseries.son.png") + system("mv "+OUTDIR+"psa1.timeseries.000005.png "+OUTDIR+"psa1.timeseries.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psa1.timeseries.000006.png "+OUTDIR+"psa1.timeseries.mon.png") + end if + + system("mv "+OUTDIR+"psa2.timeseries.000001.png "+OUTDIR+"psa2.timeseries.djf.png") + system("mv "+OUTDIR+"psa2.timeseries.000002.png "+OUTDIR+"psa2.timeseries.mam.png") + system("mv "+OUTDIR+"psa2.timeseries.000003.png "+OUTDIR+"psa2.timeseries.jja.png") + system("mv "+OUTDIR+"psa2.timeseries.000004.png "+OUTDIR+"psa2.timeseries.son.png") + system("mv "+OUTDIR+"psa2.timeseries.000005.png "+OUTDIR+"psa2.timeseries.ann.png") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psa2.timeseries.000006.png "+OUTDIR+"psa2.timeseries.mon.png") + end if + else + system("psplit "+OUTDIR+"sam.ps "+OUTDIR+"psl_sp") + system("mv "+OUTDIR+"psl_sp0001.ps "+OUTDIR+"sam.djf.ps") + system("mv "+OUTDIR+"psl_sp0002.ps "+OUTDIR+"sam.mam.ps") + system("mv "+OUTDIR+"psl_sp0003.ps "+OUTDIR+"sam.jja.ps") + system("mv "+OUTDIR+"psl_sp0004.ps "+OUTDIR+"sam.son.ps") + system("mv "+OUTDIR+"psl_sp0005.ps "+OUTDIR+"sam.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_sp0006.ps "+OUTDIR+"sam.mon.ps") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_sp0007.ps "+OUTDIR+"sam.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_sp0008.ps "+OUTDIR+"sam.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_sp0009.ps "+OUTDIR+"sam.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_sp0010.ps "+OUTDIR+"sam.tempreg.son.ps") + system("mv "+OUTDIR+"psl_sp0011.ps "+OUTDIR+"sam.tempreg.ann.ps") + system("mv "+OUTDIR+"psl_sp0012.ps "+OUTDIR+"sam.tempreg.mon.ps") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_sp0006.ps "+OUTDIR+"sam.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_sp0007.ps "+OUTDIR+"sam.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_sp0008.ps "+OUTDIR+"sam.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_sp0009.ps "+OUTDIR+"sam.tempreg.son.ps") + system("mv "+OUTDIR+"psl_sp0010.ps "+OUTDIR+"sam.tempreg.ann.ps") + end if + end if + + if (prreg_frame.eq.0) then + system("psplit "+OUTDIR+"sam.prreg.ps "+OUTDIR+"pr_nn") + system("mv "+OUTDIR+"pr_nn0001.ps "+OUTDIR+"sam.prreg.djf.ps") + system("mv "+OUTDIR+"pr_nn0002.ps "+OUTDIR+"sam.prreg.mam.ps") + system("mv "+OUTDIR+"pr_nn0003.ps "+OUTDIR+"sam.prreg.jja.ps") + system("mv "+OUTDIR+"pr_nn0004.ps "+OUTDIR+"sam.prreg.son.ps") + system("mv "+OUTDIR+"pr_nn0005.ps "+OUTDIR+"sam.prreg.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pr_nn0006.ps "+OUTDIR+"sam.prreg.mon.ps") + end if + end if + + system("psplit "+OUTDIR+"psa1.ps "+OUTDIR+"psl_sp") + system("mv "+OUTDIR+"psl_sp0001.ps "+OUTDIR+"psa1.djf.ps") + system("mv "+OUTDIR+"psl_sp0002.ps "+OUTDIR+"psa1.mam.ps") + system("mv "+OUTDIR+"psl_sp0003.ps "+OUTDIR+"psa1.jja.ps") + system("mv "+OUTDIR+"psl_sp0004.ps "+OUTDIR+"psa1.son.ps") + system("mv "+OUTDIR+"psl_sp0005.ps "+OUTDIR+"psa1.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_sp0006.ps "+OUTDIR+"psa1.mon.ps") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_sp0007.ps "+OUTDIR+"psa1.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_sp0008.ps "+OUTDIR+"psa1.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_sp0009.ps "+OUTDIR+"psa1.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_sp0010.ps "+OUTDIR+"psa1.tempreg.son.ps") + system("mv "+OUTDIR+"psl_sp0011.ps "+OUTDIR+"psa1.tempreg.ann.ps") + system("mv "+OUTDIR+"psl_sp0012.ps "+OUTDIR+"psa1.tempreg.mon.ps") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_sp0006.ps "+OUTDIR+"psa1.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_sp0007.ps "+OUTDIR+"psa1.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_sp0008.ps "+OUTDIR+"psa1.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_sp0009.ps "+OUTDIR+"psa1.tempreg.son.ps") + system("mv "+OUTDIR+"psl_sp0010.ps "+OUTDIR+"psa1.tempreg.ann.ps") + end if + end if + + if (prreg_frame.eq.0) then + system("psplit "+OUTDIR+"psa1.prreg.ps "+OUTDIR+"pr_nn") + system("mv "+OUTDIR+"pr_nn0001.ps "+OUTDIR+"psa1.prreg.djf.ps") + system("mv "+OUTDIR+"pr_nn0002.ps "+OUTDIR+"psa1.prreg.mam.ps") + system("mv "+OUTDIR+"pr_nn0003.ps "+OUTDIR+"psa1.prreg.jja.ps") + system("mv "+OUTDIR+"pr_nn0004.ps "+OUTDIR+"psa1.prreg.son.ps") + system("mv "+OUTDIR+"pr_nn0005.ps "+OUTDIR+"psa1.prreg.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pr_nn0006.ps "+OUTDIR+"psa1.prreg.mon.ps") + end if + end if + + system("psplit "+OUTDIR+"psa2.ps "+OUTDIR+"psl_sp") + system("mv "+OUTDIR+"psl_sp0001.ps "+OUTDIR+"psa2.djf.ps") + system("mv "+OUTDIR+"psl_sp0002.ps "+OUTDIR+"psa2.mam.ps") + system("mv "+OUTDIR+"psl_sp0003.ps "+OUTDIR+"psa2.jja.ps") + system("mv "+OUTDIR+"psl_sp0004.ps "+OUTDIR+"psa2.son.ps") + system("mv "+OUTDIR+"psl_sp0005.ps "+OUTDIR+"psa2.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_sp0006.ps "+OUTDIR+"psa2.mon.ps") + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_sp0007.ps "+OUTDIR+"psa2.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_sp0008.ps "+OUTDIR+"psa2.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_sp0009.ps "+OUTDIR+"psa2.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_sp0010.ps "+OUTDIR+"psa2.tempreg.son.ps") + system("mv "+OUTDIR+"psl_sp0011.ps "+OUTDIR+"psa2.tempreg.ann.ps") + system("mv "+OUTDIR+"psl_sp0012.ps "+OUTDIR+"psa2.tempreg.mon.ps") + end if + else + if (sstreg_frame.eq.0) then + system("mv "+OUTDIR+"psl_sp0006.ps "+OUTDIR+"psa2.tempreg.djf.ps") + system("mv "+OUTDIR+"psl_sp0007.ps "+OUTDIR+"psa2.tempreg.mam.ps") + system("mv "+OUTDIR+"psl_sp0008.ps "+OUTDIR+"psa2.tempreg.jja.ps") + system("mv "+OUTDIR+"psl_sp0009.ps "+OUTDIR+"psa2.tempreg.son.ps") + system("mv "+OUTDIR+"psl_sp0010.ps "+OUTDIR+"psa2.tempreg.ann.ps") + end if + end if + + if (prreg_frame.eq.0) then + system("psplit "+OUTDIR+"psa2.prreg.ps "+OUTDIR+"pr_nn") + system("mv "+OUTDIR+"pr_nn0001.ps "+OUTDIR+"psa2.prreg.djf.ps") + system("mv "+OUTDIR+"pr_nn0002.ps "+OUTDIR+"psa2.prreg.mam.ps") + system("mv "+OUTDIR+"pr_nn0003.ps "+OUTDIR+"psa2.prreg.jja.ps") + system("mv "+OUTDIR+"pr_nn0004.ps "+OUTDIR+"psa2.prreg.son.ps") + system("mv "+OUTDIR+"pr_nn0005.ps "+OUTDIR+"psa2.prreg.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"pr_nn0006.ps "+OUTDIR+"psa2.prreg.mon.ps") + end if + system("rm "+OUTDIR+"sam.prreg.ps "+OUTDIR+"psa1.prreg.ps "+OUTDIR+"psa2.prreg.ps") + end if + + system("psplit "+OUTDIR+"sam.timeseries.ps "+OUTDIR+"psl_sp") + system("mv "+OUTDIR+"psl_sp0001.ps "+OUTDIR+"sam.timeseries.djf.ps") + system("mv "+OUTDIR+"psl_sp0002.ps "+OUTDIR+"sam.timeseries.mam.ps") + system("mv "+OUTDIR+"psl_sp0003.ps "+OUTDIR+"sam.timeseries.jja.ps") + system("mv "+OUTDIR+"psl_sp0004.ps "+OUTDIR+"sam.timeseries.son.ps") + system("mv "+OUTDIR+"psl_sp0005.ps "+OUTDIR+"sam.timeseries.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_sp0006.ps "+OUTDIR+"sam.timeseries.mon.ps") + end if + + system("psplit "+OUTDIR+"psa1.timeseries.ps "+OUTDIR+"psl_sp") + system("mv "+OUTDIR+"psl_sp0001.ps "+OUTDIR+"psa1.timeseries.djf.ps") + system("mv "+OUTDIR+"psl_sp0002.ps "+OUTDIR+"psa1.timeseries.mam.ps") + system("mv "+OUTDIR+"psl_sp0003.ps "+OUTDIR+"psa1.timeseries.jja.ps") + system("mv "+OUTDIR+"psl_sp0004.ps "+OUTDIR+"psa1.timeseries.son.ps") + system("mv "+OUTDIR+"psl_sp0005.ps "+OUTDIR+"psa1.timeseries.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_sp0006.ps "+OUTDIR+"psa1.timeseries.mon.ps") + end if + + system("psplit "+OUTDIR+"psa2.timeseries.ps "+OUTDIR+"psl_sp") + system("mv "+OUTDIR+"psl_sp0001.ps "+OUTDIR+"psa2.timeseries.djf.ps") + system("mv "+OUTDIR+"psl_sp0002.ps "+OUTDIR+"psa2.timeseries.mam.ps") + system("mv "+OUTDIR+"psl_sp0003.ps "+OUTDIR+"psa2.timeseries.jja.ps") + system("mv "+OUTDIR+"psl_sp0004.ps "+OUTDIR+"psa2.timeseries.son.ps") + system("mv "+OUTDIR+"psl_sp0005.ps "+OUTDIR+"psa2.timeseries.ann.ps") + if (COMPUTE_MODES_MON.eq."True") then + system("mv "+OUTDIR+"psl_sp0006.ps "+OUTDIR+"psa2.timeseries.mon.ps") + end if + system("rm "+OUTDIR+"psa2.timeseries.ps "+OUTDIR+"psa1.timeseries.ps "+OUTDIR+"sam.timeseries.ps "+OUTDIR+"psa2.ps "+OUTDIR+"psa1.ps "+OUTDIR+"sam.ps") + end if + print("Finished: psl.sam_psa.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/psl.trends.ncl b/lib/externals/CVDP/ncl_scripts/psl.trends.ncl new file mode 100644 index 000000000..7a412ce55 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/psl.trends.ncl @@ -0,0 +1,271 @@ +; Calculates PSL global trends +; +; Variables used: psl +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: psl.trends.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_psl") + na = asciiread("namelist_byvar/namelist_psl",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_trends_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.trends.djf") + wks_trends_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.trends.mam") + wks_trends_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.trends.jja") + wks_trends_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.trends.son") + wks_trends_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.trends.ann") + wks_trends_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"psl.trends.mon") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_trends_djf,"ncl_default") + gsn_define_colormap(wks_trends_mam,"ncl_default") + gsn_define_colormap(wks_trends_jja,"ncl_default") + gsn_define_colormap(wks_trends_son,"ncl_default") + gsn_define_colormap(wks_trends_ann,"ncl_default") + gsn_define_colormap(wks_trends_mon,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_trends_djf,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mam,"BlueDarkRed18") + gsn_define_colormap(wks_trends_jja,"BlueDarkRed18") + gsn_define_colormap(wks_trends_son,"BlueDarkRed18") + gsn_define_colormap(wks_trends_ann,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mon,"BlueDarkRed18") + end if + + map_djf = new(nsim,"graphic") + map_mam = new(nsim,"graphic") + map_jja = new(nsim,"graphic") + map_son = new(nsim,"graphic") + map_ann = new(nsim,"graphic") + map_mon = new(nsim,"graphic") + + do ee = 0,nsim-1 + psl = data_read_in(paths(ee),"PSL",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(psl,"is_all_missing")) then + delete(psl) + continue + end if + if (OPT_CLIMO.eq."Full") then + psl = rmMonAnnCycTLL(psl) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = psl + delete(temp_arr&time) + temp_arr&time = cd_calendar(psl&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + psl = calcMonAnomTLL(psl,climo) + delete(climo) + end if + + tttt = dtrend_msg_n(ispan(0,dimsizes(psl&time)-1,1),psl,False,True,0) + psl_trends_mon = psl(0,:,:) + psl_trends_mon = (/ onedtond(tttt@slope, (/dimsizes(psl&lat),dimsizes(psl&lon)/) ) /) + psl_trends_mon = psl_trends_mon*dimsizes(psl&time) + psl_trends_mon@units = psl@units+" "+nyr(ee)+"yr~S~-1~N~" + delete(tttt) + + psl_seas = runave_n_Wrap(psl,3,0,0) + psl_seas(0,:,:) = (/ dim_avg_n(psl(:1,:,:),0) /) + psl_seas(dimsizes(psl&time)-1,:,:) = (/ dim_avg_n(psl(dimsizes(psl&time)-2:,:,:),0) /) + psl_ann = runave_n_Wrap(psl,12,0,0) + delete(psl) + + psl_trends_seas = psl_seas(:3,:,:) + psl_trends_seas = psl_trends_seas@_FillValue + psl_trends_ann = psl_trends_seas(0,:,:) + do ff = 0,4 + if (ff.le.3) then + tarr = psl_seas(ff*3::12,:,:) + end if + if (ff.eq.4) then + tarr = psl_ann(5::12,:,:) + end if + tttt = dtrend_msg_n(ispan(0,dimsizes(tarr&time)-1,1),tarr,False,True,0) + if (ff.le.3) then + psl_trends_seas(ff,:,:) = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + end if + if (ff.eq.4) then + psl_trends_ann = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + end if + delete([/tarr,tttt/]) + end do + psl_trends_seas = psl_trends_seas*nyr(ee) + psl_trends_seas@units = psl_seas@units+" "+nyr(ee)+"yr~S~-1~N~" + psl_trends_ann = psl_trends_ann*nyr(ee) + psl_trends_ann@units = psl_ann@units+" "+nyr(ee)+"yr~S~-1~N~" + delete([/psl_seas,psl_ann/]) + + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.trends."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + z->psl_trends_djf = set_varAtts(psl_trends_seas(0,:,:),"psl linear trends (DJF)","","") + z->psl_trends_mam = set_varAtts(psl_trends_seas(1,:,:),"psl linear trends (MAM)","","") + z->psl_trends_jja = set_varAtts(psl_trends_seas(2,:,:),"psl linear trends (JJA)","","") + z->psl_trends_son = set_varAtts(psl_trends_seas(3,:,:),"psl linear trends (SON)","","") + z->psl_trends_ann = set_varAtts(psl_trends_ann,"psl linear trends (annual)","","") + z->psl_trends_mon = set_varAtts(psl_trends_mon,"psl linear trends (monthly)","","") + delete(z) + delete([/modname,fn/]) + end if + +;======================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + res@mpGeophysicalLineThicknessF = 2. + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + + res@cnLevelSelectionMode = "ExplicitLevels" + res@cnLevels = ispan(-8,8,1) + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + + res@gsnRightString = psl_trends_seas@units + res@gsnCenterString = names(ee) + map_djf(ee) = gsn_csm_contour_map(wks_trends_djf,psl_trends_seas(0,:,:),res) + map_mam(ee) = gsn_csm_contour_map(wks_trends_mam,psl_trends_seas(1,:,:),res) + map_jja(ee) = gsn_csm_contour_map(wks_trends_jja,psl_trends_seas(2,:,:),res) + map_son(ee) = gsn_csm_contour_map(wks_trends_son,psl_trends_seas(3,:,:),res) + map_ann(ee) = gsn_csm_contour_map(wks_trends_ann,psl_trends_ann,res) + map_mon(ee) = gsn_csm_contour_map(wks_trends_mon,psl_trends_mon,res) + + delete([/psl_trends_seas,psl_trends_ann,psl_trends_mon,res/]) + end do + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + panres@lbLabelFontHeightF = 0.013 + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelStride = 1 + + panres@txString = "PSL Trends (DJF)" + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + gsn_panel2(wks_trends_djf,map_djf,(/nrow,ncol/),panres) + delete(wks_trends_djf) + + panres@txString = "PSL Trends (MAM)" + gsn_panel2(wks_trends_mam,map_mam,(/nrow,ncol/),panres) + delete(wks_trends_mam) + + panres@txString = "PSL Trends (JJA)" + gsn_panel2(wks_trends_jja,map_jja,(/nrow,ncol/),panres) + delete(wks_trends_jja) + + panres@txString = "PSL Trends (SON)" + gsn_panel2(wks_trends_son,map_son,(/nrow,ncol/),panres) + delete(wks_trends_son) + + panres@txString = "PSL Trends (Annual)" + gsn_panel2(wks_trends_ann,map_ann,(/nrow,ncol/),panres) + delete(wks_trends_ann) + + panres@txString = "PSL Trends (Monthly)" + gsn_panel2(wks_trends_mon,map_mon,(/nrow,ncol/),panres) + delete(wks_trends_mon) + delete([/nrow,ncol,map_djf,map_mam,map_jja,map_son,map_ann,map_mon,panres/]) + print("Finished: psl.trends.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/runTasks.py b/lib/externals/CVDP/ncl_scripts/runTasks.py new file mode 100644 index 000000000..1d3269420 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/runTasks.py @@ -0,0 +1,58 @@ +import subprocess +import sys +import time +import os + +#--------------------------- BEGIN USER MODIFICATIONS --------------------------- +EXEC_STR = "ncl -Q" +POLL_INTERVAL = 15. # seconds +MAX_CONCURRENT = int(os.environ.get('MAX_TASKS')) # previous settings: = 4 or = sys.maxint +#--------------------------- END USER MODIFICATIONS ----------------------------- + +def launchTask(script): +# print "Launching: ", script + task = subprocess.Popen(EXEC_STR + " " + script, shell=True, executable="/bin/bash") + return task + +# ------------------------- main ----------------------------------------------- + +# get command-line args, strip out 1st element, which is the name of this script... +scripts = sys.argv[1:] +#print scripts # debugging -- remove or comment out + +# fire off up-to MAX_CONCURRENT subprocesses... +tasks = list() +for i,script in enumerate(scripts): + if i >= MAX_CONCURRENT: + break + tasks.append( launchTask(script) ) + +#print scripts +scripts = scripts[len(tasks):] # remove those scripts we've just launched... +#print scripts + +#for task in tasks: # debugging -- remove or comment out +# print(task.pid) + +while len(tasks) > 0: + finishedList = [] + for task in tasks: + retCode = task.poll() + if retCode != None: +# print "Task status ", task.pid, ": ", task.poll() + finishedList.append(task) + + # more scripts to be run? + if len(scripts) > 0: + tasks.append( launchTask(scripts[0]) ) + del scripts[0] + + for task in finishedList: + tasks.remove(task) + + time.sleep(POLL_INTERVAL) +# print "." # Feedback to show the script is doing something; not necessary + +print("runTasks.py: Done with CVDP calculation scripts") + + diff --git a/lib/externals/CVDP/ncl_scripts/snd.mean_stddev.ncl b/lib/externals/CVDP/ncl_scripts/snd.mean_stddev.ncl new file mode 100644 index 000000000..c22c8abdc --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/snd.mean_stddev.ncl @@ -0,0 +1,366 @@ +; Calculates 2m air temperature global means and standard deviations +; +; Variables used: snd +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: snd.mean_stddev.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_snowdp") + na = asciiread("namelist_byvar/namelist_snowdp",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_stddev_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.stddev.djf") + wks_stddev_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.stddev.mam") + wks_stddev_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.stddev.jja") + wks_stddev_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.stddev.son") + wks_stddev_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.stddev.ann") + wks_mean_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.mean.djf") + wks_mean_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.mean.mam") + wks_mean_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.mean.jja") + wks_mean_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.mean.son") + wks_mean_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.mean.ann") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_stddev_djf,"rainbow+white") + gsn_define_colormap(wks_stddev_mam,"rainbow+white") + gsn_define_colormap(wks_stddev_jja,"rainbow+white") + gsn_define_colormap(wks_stddev_son,"rainbow+white") + gsn_define_colormap(wks_stddev_ann,"rainbow+white") + gsn_define_colormap(wks_mean_djf,"ncl_default") + gsn_define_colormap(wks_mean_mam,"ncl_default") + gsn_define_colormap(wks_mean_jja,"ncl_default") + gsn_define_colormap(wks_mean_son,"ncl_default") + gsn_define_colormap(wks_mean_ann,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_stddev_djf,"cb_rainbow") + gsn_define_colormap(wks_stddev_mam,"cb_rainbow") + gsn_define_colormap(wks_stddev_jja,"cb_rainbow") + gsn_define_colormap(wks_stddev_son,"cb_rainbow") + gsn_define_colormap(wks_stddev_ann,"cb_rainbow") + gsn_define_colormap(wks_mean_djf,"BlueDarkRed18") + gsn_define_colormap(wks_mean_mam,"BlueDarkRed18") + gsn_define_colormap(wks_mean_jja,"BlueDarkRed18") + gsn_define_colormap(wks_mean_son,"BlueDarkRed18") + gsn_define_colormap(wks_mean_ann,"BlueDarkRed18") + end if + + plot_mean_djf = new(nsim,"graphic") + plot_mean_mam = new(nsim,"graphic") + plot_mean_jja = new(nsim,"graphic") + plot_mean_son = new(nsim,"graphic") + plot_mean_ann = new(nsim,"graphic") + plot_stddev_djf = new(nsim,"graphic") + plot_stddev_mam = new(nsim,"graphic") + plot_stddev_jja = new(nsim,"graphic") + plot_stddev_son = new(nsim,"graphic") + plot_stddev_ann = new(nsim,"graphic") + do ee = 0,nsim-1 + snd = data_read_in(paths(ee),"SNOWDP",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(snd&lat,"_FillValue")) then ; required in v6.2.0-beta to reset _FillValue to avoid error message + snd&lat@_FillValue = 1.e20 + snd&lat@missing_value = snd&lat@_FillValue + end if + if (isatt(snd&lon,"_FillValue")) then + snd&lon@_FillValue = 1.e20 + snd&lon@missing_value = snd&lon@_FillValue + end if + + if (isatt(snd,"is_all_missing")) then + delete(snd) + continue + end if + do ff = 0,1 + sndT = snd + if (ff.eq.1) then + if (OPT_CLIMO.eq."Full") then + sndT = rmMonAnnCycTLL(sndT) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sndT + delete(temp_arr&time) + temp_arr&time = cd_calendar(sndT&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sndT = calcMonAnomTLL(sndT,climo) + delete(climo) + end if + end if + snd_seas = runave_n_Wrap(sndT,3,0,0) + snd_seas(0,:,:) = (/ dim_avg_n(sndT(:1,:,:),0) /) + snd_seas(dimsizes(sndT&time)-1,:,:) = (/ dim_avg_n(sndT(dimsizes(sndT&time)-2:,:,:),0) /) + snd_ann = runave_n_Wrap(sndT,12,0,0) + delete(sndT) + + if (ff.eq.0) then + snd_mean_djf = dim_avg_n_Wrap(snd_seas(0::12,:,:),0) + snd_mean_mam = dim_avg_n_Wrap(snd_seas(3::12,:,:),0) + snd_mean_jja = dim_avg_n_Wrap(snd_seas(6::12,:,:),0) + snd_mean_son = dim_avg_n_Wrap(snd_seas(9::12,:,:),0) + snd_mean_ann = dim_avg_n_Wrap(snd_ann(5::12,:,:),0) + end if + if (ff.eq.1) then + snd_sd_djf = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),snd_seas(0::12,:,:),False,False,0),0) + snd_sd_mam = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),snd_seas(3::12,:,:),False,False,0),0) + snd_sd_jja = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),snd_seas(6::12,:,:),False,False,0),0) + snd_sd_son = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),snd_seas(9::12,:,:),False,False,0),0) + snd_sd_ann = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),snd_ann(5::12,:,:),False,False,0),0) + end if + delete([/snd_seas,snd_ann/]) + end do + delete(snd) + copy_VarMeta(snd_mean_djf,snd_sd_djf) + copy_VarMeta(snd_mean_mam,snd_sd_mam) + copy_VarMeta(snd_mean_jja,snd_sd_jja) + copy_VarMeta(snd_mean_son,snd_sd_son) + copy_VarMeta(snd_mean_ann,snd_sd_ann) + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.snd.mean_stddev."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + + mean_djf = (/ snd_mean_djf /) + mean_djf!0 = "LAT" + mean_djf&LAT = snd_mean_djf&lat + mean_djf!1 = "LON" + mean_djf&LON = snd_mean_djf&lon + copy_VarAtts(snd_mean_djf,mean_djf) + mean_mam = (/ snd_mean_mam /) + copy_VarMeta(mean_djf,mean_mam) + mean_jja = (/ snd_mean_jja /) + copy_VarMeta(mean_djf,mean_jja) + mean_son = (/ snd_mean_son /) + copy_VarMeta(mean_djf,mean_son) + mean_ann = (/ snd_mean_ann /) + copy_VarMeta(mean_djf,mean_ann) + + sd_djf = (/ snd_sd_djf /) + sd_djf!0 = "LAT" + sd_djf&LAT = snd_sd_djf&lat + sd_djf!1 = "LON" + sd_djf&LON = snd_sd_djf&lon + copy_VarAtts(snd_sd_djf,sd_djf) + sd_mam = (/ snd_sd_mam /) + copy_VarMeta(sd_djf,sd_mam) + sd_jja = (/ snd_sd_jja /) + copy_VarMeta(sd_djf,sd_jja) + sd_son = (/ snd_sd_son /) + copy_VarMeta(sd_djf,sd_son) + sd_ann = (/ snd_sd_ann /) + copy_VarMeta(sd_djf,sd_ann) + + z->snd_spatialmean_djf = set_varAtts(mean_djf,"snd mean (DJF)","","") + z->snd_spatialmean_mam = set_varAtts(mean_mam,"snd mean (MAM)","","") + z->snd_spatialmean_jja = set_varAtts(mean_jja,"snd mean (JJA)","","") + z->snd_spatialmean_son = set_varAtts(mean_son,"snd mean (SON)","","") + z->snd_spatialmean_ann = set_varAtts(mean_ann,"snd mean (annual)","","") + + z->snd_spatialstddev_djf = set_varAtts(sd_djf,"snd standard deviation (DJF)","","") + z->snd_spatialstddev_mam = set_varAtts(sd_mam,"snd standard deviation (MAM)","","") + z->snd_spatialstddev_jja = set_varAtts(sd_jja,"snd standard deviation (JJA)","","") + z->snd_spatialstddev_son = set_varAtts(sd_son,"snd standard deviation (SON)","","") + z->snd_spatialstddev_ann = set_varAtts(sd_ann,"snd standard deviation (annual)","","") + delete(z) + delete(modname) + delete([/mean_djf,mean_mam,mean_jja,mean_son,mean_ann,sd_djf,sd_mam,sd_jja,sd_son,sd_ann/]) + end if +;========================================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@gsnDraw = False + res@gsnFrame = False + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + res@cnFillMode = "RasterFill" + res@cnLevelSelectionMode = "ExplicitLevels" + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + + sres = res + + res@cnLevels = fspan(.05,.45,9) + if (COLORMAP.eq.0) then + res@cnFillColors = (/0,54,80,95,125,175,185,195,205,236/) + sres@cnLevels = fspan(0.05,1.5,30) + sres@cnFillColors = ispan(8,248,8) + sres@cnFillColors(0) = 0 + end if + if (COLORMAP.eq.1) then + res@cnFillColors = (/0,35,47,63,79,95,111,124,155,175/) + sres@cnLevels = fspan(0.05,1.45,15) + sres@cnFillColors = (/0,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18/) + end if + + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnRightString = snd_sd_djf@units + res@gsnCenterString = names(ee) + + plot_stddev_djf(ee) = gsn_csm_contour_map(wks_stddev_djf,snd_sd_djf,res) + plot_stddev_mam(ee) = gsn_csm_contour_map(wks_stddev_mam,snd_sd_mam,res) + plot_stddev_jja(ee) = gsn_csm_contour_map(wks_stddev_jja,snd_sd_jja,res) + plot_stddev_son(ee) = gsn_csm_contour_map(wks_stddev_son,snd_sd_son,res) + plot_stddev_ann(ee) = gsn_csm_contour_map(wks_stddev_ann,snd_sd_ann,res) + + sres@gsnLeftString = syear(ee)+"-"+eyear(ee) + sres@gsnRightString = snd_mean_djf@units + sres@gsnCenterString = names(ee) + plot_mean_djf(ee) = gsn_csm_contour_map(wks_mean_djf,snd_mean_djf,sres) + plot_mean_mam(ee) = gsn_csm_contour_map(wks_mean_mam,snd_mean_mam,sres) + plot_mean_jja(ee) = gsn_csm_contour_map(wks_mean_jja,snd_mean_jja,sres) + plot_mean_son(ee) = gsn_csm_contour_map(wks_mean_son,snd_mean_son,sres) + plot_mean_ann(ee) = gsn_csm_contour_map(wks_mean_ann,snd_mean_ann,sres) + delete([/snd_sd_djf,snd_sd_mam,snd_sd_jja,snd_sd_son,snd_sd_ann,snd_mean_djf,snd_mean_mam,snd_mean_jja,snd_mean_son,snd_mean_ann,res,sres/]) + end do + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelFontHeightF = 0.013 + panres@lbLabelStride = 1 + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres@txString = "SND Standard Deviations (DJF)" + gsn_panel2(wks_stddev_djf,plot_stddev_djf,(/nrow,ncol/),panres) + delete(wks_stddev_djf) + + panres@txString = "SND Standard Deviations (MAM)" + gsn_panel2(wks_stddev_mam,plot_stddev_mam,(/nrow,ncol/),panres) + delete(wks_stddev_mam) + + panres@txString = "SND Standard Deviations (JJA)" + gsn_panel2(wks_stddev_jja,plot_stddev_jja,(/nrow,ncol/),panres) + delete(wks_stddev_jja) + + panres@txString = "SND Standard Deviations (SON)" + gsn_panel2(wks_stddev_son,plot_stddev_son,(/nrow,ncol/),panres) + delete(wks_stddev_son) + + panres@txString = "SND Standard Deviations (Annual)" + gsn_panel2(wks_stddev_ann,plot_stddev_ann,(/nrow,ncol/),panres) + delete(wks_stddev_ann) + + panres@txString = "SND Means (DJF)" + gsn_panel2(wks_mean_djf,plot_mean_djf,(/nrow,ncol/),panres) + delete(wks_mean_djf) + + panres@txString = "SND Means (MAM)" + gsn_panel2(wks_mean_mam,plot_mean_mam,(/nrow,ncol/),panres) + delete(wks_mean_mam) + + panres@txString = "SND Means (JJA)" + gsn_panel2(wks_mean_jja,plot_mean_jja,(/nrow,ncol/),panres) + delete(wks_mean_jja) + + panres@txString = "SND Means (SON)" + gsn_panel2(wks_mean_son,plot_mean_son,(/nrow,ncol/),panres) + delete(wks_mean_son) + + panres@txString = "SND Means (Annual)" + gsn_panel2(wks_mean_ann,plot_mean_ann,(/nrow,ncol/),panres) + delete(wks_mean_ann) + delete(panres) + print("Finished: snd.mean_stddev.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/snd.trends.ncl b/lib/externals/CVDP/ncl_scripts/snd.trends.ncl new file mode 100644 index 000000000..76607b69b --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/snd.trends.ncl @@ -0,0 +1,320 @@ +; Calculates snow depth global trends +; +; Variables used: snd +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: snd.trends.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_snowdp") + na = asciiread("namelist_byvar/namelist_snowdp",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_trends_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.trends.djf") + wks_trends_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.trends.mam") + wks_trends_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.trends.jja") + wks_trends_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.trends.son") + wks_trends_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.trends.ann") + wks_trends_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"snd.trends.mon") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_trends_djf,"ncl_default") + gsn_define_colormap(wks_trends_mam,"ncl_default") + gsn_define_colormap(wks_trends_jja,"ncl_default") + gsn_define_colormap(wks_trends_son,"ncl_default") + gsn_define_colormap(wks_trends_ann,"ncl_default") + gsn_define_colormap(wks_trends_mon,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_trends_djf,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mam,"BlueDarkRed18") + gsn_define_colormap(wks_trends_jja,"BlueDarkRed18") + gsn_define_colormap(wks_trends_son,"BlueDarkRed18") + gsn_define_colormap(wks_trends_ann,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mon,"BlueDarkRed18") + end if + cmap = gsn_retrieve_colormap(wks_trends_djf) + + map_djf = new(nsim,"graphic") + map_mam = new(nsim,"graphic") + map_jja = new(nsim,"graphic") + map_son = new(nsim,"graphic") + map_ann = new(nsim,"graphic") + map_mon = new(nsim,"graphic") + + do ee = 0,nsim-1 + snd = data_read_in(paths(ee),"SNOWDP",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(snd&lat,"_FillValue")) then ; required in v6.2.0-beta to reset _FillValue to avoid error message + snd&lat@_FillValue = 1.e20 + snd&lat@missing_value = snd&lat@_FillValue + end if + if (isatt(snd&lon,"_FillValue")) then + snd&lon@_FillValue = 1.e20 + snd&lon@missing_value = snd&lon@_FillValue + end if + + if (isatt(snd,"is_all_missing")) then + delete(snd) + continue + end if + if (OPT_CLIMO.eq."Full") then + snd = rmMonAnnCycTLL(snd) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = snd + delete(temp_arr&time) + temp_arr&time = cd_calendar(snd&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + snd = calcMonAnomTLL(snd,climo) + delete(climo) + end if + + tttt = dtrend_msg_n(ispan(0,dimsizes(snd&time)-1,1),snd,False,True,0) + snd_trends_mon = snd(0,:,:) + snd_trends_mon = (/ onedtond(tttt@slope, (/dimsizes(snd&lat),dimsizes(snd&lon)/) ) /) + snd_trends_mon = snd_trends_mon*dimsizes(snd&time) + snd_trends_mon@units = snd@units+" "+nyr(ee)+"yr~S~-1~N~" + delete(tttt) + + snd_seas = runave_n_Wrap(snd,3,0,0) + snd_seas(0,:,:) = (/ dim_avg_n(snd(:1,:,:),0) /) + snd_seas(dimsizes(snd&time)-1,:,:) = (/ dim_avg_n(snd(dimsizes(snd&time)-2:,:,:),0) /) + snd_ann = runave_n_Wrap(snd,12,0,0) + delete(snd) + + snd_trends_seas = snd_seas(:3,:,:) + snd_trends_seas = snd_trends_seas@_FillValue + snd_trends_ann = snd_trends_seas(0,:,:) + do ff = 0,4 + if (ff.le.3) then + tarr = snd_seas(ff*3::12,:,:) + end if + if (ff.eq.4) then + tarr = snd_ann(5::12,:,:) + end if + tttt = dtrend_msg_n(ispan(0,dimsizes(tarr&time)-1,1),tarr,False,True,0) + if (ff.le.3) then + snd_trends_seas(ff,:,:) = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + end if + if (ff.eq.4) then + snd_trends_ann = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + end if + delete([/tarr,tttt/]) + end do + snd_trends_seas = snd_trends_seas*nyr(ee) + snd_trends_seas@units = snd_seas@units+" "+nyr(ee)+"yr~S~-1~N~" + snd_trends_ann = snd_trends_ann*nyr(ee) + snd_trends_ann@units = snd_ann@units+" "+nyr(ee)+"yr~S~-1~N~" + delete([/snd_seas,snd_ann/]) + + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.snd.trends."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + snd_seas = (/ snd_trends_seas /) + snd_seas!1 = "LAT" + snd_seas&LAT = snd_trends_seas&lat + snd_seas!2 = "LON" + snd_seas&LON = snd_trends_seas&lon + copy_VarAtts(snd_trends_seas,snd_seas) + + snd_ann = (/ snd_trends_ann /) + snd_ann!0 = "LAT" + snd_ann&LAT = snd_trends_ann&lat + snd_ann!1 = "LON" + snd_ann&LON = snd_trends_ann&lon + copy_VarAtts(snd_trends_ann,snd_ann) + + snd_mon = (/ snd_trends_mon /) + snd_mon!0 = "LAT" + snd_mon&LAT = snd_trends_mon&lat + snd_mon!1 = "LON" + snd_mon&LON = snd_trends_mon&lon + copy_VarAtts(snd_trends_mon,snd_mon) + + z->snd_trends_djf = set_varAtts(snd_seas(0,:,:),"snd linear trends (DJF)","","") + z->snd_trends_mam = set_varAtts(snd_seas(1,:,:),"snd linear trends (MAM)","","") + z->snd_trends_jja = set_varAtts(snd_seas(2,:,:),"snd linear trends (JJA)","","") + z->snd_trends_son = set_varAtts(snd_seas(3,:,:),"snd linear trends (SON)","","") + z->snd_trends_ann = set_varAtts(snd_ann,"snd linear trends (annual)","","") + z->snd_trends_mon = set_varAtts(snd_mon,"snd linear trends (monthly)","","") + delete(z) + delete([/snd_seas,snd_ann,snd_mon/]) + end if + + snd_trends_seas = where(abs(snd_trends_seas).le..005,snd_trends_seas@_FillValue,snd_trends_seas) ; .005m = arbitrary # to white out + snd_trends_ann = where(abs(snd_trends_ann).le..005,snd_trends_ann@_FillValue,snd_trends_ann) ; areas w/very very small trends.. + snd_trends_mon = where(abs(snd_trends_mon).le..005,snd_trends_mon@_FillValue,snd_trends_mon) +;======================================================================== +; cmap = read_colormap_file("ncl_default") + + + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 0. + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + + res@cnFillPalette = cmap(2::-1,:) + res@cnFillMode = "RasterFill" + res@cnLevelSelectionMode = "ExplicitLevels" + if (COLORMAP.eq.0) then + res@cnLevels = fspan(-.5,.5,21) + end if + if (COLORMAP.eq.1) then + res@cnLevels = fspan(-.8,.8,17) + end if + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + + res@gsnRightString = snd_trends_seas@units + res@gsnCenterString = names(ee) + map_djf(ee) = gsn_csm_contour_map(wks_trends_djf,snd_trends_seas(0,:,:),res) + map_mam(ee) = gsn_csm_contour_map(wks_trends_mam,snd_trends_seas(1,:,:),res) + map_jja(ee) = gsn_csm_contour_map(wks_trends_jja,snd_trends_seas(2,:,:),res) + map_son(ee) = gsn_csm_contour_map(wks_trends_son,snd_trends_seas(3,:,:),res) + map_ann(ee) = gsn_csm_contour_map(wks_trends_ann,snd_trends_ann,res) + map_mon(ee) = gsn_csm_contour_map(wks_trends_mon,snd_trends_mon,res) + + delete([/snd_trends_seas,snd_trends_ann,snd_trends_mon/]) + delete(res) + end do + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + panres@lbLabelFontHeightF = 0.013 + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelStride = 1 + + panres@txString = "SND Trends (DJF)" + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + gsn_panel2(wks_trends_djf,map_djf,(/nrow,ncol/),panres) + delete(wks_trends_djf) + + panres@txString = "SND Trends (MAM)" + gsn_panel2(wks_trends_mam,map_mam,(/nrow,ncol/),panres) + delete(wks_trends_mam) + + panres@txString = "SND Trends (JJA)" + gsn_panel2(wks_trends_jja,map_jja,(/nrow,ncol/),panres) + delete(wks_trends_jja) + + panres@txString = "SND Trends (SON)" + gsn_panel2(wks_trends_son,map_son,(/nrow,ncol/),panres) + delete(wks_trends_son) + + panres@txString = "SND Trends (Annual)" + gsn_panel2(wks_trends_ann,map_ann,(/nrow,ncol/),panres) + delete(wks_trends_ann) + + panres@txString = "SND Trends (Monthly)" + gsn_panel2(wks_trends_mon,map_mon,(/nrow,ncol/),panres) + delete(wks_trends_mon) + delete([/nrow,ncol,map_djf,map_mam,map_jja,map_son,map_ann,map_mon,panres,cmap/]) + print("Finished: snd.trends.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/sst.indices.ncl b/lib/externals/CVDP/ncl_scripts/sst.indices.ncl new file mode 100644 index 000000000..d58d0c4c7 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/sst.indices.ncl @@ -0,0 +1,2068 @@ +; Calculates a variety of oceanic indices, as well as hovmollers, spectra, +; monthly standard deviations, running standard deviations, and spatial +; composites based on the nino3.4 index. +; +; Variables used: ts, psl, and tas +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: sst.indices.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_ts") + na = asciiread("namelist_byvar/namelist_ts",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + delete(na) + nyr = eyear-syear+1 + nyr_max = max(nyr) +;----------- nino3.4 spatial composite coding------------- + nsim_psl = numAsciiRow("namelist_byvar/namelist_psl") + na_psl = asciiread("namelist_byvar/namelist_psl",(/nsim_psl/),"string") + names_psl = new(nsim_psl,"string") + paths_psl = new(nsim_psl,"string") + syear_psl = new(nsim_psl,"integer",-999) + eyear_psl = new(nsim_psl,"integer",-999) + + do gg = 0,nsim_psl-1 + names_psl(gg) = str_strip(str_get_field(na_psl(gg),1,delim)) + paths_psl(gg) = str_strip(str_get_field(na_psl(gg),2,delim)) + syear_psl(gg) = stringtointeger(str_strip(str_get_field(na_psl(gg),3,delim))) + eyear_psl(gg) = stringtointeger(str_strip(str_get_field(na_psl(gg),4,delim))) + end do + delete(na_psl) + nyr_psl = eyear_psl-syear_psl+1 + + nsim_trefht = numAsciiRow("namelist_byvar/namelist_trefht") + na_trefht = asciiread("namelist_byvar/namelist_trefht",(/nsim_trefht/),"string") + names_trefht = new(nsim_trefht,"string") + paths_trefht = new(nsim_trefht,"string") + syear_trefht = new(nsim_trefht,"integer",-999) + eyear_trefht = new(nsim_trefht,"integer",-999) + + do gg = 0,nsim_trefht-1 + names_trefht(gg) = str_strip(str_get_field(na_trefht(gg),1,delim)) + paths_trefht(gg) = str_strip(str_get_field(na_trefht(gg),2,delim)) + syear_trefht(gg) = stringtointeger(str_strip(str_get_field(na_trefht(gg),3,delim))) + eyear_trefht(gg) = stringtointeger(str_strip(str_get_field(na_trefht(gg),4,delim))) + end do + delete(na_trefht) + nyr_trefht = eyear_trefht-syear_trefht+1 + + nsim_prect = numAsciiRow("namelist_byvar/namelist_prect") + na_prect = asciiread("namelist_byvar/namelist_prect",(/nsim_prect/),"string") + names_prect = new(nsim_prect,"string") + paths_prect = new(nsim_prect,"string") + syear_prect = new(nsim_prect,"integer",-999) + eyear_prect = new(nsim_prect,"integer",-999) + + do gg = 0,nsim_prect-1 + names_prect(gg) = str_strip(str_get_field(na_prect(gg),1,delim)) + paths_prect(gg) = str_strip(str_get_field(na_prect(gg),2,delim)) + syear_prect(gg) = stringtointeger(str_strip(str_get_field(na_prect(gg),3,delim))) + eyear_prect(gg) = stringtointeger(str_strip(str_get_field(na_prect(gg),4,delim))) + end do + delete(na_prect) + nyr_prect = eyear_prect-syear_prect+1 +;------------------------------------------------------------------------------------------------- + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_n34 = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino34.timeseries") + wks_n4 = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino4.timeseries") + wks_n3 = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino3.timeseries") + wks_n12 = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino12.timeseries") + wks_tna = gsn_open_wks(wks_type,getenv("OUTDIR")+"tna.timeseries") + wks_tsa = gsn_open_wks(wks_type,getenv("OUTDIR")+"tsa.timeseries") + wks_tio = gsn_open_wks(wks_type,getenv("OUTDIR")+"tio.timeseries") + + wks_n34_tlon_hi = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino34.hov.elnino") + wks_n34_tlon_lo = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino34.hov.lanina") + + wks_n34_p = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino34.powspec") + + wks_n34_rst = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino34.runstddev") + + wks_n34_mst = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino34.monstddev") + + wks_n34sc = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino34.spatialcomp") + + wks_n34sc_ppt = gsn_open_wks(wks_type,getenv("OUTDIR")+"nino34.spatialcomp.ppt") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_n34,"ncl_default") + gsn_define_colormap(wks_n4,"ncl_default") + gsn_define_colormap(wks_n3,"ncl_default") + gsn_define_colormap(wks_n12,"ncl_default") + gsn_define_colormap(wks_tna,"ncl_default") + gsn_define_colormap(wks_tsa,"ncl_default") + gsn_define_colormap(wks_tio,"ncl_default") + gsn_merge_colormaps(wks_n34_tlon_hi,"BlueDarkRed18",(/"gray30","gray50","gray70"/)) + gsn_merge_colormaps(wks_n34_tlon_lo,"BlueDarkRed18",(/"gray30","gray50","gray70"/)) + gsn_define_colormap(wks_n34_p,"cb_9step") + gsn_define_colormap(wks_n34_rst,"ncl_default") + gsn_define_colormap(wks_n34_mst,"ncl_default") + gsn_define_colormap(wks_n34sc,"ncl_default") + gsn_define_colormap(wks_n34sc_ppt,"MPL_BrBG") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_n34,"ncl_default") + gsn_define_colormap(wks_n4,"ncl_default") + gsn_define_colormap(wks_n3,"ncl_default") + gsn_define_colormap(wks_n12,"ncl_default") + gsn_define_colormap(wks_tna,"ncl_default") + gsn_define_colormap(wks_tsa,"ncl_default") + gsn_define_colormap(wks_tio,"ncl_default") + gsn_merge_colormaps(wks_n34_tlon_hi,"BlueDarkRed18",(/"gray30","gray50","gray70"/)) + gsn_merge_colormaps(wks_n34_tlon_lo,"BlueDarkRed18",(/"gray30","gray50","gray70"/)) + gsn_define_colormap(wks_n34_p,"cb_9step") + gsn_define_colormap(wks_n34_rst,"ncl_default") + gsn_define_colormap(wks_n34_mst,"ncl_default") + gsn_define_colormap(wks_n34sc,"BlueDarkRed18") + gsn_define_colormap(wks_n34sc_ppt,"BrownBlue12") + end if + + xyn34 = new(nsim,"graphic") + xyn4 = new(nsim,"graphic") + xyn3 = new(nsim,"graphic") + xyn12 = new(nsim,"graphic") + xytna = new(nsim,"graphic") + xytsa = new(nsim,"graphic") + xytio = new(nsim,"graphic") + xyiod = new(nsim,"graphic") + xysocn = new(nsim,"graphic") + xyamm = new(nsim,"graphic") + xyatl3 = new(nsim,"graphic") + + plot_n34hi = new(nsim,"graphic") + plot_n34lo = new(nsim,"graphic") + + map_n34sc_jja0 = new(nsim,"graphic") + map_n34sc_son0 = new(nsim,"graphic") + map_n34sc_djf1 = new(nsim,"graphic") + map_n34sc_mam1 = new(nsim,"graphic") + + map_n34sc_ppt_jja0 = new(nsim,"graphic") + map_n34sc_ppt_son0 = new(nsim,"graphic") + map_n34sc_ppt_djf1 = new(nsim,"graphic") + map_n34sc_ppt_mam1 = new(nsim,"graphic") + + xyn34_rst = new(nsim,"graphic") + xyn34_mst = new(nsim,"graphic") + xyn34_ac = new(nsim,"graphic") + plot_wave34 = new(nsim,"graphic") + + pspec = new(nsim,"graphic") + if (isfilepresent2("obs_ts")) then + pspec_obs = new(nsim,"graphic") + xyn34_ac_obs = new(nsim,"graphic") + end if + + wgt = (/1.,2.,1./) + wgt = wgt/sum(wgt) + pi=4.*atan(1.0) + rad=(pi/180.) + + do ee = 0,nsim-1 + sst = data_read_in(paths(ee),"TS",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + + if (isatt(sst,"is_all_missing")) then + delete(sst) + continue + end if + + sst = where(sst.le.-1.8,-1.8,sst) ; set all values below -1.8 to -1.8 + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") ; mask out land (this is redundant for data that is already masked) + basemap = d->LSMASK + lsm = landsea_mask(basemap,sst&lat,sst&lon) + sst = mask(sst,conform(sst,lsm,(/1,2/)).ge.1,False) + delete([/lsm,basemap/]) + delete(d) + + if (OPT_CLIMO.eq."Full") then + sst = rmMonAnnCycTLL(sst) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sst + delete(temp_arr&time) + temp_arr&time = cd_calendar(sst&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sst = calcMonAnomTLL(sst,climo) + delete(climo) + end if + + coswgt=cos(rad*sst&lat) + coswgt!0 = "lat" + coswgt&lat= sst&lat + llats = -5. ; nino3.4 + llatn = 5. + llonw = 190. + llone = 240. + nino34 = wgt_areaave_Wrap(sst(:,{llats:llatn},{llonw:llone}),coswgt({llats:llatn}),1.0,0) + nino34@comment_cvdp = "area average domain ("+llats+":"+llatn+"N, "+llonw+":"+llone+"E)" + nino34@units = sst@units + nino34@long_name = "nino3.4 timeseries (monthly)" + + llats = -5. ; nino3 + llatn = 5. + llonw = 210. + llone = 270. + nino3 = wgt_areaave(sst(:,{llats:llatn},{llonw:llone}),coswgt({llats:llatn}),1.0,0) + nino3@comment_cvdp = "area average domain ("+llats+":"+llatn+"N, "+llonw+":"+llone+"E)" + copy_VarCoords(nino34,nino3) + nino3@units = sst@units + nino3@long_name = "nino3 timeseries (monthly)" + + llats = -5. ; nino4 + llatn = 5. + llonw = 160. + llone = 210. + nino4 = wgt_areaave(sst(:,{llats:llatn},{llonw:llone}),coswgt({llats:llatn}),1.0,0) + nino4@comment_cvdp = "area average domain ("+llats+":"+llatn+"N, "+llonw+":"+llone+"E)" + copy_VarCoords(nino34,nino4) + nino4@units = sst@units + nino4@long_name = "nino4 timeseries (monthly)" + + llats = -10. ; nino1+2 + llatn = 0. + llonw = 270. + llone = 280. + nino12 = wgt_areaave(sst(:,{llats:llatn},{llonw:llone}),coswgt({llats:llatn}),1.0,0) + nino12@comment_cvdp = "area average domain ("+llats+":"+llatn+"N, "+llonw+":"+llone+"E)" + copy_VarCoords(nino34,nino12) + nino12@units = sst@units + nino12@long_name = "nino1+2 timeseries (monthly)" + + ssttemp = lonFlip(sst) + amm_n = wgt_areaave(ssttemp(:,{5.:15.},{-50.:-20.}),coswgt({5.:15.}),1.0,0) ; Atlantic Meridional Mode + amm_s = wgt_areaave(ssttemp(:,{-15.:-5.},{-20.:10.}),coswgt({-15.:-5.}),1.0,0) + amm = amm_n + amm = (/ amm_n - amm_s /) + delete([/amm_n,amm_s/]) + amm@comment_cvdp = "area average domain (-5:20N, 80W:0E) - (-10:5N, 60W:15E)" + copy_VarCoords(nino34,amm) + amm@units = sst@units + amm@long_name = "Atlantic Meridional Mode Index (monthly)" + + llats = -3. ; Atlantic Nino (ATL3) + llatn = 3. + llonw = -20. + llone = 0. + atl3 = wgt_areaave(ssttemp(:,{llats:llatn},{llonw:llone}),coswgt({llats:llatn}),1.0,0) + atl3@comment_cvdp = "area average domain ("+llats+":"+llatn+"N, "+llonw+":"+llone+"E)" + copy_VarCoords(nino34,atl3) + atl3@units = sst@units + atl3@long_name = "Atlantic Nino Index (monthly)" + + llats = -20. ; Tropical Southern Atlantic Index + llatn = 0. + llonw = -30. + llone = 10. + tsa = wgt_areaave(ssttemp(:,{llats:llatn},{llonw:llone}),coswgt({llats:llatn}),1.0,0) + tsa@comment_cvdp = "area average domain ("+llats+":"+llatn+"N, "+llonw+":"+llone+"E)" + copy_VarCoords(nino34,tsa) + tsa@units = sst@units + tsa@long_name = "Tropical Southern Atlantic SST timeseries (monthly)" + delete(ssttemp) + + llats = 5.5 ; Tropical Northern Atlantic Index + llatn = 23.5 + llonw = 302.5 + llone = 345. + tna = wgt_areaave(sst(:,{llats:llatn},{llonw:llone}),coswgt({llats:llatn}),1.0,0) + tna@comment_cvdp = "area average domain ("+llats+":"+llatn+"N, "+llonw+":"+llone+"E)" + copy_VarCoords(nino34,tna) + tna@units = sst@units + tna@long_name = "Tropical Northern Atlantic SST timeseries (monthly)" + + llats = -15. ; Indian Ocean SST index + llatn = 15. + llonw = 40. + llone = 110. + tio = wgt_areaave(sst(:,{llats:llatn},{llonw:llone}),coswgt({llats:llatn}),1.0,0) + tio@comment_cvdp = "area average domain ("+llats+":"+llatn+"N, "+llonw+":"+llone+"E)" + copy_VarCoords(nino34,tio) + tio@units = sst@units + tio@long_name = "Tropical Indian Ocean SST timeseries (monthly)" + + ; Indian Ocean Dipole Index http://www.bom.gov.au/climate/IOD/about_IOD.shtml + iod = wgt_areaave(sst(:,{-10.:10.},{50.:70.}),coswgt({-10.:10.}),1.0,0) - wgt_areaave(sst(:,{-10.:0.},{90.:110.}),coswgt({-10.:0.}),1.0,0) + iod@comment_cvdp = "area average domain (-10:10N, 50:70E) - (-10:0N, 90:110E)" + copy_VarCoords(nino34,iod) + iod@units = sst@units + iod@long_name = "Indian Ocean Dipole Index (monthly)" + + socn = wgt_areaave(sst(:,{-70.:-50.},:),coswgt({-70.:-50.}),1.0,0) + socn@comment_cvdp = "area average domain (-70:-50N, 0:360E)" + copy_VarCoords(nino34,socn) + socn@units = sst@units + socn@long_name = "Southern Ocean Index (monthly)" + delete(coswgt) +;--------------------------------------------------------------------------------------------- + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.sst.indices."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + date = cd_calendar(nino34&time,-1) + date@long_name = "current date (YYYYMM)" + delete(date@calendar) + date!0 = "time" + date&time = nino34&time + date@units = "1" + z->date = date + delete(date) + else + z = addfile(fn,"w") + end if + z->nino34 = set_varAtts(nino34,"","","") + z->nino12 = set_varAtts(nino12,"","","") + z->nino3 = set_varAtts(nino3,"","","") + z->nino4 = set_varAtts(nino4,"","","") + z->north_tropical_atlantic = set_varAtts(tna,"","","") + z->south_tropical_atlantic = set_varAtts(tsa,"","","") + z->tropical_indian_ocean = set_varAtts(tio,"","","") + z->indian_ocean_dipole = set_varAtts(iod,"","","") + z->southern_ocean = set_varAtts(socn,"","","") + z->atlantic_meridional_mode = set_varAtts(amm,"","","") + z->atlantic_nino = set_varAtts(atl3,"","","") + delete([/modname,fn/]) + end if +;--------------------------------------------------------------------------------------------- + nino34T = wgt_runave(nino34,wgt,1) ; for use in ENSO composites / hovmuellers / running standard deviations + nino34_ndj = nino34T(11:dimsizes(nino34T)-13:12) ; cannot count last 1yr as spatial composite uses +1yrs data betond NDJ.. + nino34_ndj!0 = "time" + nino34_ndj&time = ispan(syear(ee),eyear(ee)-1,1) + nino34_ndj = dtrend_msg(ispan(0,dimsizes(nino34_ndj&time)-1,1),nino34_ndj,True,False) + nino34_ndj = dim_standardize(nino34_ndj,0) + + sst = (/ dtrend_msg_n(ispan(0,nyr(ee)*12-1,1),sst,False,False,0) /) ; detrend the sst array + + if (nyr(ee).ge.15) then ; 15+ years needed for composites + sstr = sst(:,{-3:3},{120:280}) ; ENSO hovmuellers based on NDJ nino34 + finsst_hi = sstr(:60,0,:) ; for Jan-2 -> Jan+3 + finsst_hi!0 = "time" + finsst_hi&time = ispan(0,60,1) + finsst_hi = 0. + finsst_lo = finsst_hi + finsst_mid = finsst_hi + cntr_hi = 0 + cntr_lo = 0 + cntr_mid = 0 + cntr_lo@_FillValue = default_fillvalue(typeof(cntr_lo)) + cntr_mid@_FillValue = default_fillvalue(typeof(cntr_mid)) + cntr_hi@_FillValue = default_fillvalue(typeof(cntr_hi)) + + mocntr = 24 ; note: if this is set at 24 gg should start at 2 + do gg = 2,dimsizes(nino34_ndj)-3 ; remember that Dec is month 11. End @ -3 because we need to grab + 3 yrs and 1 month from there (nino34_ndj already ends at eyear-1) + if (.not.ismissing(nino34_ndj(gg))) then ; note that finsst_* indices 24:52 (Jan+0 -> May +2) are all that is shown in the hovmoller plots + if (nino34_ndj(gg).ge.1.) then + finsst_hi = (/ finsst_hi+dim_avg_n(sstr(mocntr-24:mocntr+36,:,:),1) /) ; nino34_ndj value is at sstr index mocntr+11 + cntr_hi = cntr_hi+1 + end if + if (nino34_ndj(gg).ge.-0.5.and.nino34_ndj(gg).le.0.5) then + finsst_mid = (/ finsst_mid+dim_avg_n(sstr(mocntr-24:mocntr+36,:,:),1) /) + cntr_mid = cntr_mid+1 + end if + if (nino34_ndj(gg).le.-1.) then + finsst_lo = (/ finsst_lo+dim_avg_n(sstr(mocntr-24:mocntr+36,:,:),1) /) + cntr_lo = cntr_lo+1 + end if + end if + mocntr = mocntr+12 + end do + delete([/sstr,mocntr/]) + + cntr_hi = where(cntr_hi.eq.0, cntr_hi@_FillValue, cntr_hi) + cntr_mid = where(cntr_mid.eq.0,cntr_mid@_FillValue,cntr_mid) + cntr_lo = where(cntr_lo.eq.0, cntr_lo@_FillValue, cntr_lo) + finsst_hi = (/ finsst_hi/cntr_hi /) + finsst_mid = (/ finsst_mid/cntr_mid /) + finsst_lo = (/ finsst_lo/cntr_lo /) + + if (OUTPUT_DATA.eq."True") then + hov_hi = (/ finsst_hi(24:52,:) /) ; 24:52 runs from Jan+0->May+2 and matches range shown in plot + time_mon1 = ispan(0,28,1) + time_mon1@units = "months since 0000-01-01 00:00:00" + time_mon1@long_name = "Time" + time_mon1@standard_name = "time" + time_mon1@calendar = "standard" + time_mon1!0 = "time_mon1" + time_mon1&time_mon1 = time_mon1 + hov_hi!0 = "time_mon1" + hov_hi&time_mon1 = time_mon1 + longitude = finsst_hi&lon + longitude@standard_name = "longitude" + hov_hi!1 = "longitude" + hov_hi&longitude = longitude + delete([/time_mon1,longitude/]) + hov_lo = (/ finsst_lo(24:52,:) /) ; 24:52 runs from Jan+0->May+2 and matches range shown in plot + copy_VarCoords(hov_hi,hov_lo) + hov_hi@number_of_events = cntr_hi + hov_lo@number_of_events = cntr_lo + hov_hi@units = "C" + hov_lo@units = "C" + z->nino34_hov_elnino = set_varAtts(hov_hi,"nino3.4 El Nino Hovmoller sst composite","","") + z->nino34_hov_lanina = set_varAtts(hov_lo,"nino3.4 La Nina Hovmoller sst composite","","") + delete([/hov_hi,hov_lo/]) + end if + end if +;- - - - - -nino3.4 spatial composite section- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + if (any(ismissing((/syear(ee),syear_trefht(ee),syear_psl(ee),eyear(ee),eyear_trefht(ee),eyear_psl(ee)/)))) then + taspslreg_plot_flag = 1 + else + if (syear(ee).eq.syear_trefht(ee).and.syear(ee).eq.syear_psl(ee)) then ; check that the start and end years match for ts, trefht, and psl + if (eyear(ee).eq.eyear_trefht(ee).and.eyear(ee).eq.eyear_psl(ee)) then + taspslreg_plot_flag = 0 + else + taspslreg_plot_flag = 1 + end if + else + taspslreg_plot_flag = 1 + end if + end if + + if (taspslreg_plot_flag.eq.0) then + tas = data_read_in(paths_trefht(ee),"TREFHT",syear_trefht(ee),eyear_trefht(ee)) + psl = data_read_in(paths_psl(ee),"PSL",syear_psl(ee),eyear_psl(ee)) + + TIME = sst&time + yyyymm = cd_calendar(sst&time,-1) ; convert tas, ts, and sst from CF-conforming time to YYYYMM for coding below + delete(sst&time) + sst&time = yyyymm + delete(yyyymm) + + yyyymm = cd_calendar(tas&time,-1) + delete(tas&time) + tas&time = yyyymm + delete(yyyymm) + + yyyymm = cd_calendar(psl&time,-1) + delete(psl&time) + psl&time = yyyymm + delete(yyyymm) + + if (isatt(tas,"is_all_missing").or.isatt(psl,"is_all_missing")) then + taspslreg_plot_flag = 1 + delete([/tas,psl/]) + end if + + if (nyr(ee).lt.15) then ; 15+ years needed for composites + taspslreg_plot_flag = 1 + end if + + if (taspslreg_plot_flag.eq.0) then ; only continue if all 3 fields are present + if (OPT_CLIMO.eq."Full") then + tas = rmMonAnnCycTLL(tas) + psl = rmMonAnnCycTLL(psl) + else + check_custom_climo(names_trefht(ee),syear_trefht(ee),eyear_trefht(ee),CLIMO_SYEAR,CLIMO_EYEAR) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(tas({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(tas({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + tas = calcMonAnomTLL(tas,climo) + delete(climo) + + check_custom_climo(names_psl(ee),syear_psl(ee),eyear_psl(ee),CLIMO_SYEAR,CLIMO_EYEAR) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(psl({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(psl({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + psl = calcMonAnomTLL(psl,climo) + delete(climo) + end if + tas = (/ dtrend_msg_n(ispan(0,dimsizes(tas&time)-1,1),tas,False,False,0) /) ; sst detrended up above + psl = (/ dtrend_msg_n(ispan(0,dimsizes(psl&time)-1,1),psl,False,False,0) /) + + ta = dim_avg_n(sst(:1,:,:),0) + sst = runave_n_Wrap(sst,3,0,0) + sst(0,:,:) = (/ ta /) + delete(ta) + + ta = dim_avg_n(psl(:1,:,:),0) + psl = runave_n_Wrap(psl,3,0,0) + psl(0,:,:) = (/ ta /) + delete(ta) + + ta = dim_avg_n(tas(:1,:,:),0) + tas = runave_n_Wrap(tas,3,0,0) + tas(0,:,:) = (/ ta /) + delete(ta) + + hicntr = 0 + locntr = 0 + hiyr = new(dimsizes(nino34_ndj&time),integer) + loyr = hiyr + + do hh = 0,dimsizes(nino34_ndj)-1 + if (.not.ismissing(nino34_ndj(hh))) then + if (nino34_ndj(hh).ge.1) then + hiyr(hicntr) = nino34_ndj&time(hh) + hicntr = hicntr+1 + end if + if (nino34_ndj(hh).le.-1) then + loyr(locntr) = nino34_ndj&time(hh) + locntr = locntr+1 + end if + end if + end do + + if (hicntr.eq.0) then ; for simulations with climatological SSTs + highyr = hiyr(0) + else + highyr = hiyr(:hicntr-1) + end if + delete([/hiyr,hicntr/]) + if (locntr.eq.0) then + lowyr = loyr(0) + else + lowyr = loyr(:locntr-1) + end if + delete([/loyr,locntr/]) + + dimS = dimsizes(psl&time) ; change time from YYYYMM->YYYY.frac + tmin = psl&time(0)/100 + tmax = psl&time(dimS-1)/100 + delete(psl&time) + psl&time = fspan(tmin*1.,(tmax*1.)+(11/12.),dimS) + dimS = dimsizes(tas&time) + tmin = tas&time(0)/100 + tmax = tas&time(dimS-1)/100 + delete(tas&time) + tas&time = fspan(tmin*1.,(tmax*1.)+(11/12.),dimS) + dimS = dimsizes(sst&time) + tmin = sst&time(0)/100 + tmax = sst&time(dimS-1)/100 + delete(sst&time) + sst&time = fspan(tmin*1.,(tmax*1.)+(11/12.),dimS) + delete([/dimS,tmin,tmax/]) + ; print(sst&time) + + sc_tas_hi = tas(:23,:,:) + sc_tas_lo = tas(:23,:,:) + sc_sst_hi = sst(:23,:,:) + sc_sst_lo = sst(:23,:,:) + sc_psl_hi = psl(:23,:,:) + sc_psl_lo = psl(:23,:,:) + + sc_tas_hi = sc_tas_hi@_FillValue + sc_tas_lo = sc_tas_lo@_FillValue + sc_sst_hi = sc_sst_hi@_FillValue + sc_sst_lo = sc_sst_lo@_FillValue + sc_psl_hi = sc_psl_hi@_FillValue + sc_psl_lo = sc_psl_lo@_FillValue + + if (dimsizes(highyr).le.1) then + print("For "+names(ee)+", 1 or less (normalized) nino3.4 value greater than one standard deviation found, setting nino3.4 spatial composites to missing") ; sc_*_hi arrays left to _FillValue + else + do gg = 0,23 + tt = gg/12. + sc_psl_hi(gg,:,:) = (/ dim_avg_n(psl({highyr+tt},:,:),0) /) + sc_sst_hi(gg,:,:) = (/ dim_avg_n(sst({highyr+tt},:,:),0) /) + sc_tas_hi(gg,:,:) = (/ dim_avg_n(tas({highyr+tt},:,:),0) /) + end do + delete(tt) + end if + delete(highyr) + if (dimsizes(lowyr).le.1) then + print("For "+names(ee)+", 1 or less (normalized) nino3.4 value less than -1 standard deviation found, setting nino3.4 spatial composites to missing") ; sc_*_lo arrays left to _FillValue + else + do gg = 0,23 + tt = gg/12. + sc_psl_lo(gg,:,:) = (/ dim_avg_n(psl({lowyr+tt},:,:),0) /) + sc_sst_lo(gg,:,:) = (/ dim_avg_n(sst({lowyr+tt},:,:),0) /) + sc_tas_lo(gg,:,:) = (/ dim_avg_n(tas({lowyr+tt},:,:),0) /) + end do + delete(tt) + end if + delete(lowyr) + + n34sc_psl = sc_psl_hi + n34sc_psl = (/ sc_psl_hi - sc_psl_lo /) + n34sc_sst = sc_sst_hi + n34sc_sst = (/ sc_sst_hi - sc_sst_lo /) + n34sc_tas = sc_tas_hi + n34sc_tas = (/ sc_tas_hi - sc_tas_lo /) + delete([/sc_psl_hi,sc_psl_lo,sc_sst_hi,sc_sst_lo,sc_tas_hi,sc_tas_lo/]) + delete(sst&time) + sst&time = TIME + delete(TIME) + + if (OUTPUT_DATA.eq."True") then + n34sc_sst&lat@standard_name = "latitude" + n34sc_sst&lon@standard_name = "longitude" + z->nino34_spacomp_sst_jja0 = set_varAtts(n34sc_sst(6,:,:),"nino3.4 sst spatial composite (JJA+0)","","") + z->nino34_spacomp_sst_son0 = set_varAtts(n34sc_sst(9,:,:),"nino3.4 sst spatial composite (SON+0)","","") + z->nino34_spacomp_sst_djf1 = set_varAtts(n34sc_sst(12,:,:),"nino3.4 sst spatial composite (DJF+1)","","") + z->nino34_spacomp_sst_mam1 = set_varAtts(n34sc_sst(15,:,:),"nino3.4 sst spatial composite (MAM+1)","","") + + modname = str_sub_str(names_trefht(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.psl.sst.indices.tas."+syear_trefht(ee)+"-"+eyear_trefht(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z_tas = addfile(fn,"c") + z_tas@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z_tas@notes = "Data from "+names_trefht(ee)+" from "+syear_trefht(ee)+"-"+eyear_trefht(ee) + if (OPT_CLIMO.eq."Full") then + z_tas@climatology = syear_trefht(ee)+"-"+eyear_trefht(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z_tas@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z_tas@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + else + z_tas = addfile(fn,"w") + end if + z_tas->nino34_spacomp_tas_jja0 = set_varAtts(n34sc_tas(6,:,:),"nino3.4 tas spatial composite (JJA+0)","","") + z_tas->nino34_spacomp_tas_son0 = set_varAtts(n34sc_tas(9,:,:),"nino3.4 tas spatial composite (SON+0)","","") + z_tas->nino34_spacomp_tas_djf1 = set_varAtts(n34sc_tas(12,:,:),"nino3.4 tas spatial composite (DJF+1)","","") + z_tas->nino34_spacomp_tas_mam1 = set_varAtts(n34sc_tas(15,:,:),"nino3.4 tas spatial composite (MAM+1)","","") + delete(z_tas) + delete(modname) + + modname = str_sub_str(names_psl(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.sst.indices.psl."+syear_trefht(ee)+"-"+eyear_trefht(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z_psl = addfile(fn,"c") + z_psl@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z_psl@notes = "Data from "+names_trefht(ee)+" from "+syear_trefht(ee)+"-"+eyear_trefht(ee) + if (OPT_CLIMO.eq."Full") then + z_psl@climatology = syear_trefht(ee)+"-"+eyear_trefht(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z_psl@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z_psl@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z_psl = addfile(fn,"w") + end if + z_psl->nino34_spacomp_psl_jja0 = set_varAtts(n34sc_psl(6,:,:),"nino3.4 psl spatial composite (JJA+0)","","") + z_psl->nino34_spacomp_psl_son0 = set_varAtts(n34sc_psl(9,:,:),"nino3.4 psl spatial composite (SON+0)","","") + z_psl->nino34_spacomp_psl_djf1 = set_varAtts(n34sc_psl(12,:,:),"nino3.4 psl spatial composite (DJF+1)","","") + z_psl->nino34_spacomp_psl_mam1 = set_varAtts(n34sc_psl(15,:,:),"nino3.4 psl spatial composite (MAM+1)","","") + delete(z_psl) + delete(modname) + end if + end if + end if + if (isvar("TIME")) then + delete(TIME) + end if + if (isvar("psl")) then + delete(psl) + end if + if (isvar("tas")) then + delete(tas) + end if +;-------------nino3.4 composite (precipitation)----------------------------------------------------- + if (any(ismissing((/syear(ee),syear_prect(ee),eyear(ee),eyear_prect(ee)/)))) then + pptreg_plot_flag = 1 + else + if (syear(ee).eq.syear_prect(ee)) then ; check that the start and end years match for ts, trefht, and psl + if (eyear(ee).eq.eyear_prect(ee)) then + pptreg_plot_flag = 0 + else + pptreg_plot_flag = 1 + end if + else + pptreg_plot_flag = 1 + end if + end if + + if (pptreg_plot_flag.eq.0) then + ppt = data_read_in(paths_prect(ee),"PRECT",syear_prect(ee),eyear_prect(ee)) + + yyyymm = cd_calendar(ppt&time,-1) ; convert ppt from CF-conforming time to YYYYMM for coding below + delete(ppt&time) + ppt&time = yyyymm + delete(yyyymm) + + if (isatt(ppt,"is_all_missing")) then + pptreg_plot_flag = 1 + delete(ppt) + end if + + if (nyr(ee).lt.15) then ; 15+ years needed for composites + pptreg_plot_flag = 1 + end if + + if (pptreg_plot_flag.eq.0) then ; only continue if all 3 fields are present + ; d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") ; mask ocean for TAS array + ; basemap = d->LSMASK ; This is now done right before plotting. + ; lsm = landsea_mask(basemap,tas&lat,tas&lon) ; so that the entire TAS array is used + ; tas = mask(tas,conform(tas,lsm,(/1,2/)).eq.0,False) ; in the nino3.4 pattern correlations + ; delete([/lsm,basemap/]) ; (Even if the land portion of TAS is the + ; delete(d) ; only portion plotted as SST shown over oceans.) + + if (OPT_CLIMO.eq."Full") then + ppt = rmMonAnnCycTLL(ppt) + else + check_custom_climo(names_prect(ee),syear_prect(ee),eyear_prect(ee),CLIMO_SYEAR,CLIMO_EYEAR) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(ppt({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(ppt({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + ppt = calcMonAnomTLL(ppt,climo) + delete(climo) + end if + ppt = (/ dtrend_msg_n(ispan(0,dimsizes(ppt&time)-1,1),ppt,False,False,0) /) + + ta = dim_avg_n(ppt(:1,:,:),0) + ppt = runave_n_Wrap(ppt,3,0,0) + ppt(0,:,:) = (/ ta /) + delete(ta) + + hicntr = 0 + locntr = 0 + hiyr = new(dimsizes(nino34_ndj&time),integer) + loyr = hiyr + + do hh = 0,dimsizes(nino34_ndj)-1 + if (.not.ismissing(nino34_ndj(hh))) then + if (nino34_ndj(hh).ge.1) then + hiyr(hicntr) = nino34_ndj&time(hh) + hicntr = hicntr+1 + end if + if (nino34_ndj(hh).le.-1) then + loyr(locntr) = nino34_ndj&time(hh) + locntr = locntr+1 + end if + end if + end do + + if (hicntr.eq.0) then ; for simulations with climatological SSTs + highyr = hiyr(0) + else + highyr = hiyr(:hicntr-1) + end if + delete([/hiyr,hicntr/]) + if (locntr.eq.0) then + lowyr = loyr(0) + else + lowyr = loyr(:locntr-1) + end if + delete([/loyr,locntr/]) + + dimS = dimsizes(ppt&time) ; change time from YYYYMM->YYYY.frac + tmin = ppt&time(0)/100 + tmax = ppt&time(dimS-1)/100 + delete(ppt&time) + ppt&time = fspan(tmin*1.,(tmax*1.)+(11/12.),dimS) + delete([/dimS,tmin,tmax/]) + + sc_ppt_hi = ppt(:23,:,:) + sc_ppt_lo = ppt(:23,:,:) + + sc_ppt_hi = sc_ppt_hi@_FillValue + sc_ppt_lo = sc_ppt_lo@_FillValue + + if (dimsizes(highyr).le.1) then + print("For "+names(ee)+", 1 or less (normalized) nino3.4 value greater than one standard deviation found, setting nino3.4 spatial composites to missing") ; sc_*_hi arrays left to _FillValue + else + do gg = 0,23 + tt = gg/12. + sc_ppt_hi(gg,:,:) = (/ dim_avg_n(ppt({highyr+tt},:,:),0) /) + end do + delete(tt) + end if + delete(highyr) + if (dimsizes(lowyr).le.1) then + print("For "+names(ee)+", 1 or less (normalized) nino3.4 value less than -1 standard deviation found, setting nino3.4 spatial composites to missing") ; sc_*_lo arrays left to _FillValue + else + do gg = 0,23 + tt = gg/12. + sc_ppt_lo(gg,:,:) = (/ dim_avg_n(ppt({lowyr+tt},:,:),0) /) + end do + delete(tt) + end if + delete(lowyr) + + n34sc_ppt = sc_ppt_hi + n34sc_ppt = (/ sc_ppt_hi - sc_ppt_lo /) + delete([/sc_ppt_hi,sc_ppt_lo/]) + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names_prect(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.sst.indices.ppt."+syear_trefht(ee)+"-"+eyear_trefht(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z_ppt = addfile(fn,"c") + z_ppt@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z_ppt@notes = "Data from "+names_trefht(ee)+" from "+syear_trefht(ee)+"-"+eyear_trefht(ee) + if (OPT_CLIMO.eq."Full") then + z_ppt@climatology = syear_trefht(ee)+"-"+eyear_trefht(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z_ppt@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z_ppt@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z_ppt = addfile(fn,"w") + end if + z_ppt->nino34_spacomp_pr_jja0 = set_varAtts(n34sc_ppt(6,:,:),"nino3.4 pr spatial composite (JJA+0)","","") + z_ppt->nino34_spacomp_pr_son0 = set_varAtts(n34sc_ppt(9,:,:),"nino3.4 pr spatial composite (SON+0)","","") + z_ppt->nino34_spacomp_pr_djf1 = set_varAtts(n34sc_ppt(12,:,:),"nino3.4 pr spatial composite (DJF+1)","","") + z_ppt->nino34_spacomp_pr_mam1 = set_varAtts(n34sc_ppt(15,:,:),"nino3.4 pr spatial composite (MAM+1)","","") + delete(z_ppt) + delete(modname) + end if + end if + end if + if (isvar("TIME")) then + delete(TIME) + end if + if (isvar("ppt")) then + delete(ppt) + end if + delete([/sst,nino34_ndj/]) +;----------------------------------------------------------------------------------------- + if (nyr(ee).ge.35) then ; need a minimum number of years to compute running nino3.4 standard deviations + nino34T = dtrend_msg(ispan(0,dimsizes(nino34T)-1,1),nino34T,True,False) + nino34T!0 = "time" + nino34T&time = nino34&time + sd_run = nino34T + sd_run = sd_run@_FillValue + sd_run@units = nino34@units + sd_run@long_name = "nino3.4 30yr running standard deviation" + do gg = 180,dimsizes(nino34T)-180 + sd_run(gg) = (/ dim_stddev(nino34T(gg-180:gg+179)) /) + end do + if (OUTPUT_DATA.eq."True") then + z->nino34_runstddev = set_varAtts(sd_run,"","","") + end if + end if + delete(nino34T) +;----------------------------------------------------------------------------------------- + iopt = 0 ; nino3.4 power spectra + jave = (7*nyr(ee))/100 + val1 = .95 + val2 = .99 + pct = 0.1 + spectra_mvf = False ; missing value flag for nino3.4 + if (any(ismissing(nino34))) then ; check for missing data + print("Missing data detected for "+names(ee)+", not creating spectra in sst.indices.ncl") + spectra_mvf = True + if (isfilepresent2("obs_ts").and.ee.eq.0) then + spectra_mvf_obs = True + end if + else + if (isfilepresent2("obs_ts").and.ee.eq.0) then + spectra_mvf_obs = False ; missing value flag for obs nino3.4 + end if + nino34_dt = dtrend_msg(ispan(0,dimsizes(nino34)-1,1),nino34,True,False) + + sdof = specx_anal(nino34_dt,iopt,jave,pct) + mval = sum(1/(1.+((sdof@xlag1)^2)-((2*sdof@xlag1)*cos(6.28318*sdof@frq)))) + if (mval.eq.0) then ; check for cyclic data that results in sum of Markov elements = 0. + spectra_mvf = True + if (isfilepresent2("obs_ts").and.ee.eq.0) then + spectra_mvf_obs = True ; missing value flag for obs nino3.4 + end if + else + splt1 = specx_ci(sdof,val1,val2) + if (OUTPUT_DATA.eq."True") then + splt1!0 = "ncurves" + splt1&ncurves = ispan(0,3,1) + splt1&ncurves@long_name = "power spectra curves" + splt1&ncurves@units = "1" + splt1!1 = "frequency" + splt1&frequency = sdof@frq + splt1&frequency@long_name = "power spectra frequency" + splt1&frequency@units = "1" + splt1@units_info = "df refers to frequency interval" + splt1@units = "C^2/df" + splt1@comment_cvdp = "(0,:)=spectrum,(1,:)=Markov red noise spectrum, (2,:)="+val1+"% confidence bound for Markhov, (3,:)="+val2+"% confidence bound for Markhov" + z->nino34_spectra = set_varAtts(splt1,"nino3.4 power spectra","","") + end if + if (isfilepresent2("obs_ts").and.ee.eq.0) then + sdof_obs = sdof + end if + end if + delete([/nino34_dt,iopt,jave,pct,mval/]) + end if +;------------------------------------------------------------------------------------------ + nino34_dt = dtrend_msg(ispan(0,dimsizes(nino34&time)-1,1),nino34,True,False) + nino34_mon_sd = new(12,typeof(nino34)) + + do hh = 0,11 + nino34_mon_sd(hh) = (/ dim_stddev(nino34_dt(hh::12)) /) + end do + nino34_mon_sd@units = "C" + if (OUTPUT_DATA.eq."True") then + time_mon2 = ispan(0,11,1) + time_mon2@units = "months since 0000-01-01 00:00:00" + time_mon2@long_name = "Time" + time_mon2@standard_name = "time" + time_mon2@calendar = "standard" + time_mon2!0 = "time_mon2" + time_mon2&time_mon2 = time_mon2 + nino34_mon_sd!0 = "time_mon2" + nino34_mon_sd&time_mon2 = time_mon2 + z->nino34_monthly_stddev = set_varAtts(nino34_mon_sd,"nino3.4 monthly standard deviation","","") + delete(time_mon2) + end if +;------------------------------------------------------------------------------------------ +; nino3.4 wavelet analysis, autocorrelation + + if (spectra_mvf.eq.False) then + N = dimsizes(nino34) + mother = 0 + param = 6.0 + dt = 1./12. + s0 = dt + dj = 1./12. + jtot = 1+floattointeger(((log10(N*dt/s0))/dj)/log10(2.)) + npad = N + nadof = 0 + noise = 1 + siglvl = .05 + isigtest= 0 + wave34 = wavelet(nino34,mother,dt,param,s0,dj,jtot,npad,noise,isigtest,siglvl,nadof) + + power34 = onedtond(wave34@power,(/jtot,N/)) + power34!0 = "period" + power34&period = wave34@period + power34&period@long_name = "wavelet period" + power34&period@units = "1" + power34!1 = "time" + power34&time = nino34&time + power34@units = nino34@units+"^2" + + sig34 = power34 + sig34 = power34/conform (power34,wave34@signif,0) + sig34@long_name = "wavelet significance" + sig34@units = "" + delete([/N,mother,param,dt,s0,dj,jtot,npad,nadof,noise,siglvl,isigtest/]) + + ac34 = esacr(nino34_dt,48) + time_mon3 = ispan(0,48,1) + time_mon3@units = "months since 0000-01-01 00:00:00" + time_mon3@long_name = "Time" + time_mon3@standard_name = "time" + time_mon3@calendar = "standard" + time_mon3!0 = "time_mon3" + time_mon3&time_mon3 = time_mon3 + ac34!0 = "time_mon3" + ac34&time_mon3 = time_mon3 + ac34@units = "1" + if (OUTPUT_DATA.eq."True") then + z->nino34_wavelet_power = set_varAtts(power34,"nino3.4 wavelet power","","") + z->nino34_wavelet_significance = set_varAtts(sig34,"nino3.4 wavelet significance","","") + z->nino34_autocorrelation = set_varAtts(ac34,"nino3.4 autocorrelation","","") + end if + if (isfilepresent2("obs_ts").and.ee.eq.0) then + ac34_obs = ac34 + end if + end if + delete(nino34_dt) + if (isvar("z")) then + delete(z) + end if +;========================================================================================== + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnRightString = "" + xyres@gsnLeftString = "" + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + xyres@xyLineColor = "gray62" + if (wks_type.eq."png") then + xyres@xyLineThicknessF = .75 + else + xyres@xyLineThicknessF = .5 + end if + xyres@tiYAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnLeftStringFontHeightF = 0.017 + xyres@gsnCenterStringFontHeightF = 0.017 + xyres@gsnRightStringFontHeightF = 0.013 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnLeftStringFontHeightF = 0.024 + xyres@gsnCenterStringFontHeightF = 0.024 + xyres@gsnRightStringFontHeightF = 0.020 + end if +; xyres@vpXF = 0.05 + xyres@vpHeightF = 0.3 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnCenterString = "" + + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+1.5 + xyres@tiMainOn = False + xyres@gsnLeftStringOrthogonalPosF = 0.025 + xyres@gsnCenterStringOrthogonalPosF = xyres@gsnLeftStringOrthogonalPosF + xyres@gsnRightStringOrthogonalPosF = xyres@gsnLeftStringOrthogonalPosF + + xyres2 = xyres + xyres2@vpHeightF = 0.15 + xyres2@gsnXYBarChart = False + + xyres2@xyLineColor = "royalblue" + xyres2@trYMinF = 0.15 ; hard wire YMinF and YMaxF for running stddev plots + xyres2@trYMaxF = 1.95 + if (wks_type.eq."png") then + xyres2@xyLineThicknessF = 3.5 + else + xyres2@xyLineThicknessF = 1.75 + end if + delete(xyres2@gsnYRefLine) + xyres2@gsnYRefLine = (/.3,.6,0.9,1.2,1.5,1.8/) + xyres2@gsnYRefLineColor = "gray85" + + xyres3 = xyres ; resource list for monthly nino3.4 standard deviations + xyres3@trXMinF = 0.5 + xyres3@trXMaxF = 12.5 + xyres3@vpWidthF = 0.65 + xyres3@vpHeightF = 0.35 + xyres3@trYMinF = 0.2 + xyres3@trYMaxF = 2.0 + xyres3@gsnAboveYRefLineColor = "gray50" + xyres3@xyLineColor = "black" + if (wks_type.eq."png") then + xyres3@xyLineThicknessF = 3.5 + else + xyres3@xyLineThicknessF = 1.75 + end if + xyres3@gsnXYBarChart = True + xyres3@gsnXYBarChartBarWidth = 0.75 + xyres3@tmXBMode = "Explicit" ; explicit labels + xyres3@tmXBValues = ispan(1,12,1) + xyres3@tmXBLabels = (/"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"/) + xyres3@tmXTOn = False + + xyres4 = xyres ; resource list for nino3.4 autocorrelations + xyres4@trXMinF = 0.0 + xyres4@trXMaxF = 48.0 + xyres4@trYMinF = -1.05 + xyres4@trYMaxF = 1.05 + xyres4@vpHeightF = 0.3 + xyres4@vpWidthF = 0.3 + if (wks_type.eq."png") then + xyres4@xyLineThicknessF = 3.5 + else + xyres4@xyLineThicknessF = 1.75 + end if + xyres4@xyLineColor = "black" + xyres4@gsnAboveYRefLineColor = "firebrick2" + xyres4@gsnBelowYRefLineColor = "dodgerblue3" + xyres4@tmYLMode = "Explicit" + xyres4@tmYLValues = (/-1,0,1/) + xyres4@tmYLLabels = (/"-1","0","1"/) + xyres4@tmYLMinorValues = fspan(-1,1,9) + xyres4@tmXBMode = "Explicit" + xyres4@tmXBValues = (/0,12,24,36,48/) + xyres4@tmXBLabels = (/"0","12","24","36","48"/) + if (nsim.le.5) then + xyres4@tmXBLabelFontHeightF = 0.0105 + xyres4@tmYLLabelFontHeightF = 0.0105 + xyres4@gsnLeftStringFontHeightF = 0.015 + xyres4@gsnCenterStringFontHeightF = 0.015 + xyres4@gsnRightStringFontHeightF = 0.012 + else + xyres4@tmXBLabelFontHeightF = 0.015 + xyres4@tmYLLabelFontHeightF = 0.015 + xyres4@gsnLeftStringFontHeightF = 0.021 + xyres4@gsnCenterStringFontHeightF = 0.021 + xyres4@gsnRightStringFontHeightF = 0.016 + end if + xyres4@gsnRightStringOrthogonalPosF = -0.115 + xyres4@gsnRightStringParallelPosF = 0.96 + xyres4@gsnCenterStringOrthogonalPosF = 0.025 + + xyres@gsnLeftString = names(ee) + arr = new((/2,dimsizes(nino34)/),typeof(nino34)) + + tttt = dtrend_msg(ispan(0,dimsizes(nino34)-1,1),nino34,False,True) + arr(0,:) = (/ nino34 /) + arr(1,:) = (/ (ispan(0,dimsizes(nino34)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(nino34),2,True)+nino34@units+" "+nyr(ee)+"yr~S~-1~N~" + xyn34(ee) = gsn_csm_xy(wks_n34,fspan(syear(ee),eyear(ee)+.91667,dimsizes(nino34)),arr,xyres) + delete(tttt) + + tttt = dtrend_msg(ispan(0,dimsizes(nino3)-1,1),nino3,False,True) + arr(0,:) = (/ nino3 /) + arr(1,:) = (/ (ispan(0,dimsizes(nino3)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(nino3),2,True)+nino3@units+" "+nyr(ee)+"yr~S~-1~N~" + xyn3(ee) = gsn_csm_xy(wks_n3,fspan(syear(ee),eyear(ee)+.91667,dimsizes(nino3)),arr,xyres) + delete(tttt) + + tttt = dtrend_msg(ispan(0,dimsizes(nino4)-1,1),nino4,False,True) + arr(0,:) = (/ nino4 /) + arr(1,:) = (/ (ispan(0,dimsizes(nino4)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(nino4),2,True)+nino4@units+" "+nyr(ee)+"yr~S~-1~N~" + xyn4(ee) = gsn_csm_xy(wks_n4,fspan(syear(ee),eyear(ee)+.91667,dimsizes(nino4)),arr,xyres) + delete(tttt) + + tttt = dtrend_msg(ispan(0,dimsizes(nino12)-1,1),nino12,False,True) + arr(0,:) = (/ nino12 /) + arr(1,:) = (/ (ispan(0,dimsizes(nino12)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(nino12),2,True)+nino12@units+" "+nyr(ee)+"yr~S~-1~N~" + xyn12(ee) = gsn_csm_xy(wks_n12,fspan(syear(ee),eyear(ee)+.91667,dimsizes(nino12)),arr,xyres) + delete(tttt) + + tttt = dtrend_msg(ispan(0,dimsizes(tna)-1,1),tna,False,True) + arr(0,:) = (/ tna /) + arr(1,:) = (/ (ispan(0,dimsizes(tna)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(tna),2,True)+tna@units+" "+nyr(ee)+"yr~S~-1~N~" + xytna(ee) = gsn_csm_xy(wks_tna,fspan(syear(ee),eyear(ee)+.91667,dimsizes(tna)),arr,xyres) + delete(tttt) + + tttt = dtrend_msg(ispan(0,dimsizes(tsa)-1,1),tsa,False,True) + arr(0,:) = (/ tsa /) + arr(1,:) = (/ (ispan(0,dimsizes(tsa)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(tsa),2,True)+tsa@units+" "+nyr(ee)+"yr~S~-1~N~" + xytsa(ee) = gsn_csm_xy(wks_tsa,fspan(syear(ee),eyear(ee)+.91667,dimsizes(tsa)),arr,xyres) + delete(tttt) + + tttt = dtrend_msg(ispan(0,dimsizes(tio)-1,1),tio,False,True) + arr(0,:) = (/ tio /) + arr(1,:) = (/ (ispan(0,dimsizes(tio)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(tio),2,True)+tio@units+" "+nyr(ee)+"yr~S~-1~N~" + xytio(ee) = gsn_csm_xy(wks_tio,fspan(syear(ee),eyear(ee)+.91667,dimsizes(tio)),arr,xyres) + delete(tttt) + + tttt = dtrend_msg(ispan(0,dimsizes(iod)-1,1),iod,False,True) + arr(0,:) = (/ iod /) + arr(1,:) = (/ (ispan(0,dimsizes(iod)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(iod),2,True)+iod@units+" "+nyr(ee)+"yr~S~-1~N~" + xyiod(ee) = gsn_csm_xy(wks_tio,fspan(syear(ee),eyear(ee)+.91667,dimsizes(iod)),arr,xyres) + delete([/tttt/]) + + tttt = dtrend_msg(ispan(0,dimsizes(socn)-1,1),socn,False,True) + arr(0,:) = (/ socn /) + arr(1,:) = (/ (ispan(0,dimsizes(socn)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(socn),2,True)+socn@units+" "+nyr(ee)+"yr~S~-1~N~" + xysocn(ee) = gsn_csm_xy(wks_tio,fspan(syear(ee),eyear(ee)+.91667,dimsizes(socn)),arr,xyres) + delete([/tttt/]) + + tttt = dtrend_msg(ispan(0,dimsizes(amm)-1,1),amm,False,True) + arr(0,:) = (/ amm /) + arr(1,:) = (/ (ispan(0,dimsizes(amm)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(amm),2,True)+amm@units+" "+nyr(ee)+"yr~S~-1~N~" + xyamm(ee) = gsn_csm_xy(wks_tio,fspan(syear(ee),eyear(ee)+.91667,dimsizes(amm)),arr,xyres) + delete([/tttt/]) + + tttt = dtrend_msg(ispan(0,dimsizes(atl3)-1,1),atl3,False,True) + arr(0,:) = (/ atl3 /) + arr(1,:) = (/ (ispan(0,dimsizes(atl3)-1,1)*tttt@slope)+tttt@y_intercept /) + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(atl3),2,True)+atl3@units+" "+nyr(ee)+"yr~S~-1~N~" + xyatl3(ee) = gsn_csm_xy(wks_tio,fspan(syear(ee),eyear(ee)+.91667,dimsizes(atl3)),arr,xyres) + delete([/arr,tttt/]) + + xyres2@gsnLeftString = names(ee) + if (nyr(ee).ge.35) then + xyres2@gsnRightString = sprintf("%4.2f", min(sd_run))+" / "+sprintf("%4.2f", avg(sd_run))+" / "+sprintf("%4.2f", max(sd_run))+sd_run@units + xyn34_rst(ee) = gsn_csm_xy(wks_n34_rst,fspan(syear(ee),eyear(ee)+.91667,dimsizes(sd_run)),sd_run,xyres2) + end if + + xyres3@gsnRightStringFontHeightF = xyres3@gsnCenterStringFontHeightF + xyres3@gsnLeftString = syear(ee)+"-"+eyear(ee) + xyres3@gsnCenterString = names(ee) + xyres3@gsnRightString = "C" + if (max(nino34_mon_sd).gt.xyres3@gsnYRefLine) then + xyn34_mst(ee) = gsn_csm_xy(wks_n34_mst,ispan(1,12,1),nino34_mon_sd,xyres3) + end if + title_n34 = nino34@comment_cvdp + title_n4 = nino4@comment_cvdp + title_n3 = nino3@comment_cvdp + title_n12 = nino12@comment_cvdp + + title_tna = tna@comment_cvdp + title_tsa = tsa@comment_cvdp + + title_tio = tio@comment_cvdp + title_iod = iod@comment_cvdp + title_socn = socn@comment_cvdp + title_amm = amm@comment_cvdp + title_atl3 = atl3@comment_cvdp + delete([/nino34,nino3,nino4,nino12,tsa,tna,tio,iod,socn,amm,atl3/]) + + if (spectra_mvf.eq.False) then + xyres4@gsnCenterString = names(ee) + xyres4@gsnRightString = syear(ee)+"-"+eyear(ee) + xyn34_ac(ee) = gsn_csm_xy(wks_n34_p,ispan(0,48,1),ac34,xyres4) + if (ee.ge.1.and.isvar("ac34_obs")) then + delete([/xyres4@gsnAboveYRefLineColor,xyres4@gsnBelowYRefLineColor/]) + xyres4@xyLineColor = "gray62" + xyres4@xyCurveDrawOrder = "PreDraw" + xyres4@gsnCenterString = "" + xyres4@gsnRightString = "" + xyn34_ac_obs(ee) = gsn_csm_xy(wks_n34_p,ispan(0,48,1),ac34_obs,xyres4) + overlay(xyn34_ac(ee),xyn34_ac_obs(ee)) + delete(xyres4@xyCurveDrawOrder) + delete(ac34) + end if + end if + delete([/xyres,xyres2,xyres3,xyres4,nino34_mon_sd/]) +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + res = True + res@vpHeightF = 0.45 + res@vpWidthF = 0.35 + res@gsnFrame = False + res@gsnDraw = False + + + res@tmYLMode = "Explicit" +; res@tmYLValues = ispan(0,72,6) +; res@tmYLLabels = (/"Jan~S~-2~N~","Jul~S~-2~N~","Jan~S~-1~N~","Jul~S~-1~N~", \ +; "Jan~S~0~N~","Jul~S~0~N~","Jan~S~+1~N~","Jul~S~+1~N~", \ +; "Jan~S~+2~N~","Jul~S~+2~N~","Jan~S~+3~N~","Jul~S~+3~N~","Jan~S~+4~N~"/) + res@trYMinF = 24 + res@trYMaxF = 52 + res@tmYLValues = ispan(24,52,4) + res@tmYLLabels = (/"Jan~S~0~N~","May~S~0~N~","Sep~S~0~N~","Jan~S~+1~N~", \ + "May~S~+1~N~","Sep~S~+1~N~","Jan~S~+2~N~","May~S~+2~N~"/) + res@tmYLMinorValues = ispan(24,52,2) + res@tmYLLabelJust = "CenterCenter" + res@tmYLLabelDeltaF = 1.3 ;0.05 + res@cnFillOn = True + res@gsnSpreadColors = True + res@gsnSpreadColorEnd = 19 + + res@lbLabelBarOn = False + + res@tiMainOn = False + res@cnInfoLabelOn = False + res@cnLinesOn = True + res@cnLevelSelectionMode = "ExplicitLevels" + res@cnLevels = (/-3,-2.5,-2,-1.5,-1,-.75,-.5,-.25,0,.25,.5,.75,1,1.5,2,2.5,3/) ;fspan(-2.,2.,17) + carr = new(dimsizes(res@cnLevels),"string") + carr = "transparent" + carr(8) = "gray50" + res@cnMonoLineColor = False + res@cnLineColors = carr + res@cnLineLabelsOn = False + res@tmYLLabelFontHeightF = 0.014 + res@tmXBLabelFontHeightF = 0.014 + res@gsnMajorLonSpacing = 30. + res@gsnMinorLonSpacing = 10. + res@tiYAxisOn = False + + if (wks_type.eq."png") then + res@cnLineThicknessF = 2. + else + res@cnLineThicknessF = 1. + end if + res@gsnCenterStringOrthogonalPosF = 0.025 + res@gsnRightStringOrthogonalPosF = res@gsnCenterStringOrthogonalPosF + res@gsnCenterStringFontHeightF = 0.017 + res@gsnLeftStringFontHeightF = 0.017 + res@gsnRightStringFontHeightF = 0.017 + + res@gsnLeftString = "" + res@gsnCenterString= "" + res@gsnRightString = "" + + if (isfilepresent2("obs_ts").and.ee.eq.0.and.isvar("finsst_hi")) then ; for metrics table + patcor_hov_hi = new((/nsim,dimsizes(finsst_hi&time),dimsizes(finsst_hi&lon)/),typeof(finsst_hi)) + patcor_hov_hi!1 = "time" + patcor_hov_hi&time = finsst_hi&time + patcor_hov_hi!2 = "lon" + patcor_hov_hi&lon = finsst_hi&lon + + patcor_hov_lo = patcor_hov_hi + + patcor_hov_hi(ee,:,:) = (/ finsst_hi /) + patcor_hov_lo(ee,:,:) = (/ finsst_lo /) + end if + if (isfilepresent2("obs_ts").and.ee.ge.1.and.isvar("patcor_hov_hi").and.isvar("finsst_hi")) then + dimT = dimsizes(finsst_hi&time) + do hh = 0,dimT-1 ; need to loop over each timestep, using linint1 to interpolate to set longitudes. + patcor_hov_hi(ee,hh,:) = (/ totype(linint1(finsst_hi&lon,finsst_hi(hh,:),False,patcor_hov_hi&lon,0),typeof(patcor_hov_hi)) /) + patcor_hov_lo(ee,hh,:) = (/ totype(linint1(finsst_lo&lon,finsst_lo(hh,:),False,patcor_hov_lo&lon,0),typeof(patcor_hov_lo)) /) + end do + end if + + if (isvar("finsst_hi")) then + res@gsnCenterString = names(ee) ;"El Nin~H-13V2F35~D~FV-2H3F21~o" + res@gsnRightString = cntr_hi + plot_n34hi(ee) = gsn_csm_hov(wks_n34_tlon_hi,finsst_hi,res) + + res@gsnRightString = cntr_lo + plot_n34lo(ee) = gsn_csm_hov(wks_n34_tlon_lo,finsst_lo,res) + delete([/finsst_hi,finsst_lo,finsst_mid/]) + end if + delete(res) +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + wres = True + wres@gsnDraw = False + wres@gsnFrame = False + wres@vpWidthF = 0.7 + wres@vpHeightF = 0.3 + wres@cnFillOn = True + wres@cnLinesOn = False + wres@cnLineLabelsOn = False + wres@cnInfoLabelOn = False + wres@trYReverse = True + wres@trYMinF = 1.0 + wres@trYMaxF = (nyr(ee)/2) - (nyr(ee)*0.05) + wres@tmYLOn = True + wres@tmYLMode = "Explicit" + if (nyr(ee).lt.200) then + wres@tmYLValues = (/1,2,3,5,10,20,50,100,150/) + else + wres@tmYLValues = (/1,5,10,50,100,200,500,1000,2000,5000,10000/) + end if + wres@tmYLLabels = wres@tmYLValues + wres@cnLevelSelectionMode = "ExplicitLevels" + wres@cnLevels = ispan(0,70,5) + if (COLORMAP.eq.0) then + wres@cnFillPalette = "precip3_16lev" + else + wres@cnFillPalette = "cb_rainbow" + end if + wres@tmXTLabelFontHeightF = 0.018 + wres@tmXBLabelFontHeightF = 0.018 + wres@tmYLLabelFontHeightF = 0.018 + wres@tiYAxisString = "Period (years)" + wres@tiXAxisOn = False + wres@lbLabelBarOn = False + wres@gsnLeftString = "" + wres@gsnCenterString = "" + wres@gsnRightString = "" + wres@gsnCenterStringOrthogonalPosF = 0.025 + + wsres = True ; res2 probability plots + wsres@trYReverse = True + wsres@tmYLMode = "Explicit" + wsres@tmYLValues = wres@tmYLValues + wsres@tmYLLabels = wres@tmYLLabels + wsres@gsnDraw = False ; Do not draw plot + wsres@gsnFrame = False ; Do not advance frome + wsres@cnLevelSelectionMode = "ManualLevels" ; set manual contour levels + wsres@cnMinLevelValF = 0.00 ; set min contour level + wsres@cnMaxLevelValF = 2.00 ; set max contour level + wsres@cnLevelSpacingF = 1.00 ; set contour spacing + wsres@cnInfoLabelOn = False + wsres@cnLinesOn = False ; do not draw contour lines + wsres@cnLineLabelsOn = False ; do not draw contour labels + wsres@cnFillScaleF = 0.5 ; add extra density + wsres@cnFillDotSizeF = .0015 + wsres@gsnLeftString = "" + wsres@gsnCenterString = "" + wsres@gsnRightString = "" + + wavecoi = True + wavecoi@gsEdgeColor = "gray40" + wavecoi@gsFillColor = wavecoi@gsEdgeColor +; wavecoi@gsFillOpacityF = 0.15 + if (wks_type.eq."png") then + wavecoi@gsFillLineThicknessF = 2.0 + wavecoi@gsEdgeThicknessF = 2.0 + else + wavecoi@gsFillLineThicknessF = 1.25 + wavecoi@gsEdgeThicknessF = 1.25 + end if + wavecoi@gsFillIndex = 3 + wavecoi@gsFillScaleF = .65 + + + if (spectra_mvf.eq.False) then + wres@gsnLeftString = "" + wres@gsnCenterString = names(ee) + delete(power34&time) + power34&time = fspan(syear(ee),eyear(ee)+.91667,nyr(ee)*12) + delete(sig34&time) + sig34&time = power34&time + plot_wave34(ee) = gsn_csm_contour(wks_n34_p,power34,wres) + plot_wave34(ee) = ShadeCOI(wks_n34_p,plot_wave34(ee),wave34,power34&time,wavecoi) + o0 = gsn_csm_contour(wks_n34_p,sig34,wsres) + opt = True + opt@gsnShadeFillType = "pattern" + opt@gsnShadeHigh = 17 + o0 = gsn_contour_shade(o0,0, 0.8, opt) + overlay(plot_wave34(ee),o0) + delete([/o0,opt,power34,sig34,wave34/]) + end if + delete([/wres,wsres,wavecoi/]) +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + pres = True + pres@vpXF = 0.07 + pres@trYMinF = 0. + pres@trXMinF = 0.0 +; pres@trYMaxF = 82. + pres@trXMaxF = 0.0832 + pres@tiYAxisString = "Power" ; yaxis + pres@xyLineColor = "black" + pres@gsnFrame = False + pres@gsnDraw = False + + pres@tmXBLabelDeltaF = -.8 + pres@tmXTLabelDeltaF = -.8 + pres@pmLegendDisplayMode = "Never" + if (wks_type.eq."png") then + pres@xyLineThicknesses = (/3.5,2.,1.,1./) + else + pres@xyLineThicknesses = (/2.5,1.5,1.,1./) + end if + pres@xyDashPatterns = (/0,0,0,0/) + pres@xyLineColors = (/"foreground","red","blue","green"/) + pres@xyLabelMode = "custom" + pres@xyLineLabelFontColors = pres@xyLineColors + pres@xyExplicitLabels = (/"","",val1*100+"%",val2*100+"%"/) + pres@tmXTOn = True + pres@tmYROn = False + pres@tmXTLabelsOn = True + pres@tmXUseBottom = False + pres@tmXTMode = "Explicit" + pres@tmXBMode = "Explicit" + pres@tmXTValues = (/".00167",".00833",".01667",".02778",".0416",".0556",".0832"/) + pres@tmXTLabels = (/"50","10","5","3","2","1.5","1"/) + pres@tmXBValues = (/".0",".01",".02",".03",".042",".056",".083"/) + pres@tmXBLabels = pres@tmXBValues + pres@tmXTLabelFontHeightF = 0.018 + pres@tmXBLabelFontHeightF = 0.018 + pres@tmYLLabelFontHeightF = 0.018 + pres@tiYAxisString = "Power (~S~o~N~C~S~2~N~ / cycles mo~S~-1~N~)" ; yaxis + pres@tiXAxisString = "Frequency (cycles mo~S~-1~N~)" + pres@tiMainString = "" + pres@txFontHeightF = 0.015 + pres@xyLineLabelFontHeightF = 0.022 + pres@tiXAxisFontHeightF = 0.025 + pres@tiYAxisFontHeightF = 0.025 + pres@tiMainFontHeightF = 0.03 + pres@gsnRightStringOrthogonalPosF = -0.115 + + if (spectra_mvf.eq.False) then + if (isfilepresent2("obs_ts").and.ee.ge.1.and.spectra_mvf_obs.eq.False) then + val = new(2,typeof(sdof_obs@spcx)) + val(0) = max(sdof_obs@spcx) + val(1) = totype(max(splt1(0,:)),typeof(sdof_obs@spcx)) + mval = max(val) + delete(val) + else + mval = max(splt1(0,:)) + end if + if (mval.lt.70) then + pres@trYMaxF = 75. + pres@tmYLMode = "Explicit" + pres@tmYLValues = (/0,25,50,75/) + pres@tmYLLabels = pres@tmYLValues + pres@tmYLMinorValues = ispan(5,70,5) + end if + if (mval.ge.70.and.mval.lt.145) then + pres@trYMaxF = 150. + pres@tmYLMode = "Explicit" + pres@tmYLValues = (/0,50,100,150/) + pres@tmYLLabels = pres@tmYLValues + pres@tmYLMinorValues = ispan(10,140,10) + end if + if (mval.ge.145) then + pres@trYMaxF = mval+15. + end if + delete(mval) + end if + + pres@tiMainOn = False + pres@gsnCenterString = "Period (years)" + pres@gsnCenterStringFontHeightF = pres@tiYAxisFontHeightF + pres@gsnRightStringFontHeightF = pres@tiYAxisFontHeightF - 0.005 + pres@gsnRightString = syear(ee)+"-"+eyear(ee)+" " + pres@gsnLeftString = "" + pres@gsnCenterString = names(ee) + if (spectra_mvf.eq.False) then + pspec(ee) = gsn_csm_xy(wks_n34_p,sdof@frq,splt1,pres) + if (isfilepresent2("obs_ts").and.ee.ge.1.and.spectra_mvf_obs.eq.False) then + pres@xyLineColors = (/"gray70","black","black","black"/) + pres@xyCurveDrawOrder = "PreDraw" + pres@gsnCenterString = "" + pres@gsnRightString = "" + pspec_obs(ee) = gsn_csm_xy(wks_n34_p,sdof_obs@frq,sdof_obs@spcx,pres) + overlay(pspec(ee),pspec_obs(ee)) + delete(pres@xyCurveDrawOrder) + end if + delete([/sdof,splt1/]) + end if + delete([/val1,val2,pres/]) +;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + if (nyr(ee).ge.35) then + delete(sd_run) + end if + + scres = True ; scres = spatial composite res + scres@mpProjection = "WinkelTripel" + scres@mpGeophysicalLineColor = "gray42" + + scres@mpPerimOn = False + scres@mpGridLatSpacingF = 90 ; change latitude line spacing + scres@mpGridLonSpacingF = 180. ; change longitude line spacing + scres@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + scres@mpGridAndLimbOn = True ; turn on lat/lon lines + scres@mpFillOn = False + scres@mpCenterLonF = 210. + scres@mpOutlineOn = True + scres@gsnDraw = False + scres@gsnFrame = False + + scres@cnLevelSelectionMode = "ExplicitLevels" + scres@cnLevels = (/-4,-3,-2,-1.5,-1,-.5,-.25,0,.25,.5,1,1.5,2,3.,4/) + + scres@cnLineLabelsOn = False + scres@cnFillOn = True + scres@cnLinesOn = False +; scres@mpOutlineDrawOrder = "PostDraw" +; scres@cnFillMode = "RasterFill" + scres@mpOutlineDrawOrder = "PostDraw" + scres@cnFillMode = "AreaFill" + scres@lbLabelBarOn = False + scres@cnInfoLabelOn = False + scres@gsnAddCyclic = True + + + scres@gsnLeftStringOrthogonalPosF = -0.05 + scres@gsnLeftStringParallelPosF = .005 + scres@gsnRightStringOrthogonalPosF = -0.05 + scres@gsnRightStringParallelPosF = 0.96 + if (isvar("cntr_hi")) then + scres@gsnRightString = cntr_hi+"/"+cntr_lo ; list number of El Nino / La Nina events that formed composites + delete([/cntr_hi,cntr_lo,cntr_mid/]) + else + scres@gsnRightString = "" + end if + scres@gsnLeftString = "" + scres@gsnLeftStringFontHeightF = 0.014 + scres@gsnCenterStringFontHeightF = 0.018 + scres@gsnRightStringFontHeightF = 0.014 + + + + scres4 = scres ; scres4 = ppt composite resources + delete(scres4@cnLevels) + if (COLORMAP.eq.0) then + scres4@cnLevels = (/-10,-8,-6,-4,-3,-2,-1,-.5,-.25,0,.25,.5,1,2,3,4,6,8,10/) + else + scres4@cnLevels = (/-5,-3,-2,-1,-.5,0,.5,1,2,3,5/) + end if + + scres2 = True + scres2@gsnDraw = False + scres2@gsnFrame = False + scres2@cnLevelSelectionMode = "ExplicitLevels" + scres2@cnLevels = scres@cnLevels + + scres2@cnLineLabelsOn = False + scres2@cnFillOn = True + scres2@cnLinesOn = False + scres2@cnFillMode = "AreaFill" + scres2@lbLabelBarOn = False + scres2@cnInfoLabelOn = False + scres2@gsnRightString = "" + scres2@gsnLeftString = "" + scres2@gsnCenterString = "" + scres2@gsnAddCyclic = True + + + scres3 = True ; PSL resources + scres3@cnLineColor = "black" + scres3@cnLineLabelsOn = False + scres3@cnLevelSelectionMode = "ExplicitLevels" + scres3@cnInfoLabelOn = False + scres3@tiMainOn = False + new_index = NhlNewDashPattern(wks_n34sc,"$_$_$_$_$_$_$_$_$_") + scres3@gsnContourNegLineDashPattern = new_index + scres3@cnLineDashSegLenF = 0.08 + scres3@gsnDraw = False + scres3@gsnFrame = False + scres3@gsnLeftString = "" + scres3@gsnRightString = "" + scres3@gsnCenterString = "" + scres3@cnLevels = ispan(-16,16,2) + + scres4@gsnLeftString = syear_prect(ee)+"-"+eyear_prect(ee) + scres4@gsnCenterString = names_prect(ee) + + scres@gsnLeftString = syear(ee)+"-"+eyear(ee) + if (names(ee).eq.names_trefht(ee).and.names(ee).eq.names_psl(ee)) then + scres@gsnCenterString = names(ee) + else + scres@gsnCenterString = names(ee)+" / "+names_trefht(ee)+" / "+names_psl(ee) + end if + + if (wks_type.eq."png") then + scres3@cnLineThicknessF = 3. + scres@mpGeophysicalLineThicknessF = 2. + scres4@mpGeophysicalLineThicknessF = 2. + else + scres3@cnLineThicknessF = 1.25 + scres@mpGeophysicalLineThicknessF = 1. + scres4@mpGeophysicalLineThicknessF = 1. + end if + + if (taspslreg_plot_flag.eq.0) then + if (isvar("patcor_tas")) then ; for metrics table + patcor_tas(ee,:,:) = (/ totype(linint2(n34sc_tas&lon,n34sc_tas&lat,n34sc_tas(12,:,:),True,patcor_tas&lon,patcor_tas&lat,0),typeof(patcor_tas)) /) + patcor_psl(ee,:,:) = (/ totype(linint2(n34sc_psl&lon,n34sc_psl&lat,n34sc_psl(12,:,:),True,patcor_psl&lon,patcor_psl&lat,0),typeof(patcor_psl)) /) + else + if (isfilepresent2("obs_trefht")) then + patcor_tas = new((/nsim,dimsizes(n34sc_tas&lat),dimsizes(n34sc_tas&lon)/),typeof(n34sc_tas)) + patcor_tas!1 = "lat" + patcor_tas&lat = n34sc_tas&lat + patcor_tas!2 = "lon" + patcor_tas&lon = n34sc_tas&lon + patcor_psl = new((/nsim,dimsizes(n34sc_psl&lat),dimsizes(n34sc_psl&lon)/),typeof(n34sc_psl)) + patcor_psl!1 = "lat" + patcor_psl&lat = n34sc_psl&lat + patcor_psl!2 = "lon" + patcor_psl&lon = n34sc_psl&lon + patcor_tas(ee,:,:) = (/ n34sc_tas(12,:,:) /) + patcor_psl(ee,:,:) = (/ n34sc_psl(12,:,:) /) + end if + end if + + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") ; mask ocean for TAS array + basemap = d->LSMASK + lsm = landsea_mask(basemap,n34sc_tas&lat,n34sc_tas&lon) + n34sc_tas = mask(n34sc_tas,conform(n34sc_tas,lsm,(/1,2/)).eq.0,False) + delete([/lsm,basemap/]) + delete(d) + + map_n34sc_jja0(ee) = gsn_csm_contour_map(wks_n34sc,n34sc_sst(6,:,:),scres) ; 6 = JJA 0 + o1 = gsn_csm_contour(wks_n34sc,n34sc_tas(6,:,:),scres2) + o2 = gsn_csm_contour(wks_n34sc,n34sc_psl(6,:,:),scres3) + overlay(map_n34sc_jja0(ee),o1) + overlay(map_n34sc_jja0(ee),o2) + delete([/o1,o2/]) + + map_n34sc_son0(ee) = gsn_csm_contour_map(wks_n34sc,n34sc_sst(9,:,:),scres) ; 9 = SON 0 + o3 = gsn_csm_contour(wks_n34sc,n34sc_tas(9,:,:),scres2) + o4 = gsn_csm_contour(wks_n34sc,n34sc_psl(9,:,:),scres3) + overlay(map_n34sc_son0(ee),o3) + overlay(map_n34sc_son0(ee),o4) + delete([/o3,o4/]) + + + map_n34sc_djf1(ee) = gsn_csm_contour_map(wks_n34sc,n34sc_sst(12,:,:),scres) ; 12 = DJF+1 + o5 = gsn_csm_contour(wks_n34sc,n34sc_tas(12,:,:),scres2) + o6 = gsn_csm_contour(wks_n34sc,n34sc_psl(12,:,:),scres3) + overlay(map_n34sc_djf1(ee),o5) + overlay(map_n34sc_djf1(ee),o6) + delete([/o5,o6/]) + + map_n34sc_mam1(ee) = gsn_csm_contour_map(wks_n34sc,n34sc_sst(15,:,:),scres) ; 15 = MAM+1 + o7 = gsn_csm_contour(wks_n34sc,n34sc_tas(15,:,:),scres2) + o8 = gsn_csm_contour(wks_n34sc,n34sc_psl(15,:,:),scres3) + overlay(map_n34sc_mam1(ee),o7) + overlay(map_n34sc_mam1(ee),o8) + delete([/o7,o8/]) + delete([/n34sc_sst,n34sc_tas,n34sc_psl/]) + end if + if (pptreg_plot_flag.eq.0) then + map_n34sc_ppt_jja0(ee) = gsn_csm_contour_map(wks_n34sc_ppt,n34sc_ppt(6,:,:),scres4) ; 6 = JJA 0 + map_n34sc_ppt_son0(ee) = gsn_csm_contour_map(wks_n34sc_ppt,n34sc_ppt(9,:,:),scres4) ; 9 = SON 0 + map_n34sc_ppt_djf1(ee) = gsn_csm_contour_map(wks_n34sc_ppt,n34sc_ppt(12,:,:),scres4) ; 12 = DJF+1 + map_n34sc_ppt_mam1(ee) = gsn_csm_contour_map(wks_n34sc_ppt,n34sc_ppt(15,:,:),scres4) ; 15 = MAM+1 + delete([/n34sc_ppt/]) + end if + end do + + if (isvar("patcor_tas")) then ; for pattern correlation table + clat_tas = cos(0.01745329*patcor_tas&lat) + clat_psl = cos(0.01745329*patcor_psl&lat) + finpr_tas = "ENSO TAS (DJF+1) " ; Must be 18 characters long + finpr_psl = "ENSO PSL (DJF+1) " + line3 = " " ; Must be 18 characters long + line4 = line3 + header = (/"","Pattern Correlations/RMS Differences Observations vs. Model(s)",""/) + do hh = 1,nsim-1 + dimY = dimsizes(tochar(names(hh))) + nchar = dimY + nchar = where(nchar.le.10,10,nchar) + if (dimY.lt.10) then + ntb = "" + do ii = 0,10-dimY-1 + ntb = ntb+" " + end do + ntb = ntb+names(hh) + else + ntb = names(hh) + end if + + ntc = "" + do ii = 0,nchar-1 + ntc = ntc+"-" + end do + format2 = "%"+(nchar-5+1)+".2f" + format3 = "%4.2f" + line3 = line3+" "+ntb + line4 = line4+" "+ntc + if (all(ismissing(patcor_tas(hh,:,:)))) then + finpr_tas = finpr_tas+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr_tas = finpr_tas+sprintf(format2,(pattern_cor(patcor_tas(0,:,:),patcor_tas(hh,:,:),clat_tas,0)))+"/"+sprintf(format3,(wgt_arearmse(patcor_tas(0,:,:),patcor_tas(hh,:,:),clat_tas,1.0,0))) + end if + if (all(ismissing(patcor_psl(hh,:,:)))) then + finpr_psl = finpr_psl+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr_psl = finpr_psl+sprintf(format2,(pattern_cor(patcor_psl(0,:,:),patcor_psl(hh,:,:),clat_psl,0)))+"/"+sprintf(format3,(wgt_arearmse(patcor_psl(0,:,:),patcor_psl(hh,:,:),clat_psl,1.0,0))) + end if + end do + if (dimsizes(tochar(line4)).ge.8190) then ; system or fortran compiler limit + print("Metrics table warning: Not creating metrics table as size of comparison results in a invalid ascii row size.") + else + write_table(getenv("OUTDIR")+"metrics.sst.indices.1.txt","w",[/header/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.indices.1.txt","a",[/line3/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.indices.1.txt","a",[/line4/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.indices.1.txt","a",[/finpr_tas/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.indices.1.txt","a",[/finpr_psl/],"%s") + end if + delete([/finpr_tas,finpr_psl,line3,line4,format2,format3,nchar,ntc,clat_tas,clat_psl,patcor_tas,patcor_psl,dimY,ntb,header/]) + end if + + if (isvar("patcor_hov_hi")) then ; for pattern correlation table + finpr_hi = "El Nino Hovmoller " ; Must be 18 characters long + finpr_lo = "La Nina Hovmoller " + line3 = " " ; Must be 18 characters long patcor_hov_hi + line4 = line3 + header = (/"","Pattern Correlations/RMS Differences Observations vs. Model(s)",""/) + do hh = 1,nsim-1 + dimY = dimsizes(tochar(names(hh))) + nchar = dimY + nchar = where(nchar.le.10,10,nchar) + if (dimY.lt.10) then + ntb = "" + do ii = 0,10-dimY-1 + ntb = ntb+" " + end do + ntb = ntb+names(hh) + else + ntb = names(hh) + end if + + ntc = "" + do ii = 0,nchar-1 + ntc = ntc+"-" + end do + format2 = "%"+(nchar-5+1)+".2f" + format3 = "%4.2f" + line3 = line3+" "+ntb + line4 = line4+" "+ntc + if (all(ismissing(patcor_hov_hi(hh,24:52,:)))) then ; 24:52 refers to Jan+0->May+2, which is the range shown in the hovmoller plots. + finpr_hi = finpr_hi+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr_hi = finpr_hi+sprintf(format2,(pattern_cor(patcor_hov_hi(0,24:52,:),patcor_hov_hi(hh,24:52,:),1.0,0)))+"/"+sprintf(format3,(wgt_arearmse(patcor_hov_hi(0,24:52,:),patcor_hov_hi(hh,24:52,:),1.0,1.0,0))) + end if + if (all(ismissing(patcor_hov_lo(hh,24:52,:)))) then + finpr_lo = finpr_lo+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr_lo = finpr_lo+sprintf(format2,(pattern_cor(patcor_hov_lo(0,24:52,:),patcor_hov_lo(hh,24:52,:),1.0,0)))+"/"+sprintf(format3,(wgt_arearmse(patcor_hov_lo(0,24:52,:),patcor_hov_lo(hh,24:52,:),1.0,1.0,0))) + end if + end do + if (dimsizes(tochar(line4)).ge.8190) then ; system or fortran compiler limit + print("Metrics table warning: Not creating metrics table as size of comparison results in a invalid ascii row size.") + else + write_table(getenv("OUTDIR")+"metrics.sst.indices.2.txt","w",[/header/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.indices.2.txt","a",[/line3/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.indices.2.txt","a",[/line4/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.indices.2.txt","a",[/finpr_hi/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.indices.2.txt","a",[/finpr_lo/],"%s") + end if + delete([/finpr_hi,finpr_lo,line3,line4,format2,format3,nchar,ntc,patcor_hov_hi,patcor_hov_lo,dimY,ntb,header/]) + end if + + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelYWhiteSpacePercent = 3.0 + if (nsim.le.10) then + panres@txFontHeightF = 0.016 + else + panres@txFontHeightF = 0.012 + end if + + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) ;(/nsim/2+1,nsim/8+1/) + end if + + if (isvar("title_n34")) then + panres@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 (Monthly, "+title_n34+")" + gsn_panel2(wks_n34,xyn34,lp,panres) + + panres@txString = "Nin~H-13V2F35~D~FV-2H3F21~o4 (Monthly, "+title_n4+")" + gsn_panel2(wks_n4,xyn4,lp,panres) + + panres@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3 (Monthly, "+title_n3+")" + gsn_panel2(wks_n3,xyn3,lp,panres) + + panres@txString = "Nin~H-13V2F35~D~FV-2H3F21~o1+2 (Monthly, "+title_n12+")" + gsn_panel2(wks_n12,xyn12,lp,panres) + + panres@txString = "Tropical North Atlantic (Monthly, "+title_tna+")" + gsn_panel2(wks_tna,xytna,lp,panres) + + panres@txString = "Tropical South Atlantic (Monthly, "+title_tsa+")" + gsn_panel2(wks_tsa,xytsa,lp,panres) + + panres@txString = "Tropical Indian Ocean (Monthly, "+title_tio+")" + gsn_panel2(wks_tio,xytio,lp,panres) + + panres@txString = "Indian Ocean Dipole (Monthly, "+title_iod+")" + gsn_panel2(wks_tio,xyiod,lp,panres) + + panres@txString = "Southern Ocean (Monthly, "+title_socn+")" + gsn_panel2(wks_tio,xysocn,lp,panres) + + panres@txString = "Atlantic Meridional Mode (Monthly, "+title_iod+")" + gsn_panel2(wks_tio,xyiod,lp,panres) + + panres@txString = "Atlantic Nin~H-13V2F35~D~FV-2H3F21~o3 (Monthly, "+title_socn+")" + gsn_panel2(wks_tio,xyatl3,lp,panres) + end if + delete(wks_tio) + + if (all(ismissing(xyn34_rst))) then +; print("No valid running standard deviation plots, skipping") + else + panres@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 30yr running standard deviation" + gsn_panel2(wks_n34_rst,xyn34_rst,lp,panres) + delete(xyn34_rst) + end if + panres@gsnPanelYWhiteSpacePercent = 0.5 + panres@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 standard deviation (Monthly)" + gsn_panel2(wks_n34_mst,xyn34_mst,(/nrow,ncol/),panres) + + panres2 = True + panres2@gsnMaximize = True + panres2@gsnPaperOrientation = "portrait" + panres2@gsnPanelLabelBar = True + panres2@lbLabelStride = 1 + panres2@pmLabelBarWidthF = 0.4 + panres2@pmLabelBarHeightF = 0.06 + panres2@lbLabelFontHeightF = 0.013 + panres2@txString = "" + + if (nsim.le.4) then + if (nsim.eq.1) then + panres2@txFontHeightF = 0.022 + panres2@gsnPanelBottom = 0.50 + else + panres2@txFontHeightF = 0.0145 + panres2@gsnPanelBottom = 0.50 + end if + else + panres2@txFontHeightF = 0.016 + panres2@gsnPanelBottom = 0.05 + end if + panres2@lbTitleOn = True + panres2@lbTitlePosition = "Bottom" + panres2@lbTitleFontHeightF = panres2@lbLabelFontHeightF - 0.002 + panres2@lbTitleString = "C" + + panres2@txString = "El Nin~H-13V2F35~D~FV-2H3F21~o Composite (3~S~o~N~S:3~S~o~N~N)" + gsn_panel2(wks_n34_tlon_hi,plot_n34hi,(/nrow,ncol/),panres2) + panres2@txString = "La Nin~H-13V2F35~D~FV-2H3F21~a Composite (3~S~o~N~S:3~S~o~N~N)" + gsn_panel2(wks_n34_tlon_lo,plot_n34lo,(/nrow,ncol/),panres2) + delete([/panres2@lbTitleOn,panres2@lbTitlePosition,panres2@lbTitleFontHeightF,panres2@lbTitleString/]) + + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 (Monthly, detrended)" + gsn_panel2(wks_n34_p,pspec,(/nrow,ncol/),panres) + panres@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 Autocorrelation (Monthly)" + gsn_panel2(wks_n34_p,xyn34_ac,(/nrow,ncol/),panres) + panres2@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 Wavelet (Monthly)" + panres2@gsnPanelYWhiteSpacePercent = 3.0 + panres2@gsnPanelXWhiteSpacePercent = 4.0 + gsn_panel2(wks_n34_p,plot_wave34,(/nrow,ncol/),panres2) + delete(wks_n34_p) + + delete(panres2@gsnPanelYWhiteSpacePercent) + panres2@pmLabelBarWidthF = 0.8 + panres2@lbLabelAutoStride = False + panres2@gsnPanelXWhiteSpacePercent = 8.5 + if (any(.not.ismissing(map_n34sc_jja0))) then + panres2@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 SST,TAS,PSL Spatial Composite (JJA~S~0~N~)" + gsn_panel2(wks_n34sc,map_n34sc_jja0,(/nrow,ncol/),panres2) + + panres2@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 SST,TAS,PSL Spatial Composite (SON~S~0~N~)" + gsn_panel2(wks_n34sc,map_n34sc_son0,(/nrow,ncol/),panres2) + + panres2@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 SST,TAS,PSL Spatial Composite (DJF~S~+1~N~)" + gsn_panel2(wks_n34sc,map_n34sc_djf1,(/nrow,ncol/),panres2) + + panres2@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 SST,TAS,PSL Spatial Composite (MAM~S~+1~N~)" + gsn_panel2(wks_n34sc,map_n34sc_mam1,(/nrow,ncol/),panres2) + delete(wks_n34sc) + + delete([/map_n34sc_djf1,map_n34sc_jja0,map_n34sc_son0,map_n34sc_mam1/]) + end if + if (any(.not.ismissing(map_n34sc_ppt_jja0))) then + panres2@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 PR Spatial Composite (JJA~S~0~N~)" + gsn_panel2(wks_n34sc_ppt,map_n34sc_ppt_jja0,(/nrow,ncol/),panres2) + + panres2@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 PR Spatial Composite (SON~S~0~N~)" + gsn_panel2(wks_n34sc_ppt,map_n34sc_ppt_son0,(/nrow,ncol/),panres2) + + panres2@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 PR Spatial Composite (DJF~S~+1~N~)" + gsn_panel2(wks_n34sc_ppt,map_n34sc_ppt_djf1,(/nrow,ncol/),panres2) + + panres2@txString = "Nin~H-13V2F35~D~FV-2H3F21~o3.4 PR Spatial Composite (MAM~S~+1~N~)" + gsn_panel2(wks_n34sc_ppt,map_n34sc_ppt_mam1,(/nrow,ncol/),panres2) + delete(wks_n34sc_ppt) + + delete([/map_n34sc_ppt_djf1,map_n34sc_ppt_jja0,map_n34sc_ppt_son0,map_n34sc_ppt_mam1/]) + end if + + delete([/xyn34,xyn4,xyn3,xyn12,xytna,xytsa,xytio,xyiod,plot_n34hi,plot_n34lo,pspec,pi,rad,wgt,lp/]) + + OUTDIR = getenv("OUTDIR") + + if (wks_type.eq."png") then + if (isfilepresent2(OUTDIR+"nino34.spatialcomp.000001.png")) then + system("mv "+OUTDIR+"nino34.spatialcomp.000001.png "+OUTDIR+"nino34.spatialcomp.jja0.png") + system("mv "+OUTDIR+"nino34.spatialcomp.000002.png "+OUTDIR+"nino34.spatialcomp.son0.png") + system("mv "+OUTDIR+"nino34.spatialcomp.000003.png "+OUTDIR+"nino34.spatialcomp.djf1.png") + system("mv "+OUTDIR+"nino34.spatialcomp.000004.png "+OUTDIR+"nino34.spatialcomp.mam1.png") + end if + if (isfilepresent2(OUTDIR+"nino34.spatialcomp.ppt.000001.png")) then + system("mv "+OUTDIR+"nino34.spatialcomp.ppt.000001.png "+OUTDIR+"nino34.spatialcomp.pr.jja0.png") + system("mv "+OUTDIR+"nino34.spatialcomp.ppt.000002.png "+OUTDIR+"nino34.spatialcomp.pr.son0.png") + system("mv "+OUTDIR+"nino34.spatialcomp.ppt.000003.png "+OUTDIR+"nino34.spatialcomp.pr.djf1.png") + system("mv "+OUTDIR+"nino34.spatialcomp.ppt.000004.png "+OUTDIR+"nino34.spatialcomp.pr.mam1.png") + end if + if (isfilepresent2(OUTDIR+"tio.timeseries.000001.png")) then + system("mv "+OUTDIR+"tio.timeseries.000001.png "+OUTDIR+"tio.timeseries.png") + system("mv "+OUTDIR+"tio.timeseries.000002.png "+OUTDIR+"iod.timeseries.png") + system("mv "+OUTDIR+"tio.timeseries.000003.png "+OUTDIR+"socn.timeseries.png") + system("mv "+OUTDIR+"tio.timeseries.000004.png "+OUTDIR+"amm.timeseries.png") + system("mv "+OUTDIR+"tio.timeseries.000005.png "+OUTDIR+"atl3.timeseries.png") + end if + if (isfilepresent2(OUTDIR+"nino34.powspec.000001.png")) then + system("mv "+OUTDIR+"nino34.powspec.000001.png "+OUTDIR+"nino34.powspec.png") + system("mv "+OUTDIR+"nino34.powspec.000002.png "+OUTDIR+"nino34.autocor.png") + system("mv "+OUTDIR+"nino34.powspec.000003.png "+OUTDIR+"nino34.wavelet.png") + end if + else + if (isfilepresent2(OUTDIR+"nino34.spatialcomp.ps")) then + system("psplit "+OUTDIR+"nino34.spatialcomp.ps "+OUTDIR+"sst_ind") + system("mv "+OUTDIR+"sst_ind0001.ps "+OUTDIR+"nino34.spatialcomp.jja0.ps") + system("mv "+OUTDIR+"sst_ind0002.ps "+OUTDIR+"nino34.spatialcomp.son0.ps") + system("mv "+OUTDIR+"sst_ind0003.ps "+OUTDIR+"nino34.spatialcomp.djf1.ps") + system("mv "+OUTDIR+"sst_ind0004.ps "+OUTDIR+"nino34.spatialcomp.mam1.ps") + system("rm "+OUTDIR+"nino34.spatialcomp.ps") + end if + if (isfilepresent2(OUTDIR+"nino34.spatialcomp.ppt.ps")) then + system("psplit "+OUTDIR+"nino34.spatialcomp.ppt.ps "+OUTDIR+"sst_ind") + system("mv "+OUTDIR+"sst_ind0001.ps "+OUTDIR+"nino34.spatialcomp.pr.jja0.ps") + system("mv "+OUTDIR+"sst_ind0002.ps "+OUTDIR+"nino34.spatialcomp.pr.son0.ps") + system("mv "+OUTDIR+"sst_ind0003.ps "+OUTDIR+"nino34.spatialcomp.pr.djf1.ps") + system("mv "+OUTDIR+"sst_ind0004.ps "+OUTDIR+"nino34.spatialcomp.pr.mam1.ps") + system("rm "+OUTDIR+"nino34.spatialcomp.ppt.ps") + end if + if (isfilepresent2(OUTDIR+"tio.timeseries.ps")) then + system("psplit "+OUTDIR+"tio.timeseries.ps "+OUTDIR+"sst_ind") + system("mv "+OUTDIR+"sst_ind0001.ps "+OUTDIR+"tio.timeseries.ps") + system("mv "+OUTDIR+"sst_ind0002.ps "+OUTDIR+"iod.timeseries.ps") + system("mv "+OUTDIR+"sst_ind0003.ps "+OUTDIR+"socn.timeseries.ps") + system("mv "+OUTDIR+"sst_ind0004.ps "+OUTDIR+"amm.timeseries.ps") + system("mv "+OUTDIR+"sst_ind0005.ps "+OUTDIR+"atl3.timeseries.ps") + end if + if (isfilepresent2(OUTDIR+"nino34.powspec.ps")) then + system("psplit "+OUTDIR+"nino34.powspec.ps "+OUTDIR+"n34p") + system("mv "+OUTDIR+"n34p0001.ps "+OUTDIR+"nino34.powspec.ps") + if (isfilepresent2(OUTDIR+"n34p0002.ps")) then + system("mv "+OUTDIR+"n34p0002.ps "+OUTDIR+"nino34.autocor.ps") + system("mv "+OUTDIR+"n34p0003.ps "+OUTDIR+"nino34.wavelet.ps") + end if + end if + end if + print("Finished: sst.indices.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/sst.mean_stddev.ncl b/lib/externals/CVDP/ncl_scripts/sst.mean_stddev.ncl new file mode 100644 index 000000000..4bd84baa9 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/sst.mean_stddev.ncl @@ -0,0 +1,386 @@ +; Calculates SST global means and standard deviations +; +; Variables used: ts +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: sst.mean_stddev.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_ts") + na = asciiread("namelist_byvar/namelist_ts",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_stddev_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.stddev.djf") + wks_stddev_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.stddev.mam") + wks_stddev_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.stddev.jja") + wks_stddev_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.stddev.son") + wks_stddev_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.stddev.ann") + wks_mean_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.mean.djf") + wks_mean_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.mean.mam") + wks_mean_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.mean.jja") + wks_mean_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.mean.son") + wks_mean_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.mean.ann") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_stddev_djf,"precip3_16lev") + gsn_define_colormap(wks_stddev_mam,"precip3_16lev") + gsn_define_colormap(wks_stddev_jja,"precip3_16lev") + gsn_define_colormap(wks_stddev_son,"precip3_16lev") + gsn_define_colormap(wks_stddev_ann,"precip3_16lev") + gsn_define_colormap(wks_mean_djf,"ncl_default") + gsn_define_colormap(wks_mean_mam,"ncl_default") + gsn_define_colormap(wks_mean_jja,"ncl_default") + gsn_define_colormap(wks_mean_son,"ncl_default") + gsn_define_colormap(wks_mean_ann,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_stddev_djf,"cb_rainbow") + gsn_define_colormap(wks_stddev_mam,"cb_rainbow") + gsn_define_colormap(wks_stddev_jja,"cb_rainbow") + gsn_define_colormap(wks_stddev_son,"cb_rainbow") + gsn_define_colormap(wks_stddev_ann,"cb_rainbow") + gsn_define_colormap(wks_mean_djf,"BlueDarkRed18") + gsn_define_colormap(wks_mean_mam,"BlueDarkRed18") + gsn_define_colormap(wks_mean_jja,"BlueDarkRed18") + gsn_define_colormap(wks_mean_son,"BlueDarkRed18") + gsn_define_colormap(wks_mean_ann,"BlueDarkRed18") + end if + + plot_mean_djf = new(nsim,"graphic") + plot_mean_mam = new(nsim,"graphic") + plot_mean_jja = new(nsim,"graphic") + plot_mean_son = new(nsim,"graphic") + plot_mean_ann = new(nsim,"graphic") + plot_stddev_djf = new(nsim,"graphic") + plot_stddev_mam = new(nsim,"graphic") + plot_stddev_jja = new(nsim,"graphic") + plot_stddev_son = new(nsim,"graphic") + plot_stddev_ann = new(nsim,"graphic") + do ee = 0,nsim-1 + sst = data_read_in(paths(ee),"TS",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(sst,"is_all_missing")) then + delete(sst) + continue + end if + sst = where(sst.le.-1.8,-1.8,sst) ; set all values below -1.8 to -1.8 + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") ; mask out land (this is redundant for data that is already masked) + basemap = d->LSMASK + lsm = landsea_mask(basemap,sst&lat,sst&lon) + sst = mask(sst,conform(sst,lsm,(/1,2/)).ge.1,False) + delete([/lsm,basemap/]) + delete(d) + + do ff = 0,1 + sstT = sst + if (ff.eq.1) then + if (OPT_CLIMO.eq."Full") then + sstT = rmMonAnnCycTLL(sstT) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sstT + delete(temp_arr&time) + temp_arr&time = cd_calendar(sstT&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sstT = calcMonAnomTLL(sstT,climo) + delete(climo) + end if + end if + sst_seas = runave_n_Wrap(sstT,3,0,0) + sst_seas(0,:,:) = (/ dim_avg_n(sstT(:1,:,:),0) /) + sst_seas(dimsizes(sstT&time)-1,:,:) = (/ dim_avg_n(sstT(dimsizes(sstT&time)-2:,:,:),0) /) + sst_ann = runave_n_Wrap(sstT,12,0,0) + delete(sstT) + + if (ff.eq.0) then + sst_mean_djf = dim_avg_n_Wrap(sst_seas(0::12,:,:),0) + sst_mean_mam = dim_avg_n_Wrap(sst_seas(3::12,:,:),0) + sst_mean_jja = dim_avg_n_Wrap(sst_seas(6::12,:,:),0) + sst_mean_son = dim_avg_n_Wrap(sst_seas(9::12,:,:),0) + sst_mean_ann = dim_avg_n_Wrap(sst_ann(5::12,:,:),0) + end if + if (ff.eq.1) then + sst_sd_djf = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),sst_seas(0::12,:,:),False,False,0),0) + sst_sd_mam = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),sst_seas(3::12,:,:),False,False,0),0) + sst_sd_jja = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),sst_seas(6::12,:,:),False,False,0),0) + sst_sd_son = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),sst_seas(9::12,:,:),False,False,0),0) + sst_sd_ann = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),sst_ann(5::12,:,:),False,False,0),0) + end if + delete([/sst_seas,sst_ann/]) + end do + delete(sst) + copy_VarMeta(sst_mean_djf,sst_sd_djf) + copy_VarMeta(sst_mean_mam,sst_sd_mam) + copy_VarMeta(sst_mean_jja,sst_sd_jja) + copy_VarMeta(sst_mean_son,sst_sd_son) + copy_VarMeta(sst_mean_ann,sst_sd_ann) + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.sst.mean_stddev."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + + z->sst_spatialmean_djf = set_varAtts(sst_mean_djf,"sst mean (DJF)","","") + z->sst_spatialmean_mam = set_varAtts(sst_mean_mam,"sst mean (MAM)","","") + z->sst_spatialmean_jja = set_varAtts(sst_mean_jja,"sst mean (JJA)","","") + z->sst_spatialmean_son = set_varAtts(sst_mean_son,"sst mean (SON)","","") + z->sst_spatialmean_ann = set_varAtts(sst_mean_ann,"sst mean (annual)","","") + + z->sst_spatialstddev_djf = set_varAtts(sst_sd_djf,"sst standard deviation (DJF)","","") + z->sst_spatialstddev_mam = set_varAtts(sst_sd_mam,"sst standard deviation (MAM)","","") + z->sst_spatialstddev_jja = set_varAtts(sst_sd_jja,"sst standard deviation (JJA)","","") + z->sst_spatialstddev_son = set_varAtts(sst_sd_son,"sst standard deviation (SON)","","") + z->sst_spatialstddev_ann = set_varAtts(sst_sd_ann,"sst standard deviation (annual)","","") + delete(z) + end if +;========================================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + + res@mpCenterLonF = 210. + res@mpOutlineOn = True + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@gsnDraw = False + res@gsnFrame = False + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@cnLevelSelectionMode = "ExplicitLevels" + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + + sres = res + + res@cnLevels = fspan(.2,1.6,8) + if (COLORMAP.eq.0) then + res@cnFillColors = (/2,4,6,8,10,12,14,16,18/) + res@mpLandFillColor = "gray75" + sres@cnLevels = ispan(0,36,2) + end if + if (COLORMAP.eq.1) then + res@cnFillColors = (/35,47,63,79,95,111,124,155,175/) + res@mpLandFillColor = "gray30" + sres@cnLevels = ispan(4,32,2) + end if + + if (isfilepresent2("obs_ts").and.ee.eq.0) then ; for pattern correlation table + patcor = new((/nsim,dimsizes(sst_sd_ann&lat),dimsizes(sst_sd_ann&lon)/),typeof(sst_sd_ann)) + patcor!1 = "lat" + patcor&lat = sst_sd_ann&lat + patcor!2 = "lon" + patcor&lon = sst_sd_ann&lon + patcor(ee,:,:) = (/ sst_sd_ann /) + end if + if (isfilepresent2("obs_ts").and.ee.ge.1.and.isvar("patcor")) then + patcor(ee,:,:) = (/ totype(linint2(sst_sd_ann&lon,sst_sd_ann&lat,sst_sd_ann,True,patcor&lon,patcor&lat,0),typeof(patcor)) /) + end if + + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnRightString = sst_mean_djf@units + res@gsnCenterString = names(ee) + plot_stddev_djf(ee) = gsn_csm_contour_map(wks_stddev_djf,sst_sd_djf,res) + plot_stddev_mam(ee) = gsn_csm_contour_map(wks_stddev_mam,sst_sd_mam,res) + plot_stddev_jja(ee) = gsn_csm_contour_map(wks_stddev_jja,sst_sd_jja,res) + plot_stddev_son(ee) = gsn_csm_contour_map(wks_stddev_son,sst_sd_son,res) + plot_stddev_ann(ee) = gsn_csm_contour_map(wks_stddev_ann,sst_sd_ann,res) + + sres@gsnLeftString = syear(ee)+"-"+eyear(ee) + sres@gsnRightString = sst_mean_djf@units + sres@gsnCenterString = names(ee) + plot_mean_djf(ee) = gsn_csm_contour_map(wks_mean_djf,sst_mean_djf,sres) + plot_mean_mam(ee) = gsn_csm_contour_map(wks_mean_mam,sst_mean_mam,sres) + plot_mean_jja(ee) = gsn_csm_contour_map(wks_mean_jja,sst_mean_jja,sres) + plot_mean_son(ee) = gsn_csm_contour_map(wks_mean_son,sst_mean_son,sres) + plot_mean_ann(ee) = gsn_csm_contour_map(wks_mean_ann,sst_mean_ann,sres) + delete([/sst_sd_djf,sst_sd_mam,sst_sd_jja,sst_sd_son,sst_sd_ann,sst_mean_djf,sst_mean_mam,sst_mean_jja,sst_mean_son,sst_mean_ann,res,sres/]) + end do + + if (isvar("patcor")) then ; for pattern correlation table + clat = cos(0.01745329*patcor&lat) + finpr = "SST Std Dev (Ann) " ; Must be 18 characters long + line3 = " " ; Must be 18 characters long + line4 = line3 + header = (/"","Pattern Correlations/RMS Differences Observations vs. Model(s)",""/) + do hh = 1,nsim-1 + dimY = dimsizes(tochar(names(hh))) + nchar = dimY + nchar = where(nchar.le.10,10,nchar) + if (dimY.lt.10) then + ntb = "" + do ii = 0,10-dimY-1 + ntb = ntb+" " + end do + ntb = ntb+names(hh) + else + ntb = names(hh) + end if + + ntc = "" + do ii = 0,nchar-1 + ntc = ntc+"-" + end do + format2 = "%"+(nchar-5+1)+".2f" + format3 = "%4.2f" + line3 = line3+" "+ntb + line4 = line4+" "+ntc + if (all(ismissing(patcor(hh,:,:)))) then + finpr = finpr+sprintf(format2,9.99)+"/"+sprintf(format3,9.99) + else + finpr = finpr+sprintf(format2,(pattern_cor(patcor(0,:,:),patcor(hh,:,:),clat,0)))+"/"+sprintf(format3,(wgt_arearmse(patcor(0,:,:),patcor(hh,:,:),clat,1.0,0))) + end if + end do + if (dimsizes(tochar(line4)).ge.8190) then ; system or fortran compiler limit + print("Metrics table warning: Not creating metrics table as size of comparison results in a invalid ascii row size.") + else + write_table(getenv("OUTDIR")+"metrics.sst.mean_stddev.txt","w",[/header/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.mean_stddev.txt","a",[/line3/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.mean_stddev.txt","a",[/line4/],"%s") + write_table(getenv("OUTDIR")+"metrics.sst.mean_stddev.txt","a",[/finpr/],"%s") + end if + delete([/finpr,line3,line4,format2,format3,nchar,ntc,clat,patcor,dimY,ntb,header/]) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelFontHeightF = 0.013 + panres@lbLabelStride = 1 + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres@txString = "SST Standard Deviations (DJF)" + gsn_panel2(wks_stddev_djf,plot_stddev_djf,(/nrow,ncol/),panres) + delete(wks_stddev_djf) + + panres@txString = "SST Standard Deviations (MAM)" + gsn_panel2(wks_stddev_mam,plot_stddev_mam,(/nrow,ncol/),panres) + delete(wks_stddev_mam) + + panres@txString = "SST Standard Deviations (JJA)" + gsn_panel2(wks_stddev_jja,plot_stddev_jja,(/nrow,ncol/),panres) + delete(wks_stddev_jja) + + panres@txString = "SST Standard Deviations (SON)" + gsn_panel2(wks_stddev_son,plot_stddev_son,(/nrow,ncol/),panres) + delete(wks_stddev_son) + + panres@txString = "SST Standard Deviations (Annual)" + gsn_panel2(wks_stddev_ann,plot_stddev_ann,(/nrow,ncol/),panres) + delete(wks_stddev_ann) + + panres@txString = "SST Means (DJF)" + gsn_panel2(wks_mean_djf,plot_mean_djf,(/nrow,ncol/),panres) + delete(wks_mean_djf) + + panres@txString = "SST Means (MAM)" + gsn_panel2(wks_mean_mam,plot_mean_mam,(/nrow,ncol/),panres) + delete(wks_mean_mam) + + panres@txString = "SST Means (JJA)" + gsn_panel2(wks_mean_jja,plot_mean_jja,(/nrow,ncol/),panres) + delete(wks_mean_jja) + + panres@txString = "SST Means (SON)" + gsn_panel2(wks_mean_son,plot_mean_son,(/nrow,ncol/),panres) + delete(wks_mean_son) + + panres@txString = "SST Means (Annual)" + gsn_panel2(wks_mean_ann,plot_mean_ann,(/nrow,ncol/),panres) + delete(wks_mean_ann) + delete(panres) + print("Finished: sst.mean_stddev.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/sst.trends_timeseries.ncl b/lib/externals/CVDP/ncl_scripts/sst.trends_timeseries.ncl new file mode 100644 index 000000000..371eb953d --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/sst.trends_timeseries.ncl @@ -0,0 +1,610 @@ +; Calculates SST global trends, running global trends and timeseries +; +; Variables used: ts +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: sst.trends_timeseries.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_ts") + na = asciiread("namelist_byvar/namelist_ts",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_trends_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.trends.djf") + wks_trends_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.trends.mam") + wks_trends_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.trends.jja") + wks_trends_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.trends.son") + wks_trends_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.trends.ann") + wks_trends_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.trends.mon") + + wks_aa_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.timeseries.djf") + wks_aa_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.timeseries.mam") + wks_aa_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.timeseries.jja") + wks_aa_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.timeseries.son") + wks_aa_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.timeseries.ann") + wks_aa_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.timeseries.mon") + + wks_rt_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"sst.runtrend.mon") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_trends_djf,"ncl_default") + gsn_define_colormap(wks_trends_mam,"ncl_default") + gsn_define_colormap(wks_trends_jja,"ncl_default") + gsn_define_colormap(wks_trends_son,"ncl_default") + gsn_define_colormap(wks_trends_ann,"ncl_default") + gsn_define_colormap(wks_trends_mon,"ncl_default") + gsn_define_colormap(wks_aa_djf,"ncl_default") + gsn_define_colormap(wks_aa_mam,"ncl_default") + gsn_define_colormap(wks_aa_jja,"ncl_default") + gsn_define_colormap(wks_aa_son,"ncl_default") + gsn_define_colormap(wks_aa_ann,"ncl_default") + gsn_define_colormap(wks_aa_mon,"ncl_default") + gsn_define_colormap(wks_rt_mon,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_trends_djf,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mam,"BlueDarkRed18") + gsn_define_colormap(wks_trends_jja,"BlueDarkRed18") + gsn_define_colormap(wks_trends_son,"BlueDarkRed18") + gsn_define_colormap(wks_trends_ann,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mon,"BlueDarkRed18") + gsn_define_colormap(wks_aa_djf,"ncl_default") + gsn_define_colormap(wks_aa_mam,"ncl_default") + gsn_define_colormap(wks_aa_jja,"ncl_default") + gsn_define_colormap(wks_aa_son,"ncl_default") + gsn_define_colormap(wks_aa_ann,"ncl_default") + gsn_define_colormap(wks_aa_mon,"ncl_default") + gsn_define_colormap(wks_rt_mon,"ncl_default") + end if + map_djf = new(nsim,"graphic") + map_mam = new(nsim,"graphic") + map_jja = new(nsim,"graphic") + map_son = new(nsim,"graphic") + map_ann = new(nsim,"graphic") + map_mon = new(nsim,"graphic") + xy_djf = new(nsim,"graphic") + xy_mam = new(nsim,"graphic") + xy_jja = new(nsim,"graphic") + xy_son = new(nsim,"graphic") + xy_ann = new(nsim,"graphic") + xy_mon = new(nsim,"graphic") + + xy_rt_mon = new((/5,nsim/),"graphic") + + if (isfilepresent2("obs_ts")) then + xy_obs_djf = new(nsim,"graphic") + xy_obs_mam = new(nsim,"graphic") + xy_obs_jja = new(nsim,"graphic") + xy_obs_son = new(nsim,"graphic") + xy_obs_ann = new(nsim,"graphic") + xy_obs_mon = new(nsim,"graphic") + end if + do ee = 0,nsim-1 + sst = data_read_in(paths(ee),"TS",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(sst,"is_all_missing")) then + delete(sst) + continue + end if + sst = where(sst.le.-1.8,-1.8,sst) ; set all values below -1.8 to -1.8 + d = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/landsea.nc","r") ; mask out land (this is redundant for data that is already masked) + basemap = d->LSMASK + lsm = landsea_mask(basemap,sst&lat,sst&lon) + sst = mask(sst,conform(sst,lsm,(/1,2/)).ge.1,False) + delete([/lsm,basemap/]) + delete(d) + + if (OPT_CLIMO.eq."Full") then + sst = rmMonAnnCycTLL(sst) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = sst + delete(temp_arr&time) + temp_arr&time = cd_calendar(sst&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + sst = calcMonAnomTLL(sst,climo) + delete(climo) + end if + + coswgt=cos(rad*sst&lat) + coswgt!0 = "lat" + coswgt&lat= sst&lat + + sst_aa_mon = wgt_areaave_Wrap(sst,coswgt,1.0,0) + tttt = dtrend_msg_n(ispan(0,dimsizes(sst&time)-1,1),sst,False,True,0) + sst_trends_mon = sst(0,:,:) + sst_trends_mon = (/ onedtond(tttt@slope, (/dimsizes(sst&lat),dimsizes(sst&lon)/) ) /) + sst_trends_mon = sst_trends_mon*dimsizes(sst&time) + sst_trends_mon@units = sst@units+" "+nyr(ee)+"yr~S~-1~N~" + delete(tttt) + + sst_seas = runave_n_Wrap(sst,3,0,0) + sst_seas(0,:,:) = (/ dim_avg_n(sst(:1,:,:),0) /) + sst_seas(dimsizes(sst&time)-1,:,:) = (/ dim_avg_n(sst(dimsizes(sst&time)-2:,:,:),0) /) + sst_ann = runave_n_Wrap(sst,12,0,0) + delete(sst) + + sst_trends_seas = sst_seas(:3,:,:) + sst_trends_seas = sst_trends_seas@_FillValue + sst_trends_ann = sst_trends_seas(0,:,:) + sst_aa_seas = new((/4,nyr(ee)/),typeof(sst_seas)) + sst_aa_seas!1 = "time" + sst_aa_seas&time = ispan(syear(ee),eyear(ee),1) + sst_aa_seas&time@units = "YYYY" + sst_aa_seas&time@long_name = "time" + sst_aa_ann = sst_aa_seas(0,:) + do ff = 0,4 + if (ff.le.3) then + tarr = sst_seas(ff*3::12,:,:) + end if + if (ff.eq.4) then + tarr = sst_ann(5::12,:,:) + end if + tttt = dtrend_msg_n(ispan(0,dimsizes(tarr&time)-1,1),tarr,False,True,0) + if (ff.le.3) then + sst_trends_seas(ff,:,:) = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + sst_aa_seas(ff,:) = (/ wgt_areaave(tarr,coswgt,1.0,0) /) + end if + if (ff.eq.4) then + sst_trends_ann = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + sst_aa_ann = (/ wgt_areaave(tarr,coswgt,1.0,0) /) + end if + delete([/tarr,tttt/]) + end do + sst_trends_seas = sst_trends_seas*nyr(ee) + sst_trends_seas@units = sst_seas@units+" "+nyr(ee)+"yr~S~-1~N~" + sst_trends_ann = sst_trends_ann*nyr(ee) + sst_trends_ann@units = sst_ann@units+" "+nyr(ee)+"yr~S~-1~N~" + delete([/sst_seas,sst_ann,coswgt/]) + + if (isfilepresent2("obs_ts").and.ee.eq.0) then + sst_aa_seas@syear = syear(ee) + sst_aa_seas@eyear = eyear(ee) + sst_aa_mon@syear = syear(ee) + sst_aa_mon@eyear = eyear(ee) + sst_aa_ann@syear = syear(ee) + sst_aa_ann@eyear = eyear(ee) + sst_aa_seas_obs = sst_aa_seas + sst_aa_mon_obs = sst_aa_mon + sst_aa_ann_obs = sst_aa_ann + end if + + dimT = dimsizes(sst_aa_mon) ; calculate running trends from the monthly data + sst_rt_mon = new((/5,dimT/),typeof(sst_aa_mon)) + sst_rt_mon!1 = "time" + sst_rt_mon&time = sst_aa_mon&time + copy_VarAtts(sst_aa_mon,sst_rt_mon) + sst_rt_mon@long_name = sst_rt_mon@long_name+" global average running trend" + rt_nyr = (/8,10,12,14,16/) + do ff = 0,dimsizes(rt_nyr)-1 + incr = rt_nyr(ff)*12 + do gg = 0,dimT-incr-1 + tttt = dtrend_msg(ispan(0,incr-1,1),sst_aa_mon(gg:gg+incr-1),False,True) + sst_rt_mon(ff,gg) = (/ tttt@slope*incr /) + delete(tttt) + end do + end do + delete([/dimT,incr/]) + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.sst.trends_timeseries."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + sst_aa_seas2 = sst_aa_seas + sst_aa_seas2!1 = "TIME" + sst_aa_seas2&TIME = ispan(syear(ee),eyear(ee),1) + sst_aa_seas2&TIME@units = "YYYY" + sst_aa_seas2&TIME@long_name = "time" + sst_aa_ann2 = sst_aa_ann + sst_aa_ann2!0 = "TIME" + sst_aa_ann2&TIME = ispan(syear(ee),eyear(ee),1) + sst_aa_ann2&TIME@units = "YYYY" + sst_aa_ann2&TIME@long_name = "time" + z->sst_global_avg_mon = set_varAtts(sst_aa_mon,"sst global area-average (monthly)","C","") + z->sst_global_avg_djf = set_varAtts(sst_aa_seas2(0,:),"sst global area-average (DJF)","C","") + z->sst_global_avg_mam = set_varAtts(sst_aa_seas2(1,:),"sst global area-average (MAM)","C","") + z->sst_global_avg_jja = set_varAtts(sst_aa_seas2(2,:),"sst global area-average (JJA)","C","") + z->sst_global_avg_son = set_varAtts(sst_aa_seas2(3,:),"sst global area-average (SON)","C","") + z->sst_global_avg_ann = set_varAtts(sst_aa_ann2,"sst global area-average (annual)","C","") + z->$("sst_global_avg_runtrend_"+rt_nyr(0)+"yr")$ = set_varAtts(sst_rt_mon(0,:),"sst global area-average "+rt_nyr(0)+"yr running trend","","") + z->$("sst_global_avg_runtrend_"+rt_nyr(1)+"yr")$ = set_varAtts(sst_rt_mon(1,:),"sst global area-average "+rt_nyr(1)+"yr running trend","","") + z->$("sst_global_avg_runtrend_"+rt_nyr(2)+"yr")$ = set_varAtts(sst_rt_mon(2,:),"sst global area-average "+rt_nyr(2)+"yr running trend","","") + z->$("sst_global_avg_runtrend_"+rt_nyr(3)+"yr")$ = set_varAtts(sst_rt_mon(3,:),"sst global area-average "+rt_nyr(3)+"yr running trend","","") + z->$("sst_global_avg_runtrend_"+rt_nyr(4)+"yr")$ = set_varAtts(sst_rt_mon(4,:),"sst global area-average "+rt_nyr(4)+"yr running trend","","") + z->sst_trends_djf = set_varAtts(sst_trends_seas(0,:,:),"sst linear trends (DJF)","","") + z->sst_trends_mam = set_varAtts(sst_trends_seas(1,:,:),"sst linear trends (MAM)","","") + z->sst_trends_jja = set_varAtts(sst_trends_seas(2,:,:),"sst linear trends (JJA)","","") + z->sst_trends_son = set_varAtts(sst_trends_seas(3,:,:),"sst linear trends (SON)","","") + z->sst_trends_ann = set_varAtts(sst_trends_ann,"sst linear trends (annual)","","") + z->sst_trends_mon = set_varAtts(sst_trends_mon,"sst linear trends (monthly)","","") + delete(z) + delete([/sst_aa_seas2,sst_aa_ann2/]) + end if +;======================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + + res@cnLevelSelectionMode = "ExplicitLevels" + if (COLORMAP.eq.0) then + res@cnLevels = (/-8,-6,-5,-4,-3,-2,-1,-0.5,-0.25,0,0.25,0.5,1,2,3,4,5,6,8/) + end if + if (COLORMAP.eq.1) then + res@cnLevels = (/-6,-4,-3,-2,-1,-0.5,-0.25,0,0.25,0.5,1,2,3,4,6/) + end if + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + + res@gsnRightString = sst_trends_seas@units + res@gsnCenterString = names(ee) + map_djf(ee) = gsn_csm_contour_map(wks_trends_djf,sst_trends_seas(0,:,:),res) + map_mam(ee) = gsn_csm_contour_map(wks_trends_mam,sst_trends_seas(1,:,:),res) + map_jja(ee) = gsn_csm_contour_map(wks_trends_jja,sst_trends_seas(2,:,:),res) + map_son(ee) = gsn_csm_contour_map(wks_trends_son,sst_trends_seas(3,:,:),res) + map_ann(ee) = gsn_csm_contour_map(wks_trends_ann,sst_trends_ann,res) + map_mon(ee) = gsn_csm_contour_map(wks_trends_mon,sst_trends_mon,res) + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + + if (wks_type.eq."png") then + xyres@xyLineThicknessF = 4. + else + xyres@xyLineThicknessF = 2. + end if + if (isfilepresent2("obs_ts").and.ee.eq.0) then + xyres@xyLineColor = "black" + else + xyres@xyLineColor = "royalblue" + end if + xyres@tiYAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnLeftStringFontHeightF = 0.017 + xyres@gsnRightStringFontHeightF = 0.013 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnLeftStringFontHeightF = 0.024 + xyres@gsnRightStringFontHeightF = 0.020 + end if + xyres@gsnLeftStringOrthogonalPosF = 0.025 + xyres@gsnRightStringOrthogonalPosF = xyres@gsnLeftStringOrthogonalPosF + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnLeftString = "" + xyres@gsnCenterString = "" + xyres@gsnRightString = "" + + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+0.5 + + xyres2 = xyres + xyres2@xyLineColor = "gray60" + xyres2@xyCurveDrawOrder = "PreDraw" + + xyres@gsnLeftString = names(ee) + tttt = dtrend_msg(ispan(0,dimsizes(sst_aa_seas&time)-1,1),sst_aa_seas(0,:),False,True) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xyres@trYMinF = min((/min(sst_aa_seas(0,:)),min(sst_aa_seas_obs(0,:))/))-.01 + xyres@trYMaxF = max((/max(sst_aa_seas(0,:)),max(sst_aa_seas_obs(0,:))/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+sst_trends_seas@units + xy_djf(ee) = gsn_csm_xy(wks_aa_djf,ispan(syear(ee),eyear(ee),1),sst_aa_seas(0,:),xyres) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xy_obs_djf(ee) = gsn_csm_xy(wks_aa_djf,ispan(sst_aa_seas_obs@syear,sst_aa_seas_obs@eyear,1),sst_aa_seas_obs(0,:),xyres2) + overlay(xy_djf(ee),xy_obs_djf(ee)) + end if + + tttt = dtrend_msg(ispan(0,dimsizes(sst_aa_seas&time)-1,1),sst_aa_seas(1,:),False,True) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xyres@trYMinF = min((/min(sst_aa_seas(1,:)),min(sst_aa_seas_obs(1,:))/))-.01 + xyres@trYMaxF = max((/max(sst_aa_seas(1,:)),max(sst_aa_seas_obs(1,:))/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+sst_trends_seas@units + xy_mam(ee) = gsn_csm_xy(wks_aa_mam,ispan(syear(ee),eyear(ee),1),sst_aa_seas(1,:),xyres) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xy_obs_mam(ee) = gsn_csm_xy(wks_aa_mam,ispan(sst_aa_seas_obs@syear,sst_aa_seas_obs@eyear,1),sst_aa_seas_obs(1,:),xyres2) + overlay(xy_mam(ee),xy_obs_mam(ee)) + end if + + tttt = dtrend_msg(ispan(0,dimsizes(sst_aa_seas&time)-1,1),sst_aa_seas(2,:),False,True) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xyres@trYMinF = min((/min(sst_aa_seas(2,:)),min(sst_aa_seas_obs(2,:))/))-.01 + xyres@trYMaxF = max((/max(sst_aa_seas(2,:)),max(sst_aa_seas_obs(2,:))/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+sst_trends_seas@units + xy_jja(ee) = gsn_csm_xy(wks_aa_jja,ispan(syear(ee),eyear(ee),1),sst_aa_seas(2,:),xyres) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xy_obs_jja(ee) = gsn_csm_xy(wks_aa_jja,ispan(sst_aa_seas_obs@syear,sst_aa_seas_obs@eyear,1),sst_aa_seas_obs(2,:),xyres2) + overlay(xy_jja(ee),xy_obs_jja(ee)) + end if + + tttt = dtrend_msg(ispan(0,dimsizes(sst_aa_seas&time)-1,1),sst_aa_seas(3,:),False,True) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xyres@trYMinF = min((/min(sst_aa_seas(3,:)),min(sst_aa_seas_obs(3,:))/))-.01 + xyres@trYMaxF = max((/max(sst_aa_seas(3,:)),max(sst_aa_seas_obs(3,:))/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+sst_trends_seas@units + xy_son(ee) = gsn_csm_xy(wks_aa_son,ispan(syear(ee),eyear(ee),1),sst_aa_seas(3,:),xyres) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xy_obs_son(ee) = gsn_csm_xy(wks_aa_son,ispan(sst_aa_seas_obs@syear,sst_aa_seas_obs@eyear,1),sst_aa_seas_obs(3,:),xyres2) + overlay(xy_son(ee),xy_obs_son(ee)) + end if + delete(tttt) + + tttt = dtrend_msg(ispan(0,dimsizes(sst_aa_ann&time)-1,1),sst_aa_ann,False,True) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xyres@trYMinF = min((/min(sst_aa_ann),min(sst_aa_ann_obs)/))-.01 + xyres@trYMaxF = max((/max(sst_aa_ann),max(sst_aa_ann_obs)/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+sst_trends_ann@units + xy_ann(ee) = gsn_csm_xy(wks_aa_ann,ispan(syear(ee),eyear(ee),1),sst_aa_ann,xyres) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xy_obs_ann(ee) = gsn_csm_xy(wks_aa_ann,ispan(sst_aa_seas_obs@syear,sst_aa_seas_obs@eyear,1),sst_aa_ann_obs,xyres2) + overlay(xy_ann(ee),xy_obs_ann(ee)) + delete(xyres@trYMinF) + delete(xyres@trYMaxF) + end if + delete(tttt) + + xyres@trXMaxF = eyear(ee)+1.5 + xyres2@trXMaxF = eyear(ee)+1.5 + tttt = dtrend_msg(ispan(0,dimsizes(sst_aa_mon&time)-1,1),sst_aa_mon,False,True) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xyres@trYMinF = min((/min(sst_aa_mon),min(sst_aa_mon_obs)/))-.01 + xyres@trYMaxF = max((/max(sst_aa_mon),max(sst_aa_mon_obs)/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(sst_aa_mon&time),2,True)+sst_trends_mon@units + xy_mon(ee) = gsn_csm_xy(wks_aa_mon,fspan(syear(ee),eyear(ee)+.91667,dimsizes(sst_aa_mon)),sst_aa_mon,xyres) + if (isfilepresent2("obs_ts").and.ee.ge.1) then + xy_obs_mon(ee) = gsn_csm_xy(wks_aa_mon,fspan(sst_aa_seas_obs@syear,sst_aa_seas_obs@eyear+.91667,dimsizes(sst_aa_mon_obs)),sst_aa_mon_obs,xyres2) + overlay(xy_mon(ee),xy_obs_mon(ee)) + end if + + xyres@gsnRightString = "" + do ff = 0,4 + if (.not.all(ismissing(sst_rt_mon(ff,:)))) + xyres@gsnRightString = sst_rt_mon@units + xy_rt_mon(ff,ee) = gsn_csm_xy(wks_rt_mon,fspan(syear(ee),eyear(ee)+.91667,dimsizes(sst_aa_mon&time)),sst_rt_mon(ff,:),xyres) + end if + end do + delete([/sst_trends_seas,sst_trends_ann,sst_trends_mon/]) + delete([/sst_aa_seas,sst_aa_mon,sst_aa_ann,xyres,xyres2,res,tttt,sst_rt_mon/]) + end do + if (isfilepresent2("obs_ts")) then + delete([/sst_aa_seas_obs,sst_aa_mon_obs,sst_aa_ann_obs/]) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + panres@lbLabelFontHeightF = 0.013 + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelStride = 1 + + panres@txString = "TS Trends (DJF)" + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + gsn_panel2(wks_trends_djf,map_djf,(/nrow,ncol/),panres) + delete(wks_trends_djf) + + panres@txString = "TS Trends (MAM)" + gsn_panel2(wks_trends_mam,map_mam,(/nrow,ncol/),panres) + delete(wks_trends_mam) + + panres@txString = "TS Trends (JJA)" + gsn_panel2(wks_trends_jja,map_jja,(/nrow,ncol/),panres) + delete(wks_trends_jja) + + panres@txString = "TS Trends (SON)" + gsn_panel2(wks_trends_son,map_son,(/nrow,ncol/),panres) + delete(wks_trends_son) + + panres@txString = "TS Trends (Annual)" + gsn_panel2(wks_trends_ann,map_ann,(/nrow,ncol/),panres) + delete(wks_trends_ann) + + panres@txString = "TS Trends (Monthly)" + gsn_panel2(wks_trends_mon,map_mon,(/nrow,ncol/),panres) + delete(wks_trends_mon) + delete(panres) + + panres2 = True + panres2@gsnMaximize = True + panres2@gsnPaperOrientation = "portrait" + panres2@gsnPanelYWhiteSpacePercent = 3.0 + if (nsim.le.4) then + panres2@txFontHeightF = 0.024 + else + panres2@txFontHeightF = 0.016 + end if + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres2@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) ;(/nsim/2+1,nsim/8+1/) + end if + panres2@txString = "TS Global Average (DJF)" + gsn_panel2(wks_aa_djf,xy_djf,lp,panres2) + delete(wks_aa_djf) + + panres2@txString = "TS Global Average (MAM)" + gsn_panel2(wks_aa_mam,xy_mam,lp,panres2) + delete(wks_aa_mam) + + panres2@txString = "TS Global Average (JJA)" + gsn_panel2(wks_aa_jja,xy_jja,lp,panres2) + delete(wks_aa_jja) + + panres2@txString = "TS Global Average (SON)" + gsn_panel2(wks_aa_son,xy_son,lp,panres2) + delete(wks_aa_son) + + panres2@txString = "TS Global Average (Annual)" + gsn_panel2(wks_aa_ann,xy_ann,lp,panres2) + delete(wks_aa_ann) + + panres2@txString = "TS Global Average (Monthly)" + gsn_panel2(wks_aa_mon,xy_mon,lp,panres2) + delete(wks_aa_mon) + + panres2@txString = "TS Running 8yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(0,:),lp,panres2) + + panres2@txString = "TS Running 10yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(1,:),lp,panres2) + + panres2@txString = "TS Running 12yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(2,:),lp,panres2) + + panres2@txString = "TS Running 14yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(3,:),lp,panres2) + + panres2@txString = "TS Running 16yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(4,:),lp,panres2) + delete(wks_rt_mon) + + delete([/nrow,ncol,lp,map_djf,map_mam,map_jja,map_son,map_ann,map_mon,xy_djf,xy_mam,xy_jja,xy_son,xy_ann,xy_mon/]) + delete([/xy_rt_mon/]) + delete(panres2) + if (isfilepresent2("obs_ts")) then + delete([/xy_obs_djf,xy_obs_mam,xy_obs_jja,xy_obs_son,xy_obs_ann,xy_obs_mon/]) + end if + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + do gg = 1,5 + if (isfilepresent2(OUTDIR+"sst.runtrend.mon.00000"+gg+".png")) then + system("mv "+OUTDIR+"sst.runtrend.mon.00000"+gg+".png "+OUTDIR+"sst."+rt_nyr(gg-1)+"yr_runtrend.mon.png") + end if + end do + else + if (isfilepresent2(OUTDIR+"sst.runtrend.mon.ps")) then + system("psplit "+OUTDIR+"sst.runtrend.mon.ps "+OUTDIR+"pict") + do gg = 1,5 + if (isfilepresent2(OUTDIR+"pict000"+gg+".ps")) then + system("mv "+OUTDIR+"pict000"+gg+".ps "+OUTDIR+"sst."+rt_nyr(gg-1)+"yr_runtrend.mon.ps") + end if + end do + end if + end if + delete(OUTDIR) + print("Finished: sst.trends_timeseries.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/tas.mean_stddev.ncl b/lib/externals/CVDP/ncl_scripts/tas.mean_stddev.ncl new file mode 100644 index 000000000..84eaa1100 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/tas.mean_stddev.ncl @@ -0,0 +1,322 @@ +; Calculates 2m air temperature global means and standard deviations +; +; Variables used: tas +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: tas.mean_stddev.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_trefht") + na = asciiread("namelist_byvar/namelist_trefht",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_stddev_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.stddev.djf") + wks_stddev_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.stddev.mam") + wks_stddev_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.stddev.jja") + wks_stddev_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.stddev.son") + wks_stddev_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.stddev.ann") + wks_mean_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.mean.djf") + wks_mean_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.mean.mam") + wks_mean_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.mean.jja") + wks_mean_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.mean.son") + wks_mean_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.mean.ann") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_stddev_djf,"precip3_16lev") + gsn_define_colormap(wks_stddev_mam,"precip3_16lev") + gsn_define_colormap(wks_stddev_jja,"precip3_16lev") + gsn_define_colormap(wks_stddev_son,"precip3_16lev") + gsn_define_colormap(wks_stddev_ann,"precip3_16lev") + gsn_define_colormap(wks_mean_djf,"ncl_default") + gsn_define_colormap(wks_mean_mam,"ncl_default") + gsn_define_colormap(wks_mean_jja,"ncl_default") + gsn_define_colormap(wks_mean_son,"ncl_default") + gsn_define_colormap(wks_mean_ann,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_stddev_djf,"cb_rainbow") + gsn_define_colormap(wks_stddev_mam,"cb_rainbow") + gsn_define_colormap(wks_stddev_jja,"cb_rainbow") + gsn_define_colormap(wks_stddev_son,"cb_rainbow") + gsn_define_colormap(wks_stddev_ann,"cb_rainbow") + gsn_define_colormap(wks_mean_djf,"BlueDarkRed18") + gsn_define_colormap(wks_mean_mam,"BlueDarkRed18") + gsn_define_colormap(wks_mean_jja,"BlueDarkRed18") + gsn_define_colormap(wks_mean_son,"BlueDarkRed18") + gsn_define_colormap(wks_mean_ann,"BlueDarkRed18") + end if + + plot_mean_djf = new(nsim,"graphic") + plot_mean_mam = new(nsim,"graphic") + plot_mean_jja = new(nsim,"graphic") + plot_mean_son = new(nsim,"graphic") + plot_mean_ann = new(nsim,"graphic") + plot_stddev_djf = new(nsim,"graphic") + plot_stddev_mam = new(nsim,"graphic") + plot_stddev_jja = new(nsim,"graphic") + plot_stddev_son = new(nsim,"graphic") + plot_stddev_ann = new(nsim,"graphic") + do ee = 0,nsim-1 + tas = data_read_in(paths(ee),"TREFHT",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(tas,"is_all_missing")) then + delete(tas) + continue + end if + do ff = 0,1 + tasT = tas + if (ff.eq.1) then + if (OPT_CLIMO.eq."Full") then + tasT = rmMonAnnCycTLL(tasT) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = tasT + delete(temp_arr&time) + temp_arr&time = cd_calendar(tasT&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + tasT = calcMonAnomTLL(tasT,climo) + delete(climo) + end if + end if + tas_seas = runave_n_Wrap(tasT,3,0,0) + tas_seas(0,:,:) = (/ dim_avg_n(tasT(:1,:,:),0) /) + tas_seas(dimsizes(tasT&time)-1,:,:) = (/ dim_avg_n(tasT(dimsizes(tasT&time)-2:,:,:),0) /) + tas_ann = runave_n_Wrap(tasT,12,0,0) + delete(tasT) + + if (ff.eq.0) then + tas_mean_djf = dim_avg_n_Wrap(tas_seas(0::12,:,:),0) + tas_mean_mam = dim_avg_n_Wrap(tas_seas(3::12,:,:),0) + tas_mean_jja = dim_avg_n_Wrap(tas_seas(6::12,:,:),0) + tas_mean_son = dim_avg_n_Wrap(tas_seas(9::12,:,:),0) + tas_mean_ann = dim_avg_n_Wrap(tas_ann(5::12,:,:),0) + end if + if (ff.eq.1) then + tas_sd_djf = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),tas_seas(0::12,:,:),False,False,0),0) + tas_sd_mam = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),tas_seas(3::12,:,:),False,False,0),0) + tas_sd_jja = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),tas_seas(6::12,:,:),False,False,0),0) + tas_sd_son = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),tas_seas(9::12,:,:),False,False,0),0) + tas_sd_ann = dim_stddev_n_Wrap(dtrend_msg_n(ispan(0,nyr(ee)-1,1),tas_ann(5::12,:,:),False,False,0),0) + end if + delete([/tas_seas,tas_ann/]) + end do + delete(tas) + copy_VarMeta(tas_mean_djf,tas_sd_djf) + copy_VarMeta(tas_mean_mam,tas_sd_mam) + copy_VarMeta(tas_mean_jja,tas_sd_jja) + copy_VarMeta(tas_mean_son,tas_sd_son) + copy_VarMeta(tas_mean_ann,tas_sd_ann) + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.tas.mean_stddev."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + + z->tas_spatialmean_djf = set_varAtts(tas_mean_djf,"tas mean (DJF)","","") + z->tas_spatialmean_mam = set_varAtts(tas_mean_mam,"tas mean (MAM)","","") + z->tas_spatialmean_jja = set_varAtts(tas_mean_jja,"tas mean (JJA)","","") + z->tas_spatialmean_son = set_varAtts(tas_mean_son,"tas mean (SON)","","") + z->tas_spatialmean_ann = set_varAtts(tas_mean_ann,"tas mean (annual)","","") + + z->tas_spatialstddev_djf = set_varAtts(tas_sd_djf,"tas standard deviation (DJF)","","") + z->tas_spatialstddev_mam = set_varAtts(tas_sd_mam,"tas standard deviation (MAM)","","") + z->tas_spatialstddev_jja = set_varAtts(tas_sd_jja,"tas standard deviation (JJA)","","") + z->tas_spatialstddev_son = set_varAtts(tas_sd_son,"tas standard deviation (SON)","","") + z->tas_spatialstddev_ann = set_varAtts(tas_sd_ann,"tas standard deviation (annual)","","") + delete(z) + end if + +;========================================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@gsnDraw = False + res@gsnFrame = False + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@cnLevelSelectionMode = "ExplicitLevels" + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + + sres = res + + res@cnLevels = fspan(.4,3.2,8) + if (COLORMAP.eq.0) then + res@cnFillColors = (/2,4,6,8,10,12,14,16,18/) + sres@cnLevels = ispan(-40,40,2) + end if + if (COLORMAP.eq.1) then + res@cnFillColors = (/35,47,63,79,95,111,124,155,175/) + sres@cnLevels = ispan(-20,40,4) + end if + + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + res@gsnRightString = tas_sd_djf@units + res@gsnCenterString = names(ee) + plot_stddev_djf(ee) = gsn_csm_contour_map(wks_stddev_djf,tas_sd_djf,res) + plot_stddev_mam(ee) = gsn_csm_contour_map(wks_stddev_mam,tas_sd_mam,res) + plot_stddev_jja(ee) = gsn_csm_contour_map(wks_stddev_jja,tas_sd_jja,res) + plot_stddev_son(ee) = gsn_csm_contour_map(wks_stddev_son,tas_sd_son,res) + plot_stddev_ann(ee) = gsn_csm_contour_map(wks_stddev_ann,tas_sd_ann,res) + + sres@gsnLeftString = syear(ee)+"-"+eyear(ee) + sres@gsnRightString = tas_mean_djf@units + sres@gsnCenterString = names(ee) + plot_mean_djf(ee) = gsn_csm_contour_map(wks_mean_djf,tas_mean_djf,sres) + plot_mean_mam(ee) = gsn_csm_contour_map(wks_mean_mam,tas_mean_mam,sres) + plot_mean_jja(ee) = gsn_csm_contour_map(wks_mean_jja,tas_mean_jja,sres) + plot_mean_son(ee) = gsn_csm_contour_map(wks_mean_son,tas_mean_son,sres) + plot_mean_ann(ee) = gsn_csm_contour_map(wks_mean_ann,tas_mean_ann,sres) + delete([/tas_sd_djf,tas_sd_mam,tas_sd_jja,tas_sd_son,tas_sd_ann,tas_mean_djf,tas_mean_mam,tas_mean_jja,tas_mean_son,tas_mean_ann,res,sres/]) + end do + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelFontHeightF = 0.013 + panres@lbLabelStride = 1 + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + + panres@txString = "TAS Standard Deviations (DJF)" + gsn_panel2(wks_stddev_djf,plot_stddev_djf,(/nrow,ncol/),panres) + delete(wks_stddev_djf) + + panres@txString = "TAS Standard Deviations (MAM)" + gsn_panel2(wks_stddev_mam,plot_stddev_mam,(/nrow,ncol/),panres) + delete(wks_stddev_mam) + + panres@txString = "TAS Standard Deviations (JJA)" + gsn_panel2(wks_stddev_jja,plot_stddev_jja,(/nrow,ncol/),panres) + delete(wks_stddev_jja) + + panres@txString = "TAS Standard Deviations (SON)" + gsn_panel2(wks_stddev_son,plot_stddev_son,(/nrow,ncol/),panres) + delete(wks_stddev_son) + + panres@txString = "TAS Standard Deviations (Annual)" + gsn_panel2(wks_stddev_ann,plot_stddev_ann,(/nrow,ncol/),panres) + delete(wks_stddev_ann) + + panres@txString = "TAS Means (DJF)" + gsn_panel2(wks_mean_djf,plot_mean_djf,(/nrow,ncol/),panres) + delete(wks_mean_djf) + + panres@txString = "TAS Means (MAM)" + gsn_panel2(wks_mean_mam,plot_mean_mam,(/nrow,ncol/),panres) + delete(wks_mean_mam) + + panres@txString = "TAS Means (JJA)" + gsn_panel2(wks_mean_jja,plot_mean_jja,(/nrow,ncol/),panres) + delete(wks_mean_jja) + + panres@txString = "TAS Means (SON)" + gsn_panel2(wks_mean_son,plot_mean_son,(/nrow,ncol/),panres) + delete(wks_mean_son) + + panres@txString = "TAS Means (Annual)" + gsn_panel2(wks_mean_ann,plot_mean_ann,(/nrow,ncol/),panres) + delete(wks_mean_ann) + delete(panres) + print("Finished: tas.mean_stddev.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/tas.trends_timeseries.ncl b/lib/externals/CVDP/ncl_scripts/tas.trends_timeseries.ncl new file mode 100644 index 000000000..f0494ded6 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/tas.trends_timeseries.ncl @@ -0,0 +1,606 @@ +; Calculates 2m air temperature global trends, running global trends and timeseries +; +; Variables used: tas +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: tas.trends_timeseries.ncl") + + SCALE_TIMESERIES = getenv("SCALE_TIMESERIES") + OUTPUT_DATA = getenv("OUTPUT_DATA") + PNG_SCALE = tofloat(getenv("PNG_SCALE")) + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = toint(getenv("CLIMO_SYEAR")) + CLIMO_EYEAR = toint(getenv("CLIMO_EYEAR")) + OUTPUT_TYPE = getenv("OUTPUT_TYPE") + COLORMAP = getenv("COLORMAP") + + nsim = numAsciiRow("namelist_byvar/namelist_trefht") + na = asciiread("namelist_byvar/namelist_trefht",(/nsim/),"string") + names = new(nsim,"string") + paths = new(nsim,"string") + syear = new(nsim,"integer",-999) + eyear = new(nsim,"integer",-999) + delim = "|" + + do gg = 0,nsim-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + paths(gg) = str_strip(str_get_field(na(gg),2,delim)) + syear(gg) = stringtointeger(str_strip(str_get_field(na(gg),3,delim))) + eyear(gg) = stringtointeger(str_strip(str_get_field(na(gg),4,delim))) + end do + nyr = eyear-syear+1 + nyr_max = max(nyr) + + pi=4.*atan(1.0) + rad=(pi/180.) + + wks_type = OUTPUT_TYPE + if (wks_type.eq."png") then + wks_type@wkWidth = 1500*PNG_SCALE + wks_type@wkHeight = 1500*PNG_SCALE + end if + wks_trends_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.trends.djf") + wks_trends_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.trends.mam") + wks_trends_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.trends.jja") + wks_trends_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.trends.son") + wks_trends_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.trends.ann") + wks_trends_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.trends.mon") + + wks_aa_djf = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.timeseries.djf") + wks_aa_mam = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.timeseries.mam") + wks_aa_jja = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.timeseries.jja") + wks_aa_son = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.timeseries.son") + wks_aa_ann = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.timeseries.ann") + wks_aa_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.timeseries.mon") + + wks_rt_mon = gsn_open_wks(wks_type,getenv("OUTDIR")+"tas.runtrend.mon") + + if (COLORMAP.eq.0) then + gsn_define_colormap(wks_trends_djf,"ncl_default") + gsn_define_colormap(wks_trends_mam,"ncl_default") + gsn_define_colormap(wks_trends_jja,"ncl_default") + gsn_define_colormap(wks_trends_son,"ncl_default") + gsn_define_colormap(wks_trends_ann,"ncl_default") + gsn_define_colormap(wks_trends_mon,"ncl_default") + gsn_define_colormap(wks_aa_djf,"ncl_default") + gsn_define_colormap(wks_aa_mam,"ncl_default") + gsn_define_colormap(wks_aa_jja,"ncl_default") + gsn_define_colormap(wks_aa_son,"ncl_default") + gsn_define_colormap(wks_aa_ann,"ncl_default") + gsn_define_colormap(wks_aa_mon,"ncl_default") + gsn_define_colormap(wks_rt_mon,"ncl_default") + end if + if (COLORMAP.eq.1) then + gsn_define_colormap(wks_trends_djf,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mam,"BlueDarkRed18") + gsn_define_colormap(wks_trends_jja,"BlueDarkRed18") + gsn_define_colormap(wks_trends_son,"BlueDarkRed18") + gsn_define_colormap(wks_trends_ann,"BlueDarkRed18") + gsn_define_colormap(wks_trends_mon,"BlueDarkRed18") + gsn_define_colormap(wks_aa_djf,"ncl_default") + gsn_define_colormap(wks_aa_mam,"ncl_default") + gsn_define_colormap(wks_aa_jja,"ncl_default") + gsn_define_colormap(wks_aa_son,"ncl_default") + gsn_define_colormap(wks_aa_ann,"ncl_default") + gsn_define_colormap(wks_aa_mon,"ncl_default") + gsn_define_colormap(wks_rt_mon,"ncl_default") + end if + map_djf = new(nsim,"graphic") + map_mam = new(nsim,"graphic") + map_jja = new(nsim,"graphic") + map_son = new(nsim,"graphic") + map_ann = new(nsim,"graphic") + map_mon = new(nsim,"graphic") + xy_djf = new(nsim,"graphic") + xy_mam = new(nsim,"graphic") + xy_jja = new(nsim,"graphic") + xy_son = new(nsim,"graphic") + xy_ann = new(nsim,"graphic") + xy_mon = new(nsim,"graphic") + + xy_rt_mon = new((/5,nsim/),"graphic") + + if (isfilepresent2("obs_trefht")) then + xy_obs_djf = new(nsim,"graphic") + xy_obs_mam = new(nsim,"graphic") + xy_obs_jja = new(nsim,"graphic") + xy_obs_son = new(nsim,"graphic") + xy_obs_ann = new(nsim,"graphic") + xy_obs_mon = new(nsim,"graphic") + end if + do ee = 0,nsim-1 + tas = data_read_in(paths(ee),"TREFHT",syear(ee),eyear(ee)) ; read in data, orient lats/lons correctly, set time coordinate variable up + if (isatt(tas,"is_all_missing")) then + delete(tas) + continue + end if + if (OPT_CLIMO.eq."Full") then + tas = rmMonAnnCycTLL(tas) + else + check_custom_climo(names(ee),syear(ee),eyear(ee),CLIMO_SYEAR,CLIMO_EYEAR) + temp_arr = tas + delete(temp_arr&time) + temp_arr&time = cd_calendar(tas&time,-1) + if (CLIMO_SYEAR.lt.0) then + climo = clmMonTLL(temp_arr({(eyear(ee)+CLIMO_SYEAR)*100+1:(eyear(ee)+CLIMO_EYEAR)*100+12},:,:)) + else + climo = clmMonTLL(temp_arr({CLIMO_SYEAR*100+1:CLIMO_EYEAR*100+12},:,:)) + end if + delete(temp_arr) + tas = calcMonAnomTLL(tas,climo) + delete(climo) + end if + + coswgt=cos(rad*tas&lat) + coswgt!0 = "lat" + coswgt&lat= tas&lat + + tas_aa_mon = wgt_areaave_Wrap(tas,coswgt,1.0,0) + tttt = dtrend_msg_n(ispan(0,dimsizes(tas&time)-1,1),tas,False,True,0) + tas_trends_mon = tas(0,:,:) + tas_trends_mon = (/ onedtond(tttt@slope, (/dimsizes(tas&lat),dimsizes(tas&lon)/) ) /) + tas_trends_mon = tas_trends_mon*dimsizes(tas&time) + tas_trends_mon@units = tas@units+" "+nyr(ee)+"yr~S~-1~N~" + delete(tttt) + + tas_seas = runave_n_Wrap(tas,3,0,0) + tas_seas(0,:,:) = (/ dim_avg_n(tas(:1,:,:),0) /) + tas_seas(dimsizes(tas&time)-1,:,:) = (/ dim_avg_n(tas(dimsizes(tas&time)-2:,:,:),0) /) + tas_ann = runave_n_Wrap(tas,12,0,0) + delete(tas) + + tas_trends_seas = tas_seas(:3,:,:) + tas_trends_seas = tas_trends_seas@_FillValue + tas_trends_ann = tas_trends_seas(0,:,:) + tas_aa_seas = new((/4,nyr(ee)/),typeof(tas_seas)) + tas_aa_seas!1 = "time" + tas_aa_seas&time = ispan(syear(ee),eyear(ee),1) + tas_aa_seas&time@units = "YYYY" + tas_aa_seas&time@long_name = "time" + tas_aa_ann = tas_aa_seas(0,:) + do ff = 0,4 + if (ff.le.3) then + tarr = tas_seas(ff*3::12,:,:) + end if + if (ff.eq.4) then + tarr = tas_ann(5::12,:,:) + end if + tttt = dtrend_msg_n(ispan(0,dimsizes(tarr&time)-1,1),tarr,False,True,0) + if (ff.le.3) then + tas_trends_seas(ff,:,:) = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + tas_aa_seas(ff,:) = (/ wgt_areaave(tarr,coswgt,1.0,0) /) + end if + if (ff.eq.4) then + tas_trends_ann = (/ onedtond(tttt@slope, (/dimsizes(tarr&lat),dimsizes(tarr&lon)/) ) /) + tas_aa_ann = (/ wgt_areaave(tarr,coswgt,1.0,0) /) + end if + delete([/tarr,tttt/]) + end do + tas_trends_seas = tas_trends_seas*nyr(ee) + tas_trends_seas@units = tas_seas@units+" "+nyr(ee)+"yr~S~-1~N~" + tas_trends_ann = tas_trends_ann*nyr(ee) + tas_trends_ann@units = tas_ann@units+" "+nyr(ee)+"yr~S~-1~N~" + delete([/tas_seas,tas_ann,coswgt/]) + + if (isfilepresent2("obs_trefht").and.ee.eq.0) then + tas_aa_seas@syear = syear(ee) + tas_aa_seas@eyear = eyear(ee) + tas_aa_mon@syear = syear(ee) + tas_aa_mon@eyear = eyear(ee) + tas_aa_ann@syear = syear(ee) + tas_aa_ann@eyear = eyear(ee) + tas_aa_seas_obs = tas_aa_seas + tas_aa_mon_obs = tas_aa_mon + tas_aa_ann_obs = tas_aa_ann + end if + + dimT = dimsizes(tas_aa_mon) ; calculate running trends from the monthly data + tas_rt_mon = new((/5,dimT/),typeof(tas_aa_mon)) + tas_rt_mon!1 = "time" + tas_rt_mon&time = tas_aa_mon&time + copy_VarAtts(tas_aa_mon,tas_rt_mon) + tas_rt_mon@long_name = tas_rt_mon@long_name+" global average running trend" + rt_nyr = (/8,10,12,14,16/) + do ff = 0,dimsizes(rt_nyr)-1 + incr = rt_nyr(ff)*12 + do gg = 0,dimT-incr-1 + tttt = dtrend_msg(ispan(0,incr-1,1),tas_aa_mon(gg:gg+incr-1),False,True) + tas_rt_mon(ff,gg) = (/ tttt@slope*incr /) + delete(tttt) + end do + end do + delete([/dimT,incr/]) + + if (OUTPUT_DATA.eq."True") then + modname = str_sub_str(names(ee)," ","_") + bc = (/"/","'","(",")"/) + do gg = 0,dimsizes(bc)-1 + modname = str_sub_str(modname,bc(gg),"_") + end do + fn = getenv("OUTDIR")+modname+".cvdp_data.tas.trends_timeseries."+syear(ee)+"-"+eyear(ee)+".nc" + if (.not.isfilepresent2(fn)) then + z = addfile(fn,"c") + z@source = "NCAR Climate Analysis Section's Climate Variability Diagnostics Package v"+getenv("VERSION") + z@notes = "Data from "+names(ee)+" from "+syear(ee)+"-"+eyear(ee) + if (OPT_CLIMO.eq."Full") then + z@climatology = syear(ee)+"-"+eyear(ee)+" climatology removed prior to all calculations (other than means)" + else + if (CLIMO_SYEAR.lt.0) then + z@climatology = (eyear(ee)+CLIMO_SYEAR)+"-"+(eyear(ee)+CLIMO_EYEAR)+" climatology removed prior to all calculations (other than means)" + else + z@climatology = CLIMO_SYEAR+"-"+CLIMO_EYEAR+" climatology removed prior to all calculations (other than means)" + end if + end if + z@Conventions = "CF-1.6" + else + z = addfile(fn,"w") + end if + tas_aa_seas2 = tas_aa_seas + tas_aa_seas2!1 = "TIME" + tas_aa_seas2&TIME = ispan(syear(ee),eyear(ee),1) + tas_aa_seas2&TIME@units = "YYYY" + tas_aa_seas2&TIME@long_name = "time" + tas_aa_ann2 = tas_aa_ann + tas_aa_ann2!0 = "TIME" + tas_aa_ann2&TIME = ispan(syear(ee),eyear(ee),1) + tas_aa_ann2&TIME@units = "YYYY" + tas_aa_ann2&TIME@long_name = "time" + z->tas_global_avg_mon = set_varAtts(tas_aa_mon,"tas global area-average (monthly)","C","") + z->tas_global_avg_djf = set_varAtts(tas_aa_seas2(0,:),"tas global area-average (DJF)","C","") + z->tas_global_avg_mam = set_varAtts(tas_aa_seas2(1,:),"tas global area-average (MAM)","C","") + z->tas_global_avg_jja = set_varAtts(tas_aa_seas2(2,:),"tas global area-average (JJA)","C","") + z->tas_global_avg_son = set_varAtts(tas_aa_seas2(3,:),"tas global area-average (SON)","C","") + z->tas_global_avg_ann = set_varAtts(tas_aa_ann2,"tas global area-average (annual)","C","") + z->$("tas_global_avg_runtrend_"+rt_nyr(0)+"yr")$ = set_varAtts(tas_rt_mon(0,:),"tas global area-average "+rt_nyr(0)+"yr running trend","","") + z->$("tas_global_avg_runtrend_"+rt_nyr(1)+"yr")$ = set_varAtts(tas_rt_mon(1,:),"tas global area-average "+rt_nyr(1)+"yr running trend","","") + z->$("tas_global_avg_runtrend_"+rt_nyr(2)+"yr")$ = set_varAtts(tas_rt_mon(2,:),"tas global area-average "+rt_nyr(2)+"yr running trend","","") + z->$("tas_global_avg_runtrend_"+rt_nyr(3)+"yr")$ = set_varAtts(tas_rt_mon(3,:),"tas global area-average "+rt_nyr(3)+"yr running trend","","") + z->$("tas_global_avg_runtrend_"+rt_nyr(4)+"yr")$ = set_varAtts(tas_rt_mon(4,:),"tas global area-average "+rt_nyr(4)+"yr running trend","","") + z->tas_trends_djf = set_varAtts(tas_trends_seas(0,:,:),"tas linear trends (DJF)","","") + z->tas_trends_mam = set_varAtts(tas_trends_seas(1,:,:),"tas linear trends (MAM)","","") + z->tas_trends_jja = set_varAtts(tas_trends_seas(2,:,:),"tas linear trends (JJA)","","") + z->tas_trends_son = set_varAtts(tas_trends_seas(3,:,:),"tas linear trends (SON)","","") + z->tas_trends_ann = set_varAtts(tas_trends_ann,"tas linear trends (annual)","","") + z->tas_trends_mon = set_varAtts(tas_trends_mon,"tas linear trends (monthly)","","") + delete(z) + delete([/tas_aa_seas2,tas_aa_ann2/]) + end if +;======================================================================== + res = True + res@mpProjection = "WinkelTripel" + res@mpGeophysicalLineColor = "gray42" + if (wks_type.eq."png") then + res@mpGeophysicalLineThicknessF = 2. + else + res@mpGeophysicalLineThicknessF = 1. + end if + res@mpPerimOn = False + res@mpGridLatSpacingF = 90 ; change latitude line spacing + res@mpGridLonSpacingF = 180. ; change longitude line spacing + res@mpGridLineColor = "transparent" ; trick ncl into drawing perimeter + res@mpGridAndLimbOn = True ; turn on lat/lon lines + res@mpFillOn = False + res@mpCenterLonF = 210. + res@mpOutlineOn = True + res@gsnDraw = False + res@gsnFrame = False + + res@cnLevelSelectionMode = "ExplicitLevels" + if (COLORMAP.eq.0) then + res@cnLevels = (/-8,-6,-5,-4,-3,-2,-1,-0.5,-0.25,0,0.25,0.5,1,2,3,4,5,6,8/) + end if + if (COLORMAP.eq.1) then + res@cnLevels = (/-6,-4,-3,-2,-1,-0.5,-0.25,0,0.25,0.5,1,2,3,4,6/) + end if + + res@cnLineLabelsOn = False + res@cnFillOn = True + res@cnLinesOn = False + res@lbLabelBarOn = False + + res@gsnLeftStringOrthogonalPosF = -0.05 + res@gsnLeftStringParallelPosF = .005 + res@gsnRightStringOrthogonalPosF = -0.05 + res@gsnRightStringParallelPosF = 0.96 + res@gsnRightString = "" + res@gsnLeftString = "" + res@gsnLeftStringFontHeightF = 0.014 + res@gsnCenterStringFontHeightF = 0.018 + res@gsnRightStringFontHeightF = 0.014 + res@gsnLeftString = syear(ee)+"-"+eyear(ee) + + res@gsnRightString = tas_trends_seas@units + res@gsnCenterString = names(ee) + map_djf(ee) = gsn_csm_contour_map(wks_trends_djf,tas_trends_seas(0,:,:),res) + map_mam(ee) = gsn_csm_contour_map(wks_trends_mam,tas_trends_seas(1,:,:),res) + map_jja(ee) = gsn_csm_contour_map(wks_trends_jja,tas_trends_seas(2,:,:),res) + map_son(ee) = gsn_csm_contour_map(wks_trends_son,tas_trends_seas(3,:,:),res) + map_ann(ee) = gsn_csm_contour_map(wks_trends_ann,tas_trends_ann,res) + map_mon(ee) = gsn_csm_contour_map(wks_trends_mon,tas_trends_mon,res) + + xyres = True + xyres@gsnDraw = False + xyres@gsnFrame = False + xyres@gsnYRefLine = 0.0 + xyres@gsnYRefLineColor = "gray42" + + if (wks_type.eq."png") then + xyres@xyLineThicknessF = 4. + else + xyres@xyLineThicknessF = 2. + end if + if (isfilepresent2("obs_trefht").and.ee.eq.0) then + xyres@xyLineColor = "black" + else + xyres@xyLineColor = "royalblue" + end if + xyres@tiYAxisString = "" + if (nsim.le.5) then + xyres@tmXBLabelFontHeightF = 0.0125 + xyres@tmYLLabelFontHeightF = 0.0125 + xyres@gsnLeftStringFontHeightF = 0.017 + xyres@gsnRightStringFontHeightF = 0.013 + else + xyres@tmXBLabelFontHeightF = 0.018 + xyres@tmYLLabelFontHeightF = 0.018 + xyres@gsnLeftStringFontHeightF = 0.024 + xyres@gsnRightStringFontHeightF = 0.020 + end if + xyres@gsnLeftStringOrthogonalPosF = 0.025 + xyres@gsnRightStringOrthogonalPosF = xyres@gsnLeftStringOrthogonalPosF + xyres@vpXF = 0.05 + xyres@vpHeightF = 0.15 + if (SCALE_TIMESERIES.eq."True") then + xyres@vpWidthF = 0.9*((nyr(ee)*1.)/nyr_max) + else + xyres@vpWidthF = 0.9 + end if + xyres@gsnLeftString = "" + xyres@gsnCenterString = "" + xyres@gsnRightString = "" + + xyres@trXMinF = syear(ee)-.5 + xyres@trXMaxF = eyear(ee)+0.5 + + xyres2 = xyres + xyres2@xyLineColor = "gray60" + xyres2@xyCurveDrawOrder = "PreDraw" + + xyres@gsnLeftString = names(ee) + tttt = dtrend_msg(ispan(0,dimsizes(tas_aa_seas&time)-1,1),tas_aa_seas(0,:),False,True) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xyres@trYMinF = min((/min(tas_aa_seas(0,:)),min(tas_aa_seas_obs(0,:))/))-.01 + xyres@trYMaxF = max((/max(tas_aa_seas(0,:)),max(tas_aa_seas_obs(0,:))/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+tas_trends_seas@units + xy_djf(ee) = gsn_csm_xy(wks_aa_djf,ispan(syear(ee),eyear(ee),1),tas_aa_seas(0,:),xyres) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xy_obs_djf(ee) = gsn_csm_xy(wks_aa_djf,ispan(tas_aa_seas_obs@syear,tas_aa_seas_obs@eyear,1),tas_aa_seas_obs(0,:),xyres2) + overlay(xy_djf(ee),xy_obs_djf(ee)) + end if + + tttt = dtrend_msg(ispan(0,dimsizes(tas_aa_seas&time)-1,1),tas_aa_seas(1,:),False,True) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xyres@trYMinF = min((/min(tas_aa_seas(1,:)),min(tas_aa_seas_obs(1,:))/))-.01 + xyres@trYMaxF = max((/max(tas_aa_seas(1,:)),max(tas_aa_seas_obs(1,:))/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+tas_trends_seas@units + xy_mam(ee) = gsn_csm_xy(wks_aa_mam,ispan(syear(ee),eyear(ee),1),tas_aa_seas(1,:),xyres) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xy_obs_mam(ee) = gsn_csm_xy(wks_aa_mam,ispan(tas_aa_seas_obs@syear,tas_aa_seas_obs@eyear,1),tas_aa_seas_obs(1,:),xyres2) + overlay(xy_mam(ee),xy_obs_mam(ee)) + end if + + tttt = dtrend_msg(ispan(0,dimsizes(tas_aa_seas&time)-1,1),tas_aa_seas(2,:),False,True) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xyres@trYMinF = min((/min(tas_aa_seas(2,:)),min(tas_aa_seas_obs(2,:))/))-.01 + xyres@trYMaxF = max((/max(tas_aa_seas(2,:)),max(tas_aa_seas_obs(2,:))/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+tas_trends_seas@units + xy_jja(ee) = gsn_csm_xy(wks_aa_jja,ispan(syear(ee),eyear(ee),1),tas_aa_seas(2,:),xyres) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xy_obs_jja(ee) = gsn_csm_xy(wks_aa_jja,ispan(tas_aa_seas_obs@syear,tas_aa_seas_obs@eyear,1),tas_aa_seas_obs(2,:),xyres2) + overlay(xy_jja(ee),xy_obs_jja(ee)) + end if + + tttt = dtrend_msg(ispan(0,dimsizes(tas_aa_seas&time)-1,1),tas_aa_seas(3,:),False,True) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xyres@trYMinF = min((/min(tas_aa_seas(3,:)),min(tas_aa_seas_obs(3,:))/))-.01 + xyres@trYMaxF = max((/max(tas_aa_seas(3,:)),max(tas_aa_seas_obs(3,:))/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+tas_trends_seas@units + xy_son(ee) = gsn_csm_xy(wks_aa_son,ispan(syear(ee),eyear(ee),1),tas_aa_seas(3,:),xyres) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xy_obs_son(ee) = gsn_csm_xy(wks_aa_son,ispan(tas_aa_seas_obs@syear,tas_aa_seas_obs@eyear,1),tas_aa_seas_obs(3,:),xyres2) + overlay(xy_son(ee),xy_obs_son(ee)) + end if + delete(tttt) + + + tttt = dtrend_msg(ispan(0,dimsizes(tas_aa_ann&time)-1,1),tas_aa_ann,False,True) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xyres@trYMinF = min((/min(tas_aa_ann),min(tas_aa_ann_obs)/))-.01 + xyres@trYMaxF = max((/max(tas_aa_ann),max(tas_aa_ann_obs)/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*nyr(ee),2,True)+tas_trends_ann@units + xy_ann(ee) = gsn_csm_xy(wks_aa_ann,ispan(syear(ee),eyear(ee),1),tas_aa_ann,xyres) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xy_obs_ann(ee) = gsn_csm_xy(wks_aa_ann,ispan(tas_aa_seas_obs@syear,tas_aa_seas_obs@eyear,1),tas_aa_ann_obs,xyres2) + overlay(xy_ann(ee),xy_obs_ann(ee)) + delete(xyres@trYMinF) + delete(xyres@trYMaxF) + end if + delete(tttt) + + xyres@trXMaxF = eyear(ee)+1.5 + xyres2@trXMaxF = eyear(ee)+1.5 + tttt = dtrend_msg(ispan(0,dimsizes(tas_aa_mon&time)-1,1),tas_aa_mon,False,True) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xyres@trYMinF = min((/min(tas_aa_mon),min(tas_aa_mon_obs)/))-.01 + xyres@trYMaxF = max((/max(tas_aa_mon),max(tas_aa_mon_obs)/))+.01 + end if + xyres@gsnRightString = decimalPlaces(tttt@slope*dimsizes(tas_aa_mon&time),2,True)+tas_trends_mon@units + xy_mon(ee) = gsn_csm_xy(wks_aa_mon,fspan(syear(ee),eyear(ee)+.91667,dimsizes(tas_aa_mon)),tas_aa_mon,xyres) + if (isfilepresent2("obs_trefht").and.ee.ge.1) then + xy_obs_mon(ee) = gsn_csm_xy(wks_aa_mon,fspan(tas_aa_seas_obs@syear,tas_aa_seas_obs@eyear+.91667,dimsizes(tas_aa_mon_obs)),tas_aa_mon_obs,xyres2) + overlay(xy_mon(ee),xy_obs_mon(ee)) + end if + + xyres@gsnRightString = "" + do ff = 0,4 + if (.not.all(ismissing(tas_rt_mon(ff,:)))) + xyres@gsnRightString = tas_rt_mon@units + xy_rt_mon(ff,ee) = gsn_csm_xy(wks_rt_mon,fspan(syear(ee),eyear(ee)+.91667,dimsizes(tas_aa_mon&time)),tas_rt_mon(ff,:),xyres) + end if + end do + + delete([/tas_trends_seas,tas_trends_ann,tas_trends_mon/]) + delete([/tas_aa_seas,tas_aa_mon,tas_aa_ann,xyres,xyres2,res,tttt,tas_rt_mon/]) + end do + if (isfilepresent2("obs_trefht")) then + delete([/tas_aa_seas_obs,tas_aa_mon_obs,tas_aa_ann_obs/]) + end if + + panres = True + panres@gsnMaximize = True + panres@gsnPaperOrientation = "portrait" + panres@gsnPanelLabelBar = True + panres@gsnPanelYWhiteSpacePercent = 3.0 + panres@pmLabelBarHeightF = 0.05 + panres@pmLabelBarWidthF = 0.65 + panres@lbTitleOn = False + panres@lbBoxLineColor = "gray70" + panres@lbLabelFontHeightF = 0.013 + if (nsim.le.4) then + if (nsim.eq.1) then + panres@txFontHeightF = 0.022 + panres@gsnPanelBottom = 0.50 + else + panres@txFontHeightF = 0.0145 + panres@gsnPanelBottom = 0.50 + end if + else + panres@txFontHeightF = 0.016 + panres@gsnPanelBottom = 0.05 + end if + panres@lbLabelStride = 1 + + panres@txString = "TAS Trends (DJF)" + ncol = floattointeger(sqrt(nsim)) + nrow = (nsim/ncol)+mod(nsim,ncol) + gsn_panel2(wks_trends_djf,map_djf,(/nrow,ncol/),panres) + delete(wks_trends_djf) + + panres@txString = "TAS Trends (MAM)" + gsn_panel2(wks_trends_mam,map_mam,(/nrow,ncol/),panres) + delete(wks_trends_mam) + + panres@txString = "TAS Trends (JJA)" + gsn_panel2(wks_trends_jja,map_jja,(/nrow,ncol/),panres) + delete(wks_trends_jja) + + panres@txString = "TAS Trends (SON)" + gsn_panel2(wks_trends_son,map_son,(/nrow,ncol/),panres) + delete(wks_trends_son) + + panres@txString = "TAS Trends (Annual)" + gsn_panel2(wks_trends_ann,map_ann,(/nrow,ncol/),panres) + delete(wks_trends_ann) + + panres@txString = "TAS Trends (Monthly)" + gsn_panel2(wks_trends_mon,map_mon,(/nrow,ncol/),panres) + delete(wks_trends_mon) + delete(panres) + + panres2 = True + panres2@gsnMaximize = True + panres2@gsnPaperOrientation = "portrait" + panres2@gsnPanelYWhiteSpacePercent = 3.0 + if (nsim.le.5) then + panres2@txFontHeightF = 0.024 + else + panres2@txFontHeightF = 0.016 + end if + if (SCALE_TIMESERIES.eq."True") then + tt = ind(nyr.eq.nyr_max) + panres2@gsnPanelScalePlotIndex = tt(0) + delete(tt) + end if + if (nsim.le.12) then + lp = (/nsim,1/) + else + lp = (/nrow,ncol/) ;(/nsim/2+1,nsim/8+1/) + end if + panres2@txString = "TAS Global Average (DJF)" + gsn_panel2(wks_aa_djf,xy_djf,lp,panres2) + delete(wks_aa_djf) + + panres2@txString = "TAS Global Average (MAM)" + gsn_panel2(wks_aa_mam,xy_mam,lp,panres2) + delete(wks_aa_mam) + + panres2@txString = "TAS Global Average (JJA)" + gsn_panel2(wks_aa_jja,xy_jja,lp,panres2) + delete(wks_aa_jja) + + panres2@txString = "TAS Global Average (SON)" + gsn_panel2(wks_aa_son,xy_son,lp,panres2) + delete(wks_aa_son) + + panres2@txString = "TAS Global Average (Annual)" + gsn_panel2(wks_aa_ann,xy_ann,lp,panres2) + delete(wks_aa_ann) + + panres2@txString = "TAS Global Average (Monthly)" + gsn_panel2(wks_aa_mon,xy_mon,lp,panres2) + delete(wks_aa_mon) + + panres2@txString = "TAS Running 8yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(0,:),lp,panres2) + + panres2@txString = "TAS Running 10yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(1,:),lp,panres2) + + panres2@txString = "TAS Running 12yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(2,:),lp,panres2) + + panres2@txString = "TAS Running 14yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(3,:),lp,panres2) + + panres2@txString = "TAS Running 16yr Trend (Monthly)" + gsn_panel2(wks_rt_mon,xy_rt_mon(4,:),lp,panres2) + delete(wks_rt_mon) + + delete([/nrow,ncol,lp,map_djf,map_mam,map_jja,map_son,map_ann,map_mon,xy_djf,xy_mam,xy_jja,xy_son,xy_ann,xy_mon/]) + delete([/xy_rt_mon/]) + delete(panres2) + if (isfilepresent2("obs_trefht")) then + delete([/xy_obs_djf,xy_obs_mam,xy_obs_jja,xy_obs_son,xy_obs_ann,xy_obs_mon/]) + end if + OUTDIR = getenv("OUTDIR") + if (wks_type.eq."png") then + do gg = 1,5 + if (isfilepresent2(OUTDIR+"tas.runtrend.mon.00000"+gg+".png")) then + system("mv "+OUTDIR+"tas.runtrend.mon.00000"+gg+".png "+OUTDIR+"tas."+rt_nyr(gg-1)+"yr_runtrend.mon.png") + end if + end do + else + if (isfilepresent2(OUTDIR+"tas.runtrend.mon.ps")) then + system("psplit "+OUTDIR+"tas.runtrend.mon.ps "+OUTDIR+"tas_rt") + do gg = 1,5 + if (isfilepresent2(OUTDIR+"tas_rt000"+gg+".ps")) then + system("mv "+OUTDIR+"tas_rt000"+gg+".ps "+OUTDIR+"tas."+rt_nyr(gg-1)+"yr_runtrend.mon.ps") + end if + end do + system("rm "+OUTDIR+"tas.runtrend.mon.ps") + end if + end if + delete(OUTDIR) + print("Finished: tas.trends_timeseries.ncl") +end diff --git a/lib/externals/CVDP/ncl_scripts/webpage.ncl b/lib/externals/CVDP/ncl_scripts/webpage.ncl new file mode 100644 index 000000000..02b491c79 --- /dev/null +++ b/lib/externals/CVDP/ncl_scripts/webpage.ncl @@ -0,0 +1,860 @@ +; Create the index.html, methodology.html, and metrics.html web pages. +; +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" +load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" +load "$CVDP_SCRIPTS/functions.ncl" + +begin + print("Starting: webpage.ncl") + + OUTDIR = getenv("OUTDIR") + VERSION = getenv("VERSION") + OT = getenv("OUTPUT_DATA") + OPT_CLIMO = getenv("OPT_CLIMO") + CLIMO_SYEAR = getenv("CLIMO_SYEAR") + CLIMO_EYEAR = getenv("CLIMO_EYEAR") + OBS = getenv("OBS") + + quote = str_get_dq() + + if (OPT_CLIMO.eq."Full") then + subtxt = "Climatological Period Used: Full" + end if + if (OPT_CLIMO.eq."Custom") then + if (toint(CLIMO_SYEAR).lt.0) then + subtxt = "Climo. Period (relative to record end): "+CLIMO_SYEAR+"-"+CLIMO_EYEAR + else + subtxt = "Climatological Period Used: "+CLIMO_SYEAR+"-"+CLIMO_EYEAR + end if + end if + + nsim_noobs = numAsciiRow("namelist") + na = asciiread("namelist",(/nsim_noobs/),"string") + names = new(nsim_noobs,"string") + delim = "|" + do gg = 0,nsim_noobs-1 + names(gg) = str_strip(str_get_field(na(gg),1,delim)) + end do +; print(names) + + txt = new(700,"string") + quote = str_get_dq() + + txt(0) = "Climate Variability Diagnostics Package" + txt(1) = "" + txt(2) = "" + txt(3) = "" + txt(4) = "" + txt(5) = "" + + txt(15) = "
" + txt(16) = "
" + txt(17) = "+quote+" + txt(18) = "
" + + txt(19) = "
" + txt(20) = "" + + txt(24) = "
  • Methodology and Definitions

  • " + if (isfilepresent2(OUTDIR+"metrics.txt")) then + if (isfilepresent2(OUTDIR+"metrics.table_1.gif")) then + txt(21) = "
  • Metrics Tables: Pattern Correlations | RMS

  • " + else + txt(21) = "
  • Metrics Table

  • " + end if + end if + + if (OBS.eq."True") then + txt(22) = "
  • Namelists: Input | Derived

  • " + else + txt(22) = "
  • Namelists: Input | Derived

  • " + end if + + txt(23) = "
  • "+subtxt+"

  • Created: "+systemfunc("date")+"

  • CVDP Version "+VERSION+"

"+webtitle+"

" + delete([/subtxt/]) + + txt(25) = "
" + txt(26) = "" + txt(27) = "

Means

" + txt(28) = "" + txt(29) = "" + txt(30) = "" + txt(31) = "" + txt(32) = "" + txt(33) = "" + txt(34) = "" + txt(35) = "" + txt(36) = "
SST"+table_link_setup(OUTDIR,"sst.mean.djf.png","DJF")+""+table_link_setup(OUTDIR,"sst.mean.mam.png","MAM")+""+table_link_setup(OUTDIR,"sst.mean.jja.png","JJA")+""+table_link_setup(OUTDIR,"sst.mean.son.png","SON")+""+table_link_setup(OUTDIR,"sst.mean.ann.png","Annual")+"
TAS"+table_link_setup(OUTDIR,"tas.mean.djf.png","DJF")+""+table_link_setup(OUTDIR,"tas.mean.mam.png","MAM")+""+table_link_setup(OUTDIR,"tas.mean.jja.png","JJA")+""+table_link_setup(OUTDIR,"tas.mean.son.png","SON")+""+table_link_setup(OUTDIR,"tas.mean.ann.png","Annual")+"
PSL"+table_link_setup(OUTDIR,"psl.mean.djf.png","DJF")+""+table_link_setup(OUTDIR,"psl.mean.mam.png","MAM")+""+table_link_setup(OUTDIR,"psl.mean.jja.png","JJA")+""+table_link_setup(OUTDIR,"psl.mean.son.png","SON")+""+table_link_setup(OUTDIR,"psl.mean.ann.png","Annual")+"
PR"+table_link_setup(OUTDIR,"pr.mean.djf.png","DJF")+""+table_link_setup(OUTDIR,"pr.mean.mam.png","MAM")+""+table_link_setup(OUTDIR,"pr.mean.jja.png","JJA")+""+table_link_setup(OUTDIR,"pr.mean.son.png","SON")+""+table_link_setup(OUTDIR,"pr.mean.ann.png","Annual")+"
[PR]"+table_link_setup(OUTDIR,"pr.za.djf.png","DJF")+""+table_link_setup(OUTDIR,"pr.za.mam.png","MAM")+""+table_link_setup(OUTDIR,"pr.za.jja.png","JJA")+""+table_link_setup(OUTDIR,"pr.za.son.png","SON")+""+table_link_setup(OUTDIR,"pr.za.ann.png","Annual")+"
SND"+table_link_setup(OUTDIR,"snd.mean.djf.png","DJF")+""+table_link_setup(OUTDIR,"snd.mean.mam.png","MAM")+""+table_link_setup(OUTDIR,"snd.mean.jja.png","JJA")+""+table_link_setup(OUTDIR,"snd.mean.son.png","SON")+""+table_link_setup(OUTDIR,"snd.mean.ann.png","Annual")+"
SIC NH"+table_link_setup(OUTDIR,"aice.mean.nh.djf.png","DJF")+""+table_link_setup(OUTDIR,"aice.mean.nh.mam.png","MAM")+""+table_link_setup(OUTDIR,"aice.mean.nh.jja.png","JJA")+""+table_link_setup(OUTDIR,"aice.mean.nh.son.png","SON")+""+table_link_setup(OUTDIR,"aice.mean.nh.ann.png","Annual")+"
SIC SH"+table_link_setup(OUTDIR,"aice.mean.sh.djf.png","DJF")+""+table_link_setup(OUTDIR,"aice.mean.sh.mam.png","MAM")+""+table_link_setup(OUTDIR,"aice.mean.sh.jja.png","JJA")+""+table_link_setup(OUTDIR,"aice.mean.sh.son.png","SON")+""+table_link_setup(OUTDIR,"aice.mean.sh.ann.png","Annual")+"
" + + txt(38) = "
" + txt(39) = "
" + txt(40) = "" + txt(41) = "

Standard Deviations

" + txt(42) = "" + txt(43) = "" + txt(44) = "" + txt(45) = "" + txt(46) = "" + txt(47) = "" + txt(48) = "" + txt(49) = "
SST"+table_link_setup(OUTDIR,"sst.stddev.djf.png","DJF")+""+table_link_setup(OUTDIR,"sst.stddev.mam.png","MAM")+""+table_link_setup(OUTDIR,"sst.stddev.jja.png","JJA")+""+table_link_setup(OUTDIR,"sst.stddev.son.png","SON")+""+table_link_setup(OUTDIR,"sst.stddev.ann.png","Annual")+"
TAS"+table_link_setup(OUTDIR,"tas.stddev.djf.png","DJF")+""+table_link_setup(OUTDIR,"tas.stddev.mam.png","MAM")+""+table_link_setup(OUTDIR,"tas.stddev.jja.png","JJA")+""+table_link_setup(OUTDIR,"tas.stddev.son.png","SON")+""+table_link_setup(OUTDIR,"tas.stddev.ann.png","Annual")+"
PSL"+table_link_setup(OUTDIR,"psl.stddev.djf.png","DJF")+""+table_link_setup(OUTDIR,"psl.stddev.mam.png","MAM")+""+table_link_setup(OUTDIR,"psl.stddev.jja.png","JJA")+""+table_link_setup(OUTDIR,"psl.stddev.son.png","SON")+""+table_link_setup(OUTDIR,"psl.stddev.ann.png","Annual")+"
PR"+table_link_setup(OUTDIR,"pr.stddev.djf.png","DJF")+""+table_link_setup(OUTDIR,"pr.stddev.mam.png","MAM")+""+table_link_setup(OUTDIR,"pr.stddev.jja.png","JJA")+""+table_link_setup(OUTDIR,"pr.stddev.son.png","SON")+""+table_link_setup(OUTDIR,"pr.stddev.ann.png","Annual")+"
SND"+table_link_setup(OUTDIR,"snd.stddev.djf.png","DJF")+""+table_link_setup(OUTDIR,"snd.stddev.mam.png","MAM")+""+table_link_setup(OUTDIR,"snd.stddev.jja.png","JJA")+""+table_link_setup(OUTDIR,"snd.stddev.son.png","SON")+""+table_link_setup(OUTDIR,"snd.stddev.ann.png","Annual")+"
SIC NH"+table_link_setup(OUTDIR,"aice.stddev.nh.djf.png","DJF")+""+table_link_setup(OUTDIR,"aice.stddev.nh.mam.png","MAM")+""+table_link_setup(OUTDIR,"aice.stddev.nh.jja.png","JJA")+""+table_link_setup(OUTDIR,"aice.stddev.nh.son.png","SON")+""+table_link_setup(OUTDIR,"aice.stddev.nh.ann.png","Annual")+"
SIC SH"+table_link_setup(OUTDIR,"aice.stddev.sh.djf.png","DJF")+""+table_link_setup(OUTDIR,"aice.stddev.sh.mam.png","MAM")+""+table_link_setup(OUTDIR,"aice.stddev.sh.jja.png","JJA")+""+table_link_setup(OUTDIR,"aice.stddev.sh.son.png","SON")+""+table_link_setup(OUTDIR,"aice.stddev.sh.ann.png","Annual")+"
" + + txt(68) = "
" + txt(69) = "
" + txt(70) = "" + txt(71) = "

Coupled Modes of Variability

" + txt(72) = "" + txt(73) = "" + txt(74) = "" + txt(75) = "" + txt(76) = "" + txt(77) = "" + txt(78) = "" + + txt(90) = "" + txt(91) = "" + txt(92) = "" + txt(93) = "" + txt(94) = "" + txt(95) = "" + txt(96) = "" + txt(97) = "" + + txt(101) = "" + txt(102) = "" + txt(103) = "" + txt(104) = "" + txt(105) = "" + txt(106) = "" + txt(107) = "" + txt(108) = "" + txt(109) = "" + txt(110) = "" + txt(111) = "" + txt(112) = "" + txt(113) = "" + txt(114) = "
ENSOSpatial CompositesSST/TAS/PSL
"+table_link_setup(OUTDIR,"nino34.spatialcomp.jja0.png","JJA0")+" "+table_link_setup(OUTDIR,"nino34.spatialcomp.son0.png","SON0")+"
"+table_link_setup(OUTDIR,"nino34.spatialcomp.djf1.png","DJF+1")+" "+table_link_setup(OUTDIR,"nino34.spatialcomp.mam1.png","MAM+1")+"
PR
"+table_link_setup(OUTDIR,"nino34.spatialcomp.pr.jja0.png","JJA0")+" "+table_link_setup(OUTDIR,"nino34.spatialcomp.pr.son0.png","SON0")+"
"+table_link_setup(OUTDIR,"nino34.spatialcomp.pr.djf1.png","DJF+1")+" "+table_link_setup(OUTDIR,"nino34.spatialcomp.pr.mam1.png","MAM+1")+"
"+table_link_setup(OUTDIR,"nino34.hov.elnino.png","El Niño Hovmöller")+""+table_link_setup(OUTDIR,"nino34.hov.lanina.png","La Niña Hovmöller")+"
Niño3.4"+table_link_setup(OUTDIR,"nino34.timeseries.png","Timeseries")+""+table_link_setup(OUTDIR,"nino34.powspec.png","Power Spectra")+"
"+table_link_setup(OUTDIR,"nino34.monstddev.png","Monthly Std. Dev.")+""+table_link_setup(OUTDIR,"nino34.runstddev.png","Running Std. Dev.")+"
"+table_link_setup(OUTDIR,"nino34.autocor.png","Autocorrelation")+""+table_link_setup(OUTDIR,"nino34.wavelet.png","Wavelet Analysis")+"
PDORegr:  "+table_link_setup(OUTDIR,"pdo.png","SST")+" "+table_link_setup(OUTDIR,"pdo.tasreg.png","TAS")+" "+table_link_setup(OUTDIR,"pdo.prreg.png","PR")+""+table_link_setup(OUTDIR,"pdo.timeseries.png","Timeseries")+""+table_link_setup(OUTDIR,"pdo.powspec.png","Power Spectra")+"
IPORegr:  "+table_link_setup(OUTDIR,"ipo.png","SST")+" "+table_link_setup(OUTDIR,"ipo.tasreg.png","TAS")+" "+table_link_setup(OUTDIR,"ipo.prreg.png","PR")+""+table_link_setup(OUTDIR,"ipo.timeseries.png","Timeseries")+""+table_link_setup(OUTDIR,"ipo.powspec.png","Power Spectra")+"
AMORegr:  "+table_link_setup(OUTDIR,"amo.png","SST")+" "+table_link_setup(OUTDIR,"amo.tasreg.png","TAS")+" "+table_link_setup(OUTDIR,"amo.prreg.png","PR")+""+table_link_setup(OUTDIR,"amo.timeseries.png","Timeseries")+""+table_link_setup(OUTDIR,"amo.powspec.png","Power Spectra")+"
Regr LP:  "+table_link_setup(OUTDIR,"amo.lp.png","SST")+" "+table_link_setup(OUTDIR,"amo.lp.tasreg.png","TAS")+" "+table_link_setup(OUTDIR,"amo.lp.prreg.png","PR")+"
AMOC"+table_link_setup(OUTDIR,"amoc.mean.ann.png","Means")+""+table_link_setup(OUTDIR,"amoc.stddev.ann.png","Standard Deviations")+""+table_link_setup(OUTDIR,"amoc.ann.png","Patterns")+"
"+table_link_setup(OUTDIR,"amoc.timeseries.ann.png","Timeseries")+""+table_link_setup(OUTDIR,"amoc.sstreg.ann.png","SST Regressions")+""+table_link_setup(OUTDIR,"amoc.tasreg.ann.png","TAS Regressions")+"
"+table_link_setup(OUTDIR,"amoc.powspec.ann.png","Spectra")+""+table_link_setup(OUTDIR,"amoc_amo.leadlag.ann.png","AMO/AMOC Lag Correlations")+"
" + + + txt(127) = "
" + txt(128) = "
" + txt(129) = "" + txt(130) = "

Atmospheric Modes of Variability

" + txt(131) = "" + txt(132) = "" + txt(133) = "" + txt(134) = "" + txt(135) = "" + txt(136) = "" + txt(137) = "" + txt(138) = "" + txt(139) = "" + txt(140) = "" + txt(141) = "" + txt(142) = "" + txt(143) = "" + + txt(159) = "" + txt(160) = "" + txt(161) = "" + txt(162) = "" + txt(163) = "" + txt(164) = "" + txt(165) = "" + txt(166) = "" + txt(167) = "" + txt(168) = "" + txt(169) = "" + txt(170) = "" + txt(171) = "" + txt(172) = "" + + txt(189) = "" + txt(190) = "" + txt(191) = "" + txt(192) = "" + txt(193) = "" + txt(194) = "" + txt(195) = "" + txt(196) = "" + txt(197) = "" + txt(198) = "" + txt(199) = "" + txt(200) = "" + txt(201) = "" + txt(202) = "" + + txt(219) = "" + txt(220) = "" + txt(221) = "" + txt(222) = "" + txt(223) = "" + txt(224) = "" + txt(225) = "" + txt(226) = "" + txt(227) = "" + txt(228) = "" + txt(229) = "" + txt(230) = "" + txt(231) = "" + txt(232) = "" + + txt(249) = "" + txt(250) = "" + txt(251) = "" + txt(252) = "" + txt(253) = "" + txt(254) = "" + txt(255) = "" + txt(256) = "" + txt(257) = "" + txt(258) = "" + txt(259) = "" + txt(260) = "" + txt(261) = "" + txt(262) = "" + + txt(279) = "" + txt(280) = "" + txt(281) = "" + txt(282) = "" + txt(283) = "" + txt(284) = "" + txt(285) = "" + txt(286) = "" + txt(287) = "" + txt(288) = "" + txt(289) = "" + txt(290) = "" + txt(291) = "" + txt(292) = "" + + txt(309) = "" + txt(310) = "" + txt(311) = "" + txt(312) = "" + txt(313) = "" + txt(314) = "" + txt(315) = "" + txt(316) = "" + txt(317) = "" + txt(318) = "" + txt(319) = "" + txt(320) = "" + txt(321) = "" + txt(322) = "" + txt(323) = "
NAMPatterns"+table_link_setup(OUTDIR,"nam.djf.png","DJF")+""+table_link_setup(OUTDIR,"nam.mam.png","MAM")+""+table_link_setup(OUTDIR,"nam.jja.png","JJA")+""+table_link_setup(OUTDIR,"nam.son.png","SON")+""+table_link_setup(OUTDIR,"nam.ann.png","Annual")+""+table_link_setup(OUTDIR,"nam.mon.png","Monthly")+"
Timeseries"+table_link_setup(OUTDIR,"nam.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"nam.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"nam.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"nam.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"nam.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"nam.timeseries.mon.png","Monthly")+"
SST/TAS Regressions"+table_link_setup(OUTDIR,"nam.tempreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"nam.tempreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"nam.tempreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"nam.tempreg.son.png","SON")+""+table_link_setup(OUTDIR,"nam.tempreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"nam.tempreg.mon.png","Monthly")+"
PR Regressions"+table_link_setup(OUTDIR,"nam.prreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"nam.prreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"nam.prreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"nam.prreg.son.png","SON")+""+table_link_setup(OUTDIR,"nam.prreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"nam.prreg.mon.png","Monthly")+"
SAMPatterns"+table_link_setup(OUTDIR,"sam.djf.png","DJF")+""+table_link_setup(OUTDIR,"sam.mam.png","MAM")+""+table_link_setup(OUTDIR,"sam.jja.png","JJA")+""+table_link_setup(OUTDIR,"sam.son.png","SON")+""+table_link_setup(OUTDIR,"sam.ann.png","Annual")+""+table_link_setup(OUTDIR,"sam.mon.png","Monthly")+"
Timeseries"+table_link_setup(OUTDIR,"sam.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"sam.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"sam.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"sam.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"sam.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"sam.timeseries.mon.png","Monthly")+"
SST/TAS Regressions"+table_link_setup(OUTDIR,"sam.tempreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"sam.tempreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"sam.tempreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"sam.tempreg.son.png","SON")+""+table_link_setup(OUTDIR,"sam.tempreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"sam.tempreg.mon.png","Monthly")+"
PR Regressions"+table_link_setup(OUTDIR,"sam.prreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"sam.prreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"sam.prreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"sam.prreg.son.png","SON")+""+table_link_setup(OUTDIR,"sam.prreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"sam.prreg.mon.png","Monthly")+"
NAOPatterns"+table_link_setup(OUTDIR,"nao.djf.png","DJF")+""+table_link_setup(OUTDIR,"nao.mam.png","MAM")+""+table_link_setup(OUTDIR,"nao.jja.png","JJA")+""+table_link_setup(OUTDIR,"nao.son.png","SON")+""+table_link_setup(OUTDIR,"nao.ann.png","Annual")+""+table_link_setup(OUTDIR,"nao.mon.png","Monthly")+"
Timeseries"+table_link_setup(OUTDIR,"nao.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"nao.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"nao.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"nao.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"nao.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"nao.timeseries.mon.png","Monthly")+"
SST/TAS Regressions"+table_link_setup(OUTDIR,"nao.tempreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"nao.tempreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"nao.tempreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"nao.tempreg.son.png","SON")+""+table_link_setup(OUTDIR,"nao.tempreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"nao.tempreg.mon.png","Monthly")+"
PR Regressions"+table_link_setup(OUTDIR,"nao.prreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"nao.prreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"nao.prreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"nao.prreg.son.png","SON")+""+table_link_setup(OUTDIR,"nao.prreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"nao.prreg.mon.png","Monthly")+"
PNAPatterns"+table_link_setup(OUTDIR,"pna.djf.png","DJF")+""+table_link_setup(OUTDIR,"pna.mam.png","MAM")+""+table_link_setup(OUTDIR,"pna.jja.png","JJA")+""+table_link_setup(OUTDIR,"pna.son.png","SON")+""+table_link_setup(OUTDIR,"pna.ann.png","Annual")+""+table_link_setup(OUTDIR,"pna.mon.png","Monthly")+"
Timeseries"+table_link_setup(OUTDIR,"pna.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"pna.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"pna.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"pna.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"pna.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"pna.timeseries.mon.png","Monthly")+"
SST/TAS Regressions"+table_link_setup(OUTDIR,"pna.tempreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"pna.tempreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"pna.tempreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"pna.tempreg.son.png","SON")+""+table_link_setup(OUTDIR,"pna.tempreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"pna.tempreg.mon.png","Monthly")+"
PR Regressions"+table_link_setup(OUTDIR,"pna.prreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"pna.prreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"pna.prreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"pna.prreg.son.png","SON")+""+table_link_setup(OUTDIR,"pna.prreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"pna.prreg.mon.png","Monthly")+"
NPOPatterns"+table_link_setup(OUTDIR,"npo.djf.png","DJF")+""+table_link_setup(OUTDIR,"npo.mam.png","MAM")+""+table_link_setup(OUTDIR,"npo.jja.png","JJA")+""+table_link_setup(OUTDIR,"npo.son.png","SON")+""+table_link_setup(OUTDIR,"npo.ann.png","Annual")+""+table_link_setup(OUTDIR,"npo.mon.png","Monthly")+"
Timeseries"+table_link_setup(OUTDIR,"npo.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"npo.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"npo.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"npo.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"npo.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"npo.timeseries.mon.png","Monthly")+"
SST/TAS Regressions"+table_link_setup(OUTDIR,"npo.tempreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"npo.tempreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"npo.tempreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"npo.tempreg.son.png","SON")+""+table_link_setup(OUTDIR,"npo.tempreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"npo.tempreg.mon.png","Monthly")+"
PR Regressions"+table_link_setup(OUTDIR,"npo.prreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"npo.prreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"npo.prreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"npo.prreg.son.png","SON")+""+table_link_setup(OUTDIR,"npo.prreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"npo.prreg.mon.png","Monthly")+"
PSA1Patterns"+table_link_setup(OUTDIR,"psa1.djf.png","DJF")+""+table_link_setup(OUTDIR,"psa1.mam.png","MAM")+""+table_link_setup(OUTDIR,"psa1.jja.png","JJA")+""+table_link_setup(OUTDIR,"psa1.son.png","SON")+""+table_link_setup(OUTDIR,"psa1.ann.png","Annual")+""+table_link_setup(OUTDIR,"psa1.mon.png","Monthly")+"
Timeseries"+table_link_setup(OUTDIR,"psa1.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"psa1.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"psa1.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"psa1.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"psa1.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"psa1.timeseries.mon.png","Monthly")+"
SST/TAS Regressions"+table_link_setup(OUTDIR,"psa1.tempreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"psa1.tempreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"psa1.tempreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"psa1.tempreg.son.png","SON")+""+table_link_setup(OUTDIR,"psa1.tempreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"psa1.tempreg.mon.png","Monthly")+"
PR Regressions"+table_link_setup(OUTDIR,"psa1.prreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"psa1.prreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"psa1.prreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"psa1.prreg.son.png","SON")+""+table_link_setup(OUTDIR,"psa1.prreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"psa1.prreg.mon.png","Monthly")+"
PSA2Patterns"+table_link_setup(OUTDIR,"psa2.djf.png","DJF")+""+table_link_setup(OUTDIR,"psa2.mam.png","MAM")+""+table_link_setup(OUTDIR,"psa2.jja.png","JJA")+""+table_link_setup(OUTDIR,"psa2.son.png","SON")+""+table_link_setup(OUTDIR,"psa2.ann.png","Annual")+""+table_link_setup(OUTDIR,"psa2.mon.png","Monthly")+"
Timeseries"+table_link_setup(OUTDIR,"psa2.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"psa2.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"psa2.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"psa2.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"psa2.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"psa2.timeseries.mon.png","Monthly")+"
SST/TAS Regressions"+table_link_setup(OUTDIR,"psa2.tempreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"psa2.tempreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"psa2.tempreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"psa2.tempreg.son.png","SON")+""+table_link_setup(OUTDIR,"psa2.tempreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"psa2.tempreg.mon.png","Monthly")+"
PR Regressions"+table_link_setup(OUTDIR,"psa2.prreg.djf.png","DJF")+""+table_link_setup(OUTDIR,"psa2.prreg.mam.png","MAM")+""+table_link_setup(OUTDIR,"psa2.prreg.jja.png","JJA")+""+table_link_setup(OUTDIR,"psa2.prreg.son.png","SON")+""+table_link_setup(OUTDIR,"psa2.prreg.ann.png","Annual")+""+table_link_setup(OUTDIR,"psa2.prreg.mon.png","Monthly")+"
" + + txt(329) = "
" + txt(330) = "
" + txt(331) = "" + txt(332) = "

Ice Extent Timeseries

" + txt(333) = "" + txt(334) = "" + txt(335) = "" + txt(336) = "" + txt(337) = "" + txt(338) = "" + txt(339) = "" + txt(341) = "" + txt(342) = "" + txt(343) = "" + txt(344) = "" + txt(345) = "" + txt(346) = "" + txt(347) = "" + txt(348) = "" + txt(349) = "" + txt(351) = "" + txt(352) = "
SIC NH"+table_link_setup(OUTDIR,"aice.extent.nh.djf.png","DJF")+""+table_link_setup(OUTDIR,"aice.extent.nh.mam.png","MAM")+""+table_link_setup(OUTDIR,"aice.extent.nh.jja.png","JJA")+""+table_link_setup(OUTDIR,"aice.extent.nh.son.png","SON")+""+table_link_setup(OUTDIR,"aice.extent.nh.ann.png","Annual")+""+table_link_setup(OUTDIR,"aice.extent.nh.mon.png","Monthly")+"
"+table_link_setup(OUTDIR,"aice.extent.nh.feb.png","Feb")+"  "+table_link_setup(OUTDIR,"aice.extent.nh.mar.png","Mar")+"  "+table_link_setup(OUTDIR,"aice.extent.nh.sep.png","Sep")+""+table_link_setup(OUTDIR,"aice.extent.anom.nh.mon.png","Monthly Anomalies")+""+table_link_setup(OUTDIR,"aice.extent.nh.climo.png","Climatology")+"
SIC SH"+table_link_setup(OUTDIR,"aice.extent.sh.djf.png","DJF")+""+table_link_setup(OUTDIR,"aice.extent.sh.mam.png","MAM")+""+table_link_setup(OUTDIR,"aice.extent.sh.jja.png","JJA")+""+table_link_setup(OUTDIR,"aice.extent.sh.son.png","SON")+""+table_link_setup(OUTDIR,"aice.extent.sh.ann.png","Annual")+""+table_link_setup(OUTDIR,"aice.extent.sh.mon.png","Monthly")+"
"+table_link_setup(OUTDIR,"aice.extent.sh.feb.png","Feb")+"  "+table_link_setup(OUTDIR,"aice.extent.sh.mar.png","Mar")+"  "+table_link_setup(OUTDIR,"aice.extent.sh.sep.png","Sep")+""+table_link_setup(OUTDIR,"aice.extent.anom.sh.mon.png","Monthly Anomalies")+""+table_link_setup(OUTDIR,"aice.extent.sh.climo.png","Climatology")+"
" + + + txt(360) = "
" + txt(361) = "
" + txt(362) = "" + txt(363) = "

Global Trend Maps

" + txt(364) = "" + txt(365) = "" + txt(366) = "" + txt(367) = "" + txt(368) = "" + txt(369) = "" + txt(370) = "" + txt(371) = "" + txt(372) = "" + txt(373) = "" + txt(374) = "" + txt(375) = "" + txt(376) = "" + txt(377) = "" + txt(378) = "" + txt(379) = "" + txt(380) = "" + txt(381) = "" + txt(382) = "" + txt(383) = "" + txt(384) = "" + txt(385) = "" + txt(386) = "" + txt(387) = "" + txt(388) = "" + txt(389) = "" + txt(390) = "" + txt(391) = "" + txt(392) = "" + txt(393) = "" + txt(394) = "" + txt(395) = "" + txt(396) = "" + txt(397) = "" + txt(398) = "" + txt(399) = "" + txt(400) = "" + txt(401) = "" + txt(402) = "" + txt(403) = "" + txt(404) = "" + txt(405) = "
SST"+table_link_setup(OUTDIR,"sst.trends.djf.png","DJF")+""+table_link_setup(OUTDIR,"sst.trends.mam.png","MAM")+""+table_link_setup(OUTDIR,"sst.trends.jja.png","JJA")+""+table_link_setup(OUTDIR,"sst.trends.son.png","SON")+""+table_link_setup(OUTDIR,"sst.trends.ann.png","Annual")+""+table_link_setup(OUTDIR,"sst.trends.mon.png","Monthly")+"
TAS"+table_link_setup(OUTDIR,"tas.trends.djf.png","DJF")+""+table_link_setup(OUTDIR,"tas.trends.mam.png","MAM")+""+table_link_setup(OUTDIR,"tas.trends.jja.png","JJA")+""+table_link_setup(OUTDIR,"tas.trends.son.png","SON")+""+table_link_setup(OUTDIR,"tas.trends.ann.png","Annual")+""+table_link_setup(OUTDIR,"tas.trends.mon.png","Monthly")+"
PSL"+table_link_setup(OUTDIR,"psl.trends.djf.png","DJF")+""+table_link_setup(OUTDIR,"psl.trends.mam.png","MAM")+""+table_link_setup(OUTDIR,"psl.trends.jja.png","JJA")+""+table_link_setup(OUTDIR,"psl.trends.son.png","SON")+""+table_link_setup(OUTDIR,"psl.trends.ann.png","Annual")+""+table_link_setup(OUTDIR,"psl.trends.mon.png","Monthly")+"
PR"+table_link_setup(OUTDIR,"pr.trends.djf.png","DJF")+""+table_link_setup(OUTDIR,"pr.trends.mam.png","MAM")+""+table_link_setup(OUTDIR,"pr.trends.jja.png","JJA")+""+table_link_setup(OUTDIR,"pr.trends.son.png","SON")+""+table_link_setup(OUTDIR,"pr.trends.ann.png","Annual")+""+table_link_setup(OUTDIR,"pr.trends.mon.png","Monthly")+"
SND"+table_link_setup(OUTDIR,"snd.trends.djf.png","DJF")+""+table_link_setup(OUTDIR,"snd.trends.mam.png","MAM")+""+table_link_setup(OUTDIR,"snd.trends.jja.png","JJA")+""+table_link_setup(OUTDIR,"snd.trends.son.png","SON")+""+table_link_setup(OUTDIR,"snd.trends.ann.png","Annual")+""+table_link_setup(OUTDIR,"snd.trends.mon.png","Monthly")+"
SIC NH"+table_link_setup(OUTDIR,"aice.trends.nh.djf.png","DJF")+""+table_link_setup(OUTDIR,"aice.trends.nh.mam.png","MAM")+""+table_link_setup(OUTDIR,"aice.trends.nh.jja.png","JJA")+""+table_link_setup(OUTDIR,"aice.trends.nh.son.png","SON")+""+table_link_setup(OUTDIR,"aice.trends.nh.ann.png","Annual")+""+table_link_setup(OUTDIR,"aice.trends.nh.mon.png","Monthly")+"
SIC SH"+table_link_setup(OUTDIR,"aice.trends.sh.djf.png","DJF")+""+table_link_setup(OUTDIR,"aice.trends.sh.mam.png","MAM")+""+table_link_setup(OUTDIR,"aice.trends.sh.jja.png","JJA")+""+table_link_setup(OUTDIR,"aice.trends.sh.son.png","SON")+""+table_link_setup(OUTDIR,"aice.trends.sh.ann.png","Annual")+""+table_link_setup(OUTDIR,"aice.trends.sh.mon.png","Monthly")+"
" + + txt(428) = "
" + txt(429) = "
" + txt(430) = "" + txt(431) = "

Globally-Averaged Timeseries

" + txt(432) = "" + txt(433) = "" + txt(434) = "" + txt(435) = "" + txt(436) = "" + txt(437) = "" + txt(438) = "" + txt(439) = "" + txt(440) = "" + txt(441) = "" + txt(442) = "" + txt(443) = "" + txt(444) = "" + txt(445) = "" + txt(446) = "" + txt(447) = "" + txt(448) = "" + txt(449) = "" + txt(450) = "
SST"+table_link_setup(OUTDIR,"sst.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"sst.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"sst.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"sst.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"sst.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"sst.timeseries.mon.png","Monthly")+"
TAS"+table_link_setup(OUTDIR,"tas.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"tas.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"tas.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"tas.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"tas.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"tas.timeseries.mon.png","Monthly")+"
PR"+table_link_setup(OUTDIR,"pr.timeseries.djf.png","DJF")+""+table_link_setup(OUTDIR,"pr.timeseries.mam.png","MAM")+""+table_link_setup(OUTDIR,"pr.timeseries.jja.png","JJA")+""+table_link_setup(OUTDIR,"pr.timeseries.son.png","SON")+""+table_link_setup(OUTDIR,"pr.timeseries.ann.png","Annual")+""+table_link_setup(OUTDIR,"pr.timeseries.mon.png","Monthly")+"
" + + txt(573) = "
" + txt(574) = "
" + txt(575) = "" + txt(576) = "

Running Trends of Globally-Averaged Monthly Timeseries

" + txt(577) = "" + txt(578) = "" + txt(579) = "" + txt(580) = "" + txt(581) = "" + txt(582) = "" + txt(583) = "" + txt(584) = "" + txt(585) = "" + txt(586) = "" + txt(587) = "
SST"+table_link_setup(OUTDIR,"sst.8yr_runtrend.mon.png","8yr")+""+table_link_setup(OUTDIR,"sst.10yr_runtrend.mon.png","10yr")+""+table_link_setup(OUTDIR,"sst.12yr_runtrend.mon.png","12yr")+""+table_link_setup(OUTDIR,"sst.14yr_runtrend.mon.png","14yr")+""+table_link_setup(OUTDIR,"sst.16yr_runtrend.mon.png","16yr")+"
TAS"+table_link_setup(OUTDIR,"tas.8yr_runtrend.mon.png","8yr")+""+table_link_setup(OUTDIR,"tas.10yr_runtrend.mon.png","10yr")+""+table_link_setup(OUTDIR,"tas.12yr_runtrend.mon.png","12yr")+""+table_link_setup(OUTDIR,"tas.14yr_runtrend.mon.png","14yr")+""+table_link_setup(OUTDIR,"tas.16yr_runtrend.mon.png","16yr")+"
" + + txt(608) = "
" + txt(609) = "
" + txt(610) = "" + txt(611) = "

Additional Indices

" + txt(612) = "" + txt(613) = "" + txt(614) = "" + txt(615) = "" + txt(616) = "" + txt(617) = "" + txt(618) = "" + txt(619) = "" + txt(620) = "" + txt(621) = "" + txt(622) = "" + txt(623) = "
"+table_link_setup(OUTDIR,"amm.timeseries.png","Atlantic Meridional Mode")+""+table_link_setup(OUTDIR,"atl3.timeseries.png","Atlantic Niño (ATL3)")+""+table_link_setup(OUTDIR,"tna.timeseries.png","Tropical North Atlantic SST")+""+table_link_setup(OUTDIR,"tsa.timeseries.png","Tropical South Atlantic SST")+"
"+table_link_setup(OUTDIR,"nino12.timeseries.png","niño1+2")+""+table_link_setup(OUTDIR,"nino3.timeseries.png","niño3")+""+table_link_setup(OUTDIR,"nino4.timeseries.png","niño4")+""+table_link_setup(OUTDIR,"npi.timeseries.ndjfm.png","North Pacific PSL")+"
"+table_link_setup(OUTDIR,"iod.timeseries.png","Indian Ocean SST Dipole")+""+table_link_setup(OUTDIR,"tio.timeseries.png","Tropical Indian Ocean SST")+""+table_link_setup(OUTDIR,"socn.timeseries.png","Southern Ocean SST")+"
" + +; if (OT.eq."True") then +; txt(265) = "

Output timeseries written to "+OUTDIR+"

" +; else + txt(635) = "
" +; end if + txt(636) = "" + + tt = ind(.not.ismissing(txt)) + txt2 = txt(:tt(dimsizes(tt)-1)+1) + tt2 = ind(.not.ismissing(txt2)) + txt3 = txt2(tt2) + asciiwrite(OUTDIR+"index.html",txt3) + delete([/txt,tt,tt2,txt2,txt3,quote,names,na,nsim_noobs,OT/]) +;---------------------------------------------------------------------------- +;-- Create calculation description webpage +;---------------------------------------------------------------------------- + txt = new(200,"string") + quote = str_get_dq() + + txt(0) = "Climate Variability Diagnostics Package" + txt(1) = "" + txt(2) = "" + txt(3) = "" + txt(4) = "" + + txt(5) = "" + txt(15) = "+quote+" + txt(16) = "" + txt(17) = "
Back to Diagnostics Plots

Methodology and Definitions


" + + txt(20) = "

General Notes

" + txt(21) = "" + txt(22) = "
  • TS is surface ("+quote+"skin"+quote+") temperature and is used in lieu of sea surface temperatures (SSTs), TAS is 2m air temperature (CESM equivalent = TREFHT)." + txt(23) = "
  • PR is total precipitation (CESM equivalent = PRECC+PRECL), PSL is sea level pressure, SND is snow depth (SNOWDP), and SIC is ice concentration (aice)." + txt(24) = "
  • The annual cycle is removed prior to every calculation by subtracting the long-term monthly means. Exception: The annual cycle is not removed for mean spatial maps." + txt(25) = "
  • Area-averages are always based on cosine of latitude weighting." + txt(26) = "
  • The following calculations use linearly detrended data: standard deviations, nino3.4 spectra, nino3.4 autocorrelations, ENSO spatial composites, and ENSO Hovmöllers." + txt(27) = "
  • For visual clarity, the Y-axis may differ amongst individual panels on a particular plot." + txt(28) = "
  • Climatological Zonal Averages: Climatological means are zonally averaged over the globe." + txt(29) = "
  • Power Spectra: The best-fit first-order Markov red noise spectrum (red curve) and its 95% (blue curve) and 99% (green curve) confidence bounds are shown on each panel. Top X-axis shows the period (in years), and the bottom X-axis shows the frequency (cycles/mo). If calculated, the observational spectrum is overlaid in gray on each model spectrum. The spectra are displayed in variance-conserving form." + txt(30) = "
  • Wavelet Analysis: A wavelet transform is computed using a Morlet wavelet with a wavenumber of 6. Areas significant at the 95% based on a chi-square test are stippled and the “cone of influence” is hatched. See Torrence, C. and G. P. Compo, 1998: A Practical Guide to Wavelet Analysis. Bull. Amer. Meteor. Soc., 79, 61-78. doi: http://dx.doi.org/10.1175/1520-0477(1998)079<0061:APGTWA>2.0.CO;2." + txt(31) = "
  • Running Trends: N-year running trends are computed by calculating the linear trend over the N-year interval beginning at each successive timestep. For instance, for a global timeseries that runs from 1970-2012, the 8yr running trend value for January 1970 is the linear trend during January 1970 - December 1977, and the value for January 2005 is the linear trend during January 2005 - December 2012." + txt(32) = "
  • Running Standard Deviations: 30-year running standard deviations are computed by calculating the standard deviation centered over the 30 year interval at each successive timestep, with a minimum of 35 years of data required. For example, for a timeseries that runs from 1920-2010, the 30yr running standard deviation value for January 1935 is calculated over the period January 1920-December 1949. The right subtitle shows the minimum / mean / maximum of the computed timeseries." + txt(33) = "
  • Metrics Tables: Area-weighted pattern correlations and rms differences are calculated between observations and each model simulation (regridded to match the observational grid) for 11 climate metrics. The Total Score column shows the average of the 11 pattern correlations (Z-transformed) and rms differences. The following domains are used to compute the pattern correlations and rms differences: Means, standard deviations, ENSO, AMO, and PDO: Global; global for means, standard deviations, ENSO, AMO, and PDO; entire longitude/temporal range shown for El Nino and La Nina Hovmöllers; entire domain shown for NAM (20:90°N) and SAM (20:90°S)." + txt(34) = "
  • EOF significance: If an eigenvalue is significantly seperated from neighboring values a star is appended to the percent variance explained on the plot. Significance is calculated following North et al. (MWR, 1982)." + txt(35) = "
  • Ice Extent: Any grid cell defined as having a value at or above 15% is assumed to be 100% ice covered. The area of these grid cells is summed to create ice extent. For data sets with a northern hemisphere pole hole the CVDP looks for an attribute named pole_hole_area that is attached to the AREA variable in the netCDF file. The format of pole_hole_area should be start month (YYYYMM), end month (YYYYMM), area value, (repeat as necessary). If pole_hole_area is detected the CVDP will add the area value to the calculated northern hemisphere ice extent timeseries from the specified start month to the specified end month, and a * is placed after the dataset name in the ice extent plots." + txt(36) = "
  • For more information on observational datasets and climate indices, see the Climate Data Guide.
" + txt(37) = "
" + + txt(40) = "

Modes of Variability

" + txt(41) = "" + txt(42) = "" + txt(43) = "" + txt(44) = "" + txt(45) = "" + + txt(46) = "" + txt(47) = "" + txt(48) = "" + txt(49) = "" + + txt(50) = "" + txt(51) = "" + txt(52) = "" + txt(53) = "" + + txt(55) = "" + txt(56) = "" + txt(57) = "" + txt(58) = "" + txt(59) = "" + txt(60) = "" + txt(61) = "" + txt(62) = "" + txt(63) = "" + txt(64) = "" + txt(65) = "" + txt(66) = "" + txt(67) = "" + txt(68) = "" + txt(69) = "
ENSO Spatial CompositesThe normalized December nino3.4 timeseries is used to composite all years greater than 1 standard deviation (El Niño) and all years less that -1 standard deviation (La Niña). The number of El Niño/La Niña events composited is shown in the right subtitle. The December nino3.4 timeseries is based on the December values of the monthly nino3.4 time series smoothed with a 3-point binomial filter. TS/TAS/PSL composites: Temperatures are color shaded and in units of Celsius. Sea level pressure is contoured from -16 to 16hPa by 2hPa; negative contours are dashed. PR composites: Precipitation is color shaded and is in units of mm/day. See Deser, C., A. S. Phillips, R. A. Tomas, Y. Okumura, M. A. Alexander, A. Capotondi, J. D. Scott, Y. -O. Kwon, and M. Ohba, 2012: ENSO and Pacific Decadal Variability in Community Climate System Model Version 4. J. Climate, 25, 2622-2651, doi: 10.1175/JCLI-D-11-00301.1.
ENSO HovmöllersA 1-2-1 running average is applied to the monthly nino3.4 timeseries, and then December values are selected and normalized. Meridional averages are calculated by averaging from 3°S:3°N, and spatial patterns are formed by compositing from Jan year 0 to May year 2 where the nino3.4 (1-2-1 weighted) December (year 0) index is greater than 1 (El Niño) and those years where the index is less than -1 (La Niña). See Deser, C., A. S. Phillips, R. A. Tomas, Y. Okumura, M. A. Alexander, A. Capotondi, J. D. Scott, Y. -O. Kwon, and M. Ohba, 2012: ENSO and Pacific Decadal Variability in Community Climate System Model Version 4. J. Climate, 25, 2622-2651, doi: 10.1175/JCLI-D-11-00301.1.
PDO (Pacific Decadal Oscillation)Monthly index timeseries defined as the leading principal component (PC) of North Pacific (20:70°N, 110°E:100°W) area-weighted SST* anomalies, where SST* denotes that the global mean SST anomaly has been removed at each timestep. Pattern created by regressing SST anomalies (in Celsius) at each grid box onto the normalized PC timeseries. Low pass-filtered timeseries (black curve) is based on a a 61-month running mean. See Deser, C., M. A. Alexander, S. -P. Xie, and A. S. Phillips, 2010: Sea surface temperature variability: patterns and mechanisms. Ann. Rev. Mar. Sci., 2010.2, 115-143, doi:10.1146/annurev-marine-120408-151453. Also see Mantua, N. J., S. R. Hare, Y. Zhang, J. M. Wallace, and R. Francis, 1997: A Pacific interdecadal climate oscillation with impacts on salmon production. Bull. Amer. Met. Soc., 1069-1079. For more information on the PDO see the Climate Data Guide.
IPO (Interdecadal Pacific Oscillation)Monthly index timeseries defined as the leading principal component (PC) of 13yr low pass filtered Pacific (40°S:60°N, 110°E:70°W) area-weighted SST* anomalies, where SST* denotes that the global mean SST anomaly has been removed at each timestep. Pattern created by regressing SST anomalies (in Celsius) at each grid box onto the normalized PC timeseries. At least 40 years of data are required for the IPO to be calculated. See Meehl, G.A. and A. Hu, 2007: Megadroughts in the Indian Monsoon Region and Southwest North America and a Mechanism for Associated Multidecadal Pacific Sea Surface Temperature Anomalies, J. Clim, 19, 1605-1623, doi: 10.1175/JCLI3675.1.
AMO (Atlantic Multidecadal Oscillation)Monthly index timeseries defined as area-weighted SST* anomalies averaged over the North Atlantic (0:60°N, 80°W:0°E), where SST* denotes that the global (60°S:60°N) mean SST anomaly has been removed at each timestep. Pattern created by regressing SST* anomalies onto the index timeseries and smoothing with a 9-point spatial filter. Low pass-filtered timeseries (black curve superimposed on the monthly timeseries) is based on a a 61-month running mean. Based on Trenberth, K. E., and D. J. Shea, 2006: Atlantic hurricanes and natural variability in 2005, Geophys. Res. Lett., 33, L12704, doi:10.1029/2006GL026894. Low-pass filtered regression maps ("+quote+"Regr LP"+quote+") use a 10-year running mean on both the index timeseries and the field being regressed. For more information on the AMO see the Climate Data Guide.
AMOCThe Atlantic Meridional Overturning Circulation (AMOC) is defined as the oceanic meridional mass transport (Sv) in the Atlantic sector. To compute AMOC, we follow the methods of Danabasoglu et al. (2012). Here we use annual averages of the AMOC, weighted by the cosine of the latitude and vertical extent of each model layer. Areas in which AMOC variance is low (standard deviation < 1e-6 Sv) are set to missing values for clarity. The leading EOF and associated principal component (PC) timeseries are computed over the Atlantic basin from 33°S to 90°N. The AMOC patterns are created by regressing the AMOC anomalies (in Sv) onto the normalized PC timeseries. The SST/TAS patterns associated with AMOC variations are created by regressing TAS/SST anomalies (in Celsius) at each grid box over the globe onto the normalized AMOC PC timeseries. A 15-point low-pass Lanczos filter is applied to the AMOC PC (and AMO) timeseries prior to computing lead/lag correlations, with a minimum of 90 years of data required. The data are not detrended (unlike Danabasoglu et al., 2012). See Danabasoglu, G., S. G. Yeager, Y. -O. Kwon, J. J. Tribbia, A. S. Phillips, and J. W. Hurrell, 2012. Variability of the Atlantic Meridional Overturning Circulation in CCSM4. J. Climate, 25, 5153-5172, doi: 10.1175/JCLI-D-11-00463.1.

For CCSM4 and CESM1, the MOC variable is read in, the Eulerian Mean, Eddy-Induced and Submeso components are summed, and the Atlantic Ocean + Mediterranean Sea + Labrador Sea + GIN Sea + Arctic Ocean + Hudson Bay transport region is selected. For CCSM2 and CCSM3 the same transport region is selected but only the Eulerian Mean component is used as that is all that is available. For CMIP5 (CMIP6) data the msftmyz (msftmz) variable is read in and the atlantic_arctic_ocean basin is used. For CMIP3 data, the stfmmc variable is read in and the atlantic_ocean geo_region is used.
NAM (Northern Annular Mode)Seasonal/annual PSL averages are formed, square root of the cosine of the latitude weighting is applied, and then the leading EOF and associated principal component (PC) timeseries are computed over 20:90°N, 0:360°E. Pattern created by regressing global PSL anomalies (in hPa) onto normalized PC timeseries. Based on Hurrell, J. W., and C. Deser, 2009: North Atlantic climate variability: The role of the North Atlantic Oscillation. J. Mar. Syst., 78, 28-41, doi:10.1016/j.jmarsys.2008.11.026. Also see Thompson, D. W. J., and J. M. Wallace, 2000: Annular modes in the extratropical circulation. Part I: Month-to-month variability. J. Climate, 13, 1000-1016.
NAO (North Atlantic Oscillation)Seasonal/annual PSL averages are formed, square root of the cosine of latitude weighting is applied, and then the leading EOF and associated principal component (PC) timeseries are computed over 20:80°N, 90°W:40°E. Pattern created by regressing global PSL anomalies (in hPa) onto normalized PC timeseries. Based on Hurrell, J. W. and C. Deser, 2009: North Atlantic climate variability: The role of the North Atlantic Oscillation. J. Mar. Syst., 78, 28-41, doi:10.1016/j.jmarsys.2008.11.026. For more information on the NAO see the Climate Data Guide.
SAM/PSA1/PSA2 (Southern Annular Mode, Pacific South American Patterns 1/2)Seasonal/annual PSL averages are formed, square root of the cosine of latitude weighting is applied, and then the 1st (SAM), 2nd (PSA1) and 3rd (PSA2) EOFs and associated principal component (PC) timeseries are computed over 20:90°S, 0:360°E. Patterns created by regressing global PSL anomalies (in hPa) onto normalized PC timeseries. SAM calculation based on Thompson, D. W. J. and J.M. Wallace, 2000: Annular modes in the extratropical circulation. Part I: Month-to-month variability. J. Climate, 13, 1000-1016.
PNA/NPO (Pacific North American Pattern, North Pacific Oscillation)Seasonal/annual PSL averages are formed, the square root of the cosine of the latitude weighting is applied, and then the 1st (PNA) and 2nd (NPO) EOFs and associated principal component (PC) timeseries are computed over 20:85°N, 120°E:120°W. Patterns created by regressing global PSL anomalies (in hPa) onto normalized PC timeseries.
SST RegressionsSST anomalies (in Celsius) at each grid box are regressed upon the normalized atmospheric mode timeseries.
TAS RegressionsTAS anomalies (in Celsius) at each grid box are regressed upon the normalized atmospheric mode timeseries.
PR RegressionsPR anomalies (in mm/day) at each grid box are regressed upon the normalized atmospheric mode timeseries.
" + + txt(80) = "

Climate Indices

" + txt(81) = "" + txt(82) = "" + txt(83) = "" + txt(84) = "" + txt(85) = "" + txt(86) = "" + txt(87) = "" + txt(88) = "" + txt(89) = "" + txt(90) = "" + txt(91) = "" + txt(92) = "" + txt(93) = "" + txt(94) = "" + txt(95) = "" + txt(96) = "" + txt(97) = "" + txt(98) = "" + txt(99) = "" + + txt(100) = "" + txt(101) = "" + txt(102) = "" + txt(103) = "" + txt(104)= "" + txt(105)= "" + txt(106) = "
Atlantic Meridional ModeDefined as the difference between area-averaged SST anomalies (in Celsius) computed over 5:15°N, 20:50°W and area-averaged SST anomalies computed over 5:15°S, 20°W:10°E. Red/blue shading denotes positive/negative departures from the best-fit linear trend line. See Doi, T., T. Tozuka and T. Yamagata (2009), Interannual variability of the Guinea Dome and its possible link with the Atlantic Meridional Mode. Climate Dynamics, 33, 985-998, doi:10.1007/s00382-009-0574-z.
Atlantic Niño (ATL3)Area-averaged SST anomalies (in Celsius) computed over 3°S:3°N, 20°W:0°E. Red/blue shading denotes positive/negative departures from the best-fit linear trend line. See Zebiak, S. E., (1993): Air–sea interaction in the equatorial Atlantic region. Journal of Climate, 6, 1567–1586.
Tropical North Atlantic SSTArea-averaged SST anomalies (in Celsius) computed over 5.5:23.5°N, 15:57.5°W. Red/blue shading denotes positive/negative departures from the best-fit linear trend line. See Enfield, D.B., A.M. Mestas, D.A. Mayer, and L. Cid-Serrano (1999), How ubiquitous is the dipole relationship in tropical Atlantic sea surface temperatures?, JGR-O, 104, 7841-7848.
Tropical South Atlantic SSTArea-averaged SST anomalies (in Celsius) computed over 0:20°S, 30°W:10°E. Red/blue shading denotes positive/negative departures from the best-fit linear trend line. See Enfield, D.B., A.M. Mestas, D.A. Mayer, and L. Cid-Serrano (1999), How ubiquitous is the dipole relationship in tropical Atlantic sea surface temperatures?, JGR-O, 104, 7841-7848.
niño1+2Area-averaged SST anomalies (in Celsius) computed over 0:10°S, 80:90°W. Red/blue shading denotes positive/negative departures from the best-fit linear trend line.
niño3Area-averaged SST anomalies (in Celsius) computed over 5°S:5°N, 90:150°W. Red/blue shading denotes positive/negative departures from the best-fit linear trend line. See Trenberth, K. E. (1997) The Definition of El Niño. Bulletin of the American Meteorological Society, 78, 2771-2777.
niño3.4Area-averaged SST anomalies (in Celsius) computed over 5°S:5°N, 120:170°W. Red/blue shading denotes positive/negative departures from the best-fit linear trend line. See Trenberth, K. E. (1997) The Definition of El Niño. Bulletin of the American Meteorological Society, 78, 2771-2777.
niño4Area-averaged SST anomalies (in Celsius) computed over 5°S:5°N, 160°E:150°W. Red/blue shading denotes positive/negative departures from the best-fit linear trend line.
NPI (North Pacific PSL Index)Winter (December-March) average PSL anomalies (in hPa) area-averaged over 30°:65°N, 160°E:140°W. Based on Trenberth, K. E. and J. W. Hurrell, 1994: Decadal atmosphere-ocean variations in the Pacific, Climate Dynamics, 9, 303-319.
Indian Ocean SST DipoleDefined as the difference between area-averaged SST anomalies (in Celsius) computed over 10°S:10°N, 50:70°E and area-averaged SST anomalies computed over 0:10°S, 90:110°E. Red/blue shading denotes positive/negative departures from the best-fit linear trend line. See: Saji N.H., Goswami B.N., Vinayachandran P.N., Yamagata T., 1999: A dipole mode in the tropical Indian Ocean, Nature, 401, 360-363.
Tropical Indian Ocean SSTArea-averaged SST anomalies (in Celsius) computed over 15°S:15°N, 40:110°E. Red/blue shading denotes positive/negative departures from the best-fit linear trend line.
Southern Ocean SSTArea-averaged SST anomalies (in Celsius) computed over 50°:70°S, 0:360°E. Red/blue shading denotes positive/negative departures from the best-fit linear trend line.
" + txt(107) = "" + + txt(112) = "
Created "+systemfunc("date") + txt(113) = "

CVDP Version "+VERSION+"

" + txt(114) = "" + + tt = ind(.not.ismissing(txt)) + txt2 = txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"methodology.html",txt2) + delete([/tt,txt,txt2/]) +;---------------------------------------------------------------------------- +;-- Create metrics webpage +;---------------------------------------------------------------------------- + if (isfilepresent2(OUTDIR+"metrics.txt")) then + txt = new(500,"string") + quote = str_get_dq() + + txt(0) = "Climate Variability Diagnostics Package" + txt(1) = "" + txt(2) = "" + txt(3) = "" + txt(4) = "" + + txt(5) = "" + txt(15) = "+quote+" + txt(16)= "" + txt(17) = "" + txt(18) = "

Back to Diagnostics Plots

"+webtitle+"


Metrics Table

" + + z = asciiread(OUTDIR+"metrics.txt",(/-1/),"string") + nlines = dimsizes(z) + txt(24) = "
"
+     do gg = 0,nlines-1
+        txt(25+gg) = z(gg)
+     end do
+     txt(25+nlines) = "
" + txt(25+nlines+1) = "

Observations Used

" + txt(25+nlines+2) = "Created "+systemfunc("date") + txt(25+nlines+3) = "

CVDP Version "+VERSION+"

" + + tt = ind(.not.ismissing(txt)) + txt2 = txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"metrics.html",txt2) + delete([/txt,txt2,tt/]) + end if + if (isfilepresent2(OUTDIR+"metrics.table_1.gif")) then ; create sorted metrics table pages + txt = new(500,"string") + quote = str_get_dq() + + txt(0) = "Climate Variability Diagnostics Package" + txt(1) = "" + txt(2) = "" + txt(3) = "" + txt(4) = "" + + txt(5) = "" + txt(15) = "+quote+" + txt(16)= "" + + + sort_txt = (/"Namelist (default) | ","Namelist (Alphabetically) | ","ENSO TAS | ","ENSO PSL | ", \ + "El Niño Hovmöller
","La Niña Hovmöller | ","AMO | ","PDO | ", \ + "NAM | ","SAM | ","SST std dev | ","PSL std dev | ", \ + "PR std dev | ","Mean Score"/) + sort_txt2 = (/"Namelist (default)","Namelist (Alphabetically)","ENSO TAS","ENSO PSL","El Niño Hovmöller","La Niña Hovmöller","AMO","PDO","NAM","SAM","SST std dev","PSL std dev","PR std dev","Mean Score"/) + + sort_txtA = (/"Namelist (default) | ","Namelist (Alphabetically) | ","ENSO TAS | ","ENSO PSL | ", \ + "El Niño Hovmöller
","La Niña Hovmöller | ","AMO | ","PDO | ", \ + "NAM | ","SAM | ","SST std dev | ","PSL std dev | ", \ + "PR std dev | ","Mean Score"/) + + strarr = new(14,string) + strarr = " | " + strarr(13) = " " + do gg = 0,13 + txt(17) = "" + txt(18) = "

Go to:

Methodology and Definitions
Diagnostics Plots
RMS Metric Tables

"+webtitle+"


" + sort_txtT = sort_txt + sort_txtT(gg) = ""+sort_txt2(gg)+""+strarr(gg) + txt(24) = "

Pattern Correlation Metrics Tables

" + txt(25) = "
Sort By:"+str_concat(sort_txtT)+"
" + txt(26) = "" + txt(27) = "

Observations Used

" + txt(28) = "Created "+systemfunc("date") + txt(29) = "

CVDP Version "+VERSION+"

" + tt = ind(.not.ismissing(txt)) + txt2 = txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"metrics.table_"+gg+".html",txt2) + delete([/txt2,tt,sort_txtT/]) + end do + + + do gg = 0,13 + txt(17) = "

Go to:

Methodology and Definitions
Diagnostics Plots
Pattern Correlation Metric Tables" + txt(18) = "

"+webtitle+"


" + sort_txtT = sort_txtA + sort_txtT(gg) = ""+sort_txt2(gg)+""+strarr(gg) + txt(24) = "

RMS Metrics Tables

" + txt(25) = "
Sort By:"+str_concat(sort_txtT)+"
" + txt(26) = "" + txt(27) = "

Observations Used

" + txt(28) = "Created "+systemfunc("date") + txt(29) = "

CVDP Version "+VERSION+"

" + tt = ind(.not.ismissing(txt)) + txt2 = txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"metrics.table_"+(gg+14)+".html",txt2) + delete([/txt2,tt/]) + end do + delete([/txt,strarr/]) + end if +;---------------------------------------------------------------------------- +; Namelist pages + txt := new(500,"string") + + txt(0) = "Climate Variability Diagnostics Package" + txt(25) = "+quote+" + txt(26)= "" + txt(27) = "

Go to:

Diagnostics Plots

" + + namelist_obs_qtxt = "Input Namelists: " + if (OBS.eq."True") then + txt(28) = "Input Namelists: Observations | Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Input Namelist: Observations

" + z := asciiread(OUTDIR+"namelist_obs",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_obs.html",txt2) + + namelist_obs_qtxt = "Input Namelists: Observations | " + end if + txt(28:) = txt@_FillValue + + txt(28) = namelist_obs_qtxt+"Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Input Namelist: Simulations

" + z := asciiread(OUTDIR+"namelist",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_simulations.html",txt2) + txt(28:) = txt@_FillValue + + txt(28) = namelist_obs_qtxt+"Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Derived Namelist: MSFTMZ

" + z := asciiread(OUTDIR+"namelist_moc",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_msftmz.html",txt2) + + txt(28) = namelist_obs_qtxt+"Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Derived Namelist: PR

" + z := asciiread(OUTDIR+"namelist_prect",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_pr.html",txt2) + + txt(28) = namelist_obs_qtxt+"Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Derived Namelist: PSL

" + z := asciiread(OUTDIR+"namelist_psl",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_psl.html",txt2) + + txt(28) = namelist_obs_qtxt+"Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Derived Namelist: SICONC NH

" + z := asciiread(OUTDIR+"namelist_aice_nh",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_siconc_nh.html",txt2) + + txt(28) = namelist_obs_qtxt+"Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Derived Namelist: SICONC SH

" + z := asciiread(OUTDIR+"namelist_aice_sh",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_siconc_sh.html",txt2) + + txt(28) = namelist_obs_qtxt+"Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Derived Namelist: SND

" + z := asciiread(OUTDIR+"namelist_snowdp",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_snd.html",txt2) + + txt(28) = namelist_obs_qtxt+"Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Derived Namelist: TAS

" + z := asciiread(OUTDIR+"namelist_trefht",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_tas.html",txt2) + + txt(28) = namelist_obs_qtxt+"Simulations
" + txt(29) = "Derived Namelists: MSFTMZ | PR | PSL | " + txt(30) = "
SICONC NH | SICONC SH | SND | TAS |" + txt(31) = "TS

"+webtitle+"


" + txt(32) = "

Derived Namelist: TS

" + z := asciiread(OUTDIR+"namelist_ts",(/-1/),"string") + nlines = dimsizes(z) + txt(33) = "

" + do gg = 0,nlines-1 + txt(33+gg) = z(gg)+"
" + end do + txt(34+nlines) = "

" + txt(34+nlines+1) = "Created "+systemfunc("date") + txt(34+nlines+2) = "

CVDP Version "+VERSION+"

" + tt := ind(.not.ismissing(txt)) + txt2 := txt(:tt(dimsizes(tt)-1)+1) + txt2 = where(ismissing(txt2),"",txt2) + asciiwrite(OUTDIR+"namelist_ts.html",txt2) + + print("Finished: webpage.ncl") +end + + diff --git a/lib/plotting_functions.py b/lib/plotting_functions.py index 08de58860..99ad2aa17 100644 --- a/lib/plotting_functions.py +++ b/lib/plotting_functions.py @@ -3,28 +3,6 @@ Functions --------- -load_dataset() - generalized load dataset method used for plotting/analysis functions -use_this_norm() - switches matplotlib color normalization method -get_difference_colors(values) - Provide a color norm and colormap assuming `values` is a difference field. -mask_land_or_ocean(arr, msk, use_nan=False) - Apply a land or ocean mask to provided variable. -get_central_longitude(*args) - Determine central longitude for maps. -global_average(fld, wgt, verbose=False) - pure numpy global average. -spatial_average(indata, weights=None, spatial_dims=None) - Compute spatial average -wgt_rmse(fld1, fld2, wgt): - Calculate the area-weighted RMSE. -annual_mean(data, whole_years=False, time_name='time'): - Calculate annual averages from time series data. -seasonal_mean(data, season=None, is_climo=None): - Calculates the time-weighted seasonal average (or average over all time). -domain_stats(data, domain): - Provides statistics in specified region. make_polar_plot(wks, case_nickname, base_nickname, case_climo_yrs, baseline_climo_yrs, d1:xr.DataArray, d2:xr.DataArray, difference:Optional[xr.DataArray]=None, @@ -40,22 +18,6 @@ case_climo_yrs, baseline_climo_yrs, mdlfld, obsfld, diffld, **kwargs): Map plots of `mdlfld`, `obsfld`, and their difference, `diffld`. -pres_from_hybrid(psfc, hya, hyb, p0=100000.): - Converts a hybrid level to a pressure -vert_remap(x_mdl, p_mdl, plev) - Interpolates to specified pressure levels. -lev_to_plev(data, ps, hyam, hybm, P0=100000., new_levels=None, convert_to_mb=False) - Interpolate model hybrid levels to specified pressure levels. -pmid_to_plev(data, pmid, new_levels=None, convert_to_mb=False) - Interpolate `data` from hybrid-sigma levels to isobaric levels using provided mid-level pressures. -zonal_mean_xr(fld) - Average over all dimensions except `lev` and `lat`. -validate_dims(fld, list_of_dims) - Checks if specified dimensions are in a DataArray -lat_lon_validate_dims(fld) - Check if input field has lat and lon. -zm_validate_dims(fld) - Check for dimensions for zonal average. zonal_plot(lat, data, ax=None, color=None, **kwargs) Make a line plot or pressure-latitude plot of `data`. meridional_plot(lon, data, ax=None, color=None, **kwargs) @@ -68,48 +30,27 @@ meridioanl mean plot square_contour_difference Produce filled contours of fld1, fld2, and their difference with square axes. - -Notes ------ -This module includes several "private" methods intended for internal use only. - -_plot_line(axobject, xdata, ydata, color, **kwargs) - Create a generic line plot -_meridional_plot_line - -_zonal_plot_line - -_zonal_plot_preslat - -_meridional_plot_preslon - """ #import statements: from typing import Optional import numpy as np import xarray as xr -import pandas as pd import matplotlib as mpl import cartopy.crs as ccrs #nice formatting for tick labels from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter from cartopy.util import add_cyclic_point -import geocat.comp as gcomp from mpl_toolkits.axes_grid1.inset_locator import inset_axes from matplotlib.lines import Line2D -import matplotlib.cm as cm -from adf_diag import AdfDiag from adf_base import AdfError - -import warnings # use to warn user about missing files. +import plotting_utils as plot_utils +import adf_utils as utils #Format warning messages: -def my_formatwarning(msg, *args, **kwargs): - """Issue `msg` as warning.""" - return str(msg) + '\n' -warnings.formatwarning = my_formatwarning +import warnings # use to warn user about missing files. +warnings.formatwarning = utils.my_formatwarning #Set non-X-window backend for matplotlib: mpl.use('Agg') @@ -136,8 +77,6 @@ def my_formatwarning(msg, *args, **kwargs): def load_dataset(fils): """ - This method exists to get an xarray Dataset from input file information that can be passed into the plotting methods. - Parameters ---------- fils : list @@ -149,17 +88,15 @@ def load_dataset(fils): Notes ----- - When just one entry is provided, use `open_dataset`, otherwise `open_mfdatset` + When just one entry is provided, use `open_dataset`, otherwise `open_mfdataset` """ if len(fils) == 0: - warnings.warn(f"\t WARNING: Input file list is empty.") + warnings.warn("\t WARNING: Input file list is empty.") return None elif len(fils) > 1: - return xr.open_mfdataset(fils, combine='by_coords') + return xr.open_mfdataset(fils, combine="by_coords") else: return xr.open_dataset(fils[0]) - #End if -#End def def use_this_norm(): """Just use the right normalization; avoids a deprecation warning.""" @@ -176,7 +113,6 @@ def use_this_norm(): def get_difference_colors(values): """Provide a color norm and colormap assuming this is a difference field. - Parameters ---------- values : array-like @@ -551,7 +487,6 @@ def seasonal_mean(data, season=None, is_climo=None): assert ((12 in data.shape) and (data.shape.count(12) == 1)), f"Sorry, {data.shape.count(12)} dimensions have size 12, making determination of which dimension is month ambiguous. Please provide a `time` or `month` dimension." time_dim_num = data.shape.index(12) fakedims = [f"dim{n}" for n in range(len(data.shape))] - fakedims[time_dim_num] = "time" data = xr.DataArray(data, dims=fakedims, attrs=data.attrs) timefix = pd.date_range(start='1/1/1999', end='12/1/1999', freq='MS') # generic time coordinate from a non-leap-year data = data.assign_coords({"time":timefix}) @@ -603,10 +538,18 @@ def domain_stats(data, domain): x_region_max = x_region.max().item() return x_region_mean, x_region_max, x_region_min -def make_polar_plot(wks, case_nickname, base_nickname, - case_climo_yrs, baseline_climo_yrs, - d1:xr.DataArray, d2:xr.DataArray, difference:Optional[xr.DataArray]=None,pctchange:Optional[xr.DataArray]=None, - domain:Optional[list]=None, hemisphere:Optional[str]=None, obs=False, **kwargs): +def make_polar_plot(wks, case_nickname, + base_nickname, + case_climo_yrs, + baseline_climo_yrs, + d1:xr.DataArray, + d2:xr.DataArray, + difference:Optional[xr.DataArray]=None, + pctchange:Optional[xr.DataArray]=None, + domain:Optional[list]=None, + hemisphere:Optional[str]=None, + obs=False, + **kwargs): """Make a stereographic polar plot for the given data and hemisphere. @@ -676,23 +619,23 @@ def make_polar_plot(wks, case_nickname, base_nickname, domain = [-180, 180, -90, -45] # statistics for annotation (these are scalars): - d1_region_mean, d1_region_max, d1_region_min = domain_stats(d1, domain) - d2_region_mean, d2_region_max, d2_region_min = domain_stats(d2, domain) - dif_region_mean, dif_region_max, dif_region_min = domain_stats(dif, domain) - pct_region_mean, pct_region_max, pct_region_min = domain_stats(pct, domain) + d1_region_mean, d1_region_max, d1_region_min = utils.domain_stats(d1, domain) + d2_region_mean, d2_region_max, d2_region_min = utils.domain_stats(d2, domain) + dif_region_mean, dif_region_max, dif_region_min = utils.domain_stats(dif, domain) + pct_region_mean, pct_region_max, pct_region_min = utils.domain_stats(pct, domain) #downsize to the specified region; makes plotting/rendering/saving much faster d1 = d1.sel(lat=slice(domain[2],domain[3])) d2 = d2.sel(lat=slice(domain[2],domain[3])) dif = dif.sel(lat=slice(domain[2],domain[3])) pct = pct.sel(lat=slice(domain[2],domain[3])) - + # add cyclic point to the data for better-looking plot d1_cyclic, lon_cyclic = add_cyclic_point(d1, coord=d1.lon) d2_cyclic, _ = add_cyclic_point(d2, coord=d2.lon) # since we can take difference, assume same longitude coord. dif_cyclic, _ = add_cyclic_point(dif, coord=dif.lon) pct_cyclic, _ = add_cyclic_point(pct, coord=pct.lon) - + # -- deal with optional plotting arguments that might provide variable-dependent choices # determine levels & color normalization: @@ -708,17 +651,23 @@ def make_polar_plot(wks, case_nickname, base_nickname, if 'contour_levels' in kwargs: levels1 = kwargs['contour_levels'] - norm1 = mpl.colors.Normalize(vmin=min(levels1), vmax=max(levels1)) + if 'log_normal' in kwargs: ## ADA + norm1 = mpl.colors.LogNorm(vmin=min(levels1), vmax=max(levels1)) ##ADA + else: + norm1 = mpl.colors.Normalize(vmin=min(levels1), vmax=max(levels1)) elif 'contour_levels_range' in kwargs: assert len(kwargs['contour_levels_range']) == 3, "contour_levels_range must have exactly three entries: min, max, step" levels1 = np.arange(*kwargs['contour_levels_range']) - norm1 = mpl.colors.Normalize(vmin=min(levels1), vmax=max(levels1)) + if 'log_normal' in kwargs: ## ADA + norm1 = mpl.colors.LogNorm(vmin=min(levels1), vmax=max(levels1)) ## ADA + else: + norm1 = mpl.colors.Normalize(vmin=min(levels1), vmax=max(levels1)) else: levels1 = np.linspace(minval, maxval, 12) norm1 = mpl.colors.Normalize(vmin=minval, vmax=maxval) if ('colormap' not in kwargs) and ('contour_levels' not in kwargs): - norm1, cmap1 = get_difference_colors(levels1) # maybe these are better defaults if nothing else is known. + norm1, cmap1 = plot_utils.get_difference_colors(levels1) # maybe these are better defaults if nothing else is known. if "diff_contour_levels" in kwargs: levelsdiff = kwargs["diff_contour_levels"] # a list of explicit contour levels @@ -727,7 +676,7 @@ def make_polar_plot(wks, case_nickname, base_nickname, levelsdiff = np.arange(*kwargs['diff_contour_range']) else: # set levels for difference plot (with a symmetric color bar): - levelsdiff = np.linspace(-1*absmaxdif, absmaxdif, 12) + levelsdiff = np.linspace(-1*absmaxdif.data, absmaxdif.data, 12) #End if if "pct_diff_contour_levels" in kwargs: @@ -758,7 +707,7 @@ def make_polar_plot(wks, case_nickname, base_nickname, #End if if max(np.abs(levelsdiff)) > 10*absmaxdif: - levelsdiff = np.linspace(-1*absmaxdif, absmaxdif, 12) + levelsdiff = np.linspace(-1*absmaxdif.data, absmaxdif.data, 12) #End if @@ -767,9 +716,9 @@ def make_polar_plot(wks, case_nickname, base_nickname, # Difference options -- Check in kwargs for colormap and levels if "diff_colormap" in kwargs: cmapdiff = kwargs["diff_colormap"] - dnorm, _ = get_difference_colors(levelsdiff) # color map output ignored + dnorm, _ = plot_utils.get_difference_colors(levelsdiff) # color map output ignored else: - dnorm, cmapdiff = get_difference_colors(levelsdiff) + dnorm, cmapdiff = plot_utils.get_difference_colors(levelsdiff) # Pct Difference options -- Check in kwargs for colormap and levels if "pct_diff_colormap" in kwargs: @@ -779,8 +728,7 @@ def make_polar_plot(wks, case_nickname, base_nickname, #End if # -- end options - - lons, lats = np.meshgrid(lon_cyclic, d1.lat) + lons, lats = plot_utils.transform_coordinates_for_projection(proj, lon_cyclic, d1.lat) # Explicit coordinate transform fig = plt.figure(figsize=(10,10)) gs = mpl.gridspec.GridSpec(2, 4, wspace=0.9) @@ -794,43 +742,65 @@ def make_polar_plot(wks, case_nickname, base_nickname, levs_diff = np.unique(np.array(levelsdiff)) levs_pctdiff = np.unique(np.array(levelspctdiff)) +# def safe_contourf_or_pcolormesh(ax, lons, lats, data, cmap, norm, levels=None, extend="both", transform=None): +# try: +# img = ax.contourf(lons, lats, data, levels=levels, cmap=cmap, norm=norm, extend=extend, transform=transform) +# except Exception as e: +# print(f"[contourf failed: {e}] Switching to pcolormesh.") +# for coll in list(ax.collections): +# coll.remove() +# img = ax.pcolormesh(lons, lats, data, cmap=cmap, norm=norm, transform=transform) +# return img + +# if len(levs) < 2: +# img1 = ax1.contourf(lons, lats, d1_cyclic, transform=ccrs.PlateCarree(), colors="w", norm=norm1, extend = "both") +# ax1.text(0.4, 0.4, empty_message, transform=ax1.transAxes, bbox=props) + +# img2 = ax2.contourf(lons, lats, d2_cyclic, transform=ccrs.PlateCarree(), colors="w", norm=norm1, extend = "both") +# ax2.text(0.4, 0.4, empty_message, transform=ax2.transAxes, bbox=props) +# else: +# img1 = ax1.contourf(lons, lats, d1_cyclic, transform=ccrs.PlateCarree(), cmap=cmap1, norm=norm1, levels=levels1, extend = "both") +# #img2 = ax2.contourf(lons, lats, d2_cyclic, transform=ccrs.PlateCarree(), cmap=cmap1, norm=norm1, levels=levels1, extend = "both") +# img2 = safe_contourf_or_pcolormesh(ax2, lons, lats, d2_cyclic,transform=ccrs.PlateCarree(), cmap=cmap1, norm=norm1, levels=levels1, extend="both", ) + + # BPM: removing `transform=ccrs.PlateCarree()` from contourf calls & transform_first=True if len(levs) < 2: - img1 = ax1.contourf(lons, lats, d1_cyclic, transform=ccrs.PlateCarree(), colors="w", norm=norm1) + img1 = ax1.contourf(lons, lats, d1_cyclic, colors="w", norm=norm1) ax1.text(0.4, 0.4, empty_message, transform=ax1.transAxes, bbox=props) - img2 = ax2.contourf(lons, lats, d2_cyclic, transform=ccrs.PlateCarree(), colors="w", norm=norm1) + img2 = ax2.contourf(lons, lats, d2_cyclic, colors="w", norm=norm1) ax2.text(0.4, 0.4, empty_message, transform=ax2.transAxes, bbox=props) else: - img1 = ax1.contourf(lons, lats, d1_cyclic, transform=ccrs.PlateCarree(), cmap=cmap1, norm=norm1, levels=levels1) - img2 = ax2.contourf(lons, lats, d2_cyclic, transform=ccrs.PlateCarree(), cmap=cmap1, norm=norm1, levels=levels1) + img1 = ax1.contourf(lons, lats, d1_cyclic, cmap=cmap1, norm=norm1, levels=levels1) + img2 = ax2.contourf(lons, lats, d2_cyclic, cmap=cmap1, norm=norm1, levels=levels1) if len(levs_pctdiff) < 2: - img3 = ax3.contourf(lons, lats, pct_cyclic, transform=ccrs.PlateCarree(), colors="w", norm=pctnorm, transform_first=True) + img3 = ax3.contourf(lons, lats, pct_cyclic, colors="w", norm=pctnorm) ax3.text(0.4, 0.4, empty_message, transform=ax3.transAxes, bbox=props) else: - img3 = ax3.contourf(lons, lats, pct_cyclic, transform=ccrs.PlateCarree(), cmap=cmappct, norm=pctnorm, levels=levelspctdiff, transform_first=True) + img3 = ax3.contourf(lons, lats, pct_cyclic, cmap=cmappct, norm=pctnorm, levels=levelspctdiff) if len(levs_diff) < 2: - img4 = ax4.contourf(lons, lats, dif_cyclic, transform=ccrs.PlateCarree(), colors="w", norm=dnorm) + img4 = ax4.contourf(lons, lats, dif_cyclic, colors="w", norm=dnorm) ax4.text(0.4, 0.4, empty_message, transform=ax4.transAxes, bbox=props) else: - img4 = ax4.contourf(lons, lats, dif_cyclic, transform=ccrs.PlateCarree(), cmap=cmapdiff, norm=dnorm, levels=levelsdiff) + img4 = ax4.contourf(lons, lats, dif_cyclic, cmap=cmapdiff, norm=dnorm, levels=levelsdiff) #Set Main title for subplots: st = fig.suptitle(wks.stem[:-5].replace("_"," - "), fontsize=18) st.set_y(0.95) #Set plot titles - case_title = "$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" + case_title = r"$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" ax1.set_title(case_title, loc='left', fontsize=6) #fontsize=tiFontSize if obs: obs_var = kwargs["obs_var_name"] obs_title = kwargs["obs_file"][:-3] - base_title = "$\mathbf{Baseline}:$"+obs_title+"\n"+"$\mathbf{Variable}:$"+f"{obs_var}" + base_title = r"$\mathbf{Baseline}:$"+obs_title+"\n"+r"$\mathbf{Variable}:$"+f"{obs_var}" ax2.set_title(base_title, loc='left', fontsize=6) #fontsize=tiFontSize else: - base_title = "$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" + base_title = r"$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" ax2.set_title(base_title, loc='left', fontsize=6) ax1.text(-0.2, -0.10, f"Mean: {d1_region_mean:5.2f}\nMax: {d1_region_max:5.2f}\nMin: {d1_region_min:5.2f}", transform=ax1.transAxes) @@ -841,7 +811,7 @@ def make_polar_plot(wks, case_nickname, base_nickname, ax3.set_title("Test % diff Baseline", loc='left', fontsize=8) ax4.text(-0.2, -0.10, f"Mean: {dif_region_mean:5.2f}\nMax: {dif_region_max:5.2f}\nMin: {dif_region_min:5.2f}", transform=ax4.transAxes) - ax4.set_title("$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=8) + ax4.set_title(r"$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=8) if "units" in kwargs: ax2.set_ylabel(kwargs["units"]) @@ -902,6 +872,7 @@ def make_polar_plot(wks, case_nickname, base_nickname, # Close figures to avoid memory issues: plt.close(fig) + ####### def plot_map_vect_and_save(wks, case_nickname, base_nickname, @@ -1067,29 +1038,29 @@ def plot_map_vect_and_save(wks, case_nickname, base_nickname, st.set_y(0.85) #Set plot titles - case_title = "$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" + case_title = r"$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" ax[0].set_title(case_title, loc='left', fontsize=tiFontSize) if obs: obs_var = kwargs["obs_var_name"] obs_title = kwargs["obs_file"][:-3] - base_title = "$\mathbf{Baseline}:$"+obs_title+"\n"+"$\mathbf{Variable}:$"+f"{obs_var}" + base_title = r"$\mathbf{Baseline}:$"+obs_title+"\n"+r"$\mathbf{Variable}:$"+f"{obs_var}" ax[1].set_title(base_title, loc='left', fontsize=tiFontSize) else: - base_title = "$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" + base_title = r"$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" ax[1].set_title(base_title, loc='left', fontsize=tiFontSize) #Set stats: area_avg ax[0].set_title(f"Mean: {mdl_mag.weighted(wgt).mean().item():5.2f}\nMax: {mdl_mag.max():5.2f}\nMin: {mdl_mag.min():5.2f}", loc='right', fontsize=tiFontSize) - ax[1].set_title(f"Mean: {obs_mag.weighted(wgt).mean().item():5.2f}\nMax: {obs_mag.max():5.2f}\nMin: {mdl_mag.min():5.2f}", loc='right', + ax[1].set_title(f"Mean: {obs_mag.weighted(wgt).mean().item():5.2f}\nMax: {obs_mag.max():5.2f}\nMin: {obs_mag.min():5.2f}", loc='right', fontsize=tiFontSize) - ax[-1].set_title(f"Mean: {diff_mag.weighted(wgt).mean().item():5.2f}\nMax: {diff_mag.max():5.2f}\nMin: {mdl_mag.min():5.2f}", loc='right', + ax[-1].set_title(f"Mean: {diff_mag.weighted(wgt).mean().item():5.2f}\nMax: {diff_mag.max():5.2f}\nMin: {diff_mag.min():5.2f}", loc='right', fontsize=tiFontSize) # set rmse title: ax[-1].set_title(f"RMSE: ", fontsize=tiFontSize) - ax[-1].set_title("$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=tiFontSize) + ax[-1].set_title(r"$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=tiFontSize) if "units" in kwargs: ax[1].set_ylabel(f"[{kwargs['units']}]") @@ -1218,9 +1189,9 @@ def plot_map_and_save(wks, case_nickname, base_nickname, # get statistics (from non-wrapped) fields = (mdlfld, obsfld, diffld, pctld) - area_avg = [spatial_average(x, weights=wgt, spatial_dims=None) for x in fields] + area_avg = [utils.spatial_average(x, weights=wgt, spatial_dims=None) for x in fields] - d_rmse = wgt_rmse(mdlfld, obsfld, wgt) # correct weighted RMSE for (lat,lon) fields. + d_rmse = utils.wgt_rmse(mdlfld, obsfld, wgt) # correct weighted RMSE for (lat,lon) fields. # We should think about how to do plot customization and defaults. # Here I'll just pop off a few custom ones, and then pass the rest into mpl. @@ -1237,7 +1208,7 @@ def plot_map_and_save(wks, case_nickname, base_nickname, #End if # generate dictionary of contour plot settings: - cp_info = prep_contour_plot(mdlfld, obsfld, diffld, pctld, **kwargs) + cp_info = plot_utils.prep_contour_plot(mdlfld, obsfld, diffld, pctld, **kwargs) # specify the central longitude for the plot central_longitude = kwargs.get('central_longitude', 180) @@ -1264,6 +1235,19 @@ def plot_map_and_save(wks, case_nickname, base_nickname, dateline_direction_label=False) lat_formatter = LatitudeFormatter(number_format='0.0f', degree_symbol='') + + ## Just adding this to allow for LogNormal plotting: + if 'contour_levels' in kwargs: + levels1 = kwargs['contour_levels'] + if 'log_normal' in kwargs: ## ADA + norm1 = mpl.colors.LogNorm(vmin=min(levels1), vmax=max(levels1)) ##ADA + cp_info['norm1'] = norm1 + elif 'contour_levels_range' in kwargs: + assert len(kwargs['contour_levels_range']) == 3, "contour_levels_range must have exactly three entries: min, max, step" + levels1 = np.arange(*kwargs['contour_levels_range']) + if 'log_normal' in kwargs: ## ADA + norm1 = mpl.colors.LogNorm(vmin=min(levels1), vmax=max(levels1)) ## ADA + cp_info['norm1'] = norm1 for i, a in enumerate(wrap_fields): @@ -1285,7 +1269,8 @@ def plot_map_and_save(wks, case_nickname, base_nickname, img.append(ax[i].contourf(lons,lats,a,colors="w",transform=ccrs.PlateCarree(),transform_first=True)) ax[i].text(0.4, 0.4, empty_message, transform=ax[i].transAxes, bbox=props) else: - img.append(ax[i].contourf(lons, lats, a, levels=levels, cmap=cmap, norm=norm, transform=ccrs.PlateCarree(), transform_first=True, **cp_info['contourf_opt'])) + img.append(ax[i].contourf(lons, lats, a, levels=levels, cmap=cmap, norm=norm, transform=ccrs.PlateCarree(), + transform_first=True, extend = "both", **cp_info['contourf_opt'])) #End if ax[i].set_title("AVG: {0:.3f}".format(area_avg[i]), loc='right', fontsize=11) @@ -1300,16 +1285,16 @@ def plot_map_and_save(wks, case_nickname, base_nickname, st.set_y(0.85) #Set plot titles - case_title = "$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" + case_title = r"$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" ax[0].set_title(case_title, loc='left', fontsize=tiFontSize) if obs: obs_var = kwargs["obs_var_name"] obs_title = kwargs["obs_file"][:-3] - base_title = "$\mathbf{Baseline}:$"+obs_title+"\n"+"$\mathbf{Variable}:$"+f"{obs_var}" + base_title = r"$\mathbf{Baseline}:$"+obs_title+"\n"+r"$\mathbf{Variable}:$"+f"{obs_var}" ax[1].set_title(base_title, loc='left', fontsize=tiFontSize) else: - base_title = "$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" + base_title = r"$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" ax[1].set_title(base_title, loc='left', fontsize=tiFontSize) #Set stats: area_avg @@ -1324,7 +1309,7 @@ def plot_map_and_save(wks, case_nickname, base_nickname, # set rmse title: ax[3].set_title(f"RMSE: {d_rmse:.3f}", fontsize=tiFontSize) - ax[3].set_title("$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=tiFontSize) + ax[3].set_title(r"$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=tiFontSize) ax[2].set_title("Test % Diff Baseline", loc='left', fontsize=tiFontSize,fontweight="bold") for a in ax: @@ -1377,357 +1362,7 @@ def plot_map_and_save(wks, case_nickname, base_nickname, plt.close() -# -# -- vertical interpolation code -- -# - -def pres_from_hybrid(psfc, hya, hyb, p0=100000.): - """Calculates pressure field - - pressure derived with the formula: - ```p = a(k)*p0 + b(k)*ps``` - - Parameters - ---------- - psfc - surface pressure - hya, hyb - hybrid-sigma A and B coefficients - p0 : optional - reference pressure, defaults to 100000 Pa - - Returns - ------- - pressure, size is same as `psfc` with `len(hya)` levels - """ - return hya*p0 + hyb*psfc - -##### - -def vert_remap(x_mdl, p_mdl, plev): - """Apply simple 1-d interpolation to a field - - Parameters - ---------- - x_mdl : xarray.DataArray or numpy.ndarray - input data - p_mdl : xarray.DataArray or numpy.ndarray - pressure field, same shape as `x_mdl` - plev : xarray.DataArray or numpy.ndarray - the new pressures - - Returns - ------- - output - `x_mdl` interpolated to `plev` - - Notes - ----- - Interpolation done in log pressure - """ - - #Determine array shape of output array: - out_shape = (plev.shape[0], x_mdl.shape[1]) - - #Initialize interpolated output numpy array: - output = np.full(out_shape, np.nan) - - #Perform 1-D interpolation in log-space: - for i in range(out_shape[1]): - output[:,i] = np.interp(np.log(plev), np.log(p_mdl[:,i]), x_mdl[:,i]) - #End for - - #Return interpolated output: - return output - -##### - -def lev_to_plev(data, ps, hyam, hybm, P0=100000., new_levels=None, - convert_to_mb=False): - """Interpolate model hybrid levels to specified pressure levels. - - Parameters - ---------- - data : - ps : - surface pressure - hyam, hybm : - hybrid-sigma A and B coefficients - P0 : float, optional - reference pressure, defaults to 100000 Pa - new_levels : numpy.ndarray, optional - 1-D array containing pressure levels in Pascals (Pa). - If not specified, then the levels will be set - to the GeoCAT defaults, which are (in hPa): - `1000, 925, 850, 700, 500, 400, 300, 250, 200, 150, 100, 70, 50, - 30, 20, 10, 7, 5, 3, 2, 1` - convert_to_mb : bool, optional - If True, then vertical (lev) dimension will have - values of mb/hPa, otherwise the units are Pa. - - Returns - ------- - data_interp_rename - data interpolated to new pressure levels - - Notes - ----- - The function `interp_hybrid_to_pressure` used here is dask-enabled, - and so can potentially be sped-up via the use of a DASK cluster. - """ - - #Temporary print statement to notify users to ignore warning messages. - #This should be replaced by a debug-log stdout filter at some point: - print("Please ignore the interpolation warnings that follow!") - - #Apply GeoCAT hybrid->pressure interpolation: - if new_levels is not None: - data_interp = gcomp.interpolation.interp_hybrid_to_pressure(data, ps, - hyam, - hybm, - p0=P0, - new_levels=new_levels - ) - else: - data_interp = gcomp.interpolation.interp_hybrid_to_pressure(data, ps, - hyam, - hybm, - p0=P0 - ) - - # data_interp may contain a dask array, which can cause - # trouble downstream with numpy functions, so call compute() here. - if hasattr(data_interp, "compute"): - data_interp = data_interp.compute() - - #Rename vertical dimension back to "lev" in order to work with - #the ADF plotting functions: - data_interp_rename = data_interp.rename({"plev": "lev"}) - - #Convert vertical dimension to mb/hPa, if requested: - if convert_to_mb: - data_interp_rename["lev"] = data_interp_rename["lev"] / 100.0 - - return data_interp_rename - -##### - -def pmid_to_plev(data, pmid, new_levels=None, convert_to_mb=False): - """Interpolate data from hybrid-sigma levels to isobaric levels. - - Parameters - ---------- - data : xarray.DataArray - field with a 'lev' coordinate - pmid : xarray.DataArray - the pressure field (Pa), same shape as `data` - new_levels : optional - the output pressure levels (Pa), defaults to standard levels - convert_to_mb : bool, optional - flag to convert output to mb (i.e., hPa), defaults to False - - Returns - ------- - output : xarray.DataArray - `data` interpolated onto `new_levels` - """ - - # determine pressure levels to interpolate to: - if new_levels is None: - pnew = 100.0 * np.array([1000, 925, 850, 700, 500, 400, - 300, 250, 200, 150, 100, 70, 50, - 30, 20, 10, 7, 5, 3, 2, 1]) # mandatory levels, converted to Pa - else: - pnew = new_levels - #End if - - # save name of DataArray: - data_name = data.name - - # reshape data and pressure assuming "lev" is the name of the coordinate - zdims = [i for i in data.dims if i != 'lev'] - dstack = data.stack(z=zdims) - pstack = pmid.stack(z=zdims) - output = vert_remap(dstack.values, pstack.values, pnew) - output = xr.DataArray(output, name=data_name, dims=("lev", "z"), - coords={"lev":pnew, "z":pstack['z']}) - output = output.unstack() - - # convert vertical dimension to mb/hPa, if requested: - if convert_to_mb: - output["lev"] = output["lev"] / 100.0 - #End if - - #Return interpolated output: - return output - -# -# -- zonal & meridional mean code -- -# - -def zonal_mean_xr(fld): - """Average over all dimensions except `lev` and `lat`.""" - if isinstance(fld, xr.DataArray): - d = fld.dims - davgovr = [dim for dim in d if dim not in ('lev','lat')] - else: - raise IOError("zonal_mean_xr requires Xarray DataArray input.") - return fld.mean(dim=davgovr) - - -def validate_dims(fld, list_of_dims): - """Check if specified dimensions are in a DataArray. - - Parameters - ---------- - fld : xarray.DataArray - field to check for named dimensions - list_of_dims : list - list of strings that specifiy the dimensions to check for - - Returns - ------- - dict - dict with keys that are "has_{x}" where x is the name from - `list_of_dims` and values that are boolean - - """ - if not isinstance(list_of_dims, list): - list_of_dims = list(list_of_dims) - return { "_".join(["has",f"{v}"]):(v in fld.dims) for v in list_of_dims} - - -def lat_lon_validate_dims(fld): - """Check if input field has lat and lon. - - Parameters - ---------- - fld : xarray.DataArray - data with named dimensions - - Returns - ------- - bool - True if lat and lon are both dimensions, False otherwise. - - See Also - -------- - validate_dims - """ - # note: we can only handle variables that reduce to (lat,lon) - if len(fld.dims) > 3: - return False - validate = validate_dims(fld, ['lat','lon']) - if not all(validate.values()): - return False - else: - return True - - -def zm_validate_dims(fld): - """Check for dimensions for zonal average. - - Looks for dimensions called 'lev' and 'lat'. - - - Parameters - ---------- - fld : xarray.DataArray - field to check for lat and/or lev dimensions - Returns - ------- - tuple - (has_lat, has_lev) each are bool - None - If 'lat' is not in dimensions, returns None. - """ - # note: we can only handle variables that reduce to (lev, lat) or (lat,) - if len(fld.dims) > 4: - print(f"Sorry, too many dimensions: {fld.dims}") - return None - validate = validate_dims(fld, ['lev','lat']) - has_lev, has_lat = validate['has_lev'], validate['has_lat'] - return has_lat, has_lev - -def _plot_line(axobject, xdata, ydata, color, **kwargs): - """Create a generic line plot and check for some ways to annotate.""" - - if color != None: - axobject.plot(xdata, ydata, c=color, **kwargs) - else: - axobject.plot(xdata, ydata, **kwargs) - - #Set Y-axis label: - if hasattr(ydata, "units"): - axobject.set_ylabel("[{units}]".format(units=getattr(ydata,"units"))) - elif "units" in kwargs: - axobject.set_ylabel("[{units}]".format(kwargs["units"])) - #End if - - return axobject - -def _meridional_plot_line(ax, lon, data, color, **kwargs): - """Create line plot with longitude as the X-axis.""" - - ax = _plot_line(ax, lon, data, color, **kwargs) - ax.set_xlim([lon.min(), lon.max()]) - # - # annotate - # - ax.set_xlabel("LONGITUDE") - if hasattr(data, "units"): - ax.set_ylabel("{units}".format(units=getattr(data,"units"))) - elif "units" in kwargs: - ax.set_ylabel("{units}".format(kwargs["units"])) - return ax - -def _zonal_plot_line(ax, lat, data, color, **kwargs): - """Create line plot with latitude as the X-axis.""" - ax = _plot_line(ax, lat, data, color, **kwargs) - ax.set_xlim([max([lat.min(), -90.]), min([lat.max(), 90.])]) - # - # annotate - # - ax.set_xlabel("LATITUDE") - if hasattr(data, "units"): - ax.set_ylabel("{units}".format(units=getattr(data,"units"))) - elif "units" in kwargs: - ax.set_ylabel("{units}".format(kwargs["units"])) - return ax - -def _zonal_plot_preslat(ax, lat, lev, data, **kwargs): - """Create plot with latitude as the X-axis, and pressure as the Y-axis.""" - mlev, mlat = np.meshgrid(lev, lat) - if 'cmap' in kwargs: - cmap = kwargs.pop('cmap') - else: - cmap = 'Spectral_r' - - img = ax.contourf(mlat, mlev, data.transpose('lat', 'lev'), cmap=cmap, **kwargs) - - minor_locator = mpl.ticker.FixedLocator(lev) - ax.yaxis.set_minor_locator(minor_locator) - ax.tick_params(which='minor', length=4, color='r') - ax.set_ylim([np.max(lev), np.min(lev)]) - return img, ax - - -def _meridional_plot_preslon(ax, lon, lev, data, **kwargs): - """Create plot with longitude as the X-axis, and pressure as the Y-axis.""" - - mlev, mlon = np.meshgrid(lev, lon) - if 'cmap' in kwargs: - cmap = kwargs.pop('cmap') - else: - cmap = 'Spectral_r' - - img = ax.contourf(mlon, mlev, data.transpose('lon', 'lev'), cmap=cmap, **kwargs) - - minor_locator = mpl.ticker.FixedLocator(lev) - ax.yaxis.set_minor_locator(minor_locator) - ax.tick_params(which='minor', length=4, color='r') - ax.set_ylim([np.max(lev), np.min(lev)]) - return img, ax +####### def zonal_plot(lat, data, ax=None, color=None, **kwargs): """Make zonal plot @@ -1756,10 +1391,10 @@ def zonal_plot(lat, data, ax=None, color=None, **kwargs): if ax is None: ax = plt.gca() if 'lev' in data.dims: - img, ax = _zonal_plot_preslat(ax, lat, data['lev'], data, **kwargs) + img, ax = plot_utils.zonal_plot_preslat(ax, lat, data['lev'], data, **kwargs) return img, ax else: - ax = _zonal_plot_line(ax, lat, data, color, **kwargs) + ax = plot_utils.zonal_plot_line(ax, lat, data, color, **kwargs) return ax def meridional_plot(lon, data, ax=None, color=None, **kwargs): @@ -1790,184 +1425,18 @@ def meridional_plot(lon, data, ax=None, color=None, **kwargs): if ax is None: ax = plt.gca() if 'lev' in data.dims: - img, ax = _meridional_plot_preslon(ax, lon, data['lev'], data, **kwargs) + img, ax = plot_utils.meridional_plot_preslon(ax, lon, data['lev'], data, **kwargs) return img, ax else: - ax = _meridional_plot_line(ax, lon, data, color, **kwargs) + ax = plot_utils.meridional_plot_line(ax, lon, data, color, **kwargs) return ax -def prep_contour_plot(adata, bdata, diffdata, pctdata, **kwargs): - """Preparation for making contour plots. - - Prepares for making contour plots of adata, bdata, diffdata, and pctdata, which is - presumably the difference between adata and bdata. - - set colormap from kwargs or defaults to coolwarm - - set contour levels from kwargs or 12 evenly spaced levels to span the data - - normalize colors based on specified contour levels or data range - - set option for linear or log pressure when applicable - - similar settings for difference, defaults to symmetric about zero - - separates Matplotlib kwargs into their own dicts - - Parameters - ---------- - adata, bdata, diffdata, pctdata - the data to be plotted - kwargs : dict, optional - plotting options - - Returns - ------- - dict - a dict with the following: - - 'subplots_opt': mpl kwargs for subplots - - 'contourf_opt': mpl kwargs for contourf - - 'colorbar_opt': mpl kwargs for colorbar - - 'diff_colorbar_opt' : mpl kwargs for difference colorbar - - 'normdiff': color normalization for difference panel - - 'cmapdiff': colormap for difference panel - - 'levelsdiff': contour levels for difference panel - - 'cmap1': color map for a and b panels - - 'norm1': color normalization for a and b panels - - 'levels1' : contour levels for a and b panels - - 'plot_log_p' : true/false whether to plot log(pressure) axis - """ - # determine levels & color normalization: - minval = np.min([np.min(adata), np.min(bdata)]) - maxval = np.max([np.max(adata), np.max(bdata)]) - - # determine norm to use (deprecate this once minimum MPL version is high enough) - normfunc, mplv = use_this_norm() - - if 'colormap' in kwargs: - cmap1 = kwargs['colormap'] - else: - cmap1 = 'coolwarm' - #End if - - if 'contour_levels' in kwargs: - levels1 = kwargs['contour_levels'] - if ('non_linear' in kwargs) and (kwargs['non_linear']): - cmap_obj = cm.get_cmap(cmap1) - norm1 = mpl.colors.BoundaryNorm(levels1, cmap_obj.N) - else: - norm1 = mpl.colors.Normalize(vmin=min(levels1), vmax=max(levels1)) - elif 'contour_levels_range' in kwargs: - assert len(kwargs['contour_levels_range']) == 3, \ - "contour_levels_range must have exactly three entries: min, max, step" - - levels1 = np.arange(*kwargs['contour_levels_range']) - if ('non_linear' in kwargs) and (kwargs['non_linear']): - cmap_obj = cm.get_cmap(cmap1) - norm1 = mpl.colors.BoundaryNorm(levels1, cmap_obj.N) - else: - norm1 = mpl.colors.Normalize(vmin=min(levels1), vmax=max(levels1)) - else: - levels1 = np.linspace(minval, maxval, 12) - if ('non_linear' in kwargs) and (kwargs['non_linear']): - cmap_obj = cm.get_cmap(cmap1) - norm1 = mpl.colors.BoundaryNorm(levels1, cmap_obj.N) - else: - norm1 = mpl.colors.Normalize(vmin=minval, vmax=maxval) - #End if - - #Check if the minval and maxval are actually different. If not, - #then set "levels1" to be an empty list, which will cause the - #plotting scripts to add a label instead of trying to plot a variable - #with no contours: - if minval == maxval: - levels1 = [] - #End if - - if ('colormap' not in kwargs) and ('contour_levels' not in kwargs): - if ((minval < 0) and (0 < maxval)) and mplv > 2: - norm1 = normfunc(vmin=minval, vmax=maxval, vcenter=0.0) - else: - norm1 = mpl.colors.Normalize(vmin=minval, vmax=maxval) - #End if - #End if - - # Difference options -- Check in kwargs for colormap and levels - if "diff_colormap" in kwargs: - cmapdiff = kwargs["diff_colormap"] - else: - cmapdiff = 'coolwarm' - #End if - - if "diff_contour_levels" in kwargs: - levelsdiff = kwargs["diff_contour_levels"] # a list of explicit contour levels - elif "diff_contour_range" in kwargs: - assert len(kwargs['diff_contour_range']) == 3, \ - "diff_contour_range must have exactly three entries: min, max, step" - - levelsdiff = np.arange(*kwargs['diff_contour_range']) - else: - # set a symmetric color bar for diff: - absmaxdif = np.max(np.abs(diffdata)) - # set levels for difference plot: - levelsdiff = np.linspace(-1*absmaxdif, absmaxdif, 12) - - # Percent Difference options -- Check in kwargs for colormap and levels - if "pct_diff_colormap" in kwargs: - cmappct = kwargs["pct_diff_colormap"] - else: - cmappct = "PuOr_r" - #End if - - if "pct_diff_contour_levels" in kwargs: - levelspctdiff = kwargs["pct_diff_contour_levels"] # a list of explicit contour levels - elif "pct_diff_contour_range" in kwargs: - assert len(kwargs['pct_diff_contour_range']) == 3, "pct_diff_contour_range must have exactly three entries: min, max, step" - levelspctdiff = np.arange(*kwargs['pct_diff_contour_range']) - else: - levelspctdiff = [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] - pctnorm = mpl.colors.BoundaryNorm(levelspctdiff,256) - - if "plot_log_pressure" in kwargs: - plot_log_p = kwargs["plot_log_pressure"] - else: - plot_log_p = False - - # color normalization for difference - if ((np.min(levelsdiff) < 0) and (0 < np.max(levelsdiff))) and mplv > 2: - normdiff = normfunc(vmin=np.min(levelsdiff), vmax=np.max(levelsdiff), vcenter=0.0) - else: - normdiff = mpl.colors.Normalize(vmin=np.min(levelsdiff), vmax=np.max(levelsdiff)) - - subplots_opt = {} - contourf_opt = {} - colorbar_opt = {} - diff_colorbar_opt = {} - pct_colorbar_opt = {} - - # extract any MPL kwargs that should be passed on: - if 'mpl' in kwargs: - subplots_opt.update(kwargs['mpl'].get('subplots',{})) - contourf_opt.update(kwargs['mpl'].get('contourf',{})) - colorbar_opt.update(kwargs['mpl'].get('colorbar',{})) - diff_colorbar_opt.update(kwargs['mpl'].get('diff_colorbar',{})) - pct_colorbar_opt.update(kwargs['mpl'].get('pct_diff_colorbar',{})) - #End if - return {'subplots_opt': subplots_opt, - 'contourf_opt': contourf_opt, - 'colorbar_opt': colorbar_opt, - 'diff_colorbar_opt': diff_colorbar_opt, - 'pct_colorbar_opt': pct_colorbar_opt, - 'normdiff': normdiff, - 'cmapdiff': cmapdiff, - 'levelsdiff': levelsdiff, - 'pctnorm': pctnorm, - 'cmappct': cmappct, - 'levelspctdiff':levelspctdiff, - 'cmap1': cmap1, - 'norm1': norm1, - 'levels1': levels1, - 'plot_log_p': plot_log_p - } +####### def plot_zonal_mean_and_save(wks, case_nickname, base_nickname, case_climo_yrs, baseline_climo_yrs, - adata, bdata, has_lev, log_p, obs=False, **kwargs): + adata, bdata, has_lev, log_p=False, obs=False, **kwargs): """This is the default zonal mean plot @@ -2015,19 +1484,19 @@ def plot_zonal_mean_and_save(wks, case_nickname, base_nickname, #End if #Set plot titles - case_title = "$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" + case_title = r"$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" if obs: obs_var = kwargs["obs_var_name"] obs_title = kwargs["obs_file"][:-3] - base_title = "$\mathbf{Baseline}:$"+obs_title+"\n"+"$\mathbf{Variable}:$"+f"{obs_var}" + base_title = r"$\mathbf{Baseline}:$"+obs_title+"\n"+r"$\mathbf{Variable}:$"+f"{obs_var}" else: - base_title = "$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" + base_title = r"$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" if has_lev: # calculate zonal average: - azm = zonal_mean_xr(adata) - bzm = zonal_mean_xr(bdata) + azm = utils.zonal_mean_xr(adata) + bzm = utils.zonal_mean_xr(bdata) # calculate difference: diff = azm - bzm @@ -2039,7 +1508,7 @@ def plot_zonal_mean_and_save(wks, case_nickname, base_nickname, pct = pct.fillna(0.0) # generate dictionary of contour plot settings: - cp_info = prep_contour_plot(azm, bzm, diff, pct, **kwargs) + cp_info = plot_utils.prep_contour_plot(azm, bzm, diff, pct, **kwargs) # Generate zonal plot: fig, ax = plt.subplots(figsize=(10,10),nrows=4, constrained_layout=True, sharex=True, sharey=True,**cp_info['subplots_opt']) @@ -2076,7 +1545,7 @@ def plot_zonal_mean_and_save(wks, case_nickname, base_nickname, ax[0].set_title(case_title, loc='left', fontsize=tiFontSize) ax[1].set_title(base_title, loc='left', fontsize=tiFontSize) - ax[2].set_title("$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=tiFontSize) + ax[2].set_title(r"$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=tiFontSize) ax[3].set_title("Test % Diff Baseline", loc='left', fontsize=tiFontSize,fontweight="bold") @@ -2091,14 +1560,14 @@ def plot_zonal_mean_and_save(wks, case_nickname, base_nickname, fig.text(-0.03, 0.5, 'PRESSURE [hPa]', va='center', rotation='vertical') else: - line = Line2D([0], [0], label="$\mathbf{Test}:$"+f"{case_nickname} - years: {case_climo_yrs[0]}-{case_climo_yrs[-1]}", + line = Line2D([0], [0], label=r"$\mathbf{Test}:$"+f"{case_nickname} - years: {case_climo_yrs[0]}-{case_climo_yrs[-1]}", color="#1f77b4") # #1f77b4 -> matplotlib standard blue line2 = Line2D([0], [0], label=base_title, color="#ff7f0e") # #ff7f0e -> matplotlib standard orange - azm = zonal_mean_xr(adata) - bzm = zonal_mean_xr(bdata) + azm = utils.zonal_mean_xr(adata) + bzm = utils.zonal_mean_xr(bdata) diff = azm - bzm # calculate the percent change @@ -2121,7 +1590,7 @@ def plot_zonal_mean_and_save(wks, case_nickname, base_nickname, borderaxespad=0.0,fontsize=6,frameon=False) zonal_plot(adata['lat'], diff, ax=ax[1], color="k") - ax[1].set_title("$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=10) + ax[1].set_title(r"$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=10) zonal_plot(adata['lat'], pct, ax=ax[2], color="k") ax[2].set_title("Test % Diff Baseline", loc='left', fontsize=10,fontweight="bold") @@ -2142,10 +1611,11 @@ def plot_zonal_mean_and_save(wks, case_nickname, base_nickname, plt.close() +####### def plot_meridional_mean_and_save(wks, case_nickname, base_nickname, case_climo_yrs, baseline_climo_yrs, - adata, bdata, has_lev, latbounds=None, obs=False, **kwargs): + adata, bdata, has_lev, log_p=False, latbounds=None, obs=False, **kwargs): """Default meridional mean plot @@ -2169,6 +1639,8 @@ def plot_meridional_mean_and_save(wks, case_nickname, base_nickname, It must have the same dimensions and vertical levels as adata. has_lev : bool whether lev dimension is present + log_p : bool, optional + (Not implemented) use log(pressure) vertical axis latbounds : numbers.Number or slice, optional indicates latitude bounds to average over if it is a number, assume symmetric about equator, @@ -2262,18 +1734,18 @@ def plot_meridional_mean_and_save(wks, case_nickname, base_nickname, xdim = 'lon' # the name used for the x-axis dimension pltfunc = meridional_plot # the plotting function ... maybe we can generalize to get zonal/meridional into one function (?) - case_title = "$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" + case_title = r"$\mathbf{Test}:$"+f"{case_nickname}\nyears: {case_climo_yrs[0]}-{case_climo_yrs[-1]}" if obs: obs_var = kwargs["obs_var_name"] obs_title = kwargs["obs_file"][:-3] - base_title = "$\mathbf{Baseline}:$"+obs_title+"\n"+"$\mathbf{Variable}:$"+f"{obs_var}" + base_title = r"$\mathbf{Baseline}:$"+obs_title+"\n"+r"$\mathbf{Variable}:$"+f"{obs_var}" else: - base_title = "$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" + base_title = r"$\mathbf{Baseline}:$"+f"{base_nickname}\nyears: {baseline_climo_yrs[0]}-{baseline_climo_yrs[-1]}" if has_lev: # generate dictionary of contour plot settings: - cp_info = prep_contour_plot(adata, bdata, diff, pct, **kwargs) + cp_info = plot_utils.prep_contour_plot(adata, bdata, diff, pct, **kwargs) # generate plot objects: fig, ax = plt.subplots(figsize=(10,10),nrows=4, constrained_layout=True, sharex=True, sharey=True,**cp_info['subplots_opt']) @@ -2310,7 +1782,7 @@ def plot_meridional_mean_and_save(wks, case_nickname, base_nickname, #Set plot titles ax[0].set_title(case_title, loc='left', fontsize=tiFontSize) ax[1].set_title(base_title, loc='left', fontsize=tiFontSize) - ax[2].set_title("$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=tiFontSize) + ax[2].set_title(r"$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=tiFontSize) ax[3].set_title("Test % Diff Baseline", loc='left', fontsize=tiFontSize, fontweight = "bold") # style the plot: @@ -2323,7 +1795,7 @@ def plot_meridional_mean_and_save(wks, case_nickname, base_nickname, fig.text(-0.03, 0.5, 'PRESSURE [hPa]', va='center', rotation='vertical') else: - line = Line2D([0], [0], label="$\mathbf{Test}:$"+f"{case_nickname} - years: {case_climo_yrs[0]}-{case_climo_yrs[-1]}", + line = Line2D([0], [0], label=r"$\mathbf{Test}:$"+f"{case_nickname} - years: {case_climo_yrs[0]}-{case_climo_yrs[-1]}", color="#1f77b4") # #1f77b4 -> matplotlib standard blue line2 = Line2D([0], [0], label=base_title, @@ -2339,7 +1811,7 @@ def plot_meridional_mean_and_save(wks, case_nickname, base_nickname, pltfunc(adata[xdim], diff, ax=ax[1], color="k") pltfunc(adata[xdim], pct, ax=ax[2], color="k") - ax[1].set_title("$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=10) + ax[1].set_title(r"$\mathbf{Test} - \mathbf{Baseline}$", loc='left', fontsize=10) ax[2].set_title("Test % Diff Baseline", loc='left', fontsize=10, fontweight = "bold") #Set Main title for subplots: @@ -2364,9 +1836,8 @@ def plot_meridional_mean_and_save(wks, case_nickname, base_nickname, #Close plots: plt.close() -# -# -- zonal mean annual cycle -- -# + +####### def square_contour_difference(fld1, fld2, **kwargs): """Produce filled contours of fld1, fld2, and their difference with square axes. diff --git a/lib/plotting_utils.py b/lib/plotting_utils.py new file mode 100644 index 000000000..d41695e7b --- /dev/null +++ b/lib/plotting_utils.py @@ -0,0 +1,479 @@ +""" . +Generic plotting helper functions + +Functions +--------- +use_this_norm() + switches matplotlib color normalization method +get_difference_colors(values) + Provide a color norm and colormap assuming `values` is a difference field. +get_central_longitude(*args) + Determine central longitude for maps. +meridional_plot_line(ax, lon, data, color, **kwargs) + Create line plot with longitude as the X-axis. +zonal_plot_line(ax, lat, data, color, **kwargs) + Create line plot with latitude as the X-axis. +zonal_plot_preslat(ax, lat, lev, data, **kwargs) + Create plot with latitude as the X-axis, and pressure as the Y-axis. +meridional_plot_preslon(ax, lon, lev, data, **kwargs) + Create plot with longitude as the X-axis, and pressure as the Y-axis. + +Notes +----- +This module includes "private" methods intended for internal use only. + +_plot_line(axobject, xdata, ydata, color, **kwargs) + Create a generic line plot +""" + +#import statements: +import numpy as np +import xarray as xr +import matplotlib as mpl +import matplotlib.cm as cm +import cartopy.crs as ccrs + +from adf_diag import AdfDiag +import adf_utils as utils + +import warnings # use to warn user about missing files. +warnings.formatwarning = utils.my_formatwarning + +################# +#HELPER FUNCTIONS +################# + +def load_dataset(fils): + """ + This method exists to get an xarray Dataset from input file information that can be passed into the plotting methods. + + Parameters + ---------- + fils : list + strings or paths to input file(s) + + Returns + ------- + xr.Dataset + + Notes + ----- + When just one entry is provided, use `open_dataset`, otherwise `open_mfdatset` + """ + if len(fils) == 0: + warnings.warn(f"\t WARNING: Input file list is empty.") + return None + elif len(fils) > 1: + return xr.open_mfdataset(fils, combine='by_coords') + else: + return xr.open_dataset(fils[0]) + #End if +#End def + + +####### + +def use_this_norm(): + """Just use the right normalization; avoids a deprecation warning.""" + + mplversion = [int(x) for x in mpl.__version__.split('.')] + if mplversion[0] < 3: + return mpl.colors.Normalize, mplversion[0] + else: + if mplversion[1] < 2: + return mpl.colors.DivergingNorm, mplversion[0] + else: + return mpl.colors.TwoSlopeNorm, mplversion[0] + + +####### + +def transform_coordinates_for_projection(proj, lon, lat): + """ + Explicitly project coordinates using the projection object. + + Parameters + ---------- + proj : cartopy.ccrs.CRS + projection object + lat : xarray.DataArray or numpy.ndarray + latitudes (in degrees) + lon :array.DataArray or numpy.ndarray + longitudes (in degrees) + + Returns + ------- + x_proj : numpy.ndarray + array of projected longitudes + y_proj : numpy.ndarray + array of projected latitudes + + Notes + ----- + This is what cartopy's transform_first=True *should* be doing internally. + We find that it sometimes fails for polar plots, so do it with this manually. + This dramatically speeds up polar plots. + """ + lons, lats = np.meshgrid(lon, lat) + x_proj, y_proj, _ = proj.transform_points(ccrs.PlateCarree(), lons, lats).T # .T to unpack, .T again to get x,y,z arrays + return x_proj.T, y_proj.T + + +####### + +def get_difference_colors(values): + """Provide a color norm and colormap assuming this is a difference field. + + Parameters + ---------- + values : array-like + can be either the data field or a set of specified contour levels. + + Returns + ------- + dnorm + Matplotlib color nomalization + cmap + Matplotlib colormap + + Notes + ----- + Uses 'OrRd' colormap for positive definite, 'BuPu_r' for negative definite, + and 'RdBu_r' centered on zero if there are values of both signs. + """ + normfunc, mplv = use_this_norm() + dmin = np.min(values) + dmax = np.max(values) + # color normalization for difference + if ((dmin < 0) and (0 < dmax)): + dnorm = normfunc(vmin=np.min(values), vmax=np.max(values), vcenter=0.0) + cmap = mpl.cm.RdBu_r + else: + dnorm = mpl.colors.Normalize(vmin=np.min(values), vmax=np.max(values)) + if dmin >= 0: + cmap = mpl.cm.OrRd + elif dmax <= 0: + cmap = mpl.cm.BuPu_r + else: + dnorm = mpl.colors.TwoSlopeNorm(vmin=dmin, vcenter=0, vmax=dmax) + return dnorm, cmap + + +####### + +def get_central_longitude(*args): + """Determine central longitude for maps. + + Allows an arbitrary number of arguments. + If any of the arguments is an instance of `AdfDiag`, then check + whether it has a `central_longitude` in `diag_basic_info`. + _This case takes precedence._ + _Else_, if any of the arguments are scalars in [-180, 360], + assumes the FIRST ONE is the central longitude. + There are no other possible conditions, so if none of those are met, + returns the default value of 180. + + Parameters + ---------- + *args : tuple + Any number of objects to check for `central_longitude`. + After that, looks for the first number between -180 and 360 in the args. + + Notes + ----- + This allows a script to, for example, allow a config file to specify, but also have a preference: + `get_central_longitude(AdfObj, 30.0)` + """ + chk_for_adf = [isinstance(arg, AdfDiag) for arg in args] + # preference is to get value from AdfDiag: + if any(chk_for_adf): + for arg in args: + if isinstance(arg, AdfDiag): + result = arg.get_basic_info('central_longitude', required=False) + if (isinstance(result, int) or isinstance(result, float)) and \ + (result >= -180) and (result <= 360): + return result + else: + #If result exists, then write info to debug log: + if result: + msg = f"central_lngitude of type '{type(result).__name__}'" + msg += f" and value '{result}', which is not a valid longitude" + msg += " for the ADF." + arg.debug_log(msg) + #End if + + #There is only one ADF object per ADF run, so if its + #not present or configured correctly then no + #reason to keep looking: + break + #End if + #End if + #End for + #End if + + # 2nd pass through arguments, look for numbers: + for arg in args: + if (isinstance(arg, float) or isinstance(arg, int)) and ((arg >= -180) and (arg <= 360)): + return arg + #End if + else: + # this is the `else` on the for loop --> if non of the arguments meet the criteria, do this. + print("No valid central longitude specified. Defaults to 180.") + return 180 + #End if + +####### + +# +# -- zonal & meridional mean code -- +# + +def _plot_line(axobject, xdata, ydata, color, **kwargs): + """Create a generic line plot and check for some ways to annotate.""" + + if color != None: + axobject.plot(xdata, ydata, c=color, **kwargs) + else: + axobject.plot(xdata, ydata, **kwargs) + + #Set Y-axis label: + if hasattr(ydata, "units"): + axobject.set_ylabel("[{units}]".format(units=getattr(ydata,"units"))) + elif "units" in kwargs: + axobject.set_ylabel("[{units}]".format(kwargs["units"])) + #End if + + return axobject + +def meridional_plot_line(ax, lon, data, color, **kwargs): + """Create line plot with longitude as the X-axis.""" + + ax = _plot_line(ax, lon, data, color, **kwargs) + ax.set_xlim([lon.min(), lon.max()]) + # + # annotate + # + ax.set_xlabel("LONGITUDE") + if hasattr(data, "units"): + ax.set_ylabel("{units}".format(units=getattr(data,"units"))) + elif "units" in kwargs: + ax.set_ylabel("{units}".format(kwargs["units"])) + return ax + +def zonal_plot_line(ax, lat, data, color, **kwargs): + """Create line plot with latitude as the X-axis.""" + ax = _plot_line(ax, lat, data, color, **kwargs) + ax.set_xlim([max([lat.min(), -90.]), min([lat.max(), 90.])]) + # + # annotate + # + ax.set_xlabel("LATITUDE") + if hasattr(data, "units"): + ax.set_ylabel("{units}".format(units=getattr(data,"units"))) + elif "units" in kwargs: + ax.set_ylabel("{units}".format(kwargs["units"])) + return ax + +def zonal_plot_preslat(ax, lat, lev, data, **kwargs): + """Create plot with latitude as the X-axis, and pressure as the Y-axis.""" + mlev, mlat = np.meshgrid(lev, lat) + if 'cmap' in kwargs: + cmap = kwargs.pop('cmap') + else: + cmap = 'Spectral_r' + + img = ax.contourf(mlat, mlev, data.transpose('lat', 'lev'), cmap=cmap, **kwargs) + + minor_locator = mpl.ticker.FixedLocator(lev) + ax.yaxis.set_minor_locator(minor_locator) + ax.tick_params(which='minor', length=4, color='r') + ax.set_ylim([np.max(lev), np.min(lev)]) + return img, ax + +def meridional_plot_preslon(ax, lon, lev, data, **kwargs): + """Create plot with longitude as the X-axis, and pressure as the Y-axis.""" + + mlev, mlon = np.meshgrid(lev, lon) + if 'cmap' in kwargs: + cmap = kwargs.pop('cmap') + else: + cmap = 'Spectral_r' + + img = ax.contourf(mlon, mlev, data.transpose('lon', 'lev'), cmap=cmap, **kwargs) + + minor_locator = mpl.ticker.FixedLocator(lev) + ax.yaxis.set_minor_locator(minor_locator) + ax.tick_params(which='minor', length=4, color='r') + ax.set_ylim([np.max(lev), np.min(lev)]) + return img, ax + +def prep_contour_plot(adata, bdata, diffdata, pctdata, **kwargs): + """Preparation for making contour plots. + + Prepares for making contour plots of adata, bdata, diffdata, and pctdata, which is + presumably the difference between adata and bdata. + - set colormap from kwargs or defaults to coolwarm + - set contour levels from kwargs or 12 evenly spaced levels to span the data + - normalize colors based on specified contour levels or data range + - set option for linear or log pressure when applicable + - similar settings for difference, defaults to symmetric about zero + - separates Matplotlib kwargs into their own dicts + + Parameters + ---------- + adata, bdata, diffdata, pctdata + the data to be plotted + kwargs : dict, optional + plotting options + + Returns + ------- + dict + a dict with the following: + - 'subplots_opt': mpl kwargs for subplots + - 'contourf_opt': mpl kwargs for contourf + - 'colorbar_opt': mpl kwargs for colorbar + - 'diff_colorbar_opt' : mpl kwargs for difference colorbar + - 'normdiff': color normalization for difference panel + - 'cmapdiff': colormap for difference panel + - 'levelsdiff': contour levels for difference panel + - 'cmap1': color map for a and b panels + - 'norm1': color normalization for a and b panels + - 'levels1' : contour levels for a and b panels + - 'plot_log_p' : true/false whether to plot log(pressure) axis + """ + # determine levels & color normalization: + minval = np.min([np.min(adata), np.min(bdata)]) + maxval = np.max([np.max(adata), np.max(bdata)]) + + # determine norm to use (deprecate this once minimum MPL version is high enough) + normfunc, mplv = use_this_norm() + + if 'colormap' in kwargs: + cmap1 = kwargs['colormap'] + else: + cmap1 = 'coolwarm' + #End if + + if 'contour_levels' in kwargs: + levels1 = kwargs['contour_levels'] + if ('non_linear' in kwargs) and (kwargs['non_linear']): + cmap_obj = cm.get_cmap(cmap1) + norm1 = mpl.colors.BoundaryNorm(levels1, cmap_obj.N) + else: + norm1 = mpl.colors.Normalize(vmin=min(levels1), vmax=max(levels1)) + elif 'contour_levels_range' in kwargs: + assert len(kwargs['contour_levels_range']) == 3, \ + "contour_levels_range must have exactly three entries: min, max, step" + + levels1 = np.arange(*kwargs['contour_levels_range']) + if ('non_linear' in kwargs) and (kwargs['non_linear']): + cmap_obj = cm.get_cmap(cmap1) + norm1 = mpl.colors.BoundaryNorm(levels1, cmap_obj.N) + else: + norm1 = mpl.colors.Normalize(vmin=min(levels1), vmax=max(levels1)) + else: + levels1 = np.linspace(minval, maxval, 12) + if ('non_linear' in kwargs) and (kwargs['non_linear']): + cmap_obj = cm.get_cmap(cmap1) + norm1 = mpl.colors.BoundaryNorm(levels1, cmap_obj.N) + else: + norm1 = mpl.colors.Normalize(vmin=minval, vmax=maxval) + #End if + + #Check if the minval and maxval are actually different. If not, + #then set "levels1" to be an empty list, which will cause the + #plotting scripts to add a label instead of trying to plot a variable + #with no contours: + if minval == maxval: + levels1 = [] + #End if + + if ('colormap' not in kwargs) and ('contour_levels' not in kwargs): + if ((minval < 0) and (0 < maxval)) and mplv > 2: + norm1 = normfunc(vmin=minval, vmax=maxval, vcenter=0.0) + else: + norm1 = mpl.colors.Normalize(vmin=minval, vmax=maxval) + #End if + #End if + + # Difference options -- Check in kwargs for colormap and levels + if "diff_colormap" in kwargs: + cmapdiff = kwargs["diff_colormap"] + else: + cmapdiff = 'coolwarm' + #End if + + if "diff_contour_levels" in kwargs: + levelsdiff = kwargs["diff_contour_levels"] # a list of explicit contour levels + elif "diff_contour_range" in kwargs: + assert len(kwargs['diff_contour_range']) == 3, \ + "diff_contour_range must have exactly three entries: min, max, step" + + levelsdiff = np.arange(*kwargs['diff_contour_range']) + else: + # set a symmetric color bar for diff: + absmaxdif = np.max(np.abs(diffdata.data)) + # set levels for difference plot: + levelsdiff = np.linspace(-1*absmaxdif, absmaxdif, 12) + # Percent Difference options -- Check in kwargs for colormap and levels + if "pct_diff_colormap" in kwargs: + cmappct = kwargs["pct_diff_colormap"] + else: + cmappct = "PuOr_r" + #End if + + if "pct_diff_contour_levels" in kwargs: + levelspctdiff = kwargs["pct_diff_contour_levels"] # a list of explicit contour levels + elif "pct_diff_contour_range" in kwargs: + assert len(kwargs['pct_diff_contour_range']) == 3, "pct_diff_contour_range must have exactly three entries: min, max, step" + levelspctdiff = np.arange(*kwargs['pct_diff_contour_range']) + else: + levelspctdiff = [-100,-75,-50,-40,-30,-20,-10,-8,-6,-4,-2,0,2,4,6,8,10,20,30,40,50,75,100] + pctnorm = mpl.colors.BoundaryNorm(levelspctdiff,256) + + if "plot_log_pressure" in kwargs: + plot_log_p = kwargs["plot_log_pressure"] + else: + plot_log_p = False + + # color normalization for difference + if ((np.min(levelsdiff) < 0) and (0 < np.max(levelsdiff))) and mplv > 2: + normdiff = normfunc(vmin=np.min(levelsdiff), vmax=np.max(levelsdiff), vcenter=0.0) + else: + normdiff = mpl.colors.Normalize(vmin=np.min(levelsdiff), vmax=np.max(levelsdiff)) + + subplots_opt = {} + contourf_opt = {} + colorbar_opt = {} + diff_colorbar_opt = {} + pct_colorbar_opt = {} + + # extract any MPL kwargs that should be passed on: + if 'mpl' in kwargs: + subplots_opt.update(kwargs['mpl'].get('subplots',{})) + contourf_opt.update(kwargs['mpl'].get('contourf',{})) + colorbar_opt.update(kwargs['mpl'].get('colorbar',{})) + diff_colorbar_opt.update(kwargs['mpl'].get('diff_colorbar',{})) + pct_colorbar_opt.update(kwargs['mpl'].get('pct_diff_colorbar',{})) + #End if + return {'subplots_opt': subplots_opt, + 'contourf_opt': contourf_opt, + 'colorbar_opt': colorbar_opt, + 'diff_colorbar_opt': diff_colorbar_opt, + 'pct_colorbar_opt': pct_colorbar_opt, + 'normdiff': normdiff, + 'cmapdiff': cmapdiff, + 'levelsdiff': levelsdiff, + 'pctnorm': pctnorm, + 'cmappct': cmappct, + 'levelspctdiff':levelspctdiff, + 'cmap1': cmap1, + 'norm1': norm1, + 'levels1': levels1, + 'plot_log_p': plot_log_p + } + + +##################### +#END HELPER FUNCTIONS \ No newline at end of file diff --git a/lib/website_templates/template.html b/lib/website_templates/template.html index 3a06250cb..61c4b2a80 100644 --- a/lib/website_templates/template.html +++ b/lib/website_templates/template.html @@ -12,6 +12,7 @@