def moc_flux(variables, **kwargs): """Mass weighted column integrated meridional flux by time and zonal mean flow.""" # Specify upper bound of vertical integrals. p_top = kwargs.get('p_top', 0.) trop = np.where(nc.variables['level'][:] >= p_top) # Apply mass flux correction to zonal mean data. v_znl = np.squeeze(variables[-1][:,trop]).mean(axis=-1) v_north = np.where(v_znl > 0., v_znl, 0.) v_south = np.where(v_znl < 0., v_znl, 0.) lev_thick = np.squeeze(level_thickness(nc)[:,trop])/grav lev_thick = lev_thick[np.newaxis,:,np.newaxis] # Adjustment imposes that column integrated mass flux is zero. mass_adj = -((v_north*lev_thick).sum(axis=1) / (v_south*lev_thick).sum(axis=1)) # Integrate the specified flux by the adjusted v vertically and zonally. flux_type = kwargs['flux_type'] if flux_type == 'dse': flux = (np.squeeze(dse(variables[:2])[:,trop]).mean(axis=-1) * (v_north + v_south * mass_adj[:,np.newaxis,:])) elif flux_type == 'mse': flux = (np.squeeze(mse(variables[:3])[:,trop]).mean(axis=-1) * (v_north + v_south * mass_adj[:,np.newaxis,:])) elif flux_type == 'moisture': flux = L_v*(np.squeeze(variables[0][:,trop]).mean(axis=-1) * (v_north + v_south * mass_adj[:,np.newaxis,:])) return (2.*np.pi*r_e*np.cos(np.deg2rad(nc.variables[LAT_STR][:])) * (flux*lev_thick).sum(axis=1))
def moc_flux(variables, **kwargs): """Mass weighted column integrated meridional flux by time and zonal mean flow.""" # Specify upper bound of vertical integrals. p_top = kwargs.get('p_top', 0.) trop = np.where(nc.variables['level'][:] >= p_top) # Apply mass flux correction to zonal mean data. v_znl = np.squeeze(variables[-1][:, trop]).mean(axis=-1) v_north = np.where(v_znl > 0., v_znl, 0.) v_south = np.where(v_znl < 0., v_znl, 0.) lev_thick = np.squeeze(level_thickness(nc)[:, trop]) / grav lev_thick = lev_thick[np.newaxis, :, np.newaxis] # Adjustment imposes that column integrated mass flux is zero. mass_adj = -((v_north * lev_thick).sum(axis=1) / (v_south * lev_thick).sum(axis=1)) # Integrate the specified flux by the adjusted v vertically and zonally. flux_type = kwargs['flux_type'] if flux_type == 'dse': flux = (np.squeeze(dse(variables[:2])[:, trop]).mean(axis=-1) * (v_north + v_south * mass_adj[:, np.newaxis, :])) elif flux_type == 'mse': flux = (np.squeeze(mse(variables[:3])[:, trop]).mean(axis=-1) * (v_north + v_south * mass_adj[:, np.newaxis, :])) elif flux_type == 'moisture': flux = L_v * (np.squeeze(variables[0][:, trop]).mean(axis=-1) * (v_north + v_south * mass_adj[:, np.newaxis, :])) return (2. * np.pi * r_e * np.cos(np.deg2rad(nc.variables[LAT_STR][:])) * (flux * lev_thick).sum(axis=1))
def mass_flux(variables, **kwargs): """Meridional mass flux by time and zonal mean flow.""" # Apply mass flux correction. lev_thick = level_thickness(nc)[np.newaxis,:,np.newaxis]/grav v_znl = variables[0].mean(axis=-1) v_north = np.where(v_znl > 0., v_znl, 0.) v_south = np.where(v_znl < 0., v_znl, 0.) mass_adj = -((v_north*lev_thick).sum(axis=1) / (v_south*lev_thick).sum(axis=1)) # Integrate vertically and pick level where magnitude maximized. int_flux = ((v_north + v_south*mass_adj[:,np.newaxis,:]) * lev_thick).cumsum(axis=1) flux_pos = np.amax(int_flux, axis=1) flux_neg = np.amin(int_flux, axis=1) return (2.*np.pi*r_e*np.cos(np.deg2rad(nc.variables[LAT_STR][:])) * np.where(flux_pos > - flux_neg, flux_pos, flux_neg))
def mass_flux(variables, **kwargs): """Meridional mass flux by time and zonal mean flow.""" # Apply mass flux correction. lev_thick = level_thickness(nc)[np.newaxis, :, np.newaxis] / grav v_znl = variables[0].mean(axis=-1) v_north = np.where(v_znl > 0., v_znl, 0.) v_south = np.where(v_znl < 0., v_znl, 0.) mass_adj = -((v_north * lev_thick).sum(axis=1) / (v_south * lev_thick).sum(axis=1)) # Integrate vertically and pick level where magnitude maximized. int_flux = ((v_north + v_south * mass_adj[:, np.newaxis, :]) * lev_thick).cumsum(axis=1) flux_pos = np.amax(int_flux, axis=1) flux_neg = np.amin(int_flux, axis=1) return (2. * np.pi * r_e * np.cos(np.deg2rad(nc.variables[LAT_STR][:])) * np.where(flux_pos > -flux_neg, flux_pos, flux_neg))
def st_eddy_flux(variables, **kwargs): """Mass weighted column integrated meridional flux by stationary eddies.""" p_top = kwargs.get('p_top', 0.) trop = np.where(nc.variables['level'][:] >= p_top) v = np.squeeze(variables[-1][:,trop]) flux_type = kwargs['flux_type'] if flux_type == 'dse': m = np.squeeze(dse(variables[:2])[:,trop]) elif flux_type == 'mse': m = np.squeeze(mse(variables[:3])[:,trop]) elif flux_type == 'moisture': m = np.squeeze(variables[0][:,trop])*L_v lev_thick = np.squeeze(level_thickness(nc)[:,trop])/grav lev_thick = lev_thick[np.newaxis,:,np.newaxis,np.newaxis] flux = ((m - m.mean(axis=-1)[:,:,:,np.newaxis]) * (v - v.mean(axis=-1)[:,:,:,np.newaxis])) return (2.*np.pi*r_e*np.cos(np.deg2rad(nc.variables[LAT_STR][:])) * (flux*lev_thick).sum(axis=1).mean(axis=-1))
def vert_centroid(arr, level, p_bot=850., p_top=150.): """ Compute the vertical centroid of some vertically defined field. """ desired_levs = np.where((level <= p_bot) & (level >= p_top)) lev_thick = level_thickness(level)/100. # Add axes for later broadcasting and truncate to desired vertical levels. level = level[desired_levs]; level = level[:,np.newaxis,np.newaxis] lev_thick = lev_thick[desired_levs] lev_thick = lev_thick[:,np.newaxis,np.newaxis] arr = arr[desired_levs] # For 1D arrays, have to move the vertical coordinate to leftmost dim. if arr.ndim == 1: arr = np.atleast_3d(arr).swapaxes(0,1) else: arr = np.atleast_3d(arr) return (np.sum(arr*level*lev_thick, axis=0) / np.sum(arr*lev_thick, axis=0))
def st_eddy_flux(variables, **kwargs): """Mass weighted column integrated meridional flux by stationary eddies.""" p_top = kwargs.get('p_top', 0.) trop = np.where(nc.variables['level'][:] >= p_top) v = np.squeeze(variables[-1][:, trop]) flux_type = kwargs['flux_type'] if flux_type == 'dse': m = np.squeeze(dse(variables[:2])[:, trop]) elif flux_type == 'mse': m = np.squeeze(mse(variables[:3])[:, trop]) elif flux_type == 'moisture': m = np.squeeze(variables[0][:, trop]) * L_v lev_thick = np.squeeze(level_thickness(nc)[:, trop]) / grav lev_thick = lev_thick[np.newaxis, :, np.newaxis, np.newaxis] flux = ((m - m.mean(axis=-1)[:, :, :, np.newaxis]) * (v - v.mean(axis=-1)[:, :, :, np.newaxis])) return (2. * np.pi * r_e * np.cos(np.deg2rad(nc.variables[LAT_STR][:])) * (flux * lev_thick).sum(axis=1).mean(axis=-1))
def vert_centroid(arr, level, p_bot=850., p_top=150.): """ Compute the vertical centroid of some vertically defined field. """ desired_levs = np.where((level <= p_bot) & (level >= p_top)) lev_thick = level_thickness(level) / 100. # Add axes for later broadcasting and truncate to desired vertical levels. level = level[desired_levs] level = level[:, np.newaxis, np.newaxis] lev_thick = lev_thick[desired_levs] lev_thick = lev_thick[:, np.newaxis, np.newaxis] arr = arr[desired_levs] # For 1D arrays, have to move the vertical coordinate to leftmost dim. if arr.ndim == 1: arr = np.atleast_3d(arr).swapaxes(0, 1) else: arr = np.atleast_3d(arr) return (np.sum(arr * level * lev_thick, axis=0) / np.sum(arr * lev_thick, axis=0))
def moc_flux_raw(variables, **kwargs): """Mass weighted column integrated meridional flux by time and zonal mean flow, without applying column mass flux correction.""" # Specify upper bound of vertical integrals. p_top = kwargs.get('p_top', 0.) trop = np.where(nc.variables['level'][:] >= p_top) # Take zonal mean and calculate grid level thicknesses. v_znl = np.squeeze(variables[-1][:,trop]).mean(axis=-1) lev_thick = np.squeeze(level_thickness(nc)[:,trop])/grav lev_thick = lev_thick[np.newaxis,:,np.newaxis] # Integrate the specified flux vertically and zonally. flux_type = kwargs.get('flux_type', 'mse') if flux_type == 'dse': flux = np.squeeze(dse(variables[:2])[:,trop]).mean(axis=-1) * v_znl elif flux_type == 'mse': flux = np.squeeze(mse(variables[:3])[:,trop]).mean(axis=-1) * v_znl elif flux_type == 'moisture': flux = L_v*np.squeeze(variables[0][:,trop]).mean(axis=-1) * v_znl return (2.*np.pi*r_e*np.cos(np.deg2rad(nc.variables[LAT_STR][:])) * (flux*lev_thick).sum(axis=1))
def moc_flux_raw(variables, **kwargs): """Mass weighted column integrated meridional flux by time and zonal mean flow, without applying column mass flux correction.""" # Specify upper bound of vertical integrals. p_top = kwargs.get('p_top', 0.) trop = np.where(nc.variables['level'][:] >= p_top) # Take zonal mean and calculate grid level thicknesses. v_znl = np.squeeze(variables[-1][:, trop]).mean(axis=-1) lev_thick = np.squeeze(level_thickness(nc)[:, trop]) / grav lev_thick = lev_thick[np.newaxis, :, np.newaxis] # Integrate the specified flux vertically and zonally. flux_type = kwargs.get('flux_type', 'mse') if flux_type == 'dse': flux = np.squeeze(dse(variables[:2])[:, trop]).mean(axis=-1) * v_znl elif flux_type == 'mse': flux = np.squeeze(mse(variables[:3])[:, trop]).mean(axis=-1) * v_znl elif flux_type == 'moisture': flux = L_v * np.squeeze(variables[0][:, trop]).mean(axis=-1) * v_znl return (2. * np.pi * r_e * np.cos(np.deg2rad(nc.variables[LAT_STR][:])) * (flux * lev_thick).sum(axis=1))