diff --git a/cice.setup b/cice.setup index 2fd68cd18..0e574f803 100755 --- a/cice.setup +++ b/cice.setup @@ -838,7 +838,7 @@ EOF endif # from basic script dir to case - foreach file (cice.build cice.settings Makefile ice_in makdep.c setup_run_dirs.csh timeseries.csh timeseries.py) + foreach file (cice.build cice.settings Makefile ice_in makdep.c setup_run_dirs.csh ciceplots.csh ciceplots2d.py timeseries.py) if !(-e ${ICE_SCRIPTS}/$file) then echo "${0}: ERROR, ${ICE_SCRIPTS}/$file not found" exit -1 diff --git a/cicecore/cicedyn/general/ice_forcing.F90 b/cicecore/cicedyn/general/ice_forcing.F90 index b977f54aa..241bf8b5d 100755 --- a/cicecore/cicedyn/general/ice_forcing.F90 +++ b/cicecore/cicedyn/general/ice_forcing.F90 @@ -2276,6 +2276,9 @@ subroutine JRA55_files(yr) enddo if (.not.exists) then + write(nu_diag,*) subname,' atm_data_dir = ',trim(atm_data_dir) + write(nu_diag,*) subname,' atm_data_type_prefix = ',trim(atm_data_type_prefix) + write(nu_diag,*) subname,' atm_data_version = ',trim(atm_data_version) call abort_ice(error_message=subname//' could not find forcing file') endif diff --git a/configuration/scripts/ciceplots.csh b/configuration/scripts/ciceplots.csh new file mode 100755 index 000000000..43528b33e --- /dev/null +++ b/configuration/scripts/ciceplots.csh @@ -0,0 +1,56 @@ +#!/bin/csh -f + +source ${MODULESHOME}/init/csh + +# User defined stuff +# Set case and case directory +# Set files, notes, fstr, and fields + +set case = "CICE6.5.1" +set casedir = "/glade/derecho/scratch/tcraig/CICE_RUNS/cgx1proda" + +# setup plots + +set histdir = "${casedir}/history" + +set files = ("${histdir}/iceh.2012-03.nc" \ + "${histdir}/iceh.2012-09.nc" ) +set notes = ("2012 March Mean" \ + "2012 Sept Mean" ) +set fstrs = ("Mar12" \ + "Sep12" ) + +set fields = ("aice" "hi" "hs") + +#conda config --add channels conda-forge +#conda config --set channel_priority strict +#conda search basemap --channel conda-forge +#conda create -p /glade/u/home/tcraig/conda/envs/basemap -c conda-forge basemap=1.4.1 basemap-data basemap-data-hires netCDF4 + +module load conda +source ${NCAR_ROOT_CONDA}/etc/profile.d/conda.csh + +conda activate /glade/u/home/tcraig/conda/envs/basemap + +echo " " +echo " " + +echo ./timeseries.py \"${casedir}\" --case \"${case}\" --grid +./timeseries.py "${casedir}" --case "${case}" --grid + +echo " " + +set cnt = 0 +while ($cnt < ${#files}) + @ cnt = $cnt + 1 + set file = "${files[$cnt]}" + set note = "${notes[$cnt]}" + set fstr = "${fstrs[$cnt]}" + foreach field ($fields) + echo ./ciceplots2d.py \"$field\" \"$file\" \"$case\" \"$note\" \"$fstr\" + ./ciceplots2d.py "$field" "$file" "$case" "$note" "$fstr" + end +end + +echo "DONE" + diff --git a/configuration/scripts/ciceplots2d.py b/configuration/scripts/ciceplots2d.py new file mode 100755 index 000000000..2ad73e66f --- /dev/null +++ b/configuration/scripts/ciceplots2d.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 + +#Importing the necessary libraries +import sys +import os +import numpy as np +from netCDF4 import Dataset +import matplotlib as mpl +import matplotlib.pyplot as plt +from mpl_toolkits.basemap import Basemap + +if len(sys.argv) != 6: + print("ciceplots.py requires 5 arguments") + print(" 1. field name in file, ie. \"aice\"") + print(" 2. cice history file full path, ie. \"/glade/scratch/user/case/history/iceh.2012-03.nc\"") + print(" 3. case name, used to annotate plot, ie. \"CICE6.5.1\"") + print(" 4. notes, used to annotate plot, ie. 2012 \"March Mean\"") + print(" 5. file string, use to create unique png filenames, ie. \"Mar12\"") + quit() + +field = sys.argv[1] +pathf = sys.argv[2] +casen = sys.argv[3] +notes = sys.argv[4] +fstr = sys.argv[5] +fname = os.path.basename(pathf) +title = field + " " + notes +cfnam = casen + " " + fname +#print("field = ",field) +#print("pathf = ",pathf) +#print("casen = ",casen) +#print("notes = ",notes) +#print("fname = ",fname) +#print("title = ",title) +#print("cfnam = ",cfnam) + +#Reading the netCDF file +data = Dataset(pathf,'r') +#print (data) + +lons = data.variables['TLON'][:,:] +lats = data.variables['TLAT'][:,:] +var1 = data.variables[field][:,:,:] +var1 = var1[0,:,:] +var1[ var1==0.00 ] = np.nan +#mask = data.variables['tmask'][:,:] +#mask[ mask>0.5 ] = np.nan + +#print("lons.shape = ",lons.shape) +#print("var1.shape = ",var1.shape) + +# Lon/Lat Projection + +#print("Plot global") +#m = Basemap(projection='cyl',llcrnrlat=-90,urcrnrlat=90, +# llcrnrlon=0,urcrnrlon=360,resolution='c') +m = Basemap(projection='cyl',llcrnrlat=-90,urcrnrlat=90, + llcrnrlon=0,urcrnrlon=360,resolution='l') +fig, ax = plt.subplots() +#plt.figure(figsize=(6,4)) +m.drawcoastlines(linewidth=0.2) +m.fillcontinents(color='black',lake_color='white') +#draw parallels and meridians. +m.drawparallels(np.arange(-60.,61.,30.),labels=[1,0,0,0]) +m.drawmeridians(np.arange(0.,361.,45.),labels=[1,0,0,1]) +#draw map boundary +m.drawmapboundary(fill_color='white') +#setting colorbar +cmap = plt.get_cmap('jet') +barticks = None +norm = "linear" +if field in ['hi']: + bounds = np.arange(0,2.05,0.1) + bounds = np.append(bounds,[2.25,2.5,2.75,3.0,3.25,3.5,3.75,4.0]) + norm = mpl.colors.BoundaryNorm(bounds,cmap.N,extend='max') + barticks=[0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0] +if field in ['hs']: + bounds = np.arange(0,1.02,0.05) + bounds = np.append(bounds,[1.5,2.0,2.5,3.0,3.5,4.0]) + norm = mpl.colors.BoundaryNorm(bounds,cmap.N,extend='max') + barticks=[0,0.25,0.5,0.75,1.0,2.0,3.0,4.0] +#matplotlib scatter-plot +m.scatter(lons,lats,c=var1,cmap=cmap,marker='o',s=0.2,norm=norm) +m.colorbar(label=field, ticks=barticks) +plt.rcParams["figure.dpi"] = 300 +plt.title(title) +plt.text(x=0.0,y=-0.1,s=cfnam,transform=ax.transAxes,horizontalalignment='left',verticalalignment='top',fontsize='x-small') +oname = field + "_gl_" + fstr + ".png" +print('Saving file to ',oname) +plt.savefig(oname) +#plt.show() +plt.close() + +# North Polar Stereographic Projection + +#print("Plot NH") +#m = Basemap(projection='npstere',boundinglat=45,lon_0=-45,resolution='c') +m = Basemap(projection='npstere',boundinglat=45,lon_0=-45,resolution='l') +fig, ax = plt.subplots() +#plt.figure(figsize=(6,4)) +m.drawcoastlines(linewidth=0.2) +m.fillcontinents(color='black',lake_color='white') +# draw parallels and meridians. +m.drawparallels(np.arange(-60.,61.,30.),labels=[0,0,0,0]) +m.drawmeridians(np.arange(0.,361.,45.),labels=[0,0,0,0]) +m.drawmapboundary(fill_color='white') +#setting colorbar (set above) +m.scatter(lons,lats,c=var1,cmap=cmap,marker='o',s=0.2,latlon=True,norm=norm) +#m.colorbar(label=field) +m.colorbar(label=field, ticks=barticks) +plt.rcParams["figure.dpi"] = 300 +plt.title (title) +plt.text(x=0.0,y=-0.02,s=cfnam,transform=ax.transAxes,horizontalalignment='left',verticalalignment='top',fontsize='x-small') +oname = field + "_nh_" + fstr + ".png" +print('Saving file to ',oname) +plt.savefig(oname) +#plt.show() +plt.close() + +# South Polar Stereographic Projection + +#print("Plot SH") +#m = Basemap(projection='npstere',boundinglat=45,lon_0=-45,resolution='c') +m = Basemap(projection='spstere',boundinglat=-45,lon_0=180,resolution='l') +fig, ax = plt.subplots() +#plt.figure(figsize=(6,4)) +m.drawcoastlines(linewidth=0.2) +m.fillcontinents(color='black',lake_color='white') +# draw parallels and meridians. +m.drawparallels(np.arange(-60.,61.,30.),labels=[0,0,0,0]) +m.drawmeridians(np.arange(0.,361.,45.),labels=[0,0,0,0]) +m.drawmapboundary(fill_color='white') +#setting colorbar (set above) +m.scatter(lons,lats,c=var1,cmap=cmap,marker='o',s=0.2,latlon=True,norm=norm) +#m.colorbar(label=field) +m.colorbar(label=field, ticks=barticks) +plt.rcParams["figure.dpi"] = 300 +plt.title (title) +plt.text(x=0.0,y=-0.02,s=cfnam,transform=ax.transAxes,horizontalalignment='left',verticalalignment='top',fontsize='x-small') +oname = field + "_sh_" + fstr + ".png" +print('Saving file to ',oname) +plt.savefig(oname) +#plt.show() +plt.close() + +#print("Done") +quit() + diff --git a/configuration/scripts/machines/Macros.izumi_nag b/configuration/scripts/machines/Macros.izumi_nag index c12edb904..9265c9de1 100644 --- a/configuration/scripts/machines/Macros.izumi_nag +++ b/configuration/scripts/machines/Macros.izumi_nag @@ -3,7 +3,7 @@ #============================================================================== CPP := /usr/bin/cpp -CPPDEFS := -DFORTRANUNDERSCORE -DNO_R16 $(ICE_CPPDEFS) +CPPDEFS := -DFORTRANUNDERSCORE -DNO_R16 -DNO_CDF5 $(ICE_CPPDEFS) CFLAGS := -c FIXEDFLAGS := -fixed diff --git a/configuration/scripts/machines/environment.yml b/configuration/scripts/machines/environment.yml index 30ed1e148..119bf7ea0 100644 --- a/configuration/scripts/machines/environment.yml +++ b/configuration/scripts/machines/environment.yml @@ -15,6 +15,9 @@ dependencies: - matplotlib-base - cartopy - netcdf4 + - basemap=1.4.1 + - basemap-data + - basemap-data-hires # Python dependencies for building the HTML documentation - sphinx - sphinxcontrib-bibtex diff --git a/configuration/scripts/options/set_nml.run8year b/configuration/scripts/options/set_nml.run8year new file mode 100644 index 000000000..1515fa7c9 --- /dev/null +++ b/configuration/scripts/options/set_nml.run8year @@ -0,0 +1,7 @@ +npt_unit = 'y' +npt = 8 +dumpfreq = 'y' +dumpfreq_n = 1 +diagfreq = 24 +histfreq = 'm','x','x','x','x' + diff --git a/configuration/scripts/tests/prod_suite.ts b/configuration/scripts/tests/prod_suite.ts index 877fa1ce6..5e62e94ea 100644 --- a/configuration/scripts/tests/prod_suite.ts +++ b/configuration/scripts/tests/prod_suite.ts @@ -1,6 +1,6 @@ # Test Grid PEs Sets BFB-compare qcchk gx3 72x1 qc,qcchk,medium qcchk_gx3_72x1_medium_qc_qcchk qcchk gx1 144x1 qc,qcchk,medium -smoke gx1 144x2 gx1prod,long,run10year +smoke gx1 128x2 gx1prod,long,run8year qcchk gx3 72x1 qc,qcchkf,medium,alt02 qcchk_gx3_72x1_medium_qc_qcchk qcchk gx3 72x1 qc,qcchk,dt3456s,medium qcchk_gx3_72x1_medium_qc_qcchk diff --git a/configuration/scripts/timeseries.csh b/configuration/scripts/timeseries.csh deleted file mode 100755 index b6b3fcf2e..000000000 --- a/configuration/scripts/timeseries.csh +++ /dev/null @@ -1,129 +0,0 @@ -#!/bin/csh - -# Check to see if test case directory was passed -if ( $1 == "-h" ) then - echo "To generate timeseries plots, this script can be passed a directory" - echo "containing a logs/ subdirectory, or it can be run in the directory with" - echo "the log files, without being passed a directory." - echo "Example: ./timeseries.csh ./annual_gx3_conrad_4x1.t00" - echo "Example: ./timeseries.csh" - echo "It will pull the diagnostic data from the most recently modified log file." - exit -1 -endif -set basename = `echo $1 | sed -e 's#/$##' | sed -e 's/^\.\///'` - -# Set x-axis limits - # Manually set x-axis limits -#set xrange = 'set xrange ["19980101":"19981231"]' - # Let gnuplot determine x-axis limits -set xrange = '' - -# Determine if BASELINE dataset exists -if ( $1 == "" ) then -set basefile_dir = "IGNORE" -else -source $1/cice.settings -set basefile_dir = "$ICE_BASELINE/$ICE_BASECOM/$ICE_TESTNAME" -endif - -if ( -d $basefile_dir ) then - set num_basefile = `ls $basefile_dir | grep cice.runlog | wc -l` - if ( $num_basefile > 0 ) then - set baseline_exists = 1 - foreach file ($basefile_dir/cice.runlog.*) - set base_logfile = $file - end - else - set baseline_exists = 0 - endif -else - set baseline_exists = 0 -endif - -set fieldlist=("total ice area (km^2)" \ - "total ice extent(km^2)" \ - "total ice volume (m^3)" \ - "total snw volume (m^3)" \ - "rms ice speed (m/s)" ) - -# Get the filename for the latest log -if ( $1 == "" ) then -foreach file (./cice.runlog.*) - set logfile = $file -end -else -foreach file ($1/logs/cice.runlog.*) - set logfile = $file -end -endif - -# Loop through each field and create the plot -foreach field ($fieldlist:q) - # Add backslashes before (, ), and ^ for grep searches - set search_name = "`echo '$field' | sed 's/(/\\(/' | sed 's/)/\\)/' | sed 's/\^/\\^/'`" - set fieldname = `echo "$field" | sed -e 's/([^()]*)//g'` - set search = "'$search_name'\|istep1" - rm -f data.txt - foreach line ("`egrep $search $logfile`") - if ("$line" =~ *"istep1"*) then - set argv = ( $line ) - set date = $4 - @ hour = ( $6 / 3600 ) - else - set data1 = `echo $line | rev | cut -d ' ' -f2 | rev` - set data2 = `echo $line | rev | cut -d ' ' -f1 | rev` - echo "$date-$hour,$data1,$data2" >> data.txt - endif - end - set format = "%Y%m%d-%H" - - set output = `echo $fieldname | sed 's/ /_/g'` - set output = "${output}_${ICE_CASENAME}.png" - - echo "Plotting data for '$fieldname' and saving to $output" - -# Call the plotting routine, which uses the data in the data.txt file -gnuplot << EOF > $output -# Plot style -set style data points - -set datafile separator "," - -# Term type and background color, canvas size -set terminal png size 1920,960 - -# x-axis -set xdata time -set timefmt "$format" -set format x "%Y/%m/%d" - -# Axis tick marks -set xtics rotate - -set title "$field (Diagnostic Output)" -set ylabel "$field" -set xlabel "Simulation Day" - -set key left top - -# Set x-axlis limits -$xrange - -if ( $baseline_exists == 1 ) \ - plot "data_baseline.txt" using (timecolumn(1)):2 with lines lw 2 lt 2 lc 2 title \ - "Arctic - Baseline", \ - "" using (timecolumn(1)):3 with lines lw 2 lt 2 lc 5 title "Antarctic - Baseline", \ - "data.txt" using (timecolumn(1)):2 with lines lw 2 lt 1 lc 1 title "Arctic", \ - "" using (timecolumn(1)):3 with lines lw 2 lt 1 lc 3 title "Antarctic"; \ -else \ - plot "data.txt" using (timecolumn(1)):2 with lines lw 2 lt 1 lc 1 title "Arctic", \ - "" using (timecolumn(1)):3 with lines lw 2 lt 1 lc 3 title "Antarctic" \ - -EOF - -# Delete the data file -rm -f data.txt -if ( $baseline_exists ) then - rm -f data_baseline.txt -endif -end diff --git a/configuration/scripts/timeseries.py b/configuration/scripts/timeseries.py index 2c36cea73..c53106071 100755 --- a/configuration/scripts/timeseries.py +++ b/configuration/scripts/timeseries.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 ''' This script generates timeseries plots of CICE diagnostic output. @@ -51,16 +51,16 @@ def get_data(logfile,field): logger.debug('Extracting data for {}'.format(field)) # Build the regular expression to extract the data - field_regex = field.replace('(','\(').replace('^','\^').replace(')','\)') - number_regex = '[-+]?\d+\.?\d+([eE][-+]?\d+)?' - my_regex = '^{}\s+=\s+({})\s+({})'.format(field_regex,number_regex,number_regex) + field_regex = field.replace('(','\\(').replace('^','\\^').replace(')','\\)') + number_regex = r'[-+]?\d+\.?\d+([eE][-+]?\d+)?' + my_regex = r'^{}\s+=\s+({})\s+({})'.format(field_regex,number_regex,number_regex) dtg = [] arctic = [] antarctic = [] with open(logfile) as f: for line in f.readlines(): - m1 = re.search('istep1:\s+(\d+)\s+idate:\s+(\d+)\s+sec:\s+(\d+)', line) + m1 = re.search(r'istep1:\s+(\d+)\s+idate:\s+(\d+)\s+sec:\s+(\d+)', line) if m1: # Extract the current date-time group from the file date = m1.group(2) @@ -83,6 +83,11 @@ def get_data(logfile,field): antarctic.append(float(m.group(3))) logger.debug(' Arctic = {}, Antarctic = {}'.format(arctic[-1], antarctic[-1])) + # remove first few elements of dtg + if len(dtg) > len(arctic): + stind = len(dtg) - len(arctic) + dtg = dtg[stind:] + return dtg, arctic, antarctic, expon def latexit(string): @@ -90,15 +95,17 @@ def latexit(string): return (s.replace(')','$)',1))[::-1] def plot_timeseries(log, field, dtg, arctic, antarctic, expon, dtg_base=None, arctic_base=None, \ - antarctic_base=None, base_dir=None, grid=False): + antarctic_base=None, base_dir=None, grid=False, casename=None, base_casename=None): ''' Plot the timeseries data from the CICE log file ''' import re - casename = re.sub(r"/logs", "", os.path.abspath(log).rstrip('/')).split('/')[-1] + if casename is None: + casename = re.sub(r"/logs", "", os.path.abspath(log).rstrip('/')).split('/')[-1] if base_dir: - base_casename = re.sub(r"/logs", "", os.path.abspath(base_dir).rstrip('/')).split('/')[-1] + if base_casename is None: + base_casename = re.sub(r"/logs", "", os.path.abspath(base_dir).rstrip('/')).split('/')[-1] # Load the plotting libraries, but set the logging level for matplotlib # to WARNING so that matplotlib debugging info is not printed when running @@ -108,7 +115,8 @@ def plot_timeseries(log, field, dtg, arctic, antarctic, expon, dtg_base=None, ar import matplotlib.dates as mdates import matplotlib.ticker as ticker - fig = plt.figure(figsize=(12,8)) +# fig = plt.figure(figsize=(12,8)) + fig = plt.figure(figsize=(6,4)) ax = fig.add_axes([0.05,0.08,0.9,0.9]) # Add the arctic data to the plot @@ -132,55 +140,54 @@ def plot_timeseries(log, field, dtg, arctic, antarctic, expon, dtg_base=None, ar ax.xaxis.set_minor_locator(mdates.MonthLocator()) # Add a text box that prints the test case name and the baseline case name (if given) - try: - text_field = "Test/Case: {}\nBaseline: {}".format(casename,base_casename) - from matplotlib.offsetbox import AnchoredText - anchored_text = AnchoredText(text_field,loc=2) - ax.add_artist(anchored_text) - except: - text_field = "Test/Case: {}".format(casename) - from matplotlib.offsetbox import AnchoredText - anchored_text = AnchoredText(text_field,loc=2) - ax.add_artist(anchored_text) + if base_casename is None: + text_field = "{}".format(casename) + else: + text_field = "{}\n{}".format(casename,base_casename) + + from matplotlib.offsetbox import AnchoredText + anchored_text = AnchoredText(text_field,loc='upper left') + anchored_text.patch.set_alpha(0.5) + ax.add_artist(anchored_text) - ax.legend(loc='upper right') + ax.legend(loc='upper right',framealpha=0.5) # Add grid lines if the `--grid` argument was passed at the command line. if grid: ax.grid(ls='--') # Reduce the number of ticks on the y axis - nbins = 10 - try: - minval = min( \ - min(min(arctic), min(antarctic)), \ - min(min(arctic_base), min(antarctic_base))) - maxval = max( \ - max(max(arctic), max(antarctic)), \ - max(max(arctic_base), max(antarctic_base))) - except: - minval = min(min(arctic), min(antarctic)) - maxval = max(max(arctic), max(antarctic)) - step = (maxval-minval)/nbins - ax.yaxis.set_ticks(np.arange(minval, maxval+step, step)) +# nbins = 10 +# try: +# minval = min( \ +# min(min(arctic), min(antarctic)), \ +# min(min(arctic_base), min(antarctic_base))) +# maxval = max( \ +# max(max(arctic), max(antarctic)), \ +# max(max(arctic_base), max(antarctic_base))) +# except: +# minval = min(min(arctic), min(antarctic)) +# maxval = max(max(arctic), max(antarctic)) +# step = (maxval-minval)/nbins +# ax.yaxis.set_ticks(np.arange(minval, maxval+step, step)) # Format the y-axis tick labels, based on whether or not the values in the log file # are in scientific notation or float notation. if expon: - ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%0.3e')) + ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1e')) else: - ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%0.5f')) + ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%0.3f')) # Rotate and right align the x labels for tick in ax.get_xticklabels(): - tick.set_rotation(45) + tick.set_rotation(30) # Create an output file and save the figure field_tmp = field.split('(')[0].rstrip() try: - outfile = '{}_{}_base-{}.png'.format(field_tmp.replace(' ','_'), casename,base_casename) + outfile = '{}_{}_base-{}.png'.format(field_tmp.replace(' ','_'),casename.replace(' ','_'),base_casename.replace(' ','_')) except: - outfile = '{}_{}.png'.format(field_tmp.replace(' ','_'), casename) + outfile = '{}_{}.png'.format(field_tmp.replace(' ','_'), casename.replace(' ','_')) logger.info('Saving file to {}'.format(outfile)) plt.savefig(outfile,dpi=300,bbox_inches='tight') @@ -204,6 +211,10 @@ def main(): dataset, if desired. A specific log file or case directory can \ be passed. If a directory is passed, the most recent log file \ will be used.') + parser.add_argument('--case', dest='casename', help='User specified casename for plots.', \ + action='store') + parser.add_argument('--basecase', dest='base_casename', help='User specified base casename \ + for plots.', action='store') parser.add_argument('-v', '--verbose', dest='verbose', help='Print debug output?', \ action='store_true') parser.add_argument('--area', dest='area', help='Create a plot for total ice area?', \ @@ -227,6 +238,8 @@ def main(): parser.set_defaults(snow_volume=False) parser.set_defaults(speed=False) parser.set_defaults(grid=False) + parser.set_defaults(casename=None) + parser.set_defaults(base_casename=None) args = parser.parse_args() @@ -268,7 +281,7 @@ def main(): logger.debug('{} is a file'.format(args.log_dir)) log = args.log_dir log_dir = args.log_dir.rsplit('/',1)[0] - logger.info('Log file = {}'.format(log)) + if args.base_dir: if os.path.isdir(args.base_dir): base_log = find_logfile(args.base_dir) @@ -278,6 +291,9 @@ def main(): base_dir = args.base_dir.rsplit('/',1)[0] logger.info('Base Log file = {}'.format(base_log)) + logger.info('casename = {}'.format(args.casename)) + logger.info('Log file = {}'.format(log)) + # Loop through each field and create the plot for field in fieldlist: logger.debug('Current field = {}'.format(field)) @@ -290,9 +306,11 @@ def main(): # Plot the data if args.base_dir: plot_timeseries(log_dir, field, dtg, arctic, antarctic, expon, dtg_base, \ - arctic_base, antarctic_base, base_dir, grid=args.grid) + arctic_base, antarctic_base, base_dir, grid=args.grid, \ + casename=args.casename, base_casename=args.base_casename) else: - plot_timeseries(log_dir, field, dtg, arctic, antarctic, expon, grid=args.grid) + plot_timeseries(log_dir, field, dtg, arctic, antarctic, expon, grid=args.grid, \ + casename=args.casename) if __name__ == "__main__": main() diff --git a/doc/source/developer_guide/dg_scripts.rst b/doc/source/developer_guide/dg_scripts.rst index dac5e9a52..d4b29acbb 100644 --- a/doc/source/developer_guide/dg_scripts.rst +++ b/doc/source/developer_guide/dg_scripts.rst @@ -22,6 +22,8 @@ The directory structure under configure/scripts is as follows. | **cice.run.setup.csh** sets up the run scripts | **cice.settings** defines environment, model configuration and run settings | **cice.test.setup.csh** creates configurations for testing the model +| **ciceplots.csh** general script to generate timeseries and 2d CICE plots +| **ciceplots2d.py** python script to generate 2d CICE plots | **ice_in** namelist input data | **machines/** machine specific files to set env and Macros | **makdep.c** determines module dependencies @@ -31,8 +33,7 @@ The directory structure under configure/scripts is as follows. | **parse_settings.sh** replaces settings with command-line configuration | **setup_run_dirs.csh** creates the case run directories | **set_version_number.csh** updates the model version number from the **cice.setup** command line -| **timeseries.csh** generates PNG timeseries plots from output files, using GNUPLOT -| **timeseries.py** generates PNG timeseries plots from output files, using Python +| **timeseries.py** python script to generate timeseries plots from CICE log file | **tests/** scripts for configuring and running basic tests .. _dev_strategy: diff --git a/doc/source/user_guide/ug_running.rst b/doc/source/user_guide/ug_running.rst index 7ac37f16e..021c5bcbe 100644 --- a/doc/source/user_guide/ug_running.rst +++ b/doc/source/user_guide/ug_running.rst @@ -845,12 +845,13 @@ A few notes about the conda configuration: mpirun -np ${ntasks} --oversubscribe ./cice >&! \$ICE_RUNLOG_FILE - It is not recommeded to run other test suites than ``quick_suite`` or ``travis_suite`` on a personal computer. -- The conda environment is automatically activated when compiling or running the model using the ``./cice.build`` and ``./cice.run`` scripts in the case directory. These scripts source the file ``env.conda_{linux.macos}``, which calls ``conda activate cice``. +- If needed, the conda environment is automatically activated when compiling or running the model using the ``./cice.build`` and ``./cice.run`` scripts in the case directory. These scripts source the file ``env.conda_{linux.macos}``, which calls ``conda activate cice``. - To use the "cice" conda environment with the Python plotting (see :ref:`timeseries`) and quality control (QC) scripts (see :ref:`CodeValidation`), you must manually activate the environment: .. code-block:: bash cd ~/cice-dirs/cases/case1 + conda env create -f configuration/scripts/machines/environment.yml --force conda activate cice python timeseries.py ~/cice-dirs/cases/case1/logs conda deactivate # to deactivate the environment @@ -955,58 +956,49 @@ in shell startup files or otherwise at users discretion: .. _timeseries: -Timeseries Plotting +Plotting Tools ------------------- -The CICE scripts include two scripts that will generate timeseries figures from a -diagnostic output file, a Python version (``timeseries.py``) and a csh version -(``timeseries.csh``). Both scripts create the same set of plots, but the Python -script has more capabilities, and it's likely that the csh -script will be removed in the future. +CICE includes a couple of simple scripts to generate plots. The ``timeseries.py`` +scripts generates northern and southern hemisphere timeseries plots for several +fields from the CICE log file. The ``ciceplots2d.py`` script generates some +two-dimensional plots from CICE history files as global and polar projections. +The script ``ciceplots.csh`` is a general script that sets up the inputs for the +python plotting tools and calls them. Both python tools produce png files. -To use the ``timeseries.py`` script, the following requirements must be met: +To use the python scripts, the following python packages are required: -* Python v2.7 or later -* numpy Python package -* matplotlib Python package -* datetime Python package +* Python3 +* numpy +* matplotlib +* re +* datetime +* netcdf4 +* basemap, basemap-data, basemap-data-hires -See :ref:`CodeValidation` for additional information about how to setup the Python -environment, but we recommend using ``pip`` as follows: :: +The easist way to install the package is via the cice env file provided with CICE via conda: - pip install --user numpy - pip install --user matplotlib - pip install --user datetime - -When creating a case or test via ``cice.setup``, the ``timeseries.csh`` and -``timeseries.py`` scripts are automatically copied to the case directory. -Alternatively, the plotting scripts can be found in ``./configuration/scripts``, and can be -run from any directory. - -The Python script can be passed a directory, a specific log file, or no directory at all: + .. code-block:: bash - - If a directory is passed, the script will look either in that directory or in - directory/logs for a filename like cice.run*. As such, users can point the script - to either a case directory or the ``logs`` directory directly. The script will use - the file with the most recent creation time. - - If a specific file is passed the script parses that file, assuming that the file - matches the same form of cice.run* files. - - If nothing is passed, the script will look for log files or a ``logs`` directory in the - directory from where the script was run. + conda env create -f configuration/scripts/machines/environment.yml --force + conda activate cice -For example: +Then edit the ``ciceplots.csh`` script and run it. ``ciceplots.csh`` also demonstrates +how to call each python script separately. -Run the timeseries script on the desired case. :: +When creating a case or test via ``cice.setup``, these three plotting scripts +are automatically copied to the case directory. +Alternatively, the plotting scripts can be found in ``./configuration/scripts`` and can +be run as needed. -$ python timeseries.py /p/work1/turner/CICE_RUNS/conrad_intel_smoke_col_1x1_diag1_run1year.t00/ +Briefly, the ``timeseries.py`` script has a few options but can be called as follows: -or :: + .. code-block:: bash -$ python timeseries.py /p/work1/turner/CICE_RUNS/conrad_intel_smoke_col_1x1_diag1_run1year.t00/logs - -The output figures are placed in the directory where the ``timeseries.py`` script is run. + ./timeseries.py /p/work1/turner/CICE_RUNS/conrad_intel_smoke_col_1x1_diag1_run1year.t00 --grid --case CICE6.0.1 -The plotting script will plot the following variables by default, but you can also select +The timeseries script parses the log file, so the temporal resolution is based on the log output frequency. +The timeseries plotting script will plot the following variables by default, but you can also select specific plots to create via the optional command line arguments. - total ice area (:math:`km^2`) @@ -1015,30 +1007,14 @@ specific plots to create via the optional command line arguments. - total snow volume (:math:`m^3`) - RMS ice speed (:math:`m/s`) -For example, to plot only total ice volume and total snow volume :: +The ``ciceplots2d.py`` script is called as follows: -$ python timeseries.py /p/work1/turner/CICE_RUNS/conrad_intel_smoke_col_1x1_diag1_run1year.t00/ --volume --snw_vol - -To generate plots for all of the cases within a suite with a testid, create and run a script such as :: - - #!/bin/csh - foreach dir (`ls -1 | grep testid`) - echo $dir - python timeseries.py $dir - end - -Plots are only made for a single output file at a time. The ability to plot output from -a series of cice.run* files is not currently possible, but may be added in the future. -However, using the ``--bdir`` option will plot two datasets (from log files) on the -same figure. - -For the latest help information for the script, run :: - -$ python timeseries.py -h - -The ``timeseries.csh`` script works basically the same way as the Python version, however it -does not include all of the capabilities present in the Python version. + .. code-block:: bash -To use the C-Shell version of the script, :: + ./ciceplots2d.py aice /p/work1/turner/CICE_RUNS/conrad_intel_smoke_col_1x1_diag1_run1year.t00/history/iceh.2005-09.nc CICE6.0.1 "Sept 2005 Mean" 2005Sep -$ ./timeseries.csh /p/work1/turner/CICE_RUNS/conrad_intel_smoke_col_1x1_diag1_run1year.t00/ +In the example above, a global, northern hemisphere, and southern hemisphere plot would be created +for the aice field from iceh.2005-09.nc file. Titles on the plot would reference CICE6.0.1 and +"Sept 2005 Mean" and the png files would contain the string 2005Sep as well as the field name and region. +The two-dimensional plots are generated using the scatter feature from matplotlib, so they are fairly +primitive. diff --git a/icepack b/icepack index ae69b8069..083d6e3cf 160000 --- a/icepack +++ b/icepack @@ -1 +1 @@ -Subproject commit ae69b806990ef2412e2f714c5b4ba4c096b163b6 +Subproject commit 083d6e3cf42198bc7b4ffd1f02063c4c5b35b639