def read_plot_ts_slice_diff (file_path_1, file_path_2, grid=None, lon0=None, lat0=None, point0=None, point1=None, time_index=None, t_start=None, t_end=None, time_average=False, time_index_2=None, t_start_2=None, t_end_2=None, hmin=None, hmax=None, zmin=None, zmax=None, tmin=None, tmax=None, smin=None, smax=None, tcontours=None, scontours=None, date_string=None, fig_name=None, second_file_path_1=None, second_file_path_2=None): diff_time = (time_index_2 is not None) or (time_average and (t_start_2 is not None or t_end_2 is not None)) grid = choose_grid(grid, file_path_1) check_single_time(time_index, time_average) date_string = check_date_string(date_string, file_path_1, time_index) # Inner function to read a variable from the correct NetCDF file and mask appropriately def read_and_mask (var_name, file_path, second_file_path=None, check_diff_time=False): # Do we need to choose the right file? if second_file_path is not None: file_path_use = find_variable(file_path, second_file_path, var_name) else: file_path_use = file_path # Read and mask the data if check_diff_time and diff_time: return mask_3d(read_netcdf(file_path_use, var_name, time_index=time_index_2, t_start=t_start_2, t_end=t_end_2, time_average=time_average), grid) else: return mask_3d(read_netcdf(file_path_use, var_name, time_index=time_index, t_start=t_start, t_end=t_end, time_average=time_average), grid) # Interface to call read_and_mask for each variable def read_and_mask_both (var_name): data1 = read_and_mask(var_name, file_path_1, second_file_path=second_file_path_1) data2 = read_and_mask(var_name, file_path_2, second_file_path=second_file_path_2, check_diff_time=True) return data1, data2 # Read temperature and salinity for each simulation temp_1, temp_2 = read_and_mask_both('THETA') salt_1, salt_2 = read_and_mask_both('SALT') # Plot ts_slice_plot_diff(temp_1, temp_2, salt_1, salt_2, grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, tmin=tmin, tmax=tmax, smin=smin, smax=smax, tcontours=tcontours, scontours=scontours, date_string=date_string, fig_name=fig_name)
def read_plot_hovmoller(var_name, hovmoller_file, grid, zmin=None, zmax=None, vmin=None, vmax=None, contours=None, monthly=True, fig_name=None, figsize=(14, 5)): data = read_netcdf(hovmoller_file, var_name) # Set monthly=False so we don't back up an extra month (because precomputed) time = netcdf_time(hovmoller_file, monthly=False) title, units = read_title_units(hovmoller_file, var_name) grid = choose_grid(grid, None) # Make the plot hovmoller_plot(data, time, grid, vmin=vmin, vmax=vmax, zmin=zmin, zmax=zmax, monthly=monthly, contours=contours, title=title, fig_name=fig_name, figsize=figsize)
def read_plot_hovmoller_diff(var_name, hovmoller_file_1, hovmoller_file_2, grid, zmin=None, zmax=None, vmin=None, vmax=None, contours=None, monthly=True, fig_name=None, figsize=(14, 5)): time, data_diff = read_and_trim_diff(hovmoller_file_1, hovmoller_file_2, var_name) title, units = read_title_units(hovmoller_file_1, var_name) grid = choose_grid(grid, None) hovmoller_plot(data_diff, time, grid, vmin=vmin, vmax=vmax, zmin=zmin, zmax=zmax, monthly=monthly, contours=contours, ctype='plusminus', title='Change in ' + title, fig_name=fig_name, figsize=figsize)
def read_plot_hovmoller_ts(hovmoller_file, loc, grid, smooth=0, zmin=None, zmax=None, tmin=None, tmax=None, smin=None, smax=None, t_contours=None, s_contours=None, date_since_start=False, ctype='basic', t0=None, s0=None, title=None, fig_name=None, monthly=True, figsize=(12, 7), dpi=None, return_fig=False): grid = choose_grid(grid, None) temp = read_netcdf(hovmoller_file, loc + '_temp') salt = read_netcdf(hovmoller_file, loc + '_salt') time = netcdf_time(hovmoller_file, monthly=False) loc_string = region_names[loc] return hovmoller_ts_plot(temp, salt, time, grid, smooth=smooth, tmin=tmin, tmax=tmax, smin=smin, smax=smax, zmin=zmin, zmax=zmax, monthly=monthly, t_contours=t_contours, s_contours=s_contours, loc_string=loc_string, title=title, date_since_start=date_since_start, ctype=ctype, t0=t0, s0=s0, figsize=figsize, dpi=dpi, return_fig=return_fig, fig_name=fig_name)
def read_plot_hovmoller_ts_diff(hovmoller_file_1, hovmoller_file_2, loc, grid, zmin=None, zmax=None, tmin=None, tmax=None, smin=None, smax=None, t_contours=None, s_contours=None, fig_name=None, monthly=True, figsize=(12, 7), dpi=None): time, temp_diff = read_and_trim_diff(hovmoller_file_1, hovmoller_file_2, loc + '_temp') salt_diff = read_and_trim_diff(hovmoller_file_1, hovmoller_file_2, loc + '_salt')[1] grid = choose_grid(grid, None) if loc == 'PIB': loc_string = 'Pine Island Bay ' elif loc == 'Dot': loc_string = 'Dotson front ' hovmoller_ts_plot(temp_diff, salt_diff, time, grid, tmin=tmin, tmax=tmax, smin=smin, smax=smax, zmin=zmin, zmax=zmax, monthly=monthly, t_contours=t_contours, s_contours=s_contours, ctype='plusminus', loc_string=loc_string, fig_name=fig_name, figsize=figsize, dpi=dpi)
def read_plot_hovmoller_ts_diff(hovmoller_file_1, hovmoller_file_2, loc, grid, smooth=0, zmin=None, zmax=None, tmin=None, tmax=None, smin=None, smax=None, t_contours=None, s_contours=None, fig_name=None, monthly=True, figsize=(12, 7), dpi=None): time, temp_diff = read_and_trim_diff(hovmoller_file_1, hovmoller_file_2, loc + '_temp') salt_diff = read_and_trim_diff(hovmoller_file_1, hovmoller_file_2, loc + '_salt')[1] grid = choose_grid(grid, None) loc_string = region_names[loc] hovmoller_ts_plot(temp_diff, salt_diff, time, grid, smooth=smooth, tmin=tmin, tmax=tmax, smin=smin, smax=smax, zmin=zmin, zmax=zmax, monthly=monthly, t_contours=t_contours, s_contours=s_contours, ctype='plusminus', loc_string=loc_string, fig_name=fig_name, figsize=figsize, dpi=dpi)
def read_plot_hovmoller_ts(hovmoller_file, loc, grid, zmin=None, zmax=None, tmin=None, tmax=None, smin=None, smax=None, t_contours=None, s_contours=None, fig_name=None, monthly=True, figsize=(12, 7), dpi=None): grid = choose_grid(grid, None) temp = read_netcdf(hovmoller_file, loc + '_temp') salt = read_netcdf(hovmoller_file, loc + '_salt') time = netcdf_time(hovmoller_file, monthly=False) if loc == 'PIB': loc_string = 'Pine Island Bay ' elif loc == 'Dot': loc_string = 'Dotson front ' hovmoller_ts_plot(temp, salt, time, grid, tmin=tmin, tmax=tmax, smin=smin, smax=smax, zmin=zmin, zmax=zmax, monthly=monthly, t_contours=t_contours, s_contours=s_contours, loc_string=loc_string, fig_name=fig_name, figsize=figsize, dpi=dpi)
def read_plot_ts_slice (file_path, grid=None, lon0=None, lat0=None, point0=None, point1=None, time_index=None, t_start=None, t_end=None, time_average=False, hmin=None, hmax=None, zmin=None, zmax=None, tmin=None, tmax=None, smin=None, smax=None, tcontours=None, scontours=None, date_string=None, fig_name=None, second_file_path=None): grid = choose_grid(grid, file_path) check_single_time(time_index, time_average) date_string = check_date_string(date_string, file_path, time_index) # Inner function to read a variable from the correct NetCDF file and mask appropriately def read_and_mask (var_name): # Do we need to choose the right file? if second_file_path is not None: file_path_use = find_variable(file_path, second_file_path, var_name) else: file_path_use = file_path # Read and mask the data data = mask_3d(read_netcdf(file_path_use, var_name, time_index=time_index, t_start=t_start, t_end=t_end, time_average=time_average), grid) return data # Read temperature and salinity temp = read_and_mask('THETA') salt = read_and_mask('SALT') # Plot ts_slice_plot(temp, salt, grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, tmin=tmin, tmax=tmax, smin=smin, smax=smax, tcontours=tcontours, scontours=scontours, date_string=date_string, fig_name=fig_name)
def calc_load_anomaly (grid, out_file, option='constant', ini_temp_file=None, ini_salt_file=None, ini_temp=None, ini_salt=None, constant_t=-1.9, constant_s=34.4, eosType='MDJWF', rhoConst=1035, tAlpha=None, sBeta=None, Tref=None, Sref=None, hfac=None, prec=64, check_grid=True): errorTol = 1e-13 # convergence criteria # Build the grid if needed if check_grid: grid = choose_grid(grid, None) # Decide which hfac to use if hfac is None: hfac = grid.hfac # Set temperature and salinity if ini_temp is not None and ini_salt is not None: # Deep copy of the arrays temp = np.copy(ini_temp) salt = np.copy(ini_salt) elif ini_temp_file is not None and ini_salt_file is not None: # Read from file temp = read_binary(ini_temp_file, [grid.nx, grid.ny, grid.nz], 'xyz', prec=prec) salt = read_binary(ini_salt_file, [grid.nx, grid.ny, grid.nz], 'xyz', prec=prec) else: print 'Error (calc_load_anomaly): Must either specify ini_temp and ini_salt OR ini_temp_file and ini_salt_file' sys.exit() # Fill in the ice shelves # The bathymetry will get filled too, but that doesn't matter because pressure is integrated from the top down closed = hfac==0 if option == 'constant': # Fill with constant values temp[closed] = constant_t salt[closed] = constant_s elif option == 'nearest': # Select the layer immediately below the ice shelves and tile to make it 3D temp_top = xy_to_xyz(select_top(np.ma.masked_where(closed, temp), return_masked=False), grid) salt_top = xy_to_xyz(select_top(np.ma.masked_where(closed, salt), return_masked=False), grid) # Fill the mask with these values temp[closed] = temp_top[closed] salt[closed] = salt_top[closed] elif option == 'precomputed': for data in [temp, salt]: # Make sure there are no missing values if (data[~closed]==0).any(): print 'Error (calc_load_anomaly): you selected the precomputed option, but there are appear to be missing values in the land mask.' sys.exit() # Make sure it's not a masked array as this will break the rms if isinstance(data, np.ma.MaskedArray): # Fill the mask with zeros data[data.mask] = 0 data = data.data else: print 'Error (calc_load_anomaly): invalid option ' + option sys.exit() # Get vertical integrands considering z at both centres and edges of layers dz_merged = np.zeros(2*grid.nz) dz_merged[::2] = abs(grid.z - grid.z_edges[:-1]) # dz of top half of each cell dz_merged[1::2] = abs(grid.z_edges[1:] - grid.z) # dz of bottom half of each cell # Tile to make 3D z = z_to_xyz(grid.z, grid) dz_merged = z_to_xyz(dz_merged, grid) # Initial guess for pressure (dbar) at centres of cells press = abs(z)*gravity*rhoConst*1e-4 # Iteratively calculate pressure load anomaly until it converges press_old = np.zeros(press.shape) # Dummy initial value for pressure from last iteration rms_error = 0 while True: rms_old = rms_error rms_error = rms(press, press_old) print 'RMS error = ' + str(rms_error) if rms_error < errorTol or np.abs(rms_error-rms_old) < 0.1*errorTol: print 'Converged' break # Save old pressure press_old = np.copy(press) # Calculate density anomaly at centres of cells drho_c = density(eosType, salt, temp, press, rhoConst=rhoConst, Tref=Tref, Sref=Sref, tAlpha=tAlpha, sBeta=sBeta) - rhoConst # Use this for both centres and edges of cells drho = np.zeros(dz_merged.shape) drho[::2,...] = drho_c drho[1::2,...] = drho_c # Integrate pressure load anomaly (Pa) pload_full = np.cumsum(drho*gravity*dz_merged, axis=0) # Update estimate of pressure press = (abs(z)*gravity*rhoConst + pload_full[1::2,...])*1e-4 # Extract pload at each level edge (don't care about centres anymore) pload_edges = pload_full[::2,...] # Now find pload at the ice shelf base # For each xy point, calculate three variables: # (1) pload at the base of the last fully dry ice shelf cell # (2) pload at the base of the cell beneath that # (3) hFacC for that cell # To calculate (1) we have to shift pload_3d_edges upward by 1 cell pload_edges_above = neighbours_z(pload_edges)[0] pload_above = select_top(np.ma.masked_where(closed, pload_edges_above), return_masked=False) pload_below = select_top(np.ma.masked_where(closed, pload_edges), return_masked=False) hfac_below = select_top(np.ma.masked_where(closed, hfac), return_masked=False) # Now we can interpolate to the ice base pload = pload_above + (1-hfac_below)*(pload_below - pload_above) # Write to file write_binary(pload, out_file, prec=prec)
def read_plot_slice_diff (var, file_path_1, file_path_2, grid=None, lon0=None, lat0=None, point0=None, point1=None, time_index=None, t_start=None, t_end=None, time_average=False, time_index_2=None, t_start_2=None, t_end_2=None, hmin=None, hmax=None, zmin=None, zmax=None, vmin=None, vmax=None, contours=None, date_string=None, fig_name=None, eosType='MDJWF', rhoConst=None, Tref=None, Sref=None, tAlpha=None, sBeta=None, ref_depth=0): # Figure out if the two files use different time indices diff_time = (time_index_2 is not None) or (time_average and (t_start_2 is not None or t_end_2 is not None)) # Get set up just like read_plot_slice grid = choose_grid(grid, file_path_1) check_single_time(time_index, time_average) date_string = check_date_string(date_string, file_path_1, time_index) # Inner function to read a variable from a NetCDF file and mask appropriately def read_and_mask (var_name, file_path, check_diff_time=False, gtype='t'): if var_name in ['tminustf', 'rho']: # Need to read 2 variables temp = read_and_mask('THETA', file_path, check_diff_time=check_diff_time) salt = read_and_mask('SALT', file_path, check_diff_time=check_diff_time) if var_name == 'rho': return mask_3d(density(eosType, salt, temp, ref_depth, rhoConst=rhoConst, Tref=Tref, Sref=Sref, tAlpha=tAlpha, sBeta=sBeta), grid) elif var_name == 'tminustf': return t_minus_tf(temp, salt, grid) elif var_name in ['vnorm', 'valong']: u = read_and_mask('UVEL', file_path, check_diff_time=check_diff_time, gtype='u') v = read_and_mask('VVEL', file_path, check_diff_time=check_diff_time, gtype='v') if var_name == 'vnorm': return normal_vector(u, v, grid, point0, point1) elif var_name == 'valong': return parallel_vector(u, v, grid, point0, point1) elif var_name == 'tadv_along': tadv_x = read_and_mask('ADVx_TH', file_path, check_diff_time=check_diff_time) tadv_y = read_and_mask('ADVy_TH', file_path, check_diff_time=check_diff_time) return parallel_vector(tadv_x, tadv_y, grid, point0, point1) elif var_name == 'tdif_along': tdif_x = read_and_mask('DFxE_TH', file_path, check_diff_time=check_diff_time) tdif_y = read_and_mask('DFyE_TH', file_path, check_diff_time=check_diff_time) return parallel_vector(tdif_x, tdif_y, grid, point0, point1) else: if check_diff_time and diff_time: return mask_3d(read_netcdf(file_path, var_name, time_index=time_index_2, t_start=t_start_2, t_end=t_end_2, time_average=time_average), grid, gtype=gtype) else: return mask_3d(read_netcdf(file_path, var_name, time_index=time_index, t_start=t_start, t_end=t_end, time_average=time_average), grid, gtype=gtype) # Interface to call read_and_mask for each variable def read_and_mask_both (var_name, gtype='t'): data1 = read_and_mask(var_name, file_path_1, gtype=gtype) data2 = read_and_mask(var_name, file_path_2, check_diff_time=True, gtype=gtype) return data1, data2 if var in ['vnorm', 'valong', 'tadv_along', 'tdif_along'] and None in [point0, point1]: print 'Error (read_plot_slice_diff): normal or along-transect variables require point0 and point1 to be specified.' sys.exit() # Read variables and make plots if var == 'temp': temp_1, temp_2 = read_and_mask_both('THETA') slice_plot_diff(temp_1, temp_2, grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title='Change in temperature ('+deg_string+'C)', date_string=date_string, fig_name=fig_name) elif var == 'salt': salt_1, salt_2 = read_and_mask_both('SALT') slice_plot_diff(salt_1, salt_2, grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title='Change in salinity (psu)', date_string=date_string, fig_name=fig_name) elif var == 'tminustf': tmtf_1, tmtf_2 = read_and_mask_both('tminustf') slice_plot_diff(tmtf_1, tmtf_2, grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title='Change in difference from in-situ freezing point ('+deg_string+')', date_string=date_string, fig_name=fig_name) elif var == 'rho': rho_1, rho_2 = read_and_mask_both('rho') slice_plot_diff(rho_1, rho_2, grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title=r'Change in density (kg/m$^3$)', date_string=date_string, fig_name=fig_name) elif var == 'u': u_1, u_2 = read_and_mask_both('UVEL', gtype='u') slice_plot_diff(u_1, u_2, grid, gtype='u', lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title='Change in zonal velocity (m/s)', date_string=date_string, fig_name=fig_name) elif var == 'v': v_1, v_2 = read_and_mask_both('VVEL', gtype='v') slice_plot_diff(v_1, v_2, grid, gtype='v', lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title='Change in meridional velocity (m/s)', date_string=date_string, fig_name=fig_name) elif var == 'vnorm': vnorm_1, vnorm_2 = read_and_mask_both(var) slice_plot_diff(vnorm_1, vnorm_2, grid, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title='Change in normal velocity (m/s)', date_string=date_string, fig_name=fig_name) elif var == 'valong': valong_1, valong_2 = read_and_mask_both(var) slice_plot_diff(valong_1, valong_2, grid, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title='Change in along-transect velocity (m/s)', date_string=date_string, fig_name=fig_name) elif var == 'tadv_along': tadv_along_1, tadv_along_2 = read_and_mask_both(var) slice_plot_diff(tadv_along_1, tadv_along_2, grid, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title=r'Change in along-transect advective heat transport (Km$^3$/s)', date_string=date_string, fig_name=fig_name) elif var == 'tdif_along': tdif_along_1, tdif_along_2 = read_and_mask_both(var) slice_plot_diff(tdif_along_1, tdif_along_2, grid, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title=r'Change in along-transect diffusive heat transport (Km$^3$/s)', date_string=date_string, fig_name=fig_name) else: print 'Error (read_plot_slice_diff): variable key ' + str(var) + ' does not exist' sys.exit()
def read_plot_slice (var, file_path, grid=None, lon0=None, lat0=None, point0=None, point1=None, time_index=None, t_start=None, t_end=None, time_average=False, hmin=None, hmax=None, zmin=None, zmax=None, vmin=None, vmax=None, contours=None, date_string=None, fig_name=None, second_file_path=None, eosType='MDJWF', rhoConst=None, Tref=None, Sref=None, tAlpha=None, sBeta=None, ref_depth=0): # Build the grid if needed grid = choose_grid(grid, file_path) # Make sure we'll end up with a single record in time check_single_time(time_index, time_average) # Determine what to write about the date date_string = check_date_string(date_string, file_path, time_index) # Inner function to read a variable from the correct NetCDF file and mask appropriately def read_and_mask (var_name, check_second=False, gtype='t'): # Do we need to choose the right file? if check_second and second_file_path is not None: file_path_use = find_variable(file_path, second_file_path, var_name) else: file_path_use = file_path # Read and mask the data return mask_3d(read_netcdf(file_path_use, var_name, time_index=time_index, t_start=t_start, t_end=t_end, time_average=time_average), grid, gtype=gtype) # Read necessary variables from NetCDF file and mask appropriately if var in ['temp', 'tminustf', 'rho']: temp = read_and_mask('THETA', check_second=True) if var in ['salt', 'tminustf', 'rho']: salt = read_and_mask('SALT', check_second=True) if var in ['u', 'vnorm', 'valong']: u = read_and_mask('UVEL', gtype='u') if var in ['v', 'vnorm', 'valong']: v = read_and_mask('VVEL', gtype='v') if var == 'tadv_along': tadv_x = read_and_mask('ADVx_TH') tadv_y = read_and_mask('ADVy_TH') if var == 'tdif_along': tdif_x = read_and_mask('DFxE_TH') tdif_y = read_and_mask('DFyE_TH') if var in ['vnorm', 'valong', 'tadv_along', 'tdif_along'] and None in [point0, point1]: print 'Error (read_plot_slice): normal or along-transect variables require point0 and point1 to be specified.' sys.exit() # Plot if var == 'temp': slice_plot(temp, grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title='Temperature ('+deg_string+'C)', date_string=date_string, fig_name=fig_name) elif var == 'salt': slice_plot(salt, grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title='Salinity (psu)', date_string=date_string, fig_name=fig_name) elif var == 'tminustf': slice_plot(t_minus_tf(temp, salt, grid), grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, ctype='plusminus', title='Difference from in-situ freezing point ('+deg_string+'C)', date_string=date_string, fig_name=fig_name) elif var == 'rho': # Calculate density rho = mask_3d(density(eosType, salt, temp, ref_depth, rhoConst=rhoConst, Tref=Tref, Sref=Sref, tAlpha=tAlpha, sBeta=sBeta), grid) slice_plot(rho, grid, lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, contours=contours, title=r'Density (kg/m$^3$)', date_string=date_string, fig_name=fig_name) elif var == 'u': slice_plot(u, grid, gtype='u', lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, ctype='plusminus', contours=contours, title='Zonal velocity (m/s)', date_string=date_string, fig_name=fig_name) elif var == 'v': slice_plot(v, grid, gtype='v', lon0=lon0, lat0=lat0, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, ctype='plusminus', contours=contours, title='Meridional velocity (m/s)', date_string=date_string, fig_name=fig_name) elif var == 'vnorm': vnorm = normal_vector(u, v, grid, point0, point1) slice_plot(vnorm, grid, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, ctype='plusminus', contours=contours, title='Normal velocity (m/s)', date_string=date_string, fig_name=fig_name) elif var == 'valong': valong = parallel_vector(u, v, grid, point0, point1) slice_plot(valong, grid, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, ctype='plusminus', contours=contours, title='Along-transect velocity (m/s)', date_string=date_string, fig_name=fig_name) elif var == 'tadv_along': tadv_along = parallel_vector(tadv_x, tadv_y, grid, point0, point1) slice_plot(tadv_along, grid, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, ctype='plusminus', contours=contours, title=r'Along-transect advective heat transport (Km$^3$/s)', date_string=date_string, fig_name=fig_name) elif var == 'tdif_along': tdif_along = parallel_vector(tdif_x, tdif_y, grid, point0, point1) slice_plot(tdif_along, grid, point0=point0, point1=point1, hmin=hmin, hmax=hmax, zmin=zmin, zmax=zmax, vmin=vmin, vmax=vmax, ctype='plusminus', contours=contours, title=r'Along-transect diffusive heat transport (Km$^3$/s)', date_string=date_string, fig_name=fig_name) else: print 'Error (read_plot_slice): variable key ' + str(var) + ' does not exist' sys.exit()
def ts_distribution_plot(file_path, option='fris', grid=None, time_index=None, t_start=None, t_end=None, time_average=False, second_file_path=None, tmin=None, tmax=None, smin=None, smax=None, num_bins=1000, date_string=None, figsize=(8, 6), fig_name=None): # Build the grid if needed grid = choose_grid(grid, file_path) # Make sure we'll end up with a single record in time check_single_time(time_index, time_average) # Determine what to write about the date date_string = check_date_string(date_string, file_path, time_index) # Quick inner function to read data (THETA or SALT) def read_data(var_name): # First choose the right file if second_file_path is not None: file_path_use = find_variable(file_path, second_file_path) else: file_path_use = file_path data = read_netcdf(file_path_use, var_name, time_index=time_index, t_start=t_start, t_end=t_end, time_average=time_average) return data # Call this function for each variable temp = read_data('THETA') salt = read_data('SALT') # Select the points we care about if option == 'fris': # Select all points in the FRIS cavity loc_index = (grid.hfac > 0) * xy_to_xyz(grid.fris_mask, grid) elif option == 'cavities': # Select all points in ice shelf cavities loc_index = (grid.hfac > 0) * xy_to_xyz(grid.ice_mask, grid) elif option == 'all': # Select all unmasked points loc_index = grid.hfac > 0 else: print 'Error (plot_misc): invalid option ' + option sys.exit() # Inner function to set up bins for a given variable (temp or salt) def set_bins(data): # Find the bounds on the data at the points we care about vmin = np.amin(data[loc_index]) vmax = np.amax(data[loc_index]) # Choose a small epsilon to add/subtract from the boundaries # This way nothing will be at the edge of a beginning/end bin eps = (vmax - vmin) * 1e-3 # Calculate boundaries of bins bins = np.linspace(vmin - eps, vmax + eps, num=num_bins) # Now calculate the centres of bins for plotting centres = 0.5 * (bins[:-1] + bins[1:]) return bins, centres # Call this function for each variable temp_bins, temp_centres = set_bins(temp) salt_bins, salt_centres = set_bins(salt) # Now set up a 2D array to increment with volume of water masses volume = np.zeros([temp_centres.size, salt_centres.size]) # Loop over all cells to increment volume # This can't really be vectorised unfortunately for i in range(grid.nx): for j in range(grid.ny): if option == 'fris' and not grid.fris_mask[j, i]: # Disregard all points not in FRIS cavity continue if option == 'cavities' and not grid.ice_mask[j, i]: # Disregard all points not in ice shelf cavities continue for k in range(grid.nz): if grid.hfac[k, j, i] == 0: # Disregard all masked points continue # If we're still here, it's a point we care about # Figure out which bins it falls into temp_index = np.nonzero(temp_bins > temp[k, j, i])[0][0] - 1 salt_index = np.nonzero(salt_bins > salt[k, j, i])[0][0] - 1 # Increment volume array volume[temp_index, salt_index] += grid.dV[k, j, i] # Mask bins with zero volume volume = np.ma.masked_where(volume == 0, volume) # Find the volume bounds for plotting min_vol = np.log(np.amin(volume)) max_vol = np.log(np.amax(volume)) # Calculate the surface freezing point for plotting tfreeze_sfc = tfreeze(salt_centres, 0) # Choose the plotting bounds if not set if tmin is None: tmin = temp_bins[0] if tmax is None: tmax = temp_bins[-1] if smin is None: smin = salt_bins[0] if smax is None: smax = salt_bins[-1] # Construct the title title = 'Water masses' if option == 'fris': title += ' in FRIS cavity' elif option == 'cavities': title += ' in ice shelf cavities' if date_string != '': title += ', ' + date_string # Plot fig, ax = plt.subplots(figsize=figsize) # Use a log scale for visibility img = plt.pcolor(salt_centres, temp_centres, np.log(volume), vmin=min_vol, vmax=max_vol) # Add the surface freezing point plt.plot(salt_centres, tfreeze_sfc, color='black', linestyle='dashed', linewidth=2) ax.grid(True) ax.set_xlim([smin, smax]) ax.set_ylim([tmin, tmax]) plt.xlabel('Salinity (psu)') plt.ylabel('Temperature (' + deg_string + 'C)') plt.colorbar(img) plt.text(.9, .6, 'log of volume', ha='center', rotation=-90, transform=fig.transFigure) plt.title(title) finished_plot(fig, fig_name=fig_name)
def calc_timeseries (file_path, option=None, grid=None, gtype='t', var_name=None, shelves='fris', mass_balance=False, result='massloss', xmin=None, xmax=None, ymin=None, ymax=None, threshold=None, lon0=None, lat0=None, tmin=None, tmax=None, smin=None, smax=None, shelf_option='full', point0=None, point1=None, direction='N', monthly=True): if isinstance(file_path, str): # Just one file first_file = file_path elif isinstance(file_path, list): # More than one first_file = file_path[0] else: print 'Error (calc_timeseries): file_path must be a string or a list' sys.exit() if option not in ['time', 'ismr', 'wed_gyre_trans', 'watermass', 'volume', 'transport_transect'] and var_name is None: print 'Error (calc_timeseries): must specify var_name' sys.exit() if option == 'point_vavg' and (lon0 is None or lat0 is None): print 'Error (calc_timeseries): must specify lon0 and lat0' sys.exit() if option == 'area_threshold' and threshold is None: print 'Error (calc_timeseries): must specify threshold' sys.exit() if option == 'transport_transect' and (point0 is None or point1 is None): print 'Error (calc_timeseries): must specify point0 and point1' sys.exit() # Build the grid if needed if option != 'time': grid = choose_grid(grid, first_file) if option == 'avg_sws_shelf': # Choose the right mask if shelf_option == 'full': shelf_mask = grid.sws_shelf_mask elif shelf_option == 'inner': shelf_mask = grid.sws_shelf_mask_inner elif shelf_option == 'outer': shelf_mask = grid.sws_shelf_mask_outer else: print 'Error (calc_timeseries): invalid shelf_option ' + shelf_option sys.exit() # Calculate timeseries on the first file if option == 'ismr': if mass_balance: melt, freeze = timeseries_ismr(first_file, grid, shelves=shelves, mass_balance=mass_balance, result=result) else: values = timeseries_ismr(first_file, grid, shelves=shelves, mass_balance=mass_balance, result=result) elif option == 'max': values = timeseries_max(first_file, var_name, grid, gtype=gtype, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) elif option == 'avg_sfc': values = timeseries_avg_sfc(first_file, var_name, grid, gtype=gtype) elif option == 'int_sfc': values = timeseries_int_sfc(first_file, var_name, grid, gtype=gtype) elif option == 'area_threshold': values = timeseries_area_threshold(first_file, var_name, threshold, grid, gtype=gtype) elif option == 'avg_fris': values = timeseries_avg_3d(first_file, var_name, grid, gtype=gtype, mask=grid.fris_mask) elif option == 'avg_sws_shelf': values = timeseries_avg_3d(first_file, var_name, grid, gtype=gtype, mask=shelf_mask) elif option == 'avg_domain': values = timeseries_avg_3d(first_file, var_name, grid, gtype=gtype) elif option == 'point_vavg': values = timeseries_point_vavg(first_file, var_name, lon0, lat0, grid, gtype=gtype) elif option == 'wed_gyre_trans': values = timeseries_wed_gyre(first_file, grid) elif option == 'watermass': values = timeseries_watermass_volume(first_file, grid, tmin=tmin, tmax=tmax, smin=smin, smax=smax) elif option == 'volume': values = timeseries_domain_volume(first_file, grid) elif option == 'transport_transect': values = timeseries_transport_transect(first_file, grid, point0, point1, direction=direction) elif option != 'time': print 'Error (calc_timeseries): invalid option ' + option sys.exit() # Read time axis time = netcdf_time(first_file, monthly=monthly) if isinstance(file_path, list): # More files to read for file in file_path[1:]: if option == 'ismr': if mass_balance: melt_tmp, freeze_tmp = timeseries_ismr(file, grid, shelves=shelves, mass_balance=mass_balance, result=result) else: values_tmp = timeseries_ismr(file, grid, shelves=shelves, mass_balance=mass_balance, result=result) elif option == 'max': values_tmp = timeseries_max(file, var_name, grid, gtype=gtype, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) elif option == 'avg_sfc': values_tmp = timeseries_avg_sfc(file, var_name, grid, gtype=gtype) elif option == 'int_sfc': values_tmp = timeseries_int_sfc(file, var_name, grid, gtype=gtype) elif option == 'area_threshold': values_tmp = timeseries_area_threshold(file, var_name, threshold, grid, gtype=gtype) elif option == 'avg_fris': values_tmp = timeseries_avg_3d(file, var_name, grid, gtype=gtype, mask=grid.fris_mask) elif option == 'avg_sws_shelf': values_tmp = timeseries_avg_3d(file, var_name, grid, gtype=gtype, mask=shelf_mask) elif option == 'avg_domain': values_tmp = timeseries_avg_3d(file, var_name, grid, gtype=gtype) elif option == 'point_vavg': values_tmp = timeseries_point_vavg(file, var_name, lon0, lat0, grid, gtype=gtype) elif option == 'wed_gyre_trans': values_tmp = timeseries_wed_gyre(file, grid) elif option == 'watermass': values_tmp = timeseries_watermass_volume(file, grid, tmin=tmin, tmax=tmax, smin=smin, smax=smax) elif option == 'volume': values_tmp = timeseries_domain_volume(file, grid) elif option == 'transport_transect': values_tmp = timeseries_transport_transect(file, grid, point0, point1, direction=direction) time_tmp = netcdf_time(file, monthly=monthly) # Concatenate the arrays if option == 'ismr' and mass_balance: melt = np.concatenate((melt, melt_tmp)) freeze = np.concatenate((freeze, freeze_tmp)) elif option != 'time': values = np.concatenate((values, values_tmp)) time = np.concatenate((time, time_tmp)) if option == 'ismr' and mass_balance: return time, melt, freeze elif option == 'time': return time else: return time, values
def ctd_cast_compare(loc, hovmoller_file, obs_file, grid, std=False, ens_hovmoller_files=None, month=2, fig_name=None): from scipy.io import loadmat ensemble = ens_hovmoller_files is not None grid = choose_grid(grid, None) # Get bounds on region [xmin, xmax, ymin, ymax] = region_bounds[loc] # Read obs f = loadmat(obs_file) obs_lat = np.squeeze(f['Lat']) obs_lon = np.squeeze(f['Lon']) obs_depth = -1 * np.squeeze(f['P']) obs_temp = np.transpose(f['PT']) obs_salt = np.transpose(f['S']) # Convert NaNs into mask obs_temp = np.ma.masked_where(np.isnan(obs_temp), obs_temp) obs_salt = np.ma.masked_where(np.isnan(obs_salt), obs_salt) # Find casts within given region index = (obs_lon >= xmin) * (obs_lon <= xmax) * (obs_lat >= ymin) * (obs_lat <= ymax) obs_temp = obs_temp[index, :] obs_salt = obs_salt[index, :] num_obs = obs_temp.shape[0] # Read model output model_temp = read_netcdf(hovmoller_file, loc + '_temp') model_salt = read_netcdf(hovmoller_file, loc + '_salt') if month != 0: # Select the month we want time = netcdf_time(hovmoller_file, monthly=False) index = [t.month == month for t in time] model_temp = model_temp[index, :] model_salt = model_salt[index, :] num_model = model_temp.shape[0] if ensemble: # Read model ensemble output, all in one ens_temp = None ens_salt = None ens_time = None for file_path in ens_hovmoller_files: temp_tmp = read_netcdf(file_path, loc + '_temp') salt_tmp = read_netcdf(file_path, loc + '_salt') time_tmp = netcdf_time(file_path, monthly=False) if ens_temp is None: ens_temp = temp_tmp ens_salt = salt_tmp ens_time = time_tmp else: ens_temp = np.concatenate((ens_temp, temp_tmp)) ens_salt = np.concatenate((ens_salt, salt_tmp)) ens_time = np.concatenate((ens_time, time_tmp)) if month != 0: index = [t.month == month for t in ens_time] ens_temp = ens_temp[index, :] ens_salt = ens_salt[index, :] # Set panels fig, gs = set_panels('1x2C0') # Wrap things up in lists for easier iteration obs_data = [obs_temp, obs_salt] model_data = [model_temp, model_salt] if ensemble: ens_data = [ens_temp, ens_salt] all_data = [obs_data, model_data, ens_data] depths = [obs_depth, grid.z, grid.z] colours = ['black', 'red', 'blue'] num_ranges = len(colours) titles = ['Temperature', 'Salinity'] if std: titles = [t + ' std' for t in titles] units = [deg_string + 'C', 'psu'] if std: vmin = [None, None] vmax = [None, None] else: vmin = [-2, 33] vmax = [2, 34.75] for i in range(2): ax = plt.subplot(gs[0, i]) if ensemble: # Plot transparent ranges, with means on top # OR just plot standard deviation for n in range(num_ranges): if std: ax.plot(np.std(all_data[n][i], axis=0), depths[n], color=colours[n], linewidth=2) else: ax.fill_betweenx(depths[n], np.amin(all_data[n][i], axis=0), x2=np.amax(all_data[n][i], axis=0), color=colours[n], alpha=0.3) ax.plot(np.mean(all_data[n][i], axis=0), depths[n], color=colours[n], linewidth=2) else: # Plot obs if std: ax.plot(np.std(obs_data[i], axis=0), obs_depth, color='black', linewidth=2) else: # Plot individual lines for n in range(num_obs): ax.plot(obs_data[i][n, :], obs_depth, color=(0.6, 0.6, 0.6), linewidth=1) # Plot obs mean in thicker dashedblack ax.plot(np.mean(obs_data[i], axis=0), obs_depth, color='black', linewidth=2, linestyle='dashed') # Plot model years if std: ax.plot(np.std(model_data[i], axis=0), grid.z, color='blue', linewidth=2) else: # Different colours for each year for n in range(num_model): ax.plot(model_data[i][n, :], grid.z, linewidth=1) # Plot model mean in thicker black ax.plot(np.mean(model_data[i], axis=0), grid.z, color='black', linewidth=2) ax.set_xlim([vmin[i], vmax[i]]) ax.grid(True) plt.title(titles[i], fontsize=16) plt.xlabel(units[i], fontsize=14) if i == 0: plt.ylabel('Depth (m)', fontsize=14) else: ax.set_yticklabels([]) if ensemble: plt.suptitle(loc + ': CTDs (black), ERA5 (red), PACE ensemble (blue)', fontsize=20) else: if std: plt.suptitle(loc + ': model (blue) vs CTDs (black)', fontsize=20) else: plt.suptitle(loc + ': model (colours) vs CTDs (grey)', fontsize=20) finished_plot(fig, fig_name=fig_name)
def ts_distribution_plot(file_path, region='all', grid=None, time_index=None, t_start=None, t_end=None, time_average=False, second_file_path=None, tmin=None, tmax=None, smin=None, smax=None, num_bins=1000, date_string=None, figsize=(8, 6), fig_name=None): # Build the grid if needed grid = choose_grid(grid, file_path) # Make sure we'll end up with a single record in time check_single_time(time_index, time_average) # Determine what to write about the date date_string = check_date_string(date_string, file_path, time_index) # Quick inner function to read data (THETA or SALT) def read_data(var_name): # First choose the right file if second_file_path is not None: file_path_use = find_variable(file_path, second_file_path) else: file_path_use = file_path data = read_netcdf(file_path_use, var_name, time_index=time_index, t_start=t_start, t_end=t_end, time_average=time_average) return data # Call this function for each variable temp = read_data('THETA') salt = read_data('SALT') if region == 'all': mask = grid.hfac > 0 elif region == 'cavities': mask = grid.ice_mask else: mask = grid.get_region_mask(region) # Make the bins volume, temp_centres, salt_centres, temp_edges, salt_edges = ts_binning( temp, salt, grid, mask, num_bins=num_bins) # Find the volume bounds for plotting min_vol = np.log(np.amin(volume)) max_vol = np.log(np.amax(volume)) # Calculate the surface freezing point for plotting tfreeze_sfc = tfreeze(salt_centres, 0) # Choose the plotting bounds if not set if tmin is None: tmin = temp_bins[0] if tmax is None: tmax = temp_bins[-1] if smin is None: smin = salt_bins[0] if smax is None: smax = salt_bins[-1] # Construct the title title = 'Water masses' if region == 'all': pass elif region == 'cavities': title += ' in ice shelf cavities' elif region.endswith('cavity'): title += ' in ' + region_names[region[:region.index('_cavity')]] else: title += ' in ' + region_names[region] if date_string != '': title += ', ' + date_string # Plot fig, ax = plt.subplots(figsize=figsize) # Use a log scale for visibility img = plt.pcolor(salt_centres, temp_centres, np.log(volume), vmin=min_vol, vmax=max_vol) # Add the surface freezing point plt.plot(salt_centres, tfreeze_sfc, color='black', linestyle='dashed', linewidth=2) ax.grid(True) ax.set_xlim([smin, smax]) ax.set_ylim([tmin, tmax]) plt.xlabel('Salinity (psu)') plt.ylabel('Temperature (' + deg_string + 'C)') plt.colorbar(img) plt.text(.9, .6, 'log of volume', ha='center', rotation=-90, transform=fig.transFigure) plt.title(title) finished_plot(fig, fig_name=fig_name)