def get_cols_to_keep(gctoo, cid=None, col_bool=None, cidx=None, exclude_cid=None):
    if cid is not None:
        assert type(cid) == list, "cid must be a list. cid: {}".format(cid)
        cols_to_keep = [gctoo_col for gctoo_col in gctoo.data_df.columns if gctoo_col in cid]
        num_missing_cids = len(cid) - len(cols_to_keep)
        if num_missing_cids != 0:
            logger.info("{} cids were not found in the GCT.".format(num_missing_cids))
    elif col_bool is not None:
        assert len(col_bool) == gctoo.data_df.shape[1], (
            "col_bool must have length equal to gctoo.data_df.shape[1]. " +
            "len(col_bool): {}, gctoo.data_df.shape[1]: {}".format(
                len(col_bool), gctoo.data_df.shape[1]))
        cols_to_keep = gctoo.data_df.columns[col_bool].values
    elif cidx is not None:
        assert type(cidx[0]) is int, (
            "cidx must be a list of integers. cidx[0]: {}, " +
            "type(cidx[0]): {}").format(cidx[0], type(cidx[0]))
        assert max(cidx) <= gctoo.data_df.shape[1], (
            "cidx contains an integer larger than the number of columns in " +
            "the GCToo. max(cidx): {}, gctoo.data_df.shape[1]: {}").format(
                max(cidx), gctoo.data_df.shape[1])
        cols_to_keep = gctoo.data_df.columns[cidx].values
    else:
        cols_to_keep = gctoo.data_df.columns.values
    if exclude_cid is not None:
        cols_to_keep = [col_to_keep for col_to_keep in cols_to_keep if col_to_keep not in exclude_cid]
    return cols_to_keep