chatspatial 1.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.
- chatspatial/__init__.py +11 -0
- chatspatial/__main__.py +141 -0
- chatspatial/cli/__init__.py +7 -0
- chatspatial/config.py +53 -0
- chatspatial/models/__init__.py +85 -0
- chatspatial/models/analysis.py +513 -0
- chatspatial/models/data.py +2462 -0
- chatspatial/server.py +1763 -0
- chatspatial/spatial_mcp_adapter.py +720 -0
- chatspatial/tools/__init__.py +3 -0
- chatspatial/tools/annotation.py +1903 -0
- chatspatial/tools/cell_communication.py +1603 -0
- chatspatial/tools/cnv_analysis.py +605 -0
- chatspatial/tools/condition_comparison.py +595 -0
- chatspatial/tools/deconvolution/__init__.py +402 -0
- chatspatial/tools/deconvolution/base.py +318 -0
- chatspatial/tools/deconvolution/card.py +244 -0
- chatspatial/tools/deconvolution/cell2location.py +326 -0
- chatspatial/tools/deconvolution/destvi.py +144 -0
- chatspatial/tools/deconvolution/flashdeconv.py +101 -0
- chatspatial/tools/deconvolution/rctd.py +317 -0
- chatspatial/tools/deconvolution/spotlight.py +216 -0
- chatspatial/tools/deconvolution/stereoscope.py +109 -0
- chatspatial/tools/deconvolution/tangram.py +135 -0
- chatspatial/tools/differential.py +625 -0
- chatspatial/tools/embeddings.py +298 -0
- chatspatial/tools/enrichment.py +1863 -0
- chatspatial/tools/integration.py +807 -0
- chatspatial/tools/preprocessing.py +723 -0
- chatspatial/tools/spatial_domains.py +808 -0
- chatspatial/tools/spatial_genes.py +836 -0
- chatspatial/tools/spatial_registration.py +441 -0
- chatspatial/tools/spatial_statistics.py +1476 -0
- chatspatial/tools/trajectory.py +495 -0
- chatspatial/tools/velocity.py +405 -0
- chatspatial/tools/visualization/__init__.py +155 -0
- chatspatial/tools/visualization/basic.py +393 -0
- chatspatial/tools/visualization/cell_comm.py +699 -0
- chatspatial/tools/visualization/cnv.py +320 -0
- chatspatial/tools/visualization/core.py +684 -0
- chatspatial/tools/visualization/deconvolution.py +852 -0
- chatspatial/tools/visualization/enrichment.py +660 -0
- chatspatial/tools/visualization/integration.py +205 -0
- chatspatial/tools/visualization/main.py +164 -0
- chatspatial/tools/visualization/multi_gene.py +739 -0
- chatspatial/tools/visualization/persistence.py +335 -0
- chatspatial/tools/visualization/spatial_stats.py +469 -0
- chatspatial/tools/visualization/trajectory.py +639 -0
- chatspatial/tools/visualization/velocity.py +411 -0
- chatspatial/utils/__init__.py +115 -0
- chatspatial/utils/adata_utils.py +1372 -0
- chatspatial/utils/compute.py +327 -0
- chatspatial/utils/data_loader.py +499 -0
- chatspatial/utils/dependency_manager.py +462 -0
- chatspatial/utils/device_utils.py +165 -0
- chatspatial/utils/exceptions.py +185 -0
- chatspatial/utils/image_utils.py +267 -0
- chatspatial/utils/mcp_utils.py +137 -0
- chatspatial/utils/path_utils.py +243 -0
- chatspatial/utils/persistence.py +78 -0
- chatspatial/utils/scipy_compat.py +143 -0
- chatspatial-1.1.0.dist-info/METADATA +242 -0
- chatspatial-1.1.0.dist-info/RECORD +67 -0
- chatspatial-1.1.0.dist-info/WHEEL +5 -0
- chatspatial-1.1.0.dist-info/entry_points.txt +2 -0
- chatspatial-1.1.0.dist-info/licenses/LICENSE +21 -0
- chatspatial-1.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tangram deconvolution method.
|
|
3
|
+
|
|
4
|
+
Tangram maps single-cell RNA-seq data to spatial transcriptomics
|
|
5
|
+
data using the native tangram-sc library.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import gc
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import pandas as pd
|
|
12
|
+
|
|
13
|
+
from ...utils.exceptions import DependencyError, ProcessingError
|
|
14
|
+
from .base import PreparedDeconvolutionData, create_deconvolution_stats
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def deconvolve(
|
|
18
|
+
data: PreparedDeconvolutionData,
|
|
19
|
+
n_epochs: int = 1000,
|
|
20
|
+
mode: str = "cells",
|
|
21
|
+
learning_rate: float = 0.1,
|
|
22
|
+
density_prior: str = "rna_count_based",
|
|
23
|
+
use_gpu: bool = False,
|
|
24
|
+
) -> tuple[pd.DataFrame, dict[str, Any]]:
|
|
25
|
+
"""Deconvolve spatial data using native Tangram library.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
data: Prepared deconvolution data (immutable)
|
|
29
|
+
n_epochs: Number of training epochs
|
|
30
|
+
mode: Mapping mode - 'cells' or 'clusters'
|
|
31
|
+
learning_rate: Optimizer learning rate
|
|
32
|
+
density_prior: Spatial density prior - 'rna_count_based' or 'uniform'
|
|
33
|
+
use_gpu: Whether to use GPU acceleration
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Tuple of (proportions DataFrame, statistics dictionary)
|
|
37
|
+
"""
|
|
38
|
+
# Check for tangram package (installed as tangram-sc, imported as tangram)
|
|
39
|
+
try:
|
|
40
|
+
import tangram as tg
|
|
41
|
+
except ImportError as e:
|
|
42
|
+
raise DependencyError(
|
|
43
|
+
"tangram-sc is required for Tangram. Install with: pip install tangram-sc"
|
|
44
|
+
) from e
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
# Data already copied in prepare_deconvolution
|
|
48
|
+
spatial_data = data.spatial
|
|
49
|
+
ref_data = data.reference
|
|
50
|
+
|
|
51
|
+
# Tangram requires 'cell_type' column for cluster mode
|
|
52
|
+
if "cell_type" not in ref_data.obs.columns:
|
|
53
|
+
ref_data.obs["cell_type"] = ref_data.obs[data.cell_type_key]
|
|
54
|
+
|
|
55
|
+
# Select marker genes for training (tangram recommendation: 100-1000 genes)
|
|
56
|
+
# Use up to 500 genes from common genes for efficiency
|
|
57
|
+
n_training_genes = min(500, len(data.common_genes))
|
|
58
|
+
training_genes = data.common_genes[:n_training_genes]
|
|
59
|
+
|
|
60
|
+
# Preprocess with tangram (this sets up required annotations)
|
|
61
|
+
tg.pp_adatas(ref_data, spatial_data, genes=training_genes)
|
|
62
|
+
|
|
63
|
+
# Set device
|
|
64
|
+
device = "cuda:0" if use_gpu else "cpu"
|
|
65
|
+
|
|
66
|
+
# Map cells to space
|
|
67
|
+
if mode == "clusters":
|
|
68
|
+
ad_map = tg.map_cells_to_space(
|
|
69
|
+
ref_data,
|
|
70
|
+
spatial_data,
|
|
71
|
+
mode="clusters",
|
|
72
|
+
cluster_label=data.cell_type_key,
|
|
73
|
+
density_prior=density_prior,
|
|
74
|
+
num_epochs=n_epochs,
|
|
75
|
+
learning_rate=learning_rate,
|
|
76
|
+
device=device,
|
|
77
|
+
)
|
|
78
|
+
else:
|
|
79
|
+
ad_map = tg.map_cells_to_space(
|
|
80
|
+
ref_data,
|
|
81
|
+
spatial_data,
|
|
82
|
+
mode="cells",
|
|
83
|
+
density_prior=density_prior,
|
|
84
|
+
num_epochs=n_epochs,
|
|
85
|
+
learning_rate=learning_rate,
|
|
86
|
+
device=device,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Get mapping matrix (cells x spots)
|
|
90
|
+
mapping_matrix = ad_map.X
|
|
91
|
+
|
|
92
|
+
# Calculate cell type proportions from mapping
|
|
93
|
+
cell_types = ref_data.obs[data.cell_type_key].unique()
|
|
94
|
+
|
|
95
|
+
# Create cell type indicator matrix
|
|
96
|
+
cell_type_series = ref_data.obs[data.cell_type_key]
|
|
97
|
+
type_indicators = pd.get_dummies(cell_type_series)
|
|
98
|
+
type_indicators = type_indicators.reindex(columns=cell_types, fill_value=0)
|
|
99
|
+
|
|
100
|
+
# (n_types x n_cells) @ (n_cells x n_spots) = (n_types x n_spots)
|
|
101
|
+
proportions_array = type_indicators.values.T @ mapping_matrix
|
|
102
|
+
|
|
103
|
+
# Create DataFrame
|
|
104
|
+
proportions = pd.DataFrame(
|
|
105
|
+
proportions_array.T, index=spatial_data.obs_names, columns=cell_types
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Normalize to proportions
|
|
109
|
+
row_sums = proportions.sum(axis=1)
|
|
110
|
+
row_sums = row_sums.replace(0, 1) # Avoid division by zero
|
|
111
|
+
proportions = proportions.div(row_sums, axis=0)
|
|
112
|
+
|
|
113
|
+
# Create statistics
|
|
114
|
+
stats = create_deconvolution_stats(
|
|
115
|
+
proportions,
|
|
116
|
+
data.common_genes,
|
|
117
|
+
method="Tangram",
|
|
118
|
+
device=device.upper(),
|
|
119
|
+
n_epochs=n_epochs,
|
|
120
|
+
mode=mode,
|
|
121
|
+
density_prior=density_prior,
|
|
122
|
+
n_training_genes=n_training_genes,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Memory cleanup
|
|
126
|
+
del ad_map, mapping_matrix, type_indicators
|
|
127
|
+
del spatial_data, ref_data
|
|
128
|
+
gc.collect()
|
|
129
|
+
|
|
130
|
+
return proportions, stats
|
|
131
|
+
|
|
132
|
+
except Exception as e:
|
|
133
|
+
if isinstance(e, (DependencyError, ProcessingError)):
|
|
134
|
+
raise
|
|
135
|
+
raise ProcessingError(f"Tangram deconvolution failed: {e}") from e
|