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.
Files changed (41) hide show
  1. mimyr/__init__.py +27 -0
  2. mimyr/_resources.py +10 -0
  3. mimyr/analysis.py +112 -0
  4. mimyr/api.py +638 -0
  5. mimyr/data_loader.py +1216 -0
  6. mimyr/data_modes.py +31 -0
  7. mimyr/evaluator.py +202 -0
  8. mimyr/gene_exp_model.py +84 -0
  9. mimyr/inference.py +914 -0
  10. mimyr/metrics.py +747 -0
  11. mimyr/models/__init__.py +0 -0
  12. mimyr/models/biological_model.py +395 -0
  13. mimyr/models/celltype_model.py +627 -0
  14. mimyr/models/combined_model.py +106 -0
  15. mimyr/models/diffusion_model.py +623 -0
  16. mimyr/models/generative_transformer/Mimyr.py +799 -0
  17. mimyr/models/generative_transformer/__init__.py +7 -0
  18. mimyr/models/generative_transformer/data_util.py +619 -0
  19. mimyr/models/generative_transformer/finetune_mimyr.py +1701 -0
  20. mimyr/models/generative_transformer/metadata/4hierarchy_metainfo_mouse_geneunion2_DAG.pt +0 -0
  21. mimyr/models/generative_transformer/metadata/edges_x.pkl +0 -0
  22. mimyr/models/generative_transformer/metadata/edges_y.pkl +0 -0
  23. mimyr/models/generative_transformer/metadata/edges_z.pkl +0 -0
  24. mimyr/models/generative_transformer/metadata/hierarchy.pkl +0 -0
  25. mimyr/models/generative_transformer/metadata/id_to_subclass.pkl +0 -0
  26. mimyr/models/generative_transformer/model/__init__.py +0 -0
  27. mimyr/models/generative_transformer/model/model.py +990 -0
  28. mimyr/models/generative_transformer/model/model_kvcache.py +1144 -0
  29. mimyr/models/generative_transformer/model/wtf_bias.py +185 -0
  30. mimyr/models/generative_transformer/reference/GeneSymbolUniform/__init__.py +0 -0
  31. mimyr/models/generative_transformer/reference/GeneSymbolUniform/pyGSUni.py +424 -0
  32. mimyr/models/generative_transformer/reference/GeneSymbolUniform/total_gene_list_42117.txt +42118 -0
  33. mimyr/models/generative_transformer/reference/__init__.py +0 -0
  34. mimyr/models/generative_transformer/utils/__init__.py +1 -0
  35. mimyr/models/generative_transformer/utils/hf_tokenizer.py +31 -0
  36. mimyr/pretrained.py +187 -0
  37. mimyr-0.1.0.dist-info/METADATA +479 -0
  38. mimyr-0.1.0.dist-info/RECORD +41 -0
  39. mimyr-0.1.0.dist-info/WHEEL +5 -0
  40. mimyr-0.1.0.dist-info/licenses/LICENSE +21 -0
  41. 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()