def conc_errorrate_Z(err_rates_XYZ, layer_ix, N_layers, code_lookup_x,
                     code_lookup_y, code_lookup_z):
    if layer_ix == N_layers:
        if isinstance(err_rates_XYZ, list):
            return err_rates_XYZ[0]
        else:
            return err_rates_XYZ
    else:
        err_rate_xi = conc_errorrate_X(err_rates_XYZ, layer_ix + 1, N_layers,
                                       code_lookup_x, code_lookup_y,
                                       code_lookup_z)
        err_rate_yi = conc_errorrate_Y(err_rates_XYZ, layer_ix + 1, N_layers,
                                       code_lookup_x, code_lookup_y,
                                       code_lookup_z)
        err_rate_zi = conc_errorrate_Z(err_rates_XYZ, layer_ix + 1, N_layers,
                                       code_lookup_x, code_lookup_y,
                                       code_lookup_z)
        if isinstance(code_lookup_x, dict):
            return log_op_error_prob_from_lookup_dict(code_lookup_z,
                                                      err_rate_xi, err_rate_yi,
                                                      err_rate_zi)
        else:
            return log_op_error_prob_from_lookup_dict(
                code_lookup_z[layer_ix - 1], err_rate_xi, err_rate_yi,
                err_rate_zi)
def casc_errorrate_Y(err_rates_XYZ, layer_ix, N_layers, code_lookup_x,
                     code_lookup_y, code_lookup_z, code_lookup_z_withinput):
    if layer_ix == N_layers:
        if isinstance(err_rates_XYZ, list):
            return err_rates_XYZ[1]
        else:
            return err_rates_XYZ
    else:
        err_rate_xi = casc_errorrate_X(err_rates_XYZ, layer_ix + 1, N_layers,
                                       code_lookup_x, code_lookup_y,
                                       code_lookup_z, code_lookup_z_withinput)
        err_rate_yi = casc_errorrate_Y(err_rates_XYZ, layer_ix + 1, N_layers,
                                       code_lookup_x, code_lookup_y,
                                       code_lookup_z, code_lookup_z_withinput)
        err_rate_zi = casc_errorrate_Z(err_rates_XYZ, layer_ix + 1, N_layers,
                                       code_lookup_x, code_lookup_y,
                                       code_lookup_z, code_lookup_z_withinput)
        if isinstance(err_rates_XYZ, list):
            [e_x, e_y, _] = err_rates_XYZ
        else:
            e_x = e_y = err_rates_XYZ
        if isinstance(code_lookup_x, dict):
            temp_p_x = log_op_error_prob_from_lookup_dict(
                code_lookup_x, err_rate_xi, err_rate_yi, err_rate_zi)
            temp_p_y = log_op_error_prob_from_lookup_dict(
                code_lookup_y, err_rate_xi, err_rate_yi, err_rate_zi)

        else:
            temp_p_x = log_op_error_prob_from_lookup_dict(
                code_lookup_x[layer_ix - 1], err_rate_xi, err_rate_yi,
                err_rate_zi)
            temp_p_y = log_op_error_prob_from_lookup_dict(
                code_lookup_y[layer_ix - 1], err_rate_xi, err_rate_yi,
                err_rate_zi)
        if layer_ix == 0:
            return temp_p_y
        else:
            # p_x = e_x * (1 - temp_p_x) + temp_p_x * (1 - e_x)
            # p_y = e_y * (1 - temp_p_y) + temp_p_y * (1 - e_y)
            p_x = e_x + temp_p_x - e_x * temp_p_x
            p_y = e_y + temp_p_y - e_y * temp_p_y
            if layer_ix < N_layers:
                return min(p_x, p_y)
            else:
                return p_y
def casc_errorrate_Z(err_rates_XYZ, layer_ix, N_layers, code_lookup_x,
                     code_lookup_y, code_lookup_z, code_lookup_z_withinput):
    if layer_ix == N_layers:
        if isinstance(err_rates_XYZ, list):
            return err_rates_XYZ[2]
        else:
            return err_rates_XYZ
    else:
        err_rate_xi = casc_errorrate_X(err_rates_XYZ, layer_ix + 1, N_layers,
                                       code_lookup_x, code_lookup_y,
                                       code_lookup_z, code_lookup_z_withinput)
        err_rate_yi = casc_errorrate_Y(err_rates_XYZ, layer_ix + 1, N_layers,
                                       code_lookup_x, code_lookup_y,
                                       code_lookup_z, code_lookup_z_withinput)
        err_rate_zi = casc_errorrate_Z(err_rates_XYZ, layer_ix + 1, N_layers,
                                       code_lookup_x, code_lookup_y,
                                       code_lookup_z, code_lookup_z_withinput)

        if isinstance(code_lookup_z, dict):
            if layer_ix == 0:
                return log_op_error_prob_from_lookup_dict(
                    code_lookup_z, err_rate_xi, err_rate_yi, err_rate_zi)
            else:
                return log_op_error_prob_from_lookup_dict(
                    code_lookup_z_withinput, err_rate_xi, err_rate_yi,
                    err_rate_zi)
        else:

            if layer_ix == 0:
                return log_op_error_prob_from_lookup_dict(
                    code_lookup_z[layer_ix - 1], err_rate_xi, err_rate_yi,
                    err_rate_zi)
            else:
                return log_op_error_prob_from_lookup_dict(
                    code_lookup_z_withinput[layer_ix - 1], err_rate_xi,
                    err_rate_yi, err_rate_zi)