Skip to content

Instantly share code, notes, and snippets.

@afrendeiro
Last active February 10, 2019 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afrendeiro/7ccaf324bfdbff042ae36f734f544860 to your computer and use it in GitHub Desktop.
Save afrendeiro/7ccaf324bfdbff042ae36f734f544860 to your computer and use it in GitHub Desktop.
Add a "tracker" attribute to AnnData objects to keep track of transformations to it's data
import scanpy.api as sc
import numpy as np
def add_tracker(field_name="tracker"):
from inspect import getcallargs
from functools import wraps
def tracker(f):
@wraps(f)
def wrapper(*args, **kwds):
adata = args[0]
if field_name not in adata.uns:
adata.uns[field_name] = np.array([], dtype="<U32")
adata.uns[field_name] = np.append(adata.uns[field_name], [f.__name__])
return f(*args, **kwds)
return wrapper
pp_functions = filter(
lambda x: list(getcallargs(getattr(sc.pp, x), None, None).keys())[0] in ["adata", "data"],
filter(
lambda x: not x.startswith("__"), sc.pp.__dict__.keys()))
for function in pp_functions:
setattr(sc.pp, function, tracker(getattr(sc.pp, function)))
add_tracker()
a = sc.AnnData(np.random.randint(0, 100, size=(20, 5)))
assert "tracker" not in a.uns
sc.pp.normalize_per_cell(a)
assert "tracker" in a.uns
assert a.uns['tracker'] == np.array(["normalize_per_cell"])
sc.pp.log1p(a)
assert all(a.uns['tracker'] == np.array(["normalize_per_cell", "log1p"]))
sc.write("example_anndata.h5ad", a)
a = sc.read("example_anndata.h5ad")
assert "tracker" in a.uns
assert all(a.uns['tracker'] == np.array(["normalize_per_cell", "log1p"]))
@afrendeiro
Copy link
Author

I'd prefer to have a ,more simple and discrete class attribute e.g. "_tracker" of type list to track, but since saving as h5ad is not true object serialization, adding it to uns seemed like the other obvious way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment