def fcondtop(ncid_in, index, aux_vars_non_salin, aux_vars_salin):
    try:
        return df.mmean(
            ncid_in.variables['zgrad_top_snow_adjusted_-0.500'][:][index] *
            aux_vars_salin['top_conductivity_estimate'])
    except KeyError:
        return None
def thermal_insulance(ncid_in, index, aux_vars_non_salin, aux_vars_salin):
    try:
        return df.mmean(
            ncid_in.variables['ice_thickness'][:][index] / sc.k_fresh_ice_mu +
            ncid_in.variables['snow_thickness'][:][index] / sc.k_snow)
    except KeyError:
        return None
def fcondbot(ncid_in, index, aux_vars_non_salin, aux_vars_salin):
    try:
        return df.mmean(
            ncid_in.variables['base_' + param.layer_fcondbot_label +
                              '_zgrad'][:][index] *
            aux_vars_salin['basal_conductivity_estimate'])
    except KeyError:
        return None
def sensible_heat_uptake_lowest_layer(ncid_in, index, aux_vars_non_salin,
                                      aux_vars_salin):
    try:
        return df.mmean(aux_vars_non_salin['temp_rate_of_change'] *
                        aux_vars_salin['heat_capacity'] * param.rhoi) * (
                            param.layer_shu_calc[1] - param.layer_shu_calc[0])
    except KeyError:
        return None
def sfctemp(ncid_in, index, aux_vars_non_salin, aux_vars_salin):
    try:
        return df.mmean(ncid_in.variables['surface_temp_-0.000'][:][index])
    except KeyError:
        return None
def snow_thickness(ncid_in, index, aux_vars_non_salin, aux_vars_salin):
    try:
        return df.mmean(ncid_in.variables['snow_thickness'][:][index])
    except KeyError:
        return None
def calc_aux_vars_salin(ncid_in, period, buoy_dates, salinity):
    '''Calculates auxiliary variables, dependent upon salinity, necessary for calculating vertical energy fluxes (e.g. conductivity, heat capacity)'''
    import difference_functions as df
    import numpy as np
    import copy

    aux_vars_salin = {}
    index = np.where(
        np.logical_and(buoy_dates > period[0], buoy_dates <= period[1]))

    aux_vars_salin[
        'melting_temperature'] = 0. - salinity * sc.liquidus_constant

    max_top_temp_array = copy.deepcopy(
        ncid_in.variables['surface_temp_-0.000'][:][index])
    top_exceed_index = np.where(
        max_top_temp_array > aux_vars_salin['melting_temperature'])
    max_top_temp_array[top_exceed_index] = aux_vars_salin[
        'melting_temperature']

    max_base_temp_array = copy.deepcopy(
        ncid_in.variables['basal_temp_0.000'][:][index])
    base_exceed_index = np.where(
        max_base_temp_array > aux_vars_salin['melting_temperature'])
    max_base_temp_array[base_exceed_index] = aux_vars_salin[
        'melting_temperature']

    if salinity != 0.:
        aux_vars_salin['energy_of_melting_base'] = -sc.L_fresh * (
            1 +
            sc.liquidus_constant * salinity / df.mmean(max_base_temp_array))
    else:
        aux_vars_salin['energy_of_melting_base'] = -sc.L_fresh
    if salinity != 0.:
        aux_vars_salin['energy_of_melting_top'] = -sc.L_fresh * (
            1 + sc.liquidus_constant * salinity / df.mmean(max_top_temp_array))
    else:
        aux_vars_salin['energy_of_melting_top'] = -sc.L_fresh

    aux_vars_salin[
        'top_conductivity_estimate_mu'] = sc.k_fresh_ice_mu + salinity * sc.beta_k_coefficient / df.mmean(
            max_top_temp_array)
    aux_vars_salin[
        'basal_conductivity_estimate_mu'] = sc.k_fresh_ice_mu + salinity * sc.beta_k_coefficient * ncid_in.variables[
            'base_' + param.layer_fcondbot_label + '_z_recip_mean'][:][index]

    aux_vars_salin[
        'top_conductivity_estimate_pringle'] = sc.k_fresh_ice_pringle - sc.pringle_temp_cond * df.mmean(
            max_top_temp_array
        ) + sc.pringle_saltemp_cond * salinity / df.mmean(max_top_temp_array)
    aux_vars_salin[
        'basal_conductivity_estimate_pringle'] = sc.k_fresh_ice_pringle - sc.pringle_temp_cond * df.mmean(
            max_top_temp_array
        ) + sc.pringle_saltemp_cond * salinity / df.mmean(max_top_temp_array)

    if param.conductivity_formulation == 'maykut_untersteiner':
        aux_vars_salin['top_conductivity_estimate'] = \
            aux_vars_salin['top_conductivity_estimate_mu']
        aux_vars_salin['basal_conductivity_estimate'] = \
            aux_vars_salin['basal_conductivity_estimate_mu']
    elif param.conductivity_formulation == 'pringle_bubbly_brine':
        aux_vars_salin['top_conductivity_estimate'] = \
            aux_vars_salin['top_conductivity_estimate_pringle']
        aux_vars_salin['basal_conductivity_estimate'] = \
            aux_vars_salin['basal_conductivity_estimate_pringle']
    else:
        print('Conductivity formulation must be \'maykut_untersteiner\' or '+\
             '\'pringle_bubbly_brine\'')
        raise ValueError

    aux_vars_salin[
        'heat_capacity'] = sc.c_fresh_ice + sc.gamma_c_coefficient * salinity * df.mmean(
            ncid_in.variables['base_' + param.layer_shu_label +
                              '_z_recip_sq_mean'][:][index])

    # Calculate required additional error quantities
    aux_vars_salin['temps_too_high_in_lowest_layer'] = -1. / np.sqrt(
        ncid_in.variables['base_0.000_0.400_z_recip_sq_mean']
        [:]) > aux_vars_salin['melting_temperature']
    #most_temps_too_high = np.sum(ncid_in.variables['surface_temp_-0.000'][:][index] > aux_vars_salin['melting_temperature'] + param.melting_temp_tol_most) > index[0].shape[0] * param.melting_temp_most_proportion
    #aux_vars_salin['temp_too_high'] = all_temps_too_high or most_temps_too_high

    return aux_vars_salin