This is a test version of Biostars. For the public version, visit https://www.biostars.org.
Cannot read loom file in scanpy

I have a loom file created from Seurat object by using as.loom function in Seurat3. After closing the file with $close.all(), I'm trying to read loom file by read_loom function in scanpy, but I have this error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-aed61d3d5eef> in <module>
      1 import scanpy as sc
----> 2 a = sc.read_loom('brain10x.loom')

/opt/conda/lib/python3.7/site-packages/anndata/readwrite/read.py in read_loom(filename, sparse, cleanup, X_name, obs_names, var_names, dtype)
    156 
    157         if X_name not in lc.layers.keys(): X_name = ''
--> 158         X = lc.layers[X_name].sparse().T.tocsr() if sparse else lc.layers[X_name][()].T
    159 
    160         layers = OrderedDict()

/opt/conda/lib/python3.7/site-packages/loompy/loom_layer.py in sparse(self, rows, cols)
    109                 col: List[np.ndarray] = []
    110                 i = 0
--> 111                 for (ix, selection, view) in self.ds.scan(items=cols, axis=1, layers=[self.name]):
    112                         if rows is not None:
    113                                 vals = view.layers[self.name][rows, :]

/opt/conda/lib/python3.7/site-packages/loompy/loompy.py in scan(self, items, axis, layers, key, batch_size)
    597                                 for key, layer in vals.items():
    598                                         lm[key] = loompy.MemoryLoomLayer(key, layer)
--> 599                                 view = loompy.LoomView(lm, self.ra[ordering], self.ca[ix + selection], self.row_graphs[ordering], self.col_graphs[ix + selection], filename=self.filename, file_attrs=self.attrs)
    600                                 yield (ix, ix + selection, view)
    601                                 ix += cols_per_chunk

/opt/conda/lib/python3.7/site-packages/loompy/graph_manager.py in __getitem__(self, thing)
     96                 if type(thing) is slice or type(thing) is np.ndarray or type(thing) is int:
     97                         gm = GraphManager(None, axis=self.axis)
---> 98                         for key, g in self.items():
     99                                 # Slice the graph matrix properly without making it dense
    100                                 (a, b, w) = (g.row, g.col, g.data)

/opt/conda/lib/python3.7/site-packages/loompy/graph_manager.py in items(self)
     55         def items(self) -> Iterable[Tuple[str, sparse.coo_matrix]]:
     56                 for key in self.keys():
---> 57                         yield (key, self[key])
     58 
     59         def __len__(self) -> int:

/opt/conda/lib/python3.7/site-packages/loompy/graph_manager.py in __getitem__(self, thing)
    116                         raise AttributeError(f"'{type(self)}' object has no attribute {thing}")
    117                 else:
--> 118                         return self.__getattr__(thing)
    119 
    120         def __getattr__(self, name: str) -> sparse.coo_matrix:

/opt/conda/lib/python3.7/site-packages/loompy/graph_manager.py in __getattr__(self, name)
    127                                 c = self.ds._file[a][name]["b"]
    128                                 w = self.ds._file[a][name]["w"]
--> 129                                 g = sparse.coo_matrix((w, (r, c)), shape=(self.ds.shape[self.axis], self.ds.shape[self.axis]))
    130                                 self.__dict__["storage"][name] = g
    131                         return g

/opt/conda/lib/python3.7/site-packages/scipy/sparse/coo.py in __init__(self, arg1, shape, dtype, copy)
    190             self.data = self.data.astype(dtype, copy=False)
    191 
--> 192         self._check()
    193 
    194     def reshape(self, *args, **kwargs):

/opt/conda/lib/python3.7/site-packages/scipy/sparse/coo.py in _check(self)
    279                 raise ValueError('row index exceeds matrix dimensions')
    280             if self.col.max() >= self.shape[1]:
--> 281                 raise ValueError('column index exceeds matrix dimensions')
    282             if self.row.min() < 0:
    283                 raise ValueError('negative row index found')

ValueError: column index exceeds matrix dimensions

I can read loom file with loompy seamlessly. They are in the latest versions (Seurat_3.0.0.9000, loomR_0.2.1.9000, scanpy==1.4).

