aertslab / scenicplus

SCENIC+ is a python package to build gene regulatory networks (GRNs) using combined or separate single-cell gene expression (scRNA-seq) and single-cell chromatin accessibility (scATAC-seq) data.
Other
175 stars 28 forks source link

[BUG] AttributeError: 'Index' object has no attribute 'index' #8

Closed cbravo93 closed 2 years ago

cbravo93 commented 2 years ago

When creating the scenicplus_obj:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_1651/3951783255.py in <module>
----> 1 scplus_obj = create_SCENICPLUS_object(
      2         GEX_anndata = rna_anndata,
      3         cisTopic_obj = cistopic_obj,
      4         imputed_acc_obj = imputed_acc_obj,
      5         menr = {},

/lustre1/project/stg_00002/lcb/cbravo/Multiomics_pipeline/scenicplus/src/scenicplus/scenicplus_class.py in create_SCENICPLUS_object(GEX_anndata, cisTopic_obj, menr, imputed_acc_obj, imputed_acc_kwargs, normalize_imputed_acc, normalize_imputed_acc_kwargs, cell_metadata, region_metadata, gene_metadata, bc_transform_func, ACC_prefix, GEX_prefix)
    510     with warnings.catch_warnings():
    511         warnings.simplefilter("ignore")
--> 512         X_EXP_subset = GEX_anndata[[GEX_cell_names.index(bc) for bc in common_cells], :].X.copy()
    513 
    514     ACC_cell_metadata_subset = ACC_cell_metadata.loc[common_cells]

/lustre1/project/stg_00002/lcb/cbravo/Multiomics_pipeline/scenicplus/src/scenicplus/scenicplus_class.py in <listcomp>(.0)
    510     with warnings.catch_warnings():
    511         warnings.simplefilter("ignore")
--> 512         X_EXP_subset = GEX_anndata[[GEX_cell_names.index(bc) for bc in common_cells], :].X.copy()
    513 
    514     ACC_cell_metadata_subset = ACC_cell_metadata.loc[common_cells]

AttributeError: 'Index' object has no attribute 'index'

Indeed, if I check GEX_cell_names (GEX_anndata.obs_names) it looks like:

Index(['AAACCCACACCCTAAA-1-TEW__02ff09__scNuc_frozen_mouse2',
       'AAACCCACAGACACCC-1-TEW__02ff09__scNuc_frozen_mouse2',
       'AAACCCAGTTACCGTA-1-TEW__02ff09__scNuc_frozen_mouse2',
       'AAACCCAGTTGTTGAC-1-TEW__02ff09__scNuc_frozen_mouse2',
       'AAACCCATCGCATTAG-1-TEW__02ff09__scNuc_frozen_mouse2',
       'AAACGAAAGCCGTCGT-1-TEW__02ff09__scNuc_frozen_mouse2',
       'AAACGAAAGGGAGATA-1-TEW__02ff09__scNuc_frozen_mouse2',
       'AAACGAAAGGGAGGCA-1-TEW__02ff09__scNuc_frozen_mouse2',
       'AAACGAAGTACCTAAC-1-TEW__02ff09__scNuc_frozen_mouse2',
       'AAACGAAGTCGATGCC-1-TEW__02ff09__scNuc_frozen_mouse2',
       ...
       'TTTGTGAAGCCTGATG-1-TEW__ebb273__Mouse_5_Multiome_NST',
       'TTTGTGAAGCGAGCGA-1-TEW__ebb273__Mouse_5_Multiome_NST',
       'TTTGTGAAGTTACTTC-1-TEW__ebb273__Mouse_5_Multiome_NST',
       'TTTGTGGCATCACAGC-1-TEW__ebb273__Mouse_5_Multiome_NST',
       'TTTGTGTTCACATTGA-1-TEW__ebb273__Mouse_5_Multiome_NST',
       'TTTGTGTTCGCTAAGT-1-TEW__ebb273__Mouse_5_Multiome_NST',
       'TTTGTGTTCGGTTTGG-1-TEW__ebb273__Mouse_5_Multiome_NST',
       'TTTGTGTTCTTTGTAC-1-TEW__ebb273__Mouse_5_Multiome_NST',
       'TTTGTTGGTTACATCC-1-TEW__ebb273__Mouse_5_Multiome_NST',
       'TTTGTTGGTTATTGCC-1-TEW__ebb273__Mouse_5_Multiome_NST'],
      dtype='object', length=29857)

Could this be because of the scanpy version? I'm using 1.8.2

cbravo93 commented 2 years ago

The issue arises when bc_transform_func = None. Replacing:

    if bc_transform_func is not None:
        #transform GEX barcodes to ACC barcodes
        GEX_cell_names = [bc_transform_func(bc) for bc in GEX_anndata.obs_names]
        GEX_cell_metadata.index = GEX_cell_names

by

if bc_transform_func is not None:
        bc_transform_func = lambda x: x
GEX_cell_names = [bc_transform_func(bc) for bc in GEX_anndata.obs_names]
GEX_cell_metadata.index = GEX_cell_names

will work (but takes its time in that operation, would be better to skip it)

SeppeDeWinter commented 2 years ago

Thanks for the issue.

The problem arrises because GEX_cell_names is expected to be a python list (.index function returns the index of the barcode).

If bc_transform_func is set GEX_cell_names will be transformed in a list (from a pandas.Index object).

Solution is to set GEX_cell_names to a python list when bc_transform_func is None.

i.e.

if bc_transform_func is not None:
    #transform GEX barcodes to ACC barcodes
    GEX_cell_names = [bc_transform_func(bc) for bc in GEX_anndata.obs_names]
    GEX_cell_metadata.index = GEX_cell_names
else:
    GEX_cell_names = list(GEX_cell_names)