You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of #20. Follows #27, which reads SCope looms.
adata convert now reads a SCope loom into:
obsm["RegulonsAUC"] and varm["Regulons"], dataframes with a column per regulon (any other compound attribute, such as VSN's ClusterMarkers_<i>, the same way);
obsm["X_<name>"] per embedding, and a categorical obs column per clustering;
uns["scope"]: the decoded MetaData, the regulon thresholds, and each embedding's and clustering's SCope id, name and where it went.
Writing a loom still writes a plain one: the dataframes are left out with a warning, and nothing SCope shows is written in its form. Results edited as AnnData cannot go back to SCope.
Plan
AnnData
SCope loom
a dataframe in obsm / varm
a compound col_attrs / row_attrs, a field per column
obsm["X_*"], n x 2
Embeddings_X and Embeddings_Y, a field per id; the default (id -1) also as Embedding (_X, _Y)
categorical obs columns
Clusterings, a field of cluster ids per clustering; ClusterID for the first
uns["scope"]
MetaData, base64 of zlib-compressed JSON, rebuilt so its ids match the fields: embeddings, clusterings with their clusters, regulon thresholds
Ids and names come from uns["scope"]["embeddings"] and ["clusterings"] when the AnnData came from a SCope loom, so a round trip keeps them; otherwise they are given in order, the first embedding (or one a flag names) as the default.
Open questions:
HDF5 must fit a compound type in one object header message (64 KB): a 1,000-field compound of TF<i>_(+) names was refused, 600 fields fitted. pySCENIC's own export has the same limit. Refuse past it, or split?
Flags: opt in with --scope, or whenever uns["scope"] is there? --default-embedding? Which obs columns are clusterings?
Checks
The pySCENIC tutorial's loompy recipe reads back what was written, as test_external_readers.py does for import.
SCope loom → h5ad → SCope loom keeps every attribute and MetaData.
obsm/varm dataframes (RegulonsAUC, Regulons, ClusterMarkers_<id>[_<metric>]) as compound attributes;
two-column obsm arrays as Embeddings_X/_Y (and the default as Embedding; pick it with --default-embedding);
the clusterings a SCope import recorded, plus --clusterings a,b, as Clusterings and ClusterID;
MetaData (plain JSON) with embeddings, clusterings, metrics, annotations and regulon thresholds. Ids and names recorded on import are kept, so a SCope loom round-trips through h5ad.
To fit SCope's reader: regulon names lose their spaces, clusterings and clusters are numbered 0..n-1 (marker fields renumbered with them), and markers are written only with their ClusterMarkers_<id> table and metrics. Anything HDF5 or SCope cannot take is refused or left out with a warning before writing.
Checked on the public pySCENIC pbmc3k loom (Zenodo 10944066): loom → h5ad → --scope loom gives back the same AUC, regulons, embeddings, clusterings and thresholds through the pySCENIC tutorial's loompy recipe. SCope's own server is not installable from PyPI, so it was checked against its reading rules rather than run — a report from opening one in the viewer is welcome.
concat now stacks obsm dataframes (following --join) and merges varm under --merge, as anndata.concat does.
Activity
adata convertto and from h5ad/zarr #20convert: write SCope looms with --scope (#61)
convert: write SCope looms with --scope (#61)
Merge pull request #70 from cellgeni/feat/scope-export
Claptar commentedon Oct 22, 2026
Released in 0.15.0 (#70, with
concatsupport in #69).adata convert x.h5ad -o x.loom --scopewrites a loom SCope reads:RegulonsAUC,Regulons,ClusterMarkers_<id>[_<metric>]) as compound attributes;Embeddings_X/_Y(and the default asEmbedding; pick it with--default-embedding);--clusterings a,b, asClusteringsandClusterID;MetaData(plain JSON) with embeddings, clusterings, metrics, annotations and regulon thresholds. Ids and names recorded on import are kept, so a SCope loom round-trips through h5ad.To fit SCope's reader: regulon names lose their spaces, clusterings and clusters are numbered 0..n-1 (marker fields renumbered with them), and markers are written only with their
ClusterMarkers_<id>table and metrics. Anything HDF5 or SCope cannot take is refused or left out with a warning before writing.Checked on the public pySCENIC pbmc3k loom (Zenodo 10944066): loom → h5ad →
--scopeloom gives back the same AUC, regulons, embeddings, clusterings and thresholds through the pySCENIC tutorial's loompy recipe. SCope's own server is not installable from PyPI, so it was checked against its reading rules rather than run — a report from opening one in the viewer is welcome.concatnow stacks obsm dataframes (following--join) and merges varm under--merge, asanndata.concatdoes.