def drug_combination(_all_cell_lines_arr, _means_accumulator, _errs_accumulator, _names_accumulator):

    targets, fda_status = supporting_functions.read_drug_info(_names_accumulator)

    _names_accumulator = [name + ' - ' + targets[i] + ' - ' + fda_status[i]
                          for i, name in enumerate(_names_accumulator)]
    _means_accumulator, _errs_accumulator, _all_cell_lines_arr, _names_accumulator = \
        supporting_functions.preformat(_means_accumulator, _errs_accumulator, _all_cell_lines_arr, _names_accumulator)

    support_matrix = np.zeros((_names_accumulator.shape[0], _names_accumulator.shape[0], _means_accumulator.shape[0]))
    reverse_look_up_pad = np.zeros((_names_accumulator.shape[0], _names_accumulator.shape[0], 2))
    names_len = _names_accumulator.shape[0]

    for i in range(0, names_len):
        for j in range(i, names_len):
            support_matrix[i, j, :] = _means_accumulator[:, i] * _means_accumulator[:, j]
            support_matrix[j, i, :] = _means_accumulator[:, i] * _means_accumulator[:, j]
            reverse_look_up_pad[i, j, :] = np.array([i, j])
            reverse_look_up_pad[j, i, :] = np.array([i, j])

    all_cell_lines = _all_cell_lines_arr.tolist()
    idx1 = all_cell_lines.index('184A1')
    idx2 = all_cell_lines.index('184B5')
    false_filter = np.zeros((_all_cell_lines_arr.shape[0])).astype(np.bool)
    false_filter[idx1] = True
    false_filter[idx2] = True
    false_filter[-1] = True
    false_filter = np.logical_not(false_filter)

    norm_mean = support_matrix[:, :, -1].copy()
    support_matrix = support_matrix[:, :, false_filter] / norm_mean[:, :, np.newaxis]

    combined_effect = np.zeros((_names_accumulator.shape[0], _names_accumulator.shape[0]))
    for i in range(0, names_len):
        for j in range(i, names_len):
            comparable_support = np.logical_and(np.logical_not(np.isnan(support_matrix[i, i, :])),
                                                np.logical_not(np.isnan(support_matrix[j, j, :])))
            comparable_value = np.nanmean(support_matrix[i, j, comparable_support])
            comparable_value = comparable_value / np.min(np.array([
                                np.nanmean(support_matrix[i, i, comparable_support]),
                                np.nanmean(support_matrix[j, j, comparable_support])]))
            combined_effect[i, j] = comparable_value
            combined_effect[j, i] = comparable_value

    mean_effect = np.nanmean(support_matrix, axis=2)
    support_of_effect = np.sum(np.logical_not(np.isnan(support_matrix)), axis=2)
    combined_effect[support_of_effect < 15] = np.median(combined_effect)

    sorting_index = hierchical_clustering(combined_effect, _names_accumulator)

    combined_effect = combined_effect[sorting_index, :]
    combined_effect = combined_effect[:, sorting_index]

    reverse_look_up_pad = reverse_look_up_pad[sorting_index, :, :]
    reverse_look_up_pad = reverse_look_up_pad[:, sorting_index, :]

    _names_accumulator = _names_accumulator[sorting_index]

    combined_effect[combined_effect > 0.99] = np.nan
    # combined_effect[combined_effect < 0.1] = np.nan

    plt.imshow(combined_effect, cmap='coolwarm', interpolation='nearest')
    plt.colorbar()
    plt.xticks(np.linspace(0, _names_accumulator.shape[0]-1,
                           _names_accumulator.shape[0]), _names_accumulator, rotation='vertical')
    plt.yticks(np.linspace(0, _names_accumulator.shape[0]-1,
                           _names_accumulator.shape[0]), _names_accumulator)

    mp.rc('font', size=8)
    plt.subplots_adjust(bottom=0.3)
    plt.show()

    combined_effect[np.isnan(combined_effect)] = 0

    nz = np.nonzero(np.triu(combined_effect))
    acc_dict = {}

    for _i, _j in zip(nz[0], nz[1]):
        acc_dict[(_i, _j)] = combined_effect[_i, _j]

    sort_acc_dict = sorted(acc_dict.iteritems(), key=lambda x: x[1])

    print len(sort_acc_dict)

    for (_i, _j), val in sort_acc_dict[:10]:

        i, j = tuple(reverse_look_up_pad[_i, _j, :].tolist())

        plt.title('combination score: %.2f' % val)

        void_support = np.empty_like(_means_accumulator[:, 1])[:, np.newaxis]
        void_support.fill(np.nan)
        means_stack = np.hstack((_means_accumulator[:, [i, j]],
                                 void_support,
                                 (_means_accumulator[:, i] * _means_accumulator[:, j])[:, np.newaxis]))
        names_stack = _names_accumulator[[i, j]].tolist() + ['', 'combined']
        plt.imshow(means_stack, cmap='coolwarm', interpolation='nearest', vmin=0, vmax=2)
        plt.colorbar()
        plt.yticks(np.linspace(0, _all_cell_lines_arr.shape[0] - 1,
                               _all_cell_lines_arr.shape[0]), _all_cell_lines_arr)
        plt.xticks(np.linspace(0, 3, 4), names_stack, rotation='vertical')

        mp.rc('font', size=8)
        plt.subplots_adjust(bottom=0.3)
        plt.show()
def drug_fingerprint(all_cell_lines_arr, means_accumulator, errs_accumulator, names_accumulator):
    means_accumulator, errs_accumulator, all_cell_lines_arr, names_accumulator = \
        supporting_functions.preformat(means_accumulator, errs_accumulator, all_cell_lines_arr, names_accumulator)