Should I add anything to the code below?:

a = scanpy.read_loom('brain10x.loom', sparse=True)

Thanks...

single-cell loom seurat

2 answers

I could solve this problem thanks to @ahy1221 in GitHub. The problem is solved by removing @graphs from Seurat object. Now I have another error:

---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-2-aae861244dfa> in <module>
----> 1 adata = sc.read_loom('dataset.loom')

/opt/conda/lib/python3.7/site-packages/anndata/readwrite/read.py in read_loom(filename, sparse, cleanup, X_name, obs_names, var_names, dtype, **kwargs)
    184             var=var,
    185             layers=layers,
--> 186             dtype=dtype)
    187     return adata
    188 

/opt/conda/lib/python3.7/site-packages/anndata/base.py in __init__(self, X, obs, var, uns, obsm, varm, layers, raw, dtype, shape, filename, filemode, asview, oidx, vidx)
    670                 layers=layers,
    671                 dtype=dtype, shape=shape,
--> 672                 filename=filename, filemode=filemode)
    673 
    674     def _init_as_view(self, adata_ref: 'AnnData', oidx: Index, vidx: Index):

/opt/conda/lib/python3.7/site-packages/anndata/base.py in _init_as_actual(self, X, obs, var, uns, obsm, varm, raw, layers, dtype, shape, filename, filemode)
    848         # annotations
    849         self._obs = _gen_dataframe(obs, self._n_obs,
--> 850                                    ['obs_names', 'row_names', 'smp_names'])
    851         self._var = _gen_dataframe(var, self._n_vars, ['var_names', 'col_names'])
    852 

/opt/conda/lib/python3.7/site-packages/anndata/base.py in _gen_dataframe(anno, length, index_names)
    285                 _anno = pd.DataFrame(
    286                     anno, index=anno[index_name],
--> 287                     columns=[k for k in anno.keys() if k != index_name])
    288                 break
    289         else:

/opt/conda/lib/python3.7/site-packages/pandas/core/frame.py in __init__(self, data, index, columns, dtype, copy)
    390                                  dtype=dtype, copy=copy)
    391         elif isinstance(data, dict):
--> 392             mgr = init_dict(data, index, columns, dtype=dtype)
    393         elif isinstance(data, ma.MaskedArray):
    394             import numpy.ma.mrecords as mrecords

/opt/conda/lib/python3.7/site-packages/pandas/core/internals/construction.py in init_dict(data, index, columns, dtype)
    210         arrays = [data[k] for k in keys]
    211 
--> 212     return arrays_to_mgr(arrays, data_names, index, columns, dtype=dtype)
    213 
    214 

/opt/conda/lib/python3.7/site-packages/pandas/core/internals/construction.py in arrays_to_mgr(arrays, arr_names, index, columns, dtype)
     54 
     55     # don't force copy because getting jammed in an ndarray anyway
---> 56     arrays = _homogenize(arrays, index, dtype)
     57 
     58     # from BlockManager perspective

/opt/conda/lib/python3.7/site-packages/pandas/core/internals/construction.py in _homogenize(data, index, dtype)
    275                 val = lib.fast_multiget(val, oindex.values, default=np.nan)
    276             val = sanitize_array(val, index, dtype=dtype, copy=False,
--> 277                                  raise_cast_failure=False)
    278 
    279         homogenized.append(val)

/opt/conda/lib/python3.7/site-packages/pandas/core/internals/construction.py in sanitize_array(data, index, dtype, copy, raise_cast_failure)
    656     elif subarr.ndim > 1:
    657         if isinstance(data, np.ndarray):
--> 658             raise Exception('Data must be 1-dimensional')
    659         else:
    660             subarr = com.asarray_tuplesafe(data, dtype=dtype)

Exception: Data must be 1-dimensional

Try opening the file using loompy directly to check that the loom file is valid.

import loompy
ds = loompy.connect("filename.loom")

Yeah I've tried it before. I want to read loom to convert it into h5ad, when I open with loompy.connect, it fails and gives this error:

AttributeError: 'LoomConnection' object has no attribute 'write'

Log in to answer this question.