def __call__(self, state): """ Calculate longwave optical depth from input state. Args: state (dict): A model state dictionary. Returns: tendencies (dict): A dictionary whose keys are strings indicating state quantities and values are the time derivative of those quantities in units/second at the time of the input state. diagnostics (dict): A dictionary whose keys are strings indicating state quantities and values are the value of those quantities at the time of the input state. """ lat = get_numpy_array(state['latitude'].to_units('degrees_north'), out_dims=('x', 'y', 'z')) sigma_interface = get_numpy_array( state['sigma_on_interface_levels'].to_units(''), out_dims=('x', 'y', 'z')) tau = DataArray( get_frierson_06_tau(lat, sigma_interface, self._tau0e, self._tau0p, self._fl), dims=combine_dimensions( [state['latitude'], state['sigma_on_interface_levels']], out_dims=('x', 'y', 'z')), attrs={ 'units': '' }).squeeze() return { 'longwave_optical_depth_on_interface_levels': tau, }
def _get_k_t(self, latitude, sigma): out_dims = combine_dimensions([latitude, sigma], out_dims=('x', 'y', 'z')) latitude = get_numpy_array( latitude.to_units('degrees_N'), out_dims=('x', 'y', 'z')) sigma = get_numpy_array(sigma, out_dims=('x', 'y', 'z')) return DataArray( self._k_a + (self._k_s - self._k_a) * np.maximum(0, (sigma - self._sigma_b)/(1 - self._sigma_b)) * np.cos(np.radians(latitude))**4, dims=out_dims, attrs={'units': 's^-1'})
def __call__(self, state): """ Get heating tendencies and longwave fluxes. Args: state (dict): A model state dictionary. Returns: tendencies (dict), diagnostics (dict): * A dictionary whose keys are strings indicating state quantities and values are the time derivative of those quantities in units/second at the time of the input state. * A dictionary whose keys are strings indicating state quantities and values are the value of those quantities at the time of the input state. """ tau = get_numpy_array( state['longwave_optical_depth_on_interface_levels'].to_units(''), out_dims=('x', 'y', 'z')) T = get_numpy_array(state['air_temperature'].to_units('degK'), out_dims=('x', 'y', 'z')) p_interface = get_numpy_array( state['air_pressure_on_interface_levels'].to_units('Pa'), out_dims=('x', 'y', 'z')) Ts = get_numpy_array(state['surface_temperature'].to_units('degK'), out_dims=('x', 'y')) (downward_flux, upward_flux, net_lw_flux, lw_temperature_tendency, tau) = get_longwave_fluxes(T, p_interface, Ts, tau, self._stefan_boltzmann, self._g, self._Cpd) tendencies = self.create_state_dict_for('_climt_tendencies', state) tendencies['air_temperature'].values = lw_temperature_tendency diagnostics = self.create_state_dict_for('_climt_diagnostics', state) diagnostics['downwelling_longwave_flux_in_air'].values = downward_flux diagnostics['upwelling_longwave_flux_in_air'].values = upward_flux diagnostics['longwave_heating_rate'].values = \ tendencies['air_temperature'].to_units('degK/day') return tendencies, diagnostics
def _get_Teq(self, latitude, air_pressure): out_dims = combine_dimensions( [latitude, air_pressure], out_dims=('x', 'y', 'z')) latitude = get_numpy_array( latitude.to_units('degrees_N'), out_dims=['x', 'y', 'z']) air_pressure = get_numpy_array( air_pressure.to_units('Pa'), out_dims=['x', 'y', 'z']) return DataArray(np.maximum( 200, (315 - self._delta_T_y*np.sin(np.radians(latitude))**2 - self._delta_theta_z*np.log(air_pressure/self._p0)*np.cos(np.radians(latitude))**2 ) * (air_pressure/self._p0)**self._kappa), dims=out_dims, attrs={'units': 'degK'})
def test_restore_dimensions_starz_to_zyx_has_no_attrs(): array = DataArray( np.random.randn(2, 3, 4), dims=['z', 'y', 'x'], attrs={'units': ''} ) numpy_array = get_numpy_array(array, ['*', 'z']) restored_array = restore_dimensions( numpy_array, from_dims=['*', 'z'], result_like=array) assert len(restored_array.attrs) == 0
def test_get_numpy_array_complicated_asterisk(): array = DataArray( np.random.randn(2, 3, 4, 5), dims=['x', 'h', 'y', 'q'], attrs={'units': ''} ) numpy_array = get_numpy_array(array, ['*', 'x', 'y']) for i in range(2): for j in range(4): assert np.allclose(numpy_array[:, i, j], array.values[i, :, j, :].flatten())
def test_get_numpy_array_3d_no_change(): array = DataArray( np.random.randn(2, 3, 4), dims=['x', 'y', 'z'], attrs={'units': ''}, ) numpy_array = get_numpy_array(array, ['x', 'y', 'z']) assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values) assert np.all(numpy_array == array.values) assert numpy_array.base is array.values
def test_get_numpy_array_retrieves_explicit_dimensions(): array = DataArray( np.random.randn(2, 3), dims=['alpha', 'zeta'], attrs={'units': ''}, ) numpy_array = get_numpy_array(array, ['zeta', 'alpha']) assert numpy_array.shape == (3, 2) assert np.all(np.transpose(numpy_array, (1, 0)) == array.values) assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values) assert numpy_array.base is array.values
def test_restore_dimensions_starz_to_zalphabeta(): array = DataArray( np.random.randn(2, 3, 4), dims=['z', 'alpha', 'beta'], attrs={'units': ''} ) numpy_array = get_numpy_array(array, ['*', 'z']) restored_array = restore_dimensions( numpy_array, from_dims=['*', 'z'], result_like=array) assert np.all(restored_array.values == array.values) assert len(restored_array.attrs) == 0
def test_restore_dimensions_complicated_asterisk(): array = DataArray( np.random.randn(2, 3, 4, 5), dims=['x', 'h', 'y', 'q'], attrs={'units': ''} ) numpy_array = get_numpy_array(array, ['*', 'x', 'y']) restored_array = restore_dimensions( numpy_array, from_dims=['*', 'x', 'y'], result_like=array) assert np.all(restored_array.values == array.values) assert len(restored_array.attrs) == 0
def test_get_numpy_array_1d(): array = DataArray( np.random.randn(2), dims=['y'], attrs={'units': ''}, ) numpy_array = get_numpy_array(array, ['y']) assert numpy_array.shape == (2,) assert np.all(numpy_array == array.values) assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values) assert numpy_array.base is array.values
def test_get_numpy_array_asterisk_creates_new_dim(): array = DataArray( np.random.randn(2), dims=['x'], attrs={'units': ''}, ) numpy_array = get_numpy_array(array, ['x', '*']) assert numpy_array.shape == (2, 1) assert np.all(numpy_array[:, 0] == array.values) assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values) assert numpy_array.base is array.values
def test_get_numpy_array_invalid_dimension_collected_by_asterisk(): array = DataArray( np.random.randn(2), dims=['sheep'], attrs={'units': ''}, ) numpy_array = get_numpy_array(array, ['*']) assert numpy_array.shape == (2,) assert np.all(numpy_array == array.values) assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values) assert numpy_array.base is array.values
def test_get_numpy_array_creates_new_dim_in_front(): array = DataArray( np.random.randn(2), dims=['x'], attrs={'units': ''}, ) numpy_array = get_numpy_array(array, ['y', 'x']) assert numpy_array.shape == (1, 2) assert np.all(numpy_array[0, :] == array.values) assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values) assert numpy_array.base is array.values
def test_get_numpy_array_asterisk_flattens(): array = DataArray( np.random.randn(2, 3), dims=['y', 'z'], attrs={'units': ''}, ) numpy_array = get_numpy_array(array, ['*']) assert numpy_array.shape == (6,) assert np.all(numpy_array.reshape((2, 3)) == array.values) assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values) assert numpy_array.base is array.values
def test_get_numpy_array_2d_reverse(): array = DataArray( np.random.randn(2, 3), dims=['y', 'z'], attrs={'units': ''}, ) numpy_array = get_numpy_array(array, ['z', 'y']) assert numpy_array.shape == (3, 2) assert np.all(np.transpose(numpy_array, (1, 0)) == array.values) assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values) assert numpy_array.base is array.values
def get_array_from_state(state, quantity_name, quantity_units, quantity_dims): if quantity_name not in state: raise IndexError( 'The input state does not contain {}'.format(quantity_name)) return get_numpy_array( state[quantity_name].to_units(quantity_units), quantity_dims)
def test_restore_dimensions_starz_to_zyx_doesnt_copy(): array = DataArray( np.random.randn(2, 3, 4), dims=['z', 'y', 'x'], attrs={'units': ''} ) numpy_array = get_numpy_array(array, ['*', 'z']) restored_array = restore_dimensions( numpy_array, from_dims=['*', 'z'], result_like=array) assert np.byte_bounds(restored_array.values) == np.byte_bounds( array.values) assert restored_array.values.base is array.values
def _get_k_v(self, sigma): out_dims = combine_dimensions([sigma], out_dims=('x', 'y', 'z')) sigma = get_numpy_array(sigma.to_units(''), out_dims=('x', 'y', 'z')) return DataArray( self._k_f * np.maximum( 0, (sigma - self._sigma_b)/(1 - self._sigma_b)), dims=out_dims, attrs={'units': 's^-1'})
def test_get_numpy_array_zyx_to_starz_doesnt_copy(): array = DataArray( np.random.randn(2, 3, 4), dims=['z', 'y', 'x'], attrs={'units': ''} ) original_array = array.values numpy_array = get_numpy_array(array, ['*', 'z']) for i in range(2): assert np.all(numpy_array[:, i] == array.values[i, :, :].flatten()) assert original_array is array.values assert np.byte_bounds(numpy_array) == np.byte_bounds(array.values) assert numpy_array.base is array.values
def test_restore_dimensions_starz_to_zyx_with_attrs(): array = DataArray( np.random.randn(2, 3, 4), dims=['z', 'y', 'x'], attrs={'units': ''} ) numpy_array = get_numpy_array(array, ['*', 'z']) restored_array = restore_dimensions( numpy_array, from_dims=['*', 'z'], result_like=array, result_attrs={'units': 'K'}) assert np.all(restored_array.values == array.values) assert len(restored_array.attrs) == 1 assert 'units' in restored_array.attrs assert restored_array.attrs['units'] == 'K'
def test_get_numpy_array_no_dimensions_listed_raises_value_error(): array = DataArray( np.random.randn(2), dims=['z'], attrs={'units': ''}, ) try: numpy_array = get_numpy_array(array, []) except ValueError: pass except Exception as err: raise err else: raise AssertionError('Expected ValueError but no error was raised')
def test_get_numpy_array_not_enough_out_dims(): array = DataArray( np.random.randn(2, 3), dims=['x', 'y'], attrs={'units': ''}, ) try: numpy_array = get_numpy_array(array, ['x']) except ValueError: pass except Exception as err: raise err else: raise AssertionError('Expected ValueError but no error was raised')
def test_restore_dimensions_removes_dummy_axes(): array = DataArray( np.random.randn(2), dims=['z'], attrs={'units': ''} ) numpy_array = get_numpy_array(array, ['x', 'y', 'z']) restored_array = restore_dimensions( numpy_array, from_dims=['x', 'y', 'z'], result_like=array) assert np.all(restored_array.values == array.values) assert len(restored_array.attrs) == 0 assert np.byte_bounds(restored_array.values) == np.byte_bounds( array.values) assert restored_array.values.base is array.values
def __call__(self, state, timestep): ''' Calculate surface and boundary layer tendencies. Args: state (dict): The model state dictionary timestep (timedelta): The model timestep Returns: state (dict), diagnostics(dict) : * The updated model state. * diagnostics for Simple Physics ''' if 'latitude' not in state.keys(): raise IndexError( 'Simple Physics: State must contain a quantity called latitude' ) U = get_numpy_array(state['eastward_wind'].to_units('m/s'), ['x', 'y', 'z']) V = get_numpy_array(state['northward_wind'].to_units('m/s'), ['x', 'y', 'z']) P = get_numpy_array(state['air_pressure'].to_units('Pa'), ['x', 'y', 'z']) Pint = get_numpy_array( state['air_pressure_on_interface_levels'].to_units('Pa'), ['x', 'y', 'z']) T = get_numpy_array(state['air_temperature'].to_units('degK'), ['x', 'y', 'z']) q = get_numpy_array(state['specific_humidity'].to_units('g/g'), ['x', 'y', 'z']) q_surface = get_numpy_array( state['surface_specific_humidity'].to_units('g/g'), ['x', 'y']) Ts = get_numpy_array(state['surface_temperature'].to_units('degK'), ['x', 'y']) Ps = get_numpy_array(state['surface_air_pressure'].to_units('Pa'), ['x', 'y']) lats = get_numpy_array(state['latitude'].to_units('degrees_north'), ['x', 'y']) lats = np.asfortranarray(lats, dtype=np.double) if lats.shape[0] == 1: # 1-d array only num_longitudes = Ts.shape[0] lat_list = [lats[0, :] for i in range(num_longitudes)] lats = np.asfortranarray(np.stack(lat_list, axis=0)) dims_mid = combine_dimensions([ state['surface_temperature'], state['air_temperature'], state['eastward_wind'], state['northward_wind'] ], ['x', 'y', 'z']) (t_out, u_out, v_out, q_out, precip_out, sensible_heat_flux, latent_heat_flux) = phys.get_new_state(U, V, T, P, Pint, q, Ps, Ts, q_surface, lats, timestep.total_seconds()) latent_heat_flux[latent_heat_flux < 0] = 0 new_state = { 'eastward_wind': DataArray(u_out, dims=dims_mid, attrs=state['eastward_wind'].attrs), 'northward_wind': DataArray(v_out, dims=dims_mid, attrs=state['northward_wind'].attrs), 'air_temperature': DataArray(t_out, dims=dims_mid, attrs=state['air_temperature'].attrs), 'specific_humidity': DataArray(q_out, dims=dims_mid, attrs=state['specific_humidity'].attrs), } diagnostics = self.create_state_dict_for('_climt_diagnostics', state) diagnostics['stratiform_precipitation_rate'].values[:] = precip_out diagnostics[ 'surface_upward_sensible_heat_flux'].values[:] = sensible_heat_flux diagnostics[ 'surface_upward_latent_heat_flux'].values[:] = latent_heat_flux return diagnostics, new_state
def __call__(self, state): """ Get heating tendencies and longwave fluxes. Args: state (dict): The model state dictionary. Returns: tendencies (dict), diagnostics (dict): * The longwave heating tendency. * The upward/downward longwave fluxes for cloudy and clear sky conditions. """ raw_arrays = self.get_numpy_arrays_from_state('_climt_inputs', state) Q = get_numpy_array(state['specific_humidity'].to_units('g/g'), ['x', 'y', 'z']) Q = mass_to_volume_mixing_ratio(Q, 18.02) mid_level_shape = raw_arrays['air_temperature'].shape if self._calc_Tint: Tint = get_interface_values( raw_arrays['air_temperature'], raw_arrays['surface_temperature'], raw_arrays['air_pressure'], raw_arrays['air_pressure_on_interface_levels']) else: Tint = raw_arrays['air_temperature_on_interface_levels'] diag_dict = self.create_state_dict_for('_climt_diagnostics', state) diag_arrays = numpy_version_of(diag_dict) tend_dict = self.create_state_dict_for('_climt_tendencies', state) tend_arrays = numpy_version_of(tend_dict) # TODO add dflx_dt as well raw_f_arrays = {} diag_f_arrays = {} tend_f_arrays = {} for quantity in raw_arrays.keys(): raw_f_arrays[quantity] = np.asfortranarray( raw_arrays[quantity].transpose()) for quantity in diag_arrays.keys(): diag_f_arrays[quantity] = np.asfortranarray( diag_arrays[quantity].transpose()) for quantity in tend_arrays.keys(): tend_f_arrays[quantity] = np.asfortranarray( tend_arrays[quantity].transpose()) Tint_f = np.asfortranarray(Tint.transpose()) Q_f = np.asfortranarray(Q.transpose()) _rrtmg_lw.rrtm_calculate_longwave_fluxes( mid_level_shape[0], mid_level_shape[1], mid_level_shape[2], raw_f_arrays['air_pressure'], raw_f_arrays['air_pressure_on_interface_levels'], raw_f_arrays['air_temperature'], Tint_f, raw_f_arrays['surface_temperature'], Q_f, raw_f_arrays['mole_fraction_of_ozone_in_air'], raw_f_arrays['mole_fraction_of_carbon_dioxide_in_air'], raw_f_arrays['mole_fraction_of_methane_in_air'], raw_f_arrays['mole_fraction_of_nitrous_oxide_in_air'], raw_f_arrays['mole_fraction_of_oxygen_in_air'], raw_f_arrays['mole_fraction_of_cfc11_in_air'], raw_f_arrays['mole_fraction_of_cfc12_in_air'], raw_f_arrays['mole_fraction_of_cfc22_in_air'], raw_f_arrays['mole_fraction_of_carbon_tetrachloride_in_air'], raw_f_arrays['surface_longwave_emissivity'], raw_f_arrays['cloud_area_fraction_in_atmosphere_layer'], raw_f_arrays['longwave_optical_thickness_due_to_aerosol'], diag_f_arrays['upwelling_longwave_flux_in_air'], diag_f_arrays['downwelling_longwave_flux_in_air'], tend_f_arrays['air_temperature'], diag_f_arrays['upwelling_longwave_flux_in_air_assuming_clear_sky'], diag_f_arrays[ 'downwelling_longwave_flux_in_air_assuming_clear_sky'], diag_f_arrays['longwave_heating_rate_assuming_clear_sky'], raw_f_arrays['longwave_optical_thickness_due_to_cloud'], raw_f_arrays['mass_content_of_cloud_ice_in_atmosphere_layer'], raw_f_arrays[ 'mass_content_of_cloud_liquid_water_in_atmosphere_layer'], raw_f_arrays['cloud_ice_particle_size'], raw_f_arrays['cloud_water_droplet_radius']) for quantity in diag_dict.keys(): diag_dict[quantity].values = diag_f_arrays[quantity].transpose() for quantity in tend_dict.keys(): tend_dict[quantity].values = tend_f_arrays[quantity].transpose() diag_dict['longwave_heating_rate'].values = tend_dict[ 'air_temperature'].values return tend_dict, diag_dict
def __call__(self, state, timestep): """ Gets diagnostics from the current model state and steps the state forward in time according to the timestep. Args: state (dict): A model state dictionary. Will be updated with any diagnostic quantities produced by this object for the time of the input state. Returns: next_state (dict): A dictionary whose keys are strings indicating state quantities and values are the value of those quantities at the timestep after input state. Raises: KeyError: If a required quantity is missing from the state. InvalidStateException: If state is not a valid input for the Implicit instance for other reasons. """ T = get_numpy_array(state['air_temperature'].to_units('degK'), out_dims=('x', 'y', 'z')) q = get_numpy_array(state['specific_humidity'].to_units('kg/kg'), out_dims=('x', 'y', 'z')) p = get_numpy_array(state['air_pressure'].to_units('Pa'), out_dims=('x', 'y', 'z')) p_interface = get_numpy_array( state['air_pressure_on_interface_levels'].to_units('Pa'), out_dims=('x', 'y', 'z')) q_sat = bolton_q_sat(T, p, self._Rd, self._Rh2O) saturated = q > q_sat dqsat_dT = bolton_dqsat_dT(T[saturated], self._Lv, self._Rh2O, q_sat[saturated]) condensed_q = np.zeros_like(q) condensed_q[saturated] = (q[saturated] - q_sat[saturated]) / ( 1 + self._Lv / self._Cpd * dqsat_dT) new_q = q.copy() new_T = T.copy() new_q[saturated] -= condensed_q[saturated] new_T[saturated] += self._Lv / self._Cpd * condensed_q[saturated] mass = (p_interface[:, :, 1:] - p_interface[:, :, :-1]) / (self._g * self._rhow) precipitation = np.sum(condensed_q * mass, axis=2) dims_3d = combine_dimensions([ state['air_temperature'], state['specific_humidity'], state['air_pressure'] ], out_dims=('x', 'y', 'z')) dims_2d = dims_3d[:-1] diagnostics = { 'column_integrated_precipitation_rate': DataArray(precipitation / timestep.total_seconds(), dims=dims_2d, attrs={ 'units': 'kg/s' }).squeeze() } new_state = { 'air_temperature': DataArray(new_T, dims=dims_3d, attrs=state['air_temperature'].attrs).squeeze(), 'specific_humidity': DataArray(new_q, dims=dims_3d, attrs=state['specific_humidity'].attrs).squeeze(), } return new_state, diagnostics
def __call__(self, state): """ Get heating tendencies and shortwave fluxes. Args: state (dict): The model state dictionary. Returns: tendencies (dict), diagnostics (dict): * The shortwave heating tendency. * The upward/downward shortwave fluxes for cloudy and clear sky conditions. """ raw_arrays = self.get_numpy_arrays_from_state('_climt_inputs', state) Q = get_numpy_array(state['specific_humidity'].to_units('g/g'), ['x', 'y', 'z']) Q = mass_to_volume_mixing_ratio(Q, 18.02) mid_level_shape = raw_arrays['air_temperature'].shape Tint = get_interface_values( raw_arrays['air_temperature'], raw_arrays['surface_temperature'], raw_arrays['air_pressure'], raw_arrays['air_pressure_on_interface_levels']) diag_dict = self.create_state_dict_for('_climt_diagnostics', state) diag_arrays = self.get_numpy_arrays_from_state('_climt_diagnostics', diag_dict) tend_dict = self.create_state_dict_for('_climt_tendencies', state) tend_arrays = numpy_version_of(tend_dict) model_time = state['time'] if self._ignore_day_of_year: day_of_year = 0 else: day_of_year = model_time.timetuple().tm_yday cos_zenith_angle = np.asfortranarray(np.cos( raw_arrays['zenith_angle'])) raw_f_arrays = {} diag_f_arrays = {} tend_f_arrays = {} for quantity in raw_arrays.keys(): if quantity not in [ 'flux_adjustment_for_earth_sun_distance', 'solar_cycle_fraction' ]: raw_f_arrays[quantity] = np.asfortranarray( raw_arrays[quantity].transpose()) else: raw_f_arrays[quantity] = raw_arrays[quantity] for quantity in diag_arrays.keys(): diag_f_arrays[quantity] = np.asfortranarray( diag_arrays[quantity].transpose()) for quantity in tend_arrays.keys(): tend_f_arrays[quantity] = np.asfortranarray( tend_arrays[quantity].transpose()) Tint_f = np.asfortranarray(Tint.transpose()) Q_f = np.asfortranarray(Q.transpose()) zenith_f = np.asfortranarray(cos_zenith_angle.transpose()) _rrtmg_sw.rrtm_calculate_shortwave_fluxes( mid_level_shape[0], mid_level_shape[1], mid_level_shape[2], day_of_year, raw_f_arrays['solar_cycle_fraction'], raw_f_arrays['flux_adjustment_for_earth_sun_distance'], raw_f_arrays['air_pressure'], raw_f_arrays['air_pressure_on_interface_levels'], raw_f_arrays['air_temperature'], Tint_f, raw_f_arrays['surface_temperature'], Q_f, raw_f_arrays['mole_fraction_of_ozone_in_air'], raw_f_arrays['mole_fraction_of_carbon_dioxide_in_air'], raw_f_arrays['mole_fraction_of_methane_in_air'], raw_f_arrays['mole_fraction_of_nitrous_oxide_in_air'], raw_f_arrays['mole_fraction_of_oxygen_in_air'], raw_f_arrays['surface_albedo_for_direct_shortwave'], raw_f_arrays['surface_albedo_for_direct_near_infrared'], raw_f_arrays['surface_albedo_for_diffuse_shortwave'], raw_f_arrays['surface_albedo_for_diffuse_near_infrared'], zenith_f, raw_f_arrays['cloud_area_fraction_in_atmosphere_layer'], diag_f_arrays['upwelling_shortwave_flux_in_air'], diag_f_arrays['downwelling_shortwave_flux_in_air'], tend_f_arrays['air_temperature'], diag_f_arrays[ 'upwelling_shortwave_flux_in_air_assuming_clear_sky'], diag_f_arrays[ 'downwelling_shortwave_flux_in_air_assuming_clear_sky'], diag_f_arrays['shortwave_heating_rate_assuming_clear_sky'], raw_f_arrays['shortwave_optical_thickness_due_to_aerosol'], raw_f_arrays['single_scattering_albedo_due_to_aerosol'], raw_f_arrays['aerosol_asymmetry_parameter'], raw_f_arrays['aerosol_optical_depth_at_55_micron'], raw_f_arrays['shortwave_optical_thickness_due_to_cloud'], raw_f_arrays['single_scattering_albedo_due_to_cloud'], raw_f_arrays['cloud_asymmetry_parameter'], raw_f_arrays['cloud_forward_scattering_fraction'], raw_f_arrays['mass_content_of_cloud_ice_in_atmosphere_layer'], raw_f_arrays[ 'mass_content_of_cloud_liquid_water_in_atmosphere_layer'], raw_f_arrays['cloud_ice_particle_size'], raw_f_arrays['cloud_water_droplet_radius']) for quantity in diag_arrays.keys(): diag_dict[quantity].values = diag_f_arrays[quantity].transpose() for quantity in tend_arrays.keys(): tend_dict[quantity].values = tend_f_arrays[quantity].transpose() diag_dict['shortwave_heating_rate'].values[:] = tend_dict[ 'air_temperature'].values return tend_dict, diag_dict