albis 0.1.0__tar.gz
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.
- albis-0.1.0/LICENSE +21 -0
- albis-0.1.0/PKG-INFO +54 -0
- albis-0.1.0/README.md +390 -0
- albis-0.1.0/README_PYPI.md +22 -0
- albis-0.1.0/albis/__init__.py +22 -0
- albis-0.1.0/albis/api.py +317 -0
- albis-0.1.0/albis/plotting.py +157 -0
- albis-0.1.0/albis/simulation_sphere.py +2161 -0
- albis-0.1.0/albis.egg-info/PKG-INFO +54 -0
- albis-0.1.0/albis.egg-info/SOURCES.txt +14 -0
- albis-0.1.0/albis.egg-info/dependency_links.txt +1 -0
- albis-0.1.0/albis.egg-info/requires.txt +14 -0
- albis-0.1.0/albis.egg-info/top_level.txt +1 -0
- albis-0.1.0/pyproject.toml +57 -0
- albis-0.1.0/setup.cfg +4 -0
- albis-0.1.0/tests/test_public_api.py +71 -0
albis-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jan Matthias
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
albis-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: albis
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Albis - A muLti-resolution Biological In-silico Simulator for 3D spatial transcriptomics.
|
|
5
|
+
Author: Jan Matthias, Jianing Yao, Stephanie Hicks
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/JanMatthias1/Albis
|
|
8
|
+
Project-URL: Documentation, https://github.com/JanMatthias1/Albis#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/JanMatthias1/Albis
|
|
10
|
+
Project-URL: Issues, https://github.com/JanMatthias1/Albis/issues
|
|
11
|
+
Keywords: spatial-transcriptomics,simulation,anndata,multi-resolution
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: anndata>=0.10
|
|
21
|
+
Requires-Dist: numpy>=1.23
|
|
22
|
+
Requires-Dist: scipy>=1.10
|
|
23
|
+
Provides-Extra: plot
|
|
24
|
+
Requires-Dist: matplotlib>=3.7; extra == "plot"
|
|
25
|
+
Provides-Extra: tutorial
|
|
26
|
+
Requires-Dist: ipykernel>=6; extra == "tutorial"
|
|
27
|
+
Requires-Dist: nbformat>=5; extra == "tutorial"
|
|
28
|
+
Requires-Dist: notebook>=7; extra == "tutorial"
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
# Albis
|
|
34
|
+
|
|
35
|
+
Albis — A muLti-resolution Biological In-silico Simulator — generates
|
|
36
|
+
synthetic 3D spatial-transcriptomics data as AnnData objects, with
|
|
37
|
+
cell, bin, and spot resolutions.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install albis
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
With plotting support:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install "albis[plot]"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Documentation and tutorials
|
|
52
|
+
|
|
53
|
+
See the [GitHub repository](https://github.com/JanMatthias1/Albis)
|
|
54
|
+
for usage instructions, parameter descriptions, and tutorials.
|
albis-0.1.0/README.md
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# Albis
|
|
2
|
+
|
|
3
|
+
**Albis** - A muLti-resolution Biological In-silico Simulator - is a Python
|
|
4
|
+
package for generating synthetic 3D spatial-transcriptomics data as analysis-ready
|
|
5
|
+
[`AnnData`](https://anndata.readthedocs.io/) objects.
|
|
6
|
+
It is structured as an installable package with a small tutorial workflow.
|
|
7
|
+
|
|
8
|
+
The simulator creates cells in a sphere, generates negative-binomial
|
|
9
|
+
gene-expression counts, expands those counts into individual transcript
|
|
10
|
+
locations, and aggregates transcripts to cell, bin, or spot observations.
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
albis/
|
|
14
|
+
├── pyproject.toml
|
|
15
|
+
├── README.md
|
|
16
|
+
├── albis/
|
|
17
|
+
│ ├── api.py
|
|
18
|
+
│ ├── plotting.py
|
|
19
|
+
│ └── simulation_sphere.py
|
|
20
|
+
├── tests/
|
|
21
|
+
└── tutorial/
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
import albis as ab
|
|
26
|
+
|
|
27
|
+
adata = ab.generate_data(...)
|
|
28
|
+
summary = ab.describe(adata)
|
|
29
|
+
figure = ab.plot(adata, ...)
|
|
30
|
+
path = ab.save(adata, "simulation.h5ad")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
For local development, install the package from the repository root:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
python -m pip install -e .
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Install optional static plotting support as well:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
python -m pip install -e ".[plot]"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The PyPI package name and the Python import name are both `albis` (`pip install albis`, `import albis as ab`).
|
|
48
|
+
|
|
49
|
+
## Development
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python -m pip install -e ".[dev,plot]"
|
|
53
|
+
python -m pytest
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This repository now contains only the Python package. Manuscript, paper,
|
|
57
|
+
notebook, and tutorial material lives in the separate `sim_paper` repository.
|
|
58
|
+
|
|
59
|
+
## Tutorial
|
|
60
|
+
|
|
61
|
+
Two package-focused tutorials are available:
|
|
62
|
+
|
|
63
|
+
- [`tutorial/higher_level_api_tutorial.ipynb`](tutorial/higher_level_api_tutorial.ipynb) —
|
|
64
|
+
the app-facing `generate_data()` workflow: generate a small dataset,
|
|
65
|
+
inspect the returned `AnnData`, plot aligned and unaligned coordinates, and
|
|
66
|
+
save the result.
|
|
67
|
+
- [`tutorial/lower_level_api_tutorial.ipynb`](tutorial/lower_level_api_tutorial.ipynb) —
|
|
68
|
+
the low-level simulator API, with every parameter exposed as one plain
|
|
69
|
+
dictionary (see [Low-level simulator](#low-level-simulator) below).
|
|
70
|
+
|
|
71
|
+
To run the tutorial notebooks, install with the tutorial extras:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install -e ".[tutorial,plot]" # from a clone; or: pip install "albis[tutorial,plot]"
|
|
75
|
+
jupyter-notebook --no-browser --ip=0.0.0.0 --port 8888
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
On a conda-based cluster, `env/create_tutorial_env.sh` does the same in a
|
|
79
|
+
dedicated prefix env and registers a Jupyter kernel:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
bash env/create_tutorial_env.sh # builds env/albis-tutorial/
|
|
83
|
+
conda activate env/albis-tutorial
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Quick start
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
import albis as ab
|
|
90
|
+
|
|
91
|
+
adata = ab.generate_data(
|
|
92
|
+
output="bin",
|
|
93
|
+
slice_axis="Z",
|
|
94
|
+
n_cells=1_000,
|
|
95
|
+
n_slices=5,
|
|
96
|
+
n_domains=4,
|
|
97
|
+
seed=2025,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
summary = ab.describe(adata)
|
|
101
|
+
|
|
102
|
+
figure = ab.plot(
|
|
103
|
+
adata,
|
|
104
|
+
view="2d",
|
|
105
|
+
coordinates="aligned",
|
|
106
|
+
color="domain_true",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
ab.save(adata, "simulation_bins_z.h5ad")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## `generate_data`
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
adata = ab.generate_data(output="bin", slice_axis="Z")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Parameters are usually passed as keyword arguments. They can also be omitted to
|
|
119
|
+
use `ab.DEFAULT_PARAMETERS`:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
adata = ab.generate_data(output="spot", slice_axis="X", n_cells=2_000)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
If you build a configuration programmatically, passing a dictionary is still
|
|
126
|
+
supported:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
params = {"output": "spot", "slice_axis": "X", "n_cells": 2_000}
|
|
130
|
+
adata = ab.generate_data(params)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The function returns exactly **one** `AnnData` object. It does not generate
|
|
134
|
+
unrequested platforms or slice axes. For example, requesting Z-axis bins skips
|
|
135
|
+
cell-section outputs, spots, and X/Y bin outputs.
|
|
136
|
+
|
|
137
|
+
For a small tutorial or smoke-test dataset, use:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
adata = ab.example_data()
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`example_data()` calls `generate_data()` with smaller defaults. Keyword
|
|
144
|
+
arguments can override those defaults:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
adata = ab.example_data(output="spot", slice_axis="Y", n_cells=500)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Parameters
|
|
151
|
+
|
|
152
|
+
Parameters are grouped below in the order the simulator applies them: select
|
|
153
|
+
an output, build the tissue sphere, place cells within it, assign each cell to
|
|
154
|
+
a spatial domain with irregular boundaries, assign cell types and generate
|
|
155
|
+
genes and molecules, then slice, capture, and apply batch effects.
|
|
156
|
+
|
|
157
|
+
#### Output selection
|
|
158
|
+
|
|
159
|
+
| Parameter | Default | Meaning |
|
|
160
|
+
| --- | ---: | --- |
|
|
161
|
+
| `output` | `"bin"` | Observation type to generate: `"cell"`, `"bin"`, or `"spot"`. |
|
|
162
|
+
| `slice_axis` | `"Z"` | Axis normal to the 2D slice plane: `"X"`, `"Y"`, or `"Z"`. |
|
|
163
|
+
|
|
164
|
+
#### 1. Tissue sphere
|
|
165
|
+
|
|
166
|
+
| Parameter | Default | Meaning |
|
|
167
|
+
| --- | ---: | --- |
|
|
168
|
+
| `tissue_shape` | `"sphere"` | Overall tissue geometry; only `"sphere"` is currently supported. |
|
|
169
|
+
| `sphere_radius_um` | `300.0` | Radius of the tissue sphere, in microns. |
|
|
170
|
+
|
|
171
|
+
#### 2. Cell placement
|
|
172
|
+
|
|
173
|
+
Cell centroids and radii are sampled within the tissue sphere before domains
|
|
174
|
+
are assigned; domain membership is determined afterward, from each cell's
|
|
175
|
+
position.
|
|
176
|
+
|
|
177
|
+
| Parameter | Default | Meaning |
|
|
178
|
+
| --- | ---: | --- |
|
|
179
|
+
| `n_cells` | `1000` | Number of simulated cells. |
|
|
180
|
+
| `allow_cell_overlap` | `False` | Whether overlapping cell spheres are permitted during placement. |
|
|
181
|
+
| `cell_radius_kwargs` | `None` | Optional low-level cell-radius distribution settings (`radius_dist`, `r_mean`, `r_sigma`, `r_min`, `r_max`). |
|
|
182
|
+
|
|
183
|
+
#### 3. Spatial domains
|
|
184
|
+
|
|
185
|
+
Domain membership is evaluated per cell, using each cell's position within
|
|
186
|
+
the sphere.
|
|
187
|
+
|
|
188
|
+
| Parameter | Default | Meaning |
|
|
189
|
+
| --- | ---: | --- |
|
|
190
|
+
| `n_domains` | `4` | Number of spatial domains: `n_domains - 1` angular wedges surrounding one central core. |
|
|
191
|
+
| `domain_layout` | `"core_wedges"` | Domain-generation strategy; only `"core_wedges"` is currently supported. |
|
|
192
|
+
| `core_frac` | `0.35` | Core radius as a fraction of the sphere radius, not its volume. For example, `0.55` yields a core occupying roughly 17% of the sphere's volume. |
|
|
193
|
+
|
|
194
|
+
#### 4. Domain boundary irregularity
|
|
195
|
+
|
|
196
|
+
By default, core and wedge boundaries are smooth and straight. These
|
|
197
|
+
parameters introduce two independent forms of irregularity: a continuous
|
|
198
|
+
geometric warp of the boundary surfaces, and discrete relabeling ("fuzz") of
|
|
199
|
+
individual points near those boundaries.
|
|
200
|
+
|
|
201
|
+
| Parameter | Default | Meaning |
|
|
202
|
+
| --- | ---: | --- |
|
|
203
|
+
| `core_bump_amp` | `0.12` | Fractional, direction-dependent perturbation of the core radius; `0.0` yields a perfect sphere. |
|
|
204
|
+
| `wedge_angle_amp_deg` | `12.0` | Angular perturbation applied to wedge boundaries, in degrees; `0.0` yields straight radial cuts. |
|
|
205
|
+
| `noise_terms` | `6` | Number of sinusoidal components summed to construct the smooth noise field underlying `core_bump_amp` and `wedge_angle_amp_deg`. Higher values yield smoother, less directional noise. |
|
|
206
|
+
| `noise_freq_range` | `(0.8, 2.2)` | Spatial-frequency range (cycles per micron) of that noise field. Higher frequencies yield finer-grained boundary texture. |
|
|
207
|
+
| `boundary_fuzz_width_deg` | `0.0` | Angular band, in degrees, around each wedge-wedge boundary within which points may be relabeled to the neighboring wedge. |
|
|
208
|
+
| `boundary_fuzz_flip_prob` | `0.0` | Probability that a point within `boundary_fuzz_width_deg` of a boundary is relabeled to the neighboring wedge. |
|
|
209
|
+
| `core_fuzz_width_um` | `0.0` | Radial band, in microns, around the core boundary within which points may be relabeled across the core/wedge interface. |
|
|
210
|
+
| `core_fuzz_flip_prob` | `0.0` | Probability that a point within `core_fuzz_width_um` of the core boundary is relabeled across the core/wedge interface. |
|
|
211
|
+
|
|
212
|
+
#### 5. Cell types, genes, and molecules
|
|
213
|
+
|
|
214
|
+
Once each cell has a domain, it is assigned a cell type, a gene panel is
|
|
215
|
+
built, and gene-expression counts are expanded into individual transcript
|
|
216
|
+
locations.
|
|
217
|
+
|
|
218
|
+
| Parameter | Default | Meaning |
|
|
219
|
+
| --- | ---: | --- |
|
|
220
|
+
| `n_cell_types` | `4` | Number of cell types. |
|
|
221
|
+
| `domain_type_mix` | `None` | Optional `(n_domains, n_cell_types)` composition matrix specifying which cell types occur in each domain, and in what proportions. Each row is renormalized to a probability distribution and used to draw the cell type of every cell assigned to that domain. `None` uses a small built-in example composition, but that built-in matrix is a fixed 4x4 — it only applies as-is when `n_domains=4` and `n_cell_types=4`. Change either away from the 4/4 default without supplying your own `domain_type_mix`, and every domain silently gets the exact same uniform mix instead (a `UserWarning` is raised, but nothing errors — see below). |
|
|
222
|
+
| `marker_genes_per_type` | `80` | Number of marker genes assigned to each cell type. |
|
|
223
|
+
| `noise_gene_frac` | `0.10` | Fraction of the gene panel carrying no cell-type signal. |
|
|
224
|
+
| `shared_marker_frac` | `0.25` | Fraction of each cell type's markers shared with other cell types, rather than unique to it. |
|
|
225
|
+
| `inside_prob` | `0.95` | Target fraction of a cell's transcripts generated within its cell radius. |
|
|
226
|
+
| `assign_k` | `8` | Number of nearest cells considered when reassigning transcripts to cells by containment, for `output="cell"`. |
|
|
227
|
+
|
|
228
|
+
> **If you change `n_domains` or `n_cell_types` away from the 4/4 default, you must
|
|
229
|
+
> supply your own `domain_type_mix`.** The uniform fallback isn't a mild or
|
|
230
|
+
> approximate composition — every domain gets the exact same flat distribution
|
|
231
|
+
> over cell types (e.g. all `1/8` for 8 types), so domains carry no
|
|
232
|
+
> cell-type signal at all. Any benchmark relying on domain-specific
|
|
233
|
+
> composition (e.g. "does this method preserve local cell-type mixture?")
|
|
234
|
+
> will be silently meaningless without an explicit `domain_type_mix`.
|
|
235
|
+
|
|
236
|
+
#### 6. Slicing, capture, and batch effects
|
|
237
|
+
|
|
238
|
+
| Parameter | Default | Meaning |
|
|
239
|
+
| --- | ---: | --- |
|
|
240
|
+
| `n_slices` | `5` | Number of slices generated along the selected axis. |
|
|
241
|
+
| `capture_window_um` | `"platform"` | Capture area cropped from each 2D slice. `"platform"` uses the real slide area for the chosen `output`: 6.5 × 6.5 mm for `"bin"`/`"spot"` (Visium / Visium HD) and `xenium_capture_window_um` (12 × 24 mm) for `"cell"` (Xenium). Pass `False` to disable the crop (bin/spot grids then span the molecule bounding box, with no empty border), or a `(width, height)` pair in microns to apply a custom window to any modality. **When the tissue is smaller than the window, `"bin"`/`"spot"` output contains all-zero observations around the tissue — see [Empty bins and spots](#empty-bins-and-spots) below.** |
|
|
242
|
+
| `xenium_capture_window_um` | `(12000, 24000)` | Xenium slide area, in microns, used as the `"cell"` capture window when `capture_window_um="platform"`. Cells whose in-plane centroid falls outside it are dropped. |
|
|
243
|
+
| `bin_size_um` | `16.0` | Bin width, in microns, for `output="bin"` (Visium HD 16um bin). |
|
|
244
|
+
| `spot_spacing_um` | `100.0` | Center-to-center spacing between spots, in microns, for `output="spot"`. |
|
|
245
|
+
| `spot_radius_um` | `27.5` | Capture radius of each spot, in microns, for `output="spot"`. |
|
|
246
|
+
| `batch_sigma` | `0.15` | Standard deviation of the per-slice, per-gene log-fold-change applied to simulate batch effects across slices. |
|
|
247
|
+
| `unaligned_coordinates` | `True` | Whether to additionally generate a randomly rotated and translated ("unaligned") copy of each slice's coordinates. |
|
|
248
|
+
| `max_deg` | `180.0` | Maximum absolute per-slice in-plane rotation, in degrees, applied when generating unaligned coordinates. |
|
|
249
|
+
| `max_shift` | `200.0` | Maximum absolute per-slice in-plane translation, in microns, applied when generating unaligned coordinates. |
|
|
250
|
+
| `include_truth` | `True` | Whether to retain pre-batch-effect counts and ground-truth annotations in the returned object. |
|
|
251
|
+
|
|
252
|
+
#### Reproducibility
|
|
253
|
+
|
|
254
|
+
| Parameter | Default | Meaning |
|
|
255
|
+
| --- | ---: | --- |
|
|
256
|
+
| `seed` | `2025` | Random seed governing cell placement, gene expression, and batch effects. |
|
|
257
|
+
| `base_seed_unaligned` | `12345` | Random seed governing the per-slice rotation and translation used to generate unaligned coordinates. |
|
|
258
|
+
| `sync_unaligned_seed` | `False` | By default, each `output` modality (`"cell"`/`"bin"`/`"spot"`) draws a *different* per-slice unaligned rotation/translation even with the same `base_seed_unaligned` and `seed` -- separate `generate_data()` calls per modality are decorrelated on purpose. Set `sync_unaligned_seed=True` to make all three modalities draw the *same* per-slice transform instead (same `sphere_radius_um`/`max_deg`/`max_shift`/`base_seed_unaligned`/`seed` required too), e.g. to compare how different modalities' own alignment method resolves an identical starting misalignment. |
|
|
259
|
+
|
|
260
|
+
Use `ab.DEFAULT_PARAMETERS` to inspect the complete supported parameter
|
|
261
|
+
set. Unsupported values fail early with a descriptive error.
|
|
262
|
+
|
|
263
|
+
## AnnData Output
|
|
264
|
+
|
|
265
|
+
All coordinates use microns. `adata.X` is a sparse count matrix containing the
|
|
266
|
+
final observed counts after slice-specific batch effects.
|
|
267
|
+
|
|
268
|
+
| Location | Contents |
|
|
269
|
+
| --- | --- |
|
|
270
|
+
| `adata.X` | Final observation-by-gene count matrix. |
|
|
271
|
+
| `adata.layers["counts_pre_batch"]` | Counts before batch effects; present when `include_truth=True`. |
|
|
272
|
+
| `adata.obs` | Slice IDs and capture/grid metadata. |
|
|
273
|
+
| `adata.obs["domain_true"]` | Ground-truth spatial domain. For `"cell"`, the identity draw fixed at cell-placement time; for `"bin"`/`"spot"`, the argmax of `domain_frac_true`. |
|
|
274
|
+
| `adata.obs["cell_type_true"]` | Ground-truth cell type. Same true/derived split as `domain_true` above. |
|
|
275
|
+
| `adata.obs["is_empty"]` | `"bin"`/`"spot"` only — `True` for grid cells with no molecules (see [Empty bins and spots](#empty-bins-and-spots)); those rows get `domain_true`/`cell_type_true` `"unassigned"`. Not present for `"cell"`. |
|
|
276
|
+
| `adata.var` | Marker/noise-gene annotations. |
|
|
277
|
+
| `adata.obsm["spatial"]` | Canonical aligned 2D coordinates in the selected slice plane. |
|
|
278
|
+
| `adata.obsm["spatial_unaligned"]` | Per-slice rigidly transformed 2D coordinates. |
|
|
279
|
+
| `adata.obsm["spatial_3d"]` | Canonical 3D coordinates. |
|
|
280
|
+
| `adata.obsm["spatial_3d_unaligned"]` | 3D representation of the in-plane unaligned transforms. |
|
|
281
|
+
| `adata.obsm["cell_type_frac_true"]` | Source cell-type fractions for bin/spot observations. |
|
|
282
|
+
| `adata.obsm["domain_frac_true"]` | Source-domain fractions for bin/spot observations. |
|
|
283
|
+
| `adata.uns["batch_effect_factors"]` | Per-slice gene-wise multiplicative batch factors. |
|
|
284
|
+
| `adata.uns["sim_params"]` | Resolved simulation configuration and simulator metadata. |
|
|
285
|
+
| `adata.uns["output"]` | Selected platform and slice axis. |
|
|
286
|
+
|
|
287
|
+
`spatial_unaligned` is not shuffled data. Each slice receives one deterministic
|
|
288
|
+
random rigid transform: a rotation plus a translation. No scaling, shearing,
|
|
289
|
+
or molecule resimulation occurs. `spatial_3d_unaligned` applies that transform
|
|
290
|
+
to the corresponding plane while retaining the coordinate normal to the slice.
|
|
291
|
+
This per-slice transform is independent across `output` modalities by default
|
|
292
|
+
(a `"bin"` call and a `"spot"` call with identical parameters still get
|
|
293
|
+
different unaligned coordinates) -- pass `sync_unaligned_seed=True` if you
|
|
294
|
+
want `"cell"`/`"bin"`/`"spot"` to share the same perturbation instead.
|
|
295
|
+
|
|
296
|
+
### Empty bins and spots
|
|
297
|
+
|
|
298
|
+
The `"bin"`/`"spot"` grid always tiles the **whole capture window**, on every
|
|
299
|
+
slice, regardless of how much tissue that slice actually contains. When the
|
|
300
|
+
tissue is smaller than the window (or a slice only clips its edge), the grid
|
|
301
|
+
cells outside the tissue are still returned as all-zero observations.
|
|
302
|
+
|
|
303
|
+
These empty observations are handled explicitly:
|
|
304
|
+
|
|
305
|
+
- `adata.obs["is_empty"]` is `True` for every observation with no molecules
|
|
306
|
+
(equivalently `adata.layers["counts_pre_batch"].sum(axis=1) == 0`). It is a
|
|
307
|
+
structural flag, not a truth label, so it survives `include_truth=False`.
|
|
308
|
+
- `adata.obs["domain_true"]` and `adata.obs["cell_type_true"]` are set to
|
|
309
|
+
`"unassigned"` for those rows.
|
|
310
|
+
|
|
311
|
+
Empty observations are **not dropped** by the simulator — that is the caller's
|
|
312
|
+
choice. Filter them before analysis with a per-observation minimum-count QC,
|
|
313
|
+
e.g. `adata = adata[~adata.obs["is_empty"]].copy()`, or pass
|
|
314
|
+
`capture_window_um=False` to fit the grid to the tissue in the first place.
|
|
315
|
+
`"cell"` output is unaffected: cells only exist where there is tissue, so it
|
|
316
|
+
has no `is_empty` column and never uses the `"unassigned"` label.
|
|
317
|
+
|
|
318
|
+
## Describe and Save
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
summary = ab.describe(adata)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
`describe()` returns a plain dictionary with the most important contents of the
|
|
325
|
+
object: observation and gene counts, total counts, output platform, slice axis,
|
|
326
|
+
available coordinate keys, layers, metadata keys, and truth annotations.
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
path = ab.save(adata, "simulation_bins_z.h5ad")
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
`save()` writes the object with AnnData's `.h5ad` format and returns the path.
|
|
333
|
+
It is a convenience wrapper around `adata.write_h5ad(...)`.
|
|
334
|
+
|
|
335
|
+
## Plotting
|
|
336
|
+
|
|
337
|
+
```python
|
|
338
|
+
# Aligned 2D tissue view, colored by an observation annotation
|
|
339
|
+
ab.plot(adata, view="2d", coordinates="aligned", color="domain_true")
|
|
340
|
+
|
|
341
|
+
# Unaligned 3D view, colored by slice
|
|
342
|
+
ab.plot(adata, view="3d", coordinates="unaligned", color="slice_id")
|
|
343
|
+
|
|
344
|
+
# Expression of one gene in a single slice
|
|
345
|
+
ab.plot(adata, view="2d", color="G1", slice_id=0, point_size=8)
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
`ab.plot()` returns a Matplotlib `Figure`. It supports:
|
|
349
|
+
|
|
350
|
+
- `view="2d"` or `view="3d"`
|
|
351
|
+
- `coordinates="aligned"` or `coordinates="unaligned"`
|
|
352
|
+
- `color` set to an `obs` column or gene name
|
|
353
|
+
- `slice_id` to show one slice
|
|
354
|
+
- `point_size`, `alpha`, `max_points`, and `seed` rendering controls
|
|
355
|
+
|
|
356
|
+
Large datasets are deterministically downsampled to `max_points=50_000` by
|
|
357
|
+
default. Use `max_points=None` only when the output size is known to be safe.
|
|
358
|
+
|
|
359
|
+
## Performance guidance
|
|
360
|
+
|
|
361
|
+
Runtime and memory scale primarily with the number of generated molecules,
|
|
362
|
+
which in turn grows with `n_cells` and the simulated expression level.
|
|
363
|
+
|
|
364
|
+
- Start with `n_cells=1_000`, then increase gradually.
|
|
365
|
+
- Pass a smaller `capture_window_um` (or `False`, which fits the grid to the
|
|
366
|
+
tissue) or a larger `bin_size_um` to reduce the number of bin observations —
|
|
367
|
+
the default `"platform"` tiles the full 6.5 mm Visium window regardless of
|
|
368
|
+
tissue size.
|
|
369
|
+
- Request one output and one axis at a time through `generate_data()`.
|
|
370
|
+
- Use `max_points` in plotting rather than trying to render every bin/cell.
|
|
371
|
+
|
|
372
|
+
The default parameters are chosen for interactive experimentation, not for
|
|
373
|
+
reproducing the original large-scale standalone example.
|
|
374
|
+
|
|
375
|
+
## Low-level simulator
|
|
376
|
+
|
|
377
|
+
`generate_data()` always builds exactly one modality/axis pair, so generating
|
|
378
|
+
several combinations that way re-simulates the tissue sphere, cells, domains,
|
|
379
|
+
and gene panel from scratch for each call. If you need multiple
|
|
380
|
+
resolutions — several modalities, several slice axes, or both — from the same
|
|
381
|
+
underlying tissue, or need a parameter `generate_data()` doesn't expose (e.g.
|
|
382
|
+
`theta`, `domain_size_factors`, `noise_scale`), use the lower-level simulator
|
|
383
|
+
API instead: `ab.simulate_3d_molecule_sphere_multires(...)`.
|
|
384
|
+
|
|
385
|
+
See **[LOW_LEVEL_SIMULATOR.md](LOW_LEVEL_SIMULATOR.md)** for worked examples
|
|
386
|
+
and the full parameter reference for this API.
|
|
387
|
+
|
|
388
|
+
For everyday use, prefer `ab.generate_data(...)`: it wraps this API and
|
|
389
|
+
returns exactly one `AnnData` object for the requested modality and axis,
|
|
390
|
+
without building the others.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Albis
|
|
2
|
+
|
|
3
|
+
Albis — A muLti-resolution Biological In-silico Simulator — generates
|
|
4
|
+
synthetic 3D spatial-transcriptomics data as AnnData objects, with
|
|
5
|
+
cell, bin, and spot resolutions.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install albis
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
With plotting support:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install "albis[plot]"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Documentation and tutorials
|
|
20
|
+
|
|
21
|
+
See the [GitHub repository](https://github.com/JanMatthias1/Albis)
|
|
22
|
+
for usage instructions, parameter descriptions, and tutorials.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Public API for Albis - A muLti-resolution Biological In-silico Simulator."""
|
|
2
|
+
|
|
3
|
+
from .api import DEFAULT_PARAMETERS, describe, example_data, generate_data, save
|
|
4
|
+
from .plotting import plot
|
|
5
|
+
from .simulation_sphere import (
|
|
6
|
+
section_3d_molecule_sphere,
|
|
7
|
+
simulate_3d_molecule_sphere_base,
|
|
8
|
+
simulate_3d_molecule_sphere_multires,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"DEFAULT_PARAMETERS",
|
|
13
|
+
"describe",
|
|
14
|
+
"example_data",
|
|
15
|
+
"generate_data",
|
|
16
|
+
"plot",
|
|
17
|
+
"save",
|
|
18
|
+
"section_3d_molecule_sphere",
|
|
19
|
+
"simulate_3d_molecule_sphere_base",
|
|
20
|
+
"simulate_3d_molecule_sphere_multires",
|
|
21
|
+
]
|
|
22
|
+
__version__ = "0.1.0"
|