From 8fdab214252f58b137610a0062961c61fc85131d Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Mon, 15 Apr 2024 19:28:08 -0700 Subject: [PATCH 1/7] Add script to plot thermal forcing time series. Plot ISMIP6 thermal forcing time series for Amery/Lambert UQ paper. --- .../plot_thermal_forcing_time_series.py | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 landice/output_processing_li/plot_thermal_forcing_time_series.py diff --git a/landice/output_processing_li/plot_thermal_forcing_time_series.py b/landice/output_processing_li/plot_thermal_forcing_time_series.py new file mode 100644 index 000000000..6f28d8abc --- /dev/null +++ b/landice/output_processing_li/plot_thermal_forcing_time_series.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Plot time series of thermal forcing at specified +locations and depths. +@author: trevorhillebrand +""" + + +import numpy as np +import csv +from netCDF4 import Dataset +from optparse import OptionParser +from scipy.interpolate import LinearNDInterpolator, interp1d +import matplotlib.pyplot as plt +from matplotlib.pyplot import cm + + +parser = OptionParser(description='Plot transect from MPAS netCDF') +parser.add_option("-f", "--file", dest="thermal_forcing_file", + help="List of MPAS netCDF files that contains the ismip6shelfMelt_3dThermalForcing" \ + " field and zOcean variable. Comma-separated, no spaces.") +parser.add_option("-m", "--mesh", dest="mesh_file", + help="the MPAS netCDF file that contains the mesh variable, as well as thickness and bedTopography") +parser.add_option("--start_time", dest="start_time", default="0", + help="beginning of time range to plot") +parser.add_option("--end_time", dest="end_time", default="-1", + help="end of time range to plot") +parser.add_option('-c', dest='coords_file', default=None, + help='CSV file containing x in first column, y in second. No header.') +parser.add_option('-x', dest='x_coords', default=None, + help='List of x coordinates of transect if not \ + using a csv file. Comma-separated, no spaces.') +parser.add_option('-y', dest='y_coords', default=None, + help='List of y coordinates of transect if not \ + using a csv file. Comma-separated, no spaces.') +parser.add_option('-d', dest='depth', default=None, + help='Depth in meters at which to plot thermal forcing.' \ + ' If a single value, the script will use linear 1d' \ + ' interpolation to determine the thermal forcing' \ + ' at that depth. If two values are given, the script' \ + ' will provide the average over that depth range.') +parser.add_option("--seafloor", dest="plot_seafloor_thermal_forcing", + action="store_true", + help="plot thermal forcing at the seafloor, instead of at specific depth") +parser.add_option("--shelf_base", dest="plot_shelf_base_thermal_forcing", + action="store_true", + help="plot thermal forcing at the base of floating ice, instead of at specific depth") +parser.add_option("--average", dest="plot_average_thermal_forcing", + action="store_true", help='Whether to plot average' \ + ' thermal forcing across all coordinates provided.') +parser.add_option("--n_samples", dest="n_samples", default=None, + help="Number of random samples to take from provided coordinates.") +parser.add_option("-s", dest="save_filename", default=None, + help="File to save figure to.") + +options, args = parser.parse_args() + +rhoi = 910. +rhosw = 1028. +start_year = 1995 # first year in TF forcings + +times_list = [options.start_time, options.end_time] # list of string times for plotting +times = [int(i) for i in times_list] # list of integer time indices + +if options.coords_file is not None: + x = [] + y = [] + with open(options.coords_file, newline='') as csvfile: + reader = csv.reader(csvfile, delimiter=',') + + for row in reader: + x.append(float(row[0])) + y.append(float(row[1])) + if [options.x_coords, options.y_coords] != [None, None]: + print('-c and -x/-y options were both provided. Reading from ', + f'{options.coords_file} and ignoring -x and -y settings.') + x = np.asarray(x) + y = np.asarray(y) +else: + x = np.array([float(i) for i in options.x_coords.split(',')]) + y = np.array([float(i) for i in options.y_coords.split(',')]) + +if options.n_samples is not None: + rand_idx = np.random.choice(x.shape[0], int(options.n_samples), replace=False) + print(f"Using {options.n_samples} random samples from the {x.shape[0]} points provided.") + x = x[rand_idx] + y = y[rand_idx] + +# Mesh and geometry fields +mesh = Dataset(options.mesh_file, 'r') +mesh.set_always_mask(False) +bed = mesh.variables["bedTopography"][:] +thk = mesh.variables["thickness"][:] +xCell = mesh.variables["xCell"][:] +yCell = mesh.variables["yCell"][:] +nCells = mesh.dimensions['nCells'].size +areaCell = mesh.variables["areaCell"][:] +mesh.close() + +fig, ax = plt.subplots(1,1, layout='constrained') + +def interp_and_plot(tf_file, plot_ax): + # Thermal forcing fields + tf_data = Dataset(tf_file, 'r') + tf_data.set_always_mask(False) + tf = tf_data.variables["ismip6shelfMelt_3dThermalForcing"][:] + z = tf_data.variables["ismip6shelfMelt_zOcean"][:] + n_time_levs = tf_data.dimensions["Time"].size + tf_data.close() + if times[1] == -1: + times[1] = n_time_levs - 1 + plot_times = np.arange(times[0], times[1], step=1) # annual posting + + # Find nearest cell to desired x,y locations + nearest_cell = [] + for x_i, y_i in zip(x, y): + nearest_cell.append(np.argmin( np.sqrt((xCell - x_i)**2. + (yCell - y_i)**2) )) + + # Find depth to seafloor or ice-shelf base + if options.depth is not None: + depth = [float(i) for i in options.depth] + if options.plot_seafloor_thermal_forcing: + depth = bed[0, nearest_cell] + elif options.plot_shelf_base_thermal_forcing: + # Assume this is floating ice + depth = -1. * rhoi / rhosw * thk[0, nearest_cell] + + # Clip depth to within the range of the TF data + depth[depth > np.max(z)] = np.max(z) + depth[depth < np.min(z)] = np.min(z) + + # Vertical interpolation of ocean forcing. + tf_depth = [] + for time in plot_times: + tf_tmp = [] + for cell, cell_depth in zip(nearest_cell, depth): + tf_interp = interp1d(z, tf[time, cell, :]) + tf_tmp.append(tf_interp(cell_depth)) + tf_depth.append(tf_tmp) + + if "UKESM" in tf_file: + plot_color = 'tab:blue' + else: + plot_color = 'tab:grey' + + if options.plot_average_thermal_forcing: + tf_avg = np.mean(tf_depth, axis=1) + tf_std = np.std(tf_depth, axis=1) + plot_ax.plot(plot_times + start_year, tf_avg, c=plot_color) + plot_ax.fill_between(plot_times + start_year, tf_avg - tf_std, + tf_avg + tf_std, fc=plot_color, + alpha = 0.5) + else: + plot_ax.plot(plot_times + start_year, tf_depth, c=plot_color) + +tf_files = [i for i in options.thermal_forcing_file.split(',')] +for tf_file in tf_files: + print(f"Plotting from {tf_file}") + interp_and_plot(tf_file, ax) +ax.set_xlabel("Year") +ax.set_ylabel("Thermal Forcing (°C)") +ax.grid('on') +if options.save_filename is not None: + fig.savefig(options.save_filename, dpi=400, bbox_inches='tight') +plt.show() From 37d5311105a8a810a1b3638b48dcd08c5e42cb9f Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Mon, 22 Apr 2024 20:06:58 -0700 Subject: [PATCH 2/7] Add SMB plotting option Add option to plot SMB across a region or the entire domain. --- .../plot_thermal_forcing_time_series.py | 91 ++++++++++++++++--- 1 file changed, 80 insertions(+), 11 deletions(-) diff --git a/landice/output_processing_li/plot_thermal_forcing_time_series.py b/landice/output_processing_li/plot_thermal_forcing_time_series.py index 6f28d8abc..136fd77e8 100644 --- a/landice/output_processing_li/plot_thermal_forcing_time_series.py +++ b/landice/output_processing_li/plot_thermal_forcing_time_series.py @@ -17,11 +17,16 @@ parser = OptionParser(description='Plot transect from MPAS netCDF') -parser.add_option("-f", "--file", dest="thermal_forcing_file", +parser.add_option("-t", "--tf", dest="thermal_forcing_file", help="List of MPAS netCDF files that contains the ismip6shelfMelt_3dThermalForcing" \ " field and zOcean variable. Comma-separated, no spaces.") +parser.add_option("-s", "--smb", dest="smb_file", + help="List of MPAS netCDF files that contains the sfcMassBal" \ + " field. Comma-separated, no spaces.") parser.add_option("-m", "--mesh", dest="mesh_file", help="the MPAS netCDF file that contains the mesh variable, as well as thickness and bedTopography") +parser.add_option("-r", "--regions", dest="regions_file", default=None, + help="the MPAS netCDF file that contains the region masks") parser.add_option("--start_time", dest="start_time", default="0", help="beginning of time range to plot") parser.add_option("--end_time", dest="end_time", default="-1", @@ -40,6 +45,8 @@ ' interpolation to determine the thermal forcing' \ ' at that depth. If two values are given, the script' \ ' will provide the average over that depth range.') +parser.add_option('-n', dest='region_number', default=None, + help='Region number to plot. If None, use entire domain.') parser.add_option("--seafloor", dest="plot_seafloor_thermal_forcing", action="store_true", help="plot thermal forcing at the seafloor, instead of at specific depth") @@ -51,7 +58,7 @@ ' thermal forcing across all coordinates provided.') parser.add_option("--n_samples", dest="n_samples", default=None, help="Number of random samples to take from provided coordinates.") -parser.add_option("-s", dest="save_filename", default=None, +parser.add_option("--save", dest="save_filename", default=None, help="File to save figure to.") options, args = parser.parse_args() @@ -59,6 +66,8 @@ rhoi = 910. rhosw = 1028. start_year = 1995 # first year in TF forcings +scyr = 60. * 60. * 24. * 365. +forcing_interval_years = 1. times_list = [options.start_time, options.end_time] # list of string times for plotting times = [int(i) for i in times_list] # list of integer time indices @@ -96,11 +105,21 @@ yCell = mesh.variables["yCell"][:] nCells = mesh.dimensions['nCells'].size areaCell = mesh.variables["areaCell"][:] +ice_mask = thk[0, :] > 1. mesh.close() -fig, ax = plt.subplots(1,1, layout='constrained') +fig, ax = plt.subplots(1,2, sharex=True, layout='constrained') -def interp_and_plot(tf_file, plot_ax): +# Get region information, if desire +if options.region_number is not None: + region_number = int(options.region_number) + regions = Dataset(options.regions_file, 'r') + regionCellMasks = regions.variables["regionCellMasks"][:, region_number] + # Update ice_mask to only include desired region + ice_mask = np.logical_and(ice_mask, regionCellMasks) + regions.close() + +def interp_and_plot_tf(tf_file, plot_ax): # Thermal forcing fields tf_data = Dataset(tf_file, 'r') tf_data.set_always_mask(False) @@ -140,7 +159,10 @@ def interp_and_plot(tf_file, plot_ax): tf_depth.append(tf_tmp) if "UKESM" in tf_file: - plot_color = 'tab:blue' + if "SSP126" in tf_file: + plot_color = 'tab:green' + else: + plot_color = 'tab:blue' else: plot_color = 'tab:grey' @@ -154,13 +176,60 @@ def interp_and_plot(tf_file, plot_ax): else: plot_ax.plot(plot_times + start_year, tf_depth, c=plot_color) + +def plot_smb(smb_file, plot_ax): + smb_data = Dataset(smb_file, 'r') + smb_data.set_always_mask(False) + smb = smb_data.variables["sfcMassBal"][:, ice_mask] + smb_tot = np.sum(smb * areaCell[ice_mask] * scyr / 1.e12, axis=1) # Gt/yr + + n_time_levs = smb_data.dimensions["Time"].size + smb_data.close() + if times[1] == -1: + times[1] = n_time_levs - 1 + plot_times = np.arange(times[0], times[1], step=1) # annual posting + + # filter smb for plotting + filtered_smb = np.ones_like(smb_tot) + filtered_smb_std = np.ones_like(smb_tot) + window_width_years = 10 + for time in range(1, n_time_levs): + n_t = min(time, window_width_years) + filtered_smb[time] = np.mean(smb_tot[time-n_t:time]) + filtered_smb_std[time] = np.std(smb_tot[time-n_t:time]) + + if "UKESM" in smb_file: + if "SSP126" in tf_file: + plot_color = 'tab:green' + else: + plot_color = 'tab:blue' + else: + plot_color = 'tab:grey' + + plot_smb = filtered_smb[plot_times[0]:plot_times[-1]+1] + plot_smb_std = filtered_smb_std[plot_times[0]:plot_times[-1]+1] + + plot_ax.plot(plot_times + start_year, plot_smb, c=plot_color) + plot_ax.fill_between(plot_times + start_year, plot_smb - plot_smb_std, + plot_smb + plot_smb_std, fc=plot_color, + alpha = 0.5) + + tf_files = [i for i in options.thermal_forcing_file.split(',')] -for tf_file in tf_files: +smb_files = [i for i in options.smb_file.split(',')] +for tf_file, smb_file in zip(tf_files, smb_files): print(f"Plotting from {tf_file}") - interp_and_plot(tf_file, ax) -ax.set_xlabel("Year") -ax.set_ylabel("Thermal Forcing (°C)") -ax.grid('on') + interp_and_plot_tf(tf_file, ax[0]) + print(f"Plotting from {smb_file}") + plot_smb(smb_file, ax[1]) + +ax[0].set_xlabel("Year") +ax[0].set_ylabel("Thermal Forcing (°C)") +ax[0].grid('on') +ax[1].set_xlabel("Year") +ax[1].set_ylabel("Total Surface Mass Balance (Gt/yr)") +ax[1].grid('on') if options.save_filename is not None: - fig.savefig(options.save_filename, dpi=400, bbox_inches='tight') + fig.savefig(options.save_filename, dpi=400, bbox_inches='tight') + fig.savefig(options.save_filename, format='pdf', bbox_inches='tight') plt.show() From 6a32a76e47ebf32523b0c1c1e8787dcda4678f27 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Tue, 23 Apr 2024 09:25:15 -0700 Subject: [PATCH 3/7] Update plotting details Update linestyles based on ESM, save a pdf version, use lowercase axis labels, etc. --- .../plot_thermal_forcing_time_series.py | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/landice/output_processing_li/plot_thermal_forcing_time_series.py b/landice/output_processing_li/plot_thermal_forcing_time_series.py index 136fd77e8..dc15e8b22 100644 --- a/landice/output_processing_li/plot_thermal_forcing_time_series.py +++ b/landice/output_processing_li/plot_thermal_forcing_time_series.py @@ -108,9 +108,9 @@ ice_mask = thk[0, :] > 1. mesh.close() -fig, ax = plt.subplots(1,2, sharex=True, layout='constrained') +fig, ax = plt.subplots(1,2, sharex=True, figsize=(8,3), layout='constrained') -# Get region information, if desire +# Get region information, if desired if options.region_number is not None: region_number = int(options.region_number) regions = Dataset(options.regions_file, 'r') @@ -165,16 +165,23 @@ def interp_and_plot_tf(tf_file, plot_ax): plot_color = 'tab:blue' else: plot_color = 'tab:grey' + + if "CESM" in tf_file: + linestyle = "dashed" + elif "CCSM" in tf_file: + linestyle = "dotted" + else: + linestyle = "solid" if options.plot_average_thermal_forcing: tf_avg = np.mean(tf_depth, axis=1) tf_std = np.std(tf_depth, axis=1) - plot_ax.plot(plot_times + start_year, tf_avg, c=plot_color) + plot_ax.plot(plot_times + start_year, tf_avg, c=plot_color, linestyle=linestyle) plot_ax.fill_between(plot_times + start_year, tf_avg - tf_std, tf_avg + tf_std, fc=plot_color, alpha = 0.5) else: - plot_ax.plot(plot_times + start_year, tf_depth, c=plot_color) + plot_ax.plot(plot_times + start_year, tf_depth, c=plot_color, linestyle=linestyle) def plot_smb(smb_file, plot_ax): @@ -206,10 +213,17 @@ def plot_smb(smb_file, plot_ax): else: plot_color = 'tab:grey' + if "CESM" in smb_file: + linestyle = "dashed" + elif "CCSM" in smb_file: + linestyle = "dotted" + else: + linestyle = "solid" + plot_smb = filtered_smb[plot_times[0]:plot_times[-1]+1] plot_smb_std = filtered_smb_std[plot_times[0]:plot_times[-1]+1] - plot_ax.plot(plot_times + start_year, plot_smb, c=plot_color) + plot_ax.plot(plot_times + start_year, plot_smb, c=plot_color, linestyle=linestyle) plot_ax.fill_between(plot_times + start_year, plot_smb - plot_smb_std, plot_smb + plot_smb_std, fc=plot_color, alpha = 0.5) @@ -224,12 +238,12 @@ def plot_smb(smb_file, plot_ax): plot_smb(smb_file, ax[1]) ax[0].set_xlabel("Year") -ax[0].set_ylabel("Thermal Forcing (°C)") +ax[0].set_ylabel("Thermal forcing (°C)") ax[0].grid('on') ax[1].set_xlabel("Year") -ax[1].set_ylabel("Total Surface Mass Balance (Gt/yr)") +ax[1].set_ylabel("Total surface mass balance (Gt yr$^{-1}$)") ax[1].grid('on') if options.save_filename is not None: fig.savefig(options.save_filename, dpi=400, bbox_inches='tight') - fig.savefig(options.save_filename, format='pdf', bbox_inches='tight') + fig.savefig(options.save_filename + ".pdf", format='pdf', bbox_inches='tight') plt.show() From 3eed816a34b6c02d9cf4a8923be96ec3de1c53f8 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Tue, 23 Apr 2024 09:26:52 -0700 Subject: [PATCH 4/7] Support plotting average over depth range Support plotting average over depth range, for example using '-d -200,-500' in the command. --- .../plot_thermal_forcing_time_series.py | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/landice/output_processing_li/plot_thermal_forcing_time_series.py b/landice/output_processing_li/plot_thermal_forcing_time_series.py index dc15e8b22..2d1bf7a16 100644 --- a/landice/output_processing_li/plot_thermal_forcing_time_series.py +++ b/landice/output_processing_li/plot_thermal_forcing_time_series.py @@ -137,8 +137,12 @@ def interp_and_plot_tf(tf_file, plot_ax): nearest_cell.append(np.argmin( np.sqrt((xCell - x_i)**2. + (yCell - y_i)**2) )) # Find depth to seafloor or ice-shelf base + plot_depth_range = False if options.depth is not None: - depth = [float(i) for i in options.depth] + depth = np.array([float(i) for i in options.depth.split(',')]) + if len(depth) == 2: + plot_depth_range = True + if options.plot_seafloor_thermal_forcing: depth = bed[0, nearest_cell] elif options.plot_shelf_base_thermal_forcing: @@ -150,13 +154,22 @@ def interp_and_plot_tf(tf_file, plot_ax): depth[depth < np.min(z)] = np.min(z) # Vertical interpolation of ocean forcing. - tf_depth = [] - for time in plot_times: - tf_tmp = [] - for cell, cell_depth in zip(nearest_cell, depth): - tf_interp = interp1d(z, tf[time, cell, :]) - tf_tmp.append(tf_interp(cell_depth)) - tf_depth.append(tf_tmp) + if plot_depth_range: + # We'll just use the nearest zOcean depths to the + # requested top and bottom depths for simplicity and speed + print(f"Averaging TF over the depth range {depth}") + top_depth_index = np.argmin(np.abs(z - np.max(depth))) + bottom_depth_index = np.argmin(np.abs(z - np.min(depth))) + tf_depth = np.mean(tf[plot_times[0]:plot_times[-1] + 1, :, + top_depth_index:bottom_depth_index+1], axis=2) + else: + tf_depth = [] + for time in plot_times: + tf_tmp = [] + for cell, cell_depth in zip(nearest_cell, depth): + tf_interp = interp1d(z, tf[time, cell, :]) + tf_tmp.append(tf_interp(cell_depth)) + tf_depth.append(tf_tmp) if "UKESM" in tf_file: if "SSP126" in tf_file: @@ -245,5 +258,5 @@ def plot_smb(smb_file, plot_ax): ax[1].grid('on') if options.save_filename is not None: fig.savefig(options.save_filename, dpi=400, bbox_inches='tight') - fig.savefig(options.save_filename + ".pdf", format='pdf', bbox_inches='tight') + fig.savefig(options.save_filename + ".pdf", format='pdf', bbox_inches='tight') plt.show() From e6c67f30009f885591f93e464e2dbff5aea32b67 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Tue, 23 Apr 2024 09:27:47 -0700 Subject: [PATCH 5/7] Add option to plot over whole shelf depth range Add option to plot over whole shelf depth range, using the --shelf_range flag. This may not be very accurate because it will sample deep temperatures far from the grounding line, where they are unlikely to ever be felt by the ice shelf during a simulation, but it is much faster than interpolating to a specific depth or to the ice-shelf base or seafloor. --- .../plot_thermal_forcing_time_series.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/landice/output_processing_li/plot_thermal_forcing_time_series.py b/landice/output_processing_li/plot_thermal_forcing_time_series.py index 2d1bf7a16..419d9f6a0 100644 --- a/landice/output_processing_li/plot_thermal_forcing_time_series.py +++ b/landice/output_processing_li/plot_thermal_forcing_time_series.py @@ -53,6 +53,9 @@ parser.add_option("--shelf_base", dest="plot_shelf_base_thermal_forcing", action="store_true", help="plot thermal forcing at the base of floating ice, instead of at specific depth") +parser.add_option("--shelf_range", dest="plot_shelf_depth_range_thermal_forcing", + action="store_true", + help="plot average thermal forcing over the whole depth range spanned by the ice shelf base") parser.add_option("--average", dest="plot_average_thermal_forcing", action="store_true", help='Whether to plot average' \ ' thermal forcing across all coordinates provided.') @@ -148,6 +151,13 @@ def interp_and_plot_tf(tf_file, plot_ax): elif options.plot_shelf_base_thermal_forcing: # Assume this is floating ice depth = -1. * rhoi / rhosw * thk[0, nearest_cell] + elif options.plot_shelf_depth_range_thermal_forcing: + depth = np.zeros(2) + depth[0] = np.max( (-1. * rhoi / rhosw * thk[0, nearest_cell]) + [thk[0, nearest_cell] > 10.] ) # ignore very thin ice + depth[1] = np.min( (-1. * rhoi / rhosw * thk[0, nearest_cell]) + [thk[0, nearest_cell] > 10.] ) + plot_depth_range = True # Clip depth to within the range of the TF data depth[depth > np.max(z)] = np.max(z) From 9753ae06d0a11bea92c94ce65b9371a73f3df8de Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Tue, 23 Apr 2024 09:45:57 -0700 Subject: [PATCH 6/7] Rename script to be more general --- ...thermal_forcing_time_series.py => plot_forcing_time_series.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename landice/output_processing_li/{plot_thermal_forcing_time_series.py => plot_forcing_time_series.py} (100%) diff --git a/landice/output_processing_li/plot_thermal_forcing_time_series.py b/landice/output_processing_li/plot_forcing_time_series.py similarity index 100% rename from landice/output_processing_li/plot_thermal_forcing_time_series.py rename to landice/output_processing_li/plot_forcing_time_series.py From c76d1bc29d3752f8ab6b41ebe124547b7ee17990 Mon Sep 17 00:00:00 2001 From: Trevor Hillebrand Date: Wed, 1 May 2024 17:39:20 -0600 Subject: [PATCH 7/7] Apply suggestions from code review Co-authored-by: Matt Hoffman --- landice/output_processing_li/plot_forcing_time_series.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/landice/output_processing_li/plot_forcing_time_series.py b/landice/output_processing_li/plot_forcing_time_series.py index 419d9f6a0..3e797f5f6 100644 --- a/landice/output_processing_li/plot_forcing_time_series.py +++ b/landice/output_processing_li/plot_forcing_time_series.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Plot time series of thermal forcing at specified +Plot time series of thermal forcing and/or surface mass balance at specified locations and depths. @author: trevorhillebrand """ @@ -16,7 +16,7 @@ from matplotlib.pyplot import cm -parser = OptionParser(description='Plot transect from MPAS netCDF') +parser = OptionParser(description='Plot time series of thermal forcing and/or surface mass balance') parser.add_option("-t", "--tf", dest="thermal_forcing_file", help="List of MPAS netCDF files that contains the ismip6shelfMelt_3dThermalForcing" \ " field and zOcean variable. Comma-separated, no spaces.") @@ -24,7 +24,7 @@ help="List of MPAS netCDF files that contains the sfcMassBal" \ " field. Comma-separated, no spaces.") parser.add_option("-m", "--mesh", dest="mesh_file", - help="the MPAS netCDF file that contains the mesh variable, as well as thickness and bedTopography") + help="the MPAS netCDF file that contains the mesh variables, as well as thickness and bedTopography") parser.add_option("-r", "--regions", dest="regions_file", default=None, help="the MPAS netCDF file that contains the region masks") parser.add_option("--start_time", dest="start_time", default="0", @@ -43,7 +43,7 @@ help='Depth in meters at which to plot thermal forcing.' \ ' If a single value, the script will use linear 1d' \ ' interpolation to determine the thermal forcing' \ - ' at that depth. If two values are given, the script' \ + ' at that depth. If two comma-delimited values are given, the script' \ ' will provide the average over that depth range.') parser.add_option('-n', dest='region_number', default=None, help='Region number to plot. If None, use entire domain.')