mimyr 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mimyr/__init__.py +27 -0
- mimyr/_resources.py +10 -0
- mimyr/analysis.py +112 -0
- mimyr/api.py +638 -0
- mimyr/data_loader.py +1216 -0
- mimyr/data_modes.py +31 -0
- mimyr/evaluator.py +202 -0
- mimyr/gene_exp_model.py +84 -0
- mimyr/inference.py +914 -0
- mimyr/metrics.py +747 -0
- mimyr/models/__init__.py +0 -0
- mimyr/models/biological_model.py +395 -0
- mimyr/models/celltype_model.py +627 -0
- mimyr/models/combined_model.py +106 -0
- mimyr/models/diffusion_model.py +623 -0
- mimyr/models/generative_transformer/Mimyr.py +799 -0
- mimyr/models/generative_transformer/__init__.py +7 -0
- mimyr/models/generative_transformer/data_util.py +619 -0
- mimyr/models/generative_transformer/finetune_mimyr.py +1701 -0
- mimyr/models/generative_transformer/metadata/4hierarchy_metainfo_mouse_geneunion2_DAG.pt +0 -0
- mimyr/models/generative_transformer/metadata/edges_x.pkl +0 -0
- mimyr/models/generative_transformer/metadata/edges_y.pkl +0 -0
- mimyr/models/generative_transformer/metadata/edges_z.pkl +0 -0
- mimyr/models/generative_transformer/metadata/hierarchy.pkl +0 -0
- mimyr/models/generative_transformer/metadata/id_to_subclass.pkl +0 -0
- mimyr/models/generative_transformer/model/__init__.py +0 -0
- mimyr/models/generative_transformer/model/model.py +990 -0
- mimyr/models/generative_transformer/model/model_kvcache.py +1144 -0
- mimyr/models/generative_transformer/model/wtf_bias.py +185 -0
- mimyr/models/generative_transformer/reference/GeneSymbolUniform/__init__.py +0 -0
- mimyr/models/generative_transformer/reference/GeneSymbolUniform/pyGSUni.py +424 -0
- mimyr/models/generative_transformer/reference/GeneSymbolUniform/total_gene_list_42117.txt +42118 -0
- mimyr/models/generative_transformer/reference/__init__.py +0 -0
- mimyr/models/generative_transformer/utils/__init__.py +1 -0
- mimyr/models/generative_transformer/utils/hf_tokenizer.py +31 -0
- mimyr/pretrained.py +187 -0
- mimyr-0.1.0.dist-info/METADATA +479 -0
- mimyr-0.1.0.dist-info/RECORD +41 -0
- mimyr-0.1.0.dist-info/WHEEL +5 -0
- mimyr-0.1.0.dist-info/licenses/LICENSE +21 -0
- mimyr-0.1.0.dist-info/top_level.txt +1 -0
mimyr/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""MIMYR: generative modeling of spatial transcriptomics.
|
|
2
|
+
|
|
3
|
+
import mimyr
|
|
4
|
+
model = mimyr.Mimyr.from_pretrained("merscope")
|
|
5
|
+
section = model.generate(reference=[left, right], position=10.9)
|
|
6
|
+
|
|
7
|
+
See mimyr.api for the full interface.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
__version__ = version("mimyr")
|
|
14
|
+
except PackageNotFoundError: # running from a source tree without installing
|
|
15
|
+
__version__ = "unknown"
|
|
16
|
+
|
|
17
|
+
__all__ = ["Mimyr", "prepare", "validate", "evaluate"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def __getattr__(name):
|
|
21
|
+
# Imported on first use: the API pulls in torch and scanpy, and `import mimyr`
|
|
22
|
+
# should stay cheap for the submodules (mimyr.pretrained, mimyr.metrics).
|
|
23
|
+
if name in __all__:
|
|
24
|
+
from mimyr import api
|
|
25
|
+
|
|
26
|
+
return getattr(api, name)
|
|
27
|
+
raise AttributeError(f"module 'mimyr' has no attribute {name!r}")
|
mimyr/_resources.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Paths to the metadata files bundled with the package."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
METADATA_DIR = os.path.join(
|
|
6
|
+
os.path.dirname(os.path.abspath(__file__)), "models", "generative_transformer", "metadata"
|
|
7
|
+
)
|
|
8
|
+
META_INFO_FILE = "4hierarchy_metainfo_mouse_geneunion2_DAG.pt"
|
|
9
|
+
META_INFO_PATH = os.path.join(METADATA_DIR, META_INFO_FILE)
|
|
10
|
+
ID_TO_SUBCLASS_PATH = os.path.join(METADATA_DIR, "id_to_subclass.pkl")
|
mimyr/analysis.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import numpy as np
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import scanpy as sc
|
|
5
|
+
import seaborn as sns
|
|
6
|
+
import matplotlib.pyplot as plt
|
|
7
|
+
import matplotlib.colors as mcolors
|
|
8
|
+
import tqdm
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
import torch
|
|
12
|
+
import numpy as np
|
|
13
|
+
import anndata as ad
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def generate_anndata_from_samples(
|
|
17
|
+
region_model, xyz, device="cuda", sample_from_probs=False
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
xyz: [N, D] numpy array of coordinates (must include 3 spatial dims in [:, :3])
|
|
21
|
+
xyz_labels: [N] array of known tokens to use for conditioning (initial labels if gibbs=True)
|
|
22
|
+
use_budget: when True and use_conditionals=False, enforces budget-based sampling per group
|
|
23
|
+
graph_smooth: when True and use_conditionals=False, applies 1-step GCN-like smoothing before sampling
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
region_model.eval().to(device)
|
|
27
|
+
|
|
28
|
+
with torch.no_grad():
|
|
29
|
+
xyz_tensor = torch.tensor(xyz, dtype=torch.float32).to(device)
|
|
30
|
+
input_tensor = xyz_tensor
|
|
31
|
+
batch_size = 1000
|
|
32
|
+
outputs = []
|
|
33
|
+
for i in range(0, input_tensor.size(0), batch_size):
|
|
34
|
+
logits_batch = region_model.model(input_tensor[i : i + batch_size])
|
|
35
|
+
outputs.append(logits_batch)
|
|
36
|
+
logits = torch.cat(outputs, dim=0)
|
|
37
|
+
|
|
38
|
+
probs = torch.softmax(logits, dim=1).cpu().numpy()
|
|
39
|
+
|
|
40
|
+
preds = np.array(
|
|
41
|
+
[
|
|
42
|
+
np.random.choice(len(p), p=p) if sample_from_probs else np.argmax(p)
|
|
43
|
+
for p in probs
|
|
44
|
+
]
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if isinstance(xyz, torch.Tensor):
|
|
48
|
+
xyz = xyz.detach().cpu().numpy()
|
|
49
|
+
|
|
50
|
+
adata = ad.AnnData(X=np.zeros((xyz.shape[0], 1)))
|
|
51
|
+
adata.obsm["spatial"] = xyz[:, :3]
|
|
52
|
+
adata.obs["token"] = preds
|
|
53
|
+
return adata, preds, probs
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def assign_shared_colors(adatas, color_key="token", palette="tab10", seed=None):
|
|
57
|
+
# collect all unique labels across datasets
|
|
58
|
+
all_labels = pd.Categorical(
|
|
59
|
+
np.concatenate([adata.obs[color_key] for adata in adatas])
|
|
60
|
+
).categories
|
|
61
|
+
|
|
62
|
+
# generate colors
|
|
63
|
+
colors = [
|
|
64
|
+
mcolors.to_hex(c) for c in sns.color_palette(palette, n_colors=len(all_labels))
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
# optionally shuffle them deterministically
|
|
68
|
+
if seed is not None:
|
|
69
|
+
rng = np.random.default_rng(seed)
|
|
70
|
+
colors = list(rng.permutation(colors))
|
|
71
|
+
|
|
72
|
+
# assign to all AnnDatas
|
|
73
|
+
for adata in adatas:
|
|
74
|
+
adata.obs[color_key] = pd.Categorical(
|
|
75
|
+
adata.obs[color_key], categories=all_labels
|
|
76
|
+
)
|
|
77
|
+
adata.uns[f"{color_key}_colors"] = colors
|
|
78
|
+
|
|
79
|
+
return all_labels, colors
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def plot_spatial_with_palette(
|
|
83
|
+
adata,
|
|
84
|
+
color_key="token",
|
|
85
|
+
spot_size=0.001,
|
|
86
|
+
size=10,
|
|
87
|
+
scale_factor=1,
|
|
88
|
+
show_legend=False,
|
|
89
|
+
figsize=(10, 10),
|
|
90
|
+
save=None,
|
|
91
|
+
saggital=False,
|
|
92
|
+
):
|
|
93
|
+
adata = adata.copy()
|
|
94
|
+
if saggital:
|
|
95
|
+
print("Yes it is saggital")
|
|
96
|
+
adata.obsm["spatial"][:, [0, 1]] = adata.obsm["spatial"][:, [1, 2]]
|
|
97
|
+
with plt.rc_context({"figure.figsize": figsize}):
|
|
98
|
+
sc.pl.spatial(
|
|
99
|
+
adata,
|
|
100
|
+
color=color_key,
|
|
101
|
+
spot_size=spot_size,
|
|
102
|
+
size=size,
|
|
103
|
+
scale_factor=scale_factor,
|
|
104
|
+
legend_loc="right margin" if show_legend else None,
|
|
105
|
+
save=None,
|
|
106
|
+
title="",
|
|
107
|
+
frameon=False,
|
|
108
|
+
)
|
|
109
|
+
if save is not None:
|
|
110
|
+
os.makedirs(os.path.dirname(save), exist_ok=True)
|
|
111
|
+
plt.savefig(save, bbox_inches="tight", dpi=300)
|
|
112
|
+
plt.close()
|