pycisTopic pickles
pycisTopic, the scATAC half of SCENIC+, saves its objects only as pickles:
cistopic_obj.pkl, and the imputed accessibility and gene activity as
CistopicImputedFeatures. They convert without pycisTopic, which is not on
PyPI and pins an old pandas. pandas and scipy, which rebuild the pickle’s
tables and matrices, come with an extra: pip install 'pyadata-cli[pickle]'.
adata convert cistopic_obj.pkl -o atac.h5ad
adata convert imputed_acc_obj.pkl -o imputed.h5ad --dense
| CistopicObject | AnnData |
|---|---|
fragment_matrix (regions x cells) |
X, CSR cells x regions, its dtype kept |
binary_matrix |
layers["binary"] |
cell_names, cell_data |
obs names, obs (in cell_names order) |
region_names, region_data |
var names, var |
the selected model’s cell_topic (cell_topic_harmony) |
obsm["X_topic"] (obsm["X_topic_harmony"]), cells x topics |
the model’s region_topic |
varm["topic_region"], regions x topics |
projections["cell"] and ["region"], such as UMAP |
obsm["X_<name>"], varm["X_<name>"] |
project, path_to_fragments, the topic names, the model’s metrics, coherence, parameters and other tables |
uns["pycistopic"] |
A CistopicImputedFeatures becomes X, cells x features, CSR (--dense
keeps it dense), with feature_names and cell_names as var and obs names.
The pickle is read without running anything from it: an unpickler that
resolves only the names a pycisTopic object holds (numpy arrays, scipy
sparse matrices, pandas frames, a few builtins) and refuses any other by
name, so a pickle naming os.system is refused rather than run.
pycisTopic’s own classes are stood in for by plain holders of their
attributes. A pickle written by pycisTopic’s pandas 1.5 reads with pandas 2
or 3, as CI checks. Columns are written as anndata writes them: Categorical
as categorical, nullable integers and booleans as nullable, numbers held as
object as numbers, repeated text as categorical. Anything else on the
object is named in a warning and left out.
A pickle cannot be read in part, so it is held in memory whole, as it was when pycisTopic saved it; the fragment matrix is turned into CSR on disk by the streaming transpose rather than copied in memory.