@nahisaho/satori 0.8.0 → 0.10.0
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.
- package/README.md +138 -2
- package/package.json +1 -1
- package/src/.github/skills/scientific-admet-pharmacokinetics/SKILL.md +14 -0
- package/src/.github/skills/scientific-bioinformatics/SKILL.md +13 -0
- package/src/.github/skills/scientific-cheminformatics/SKILL.md +13 -0
- package/src/.github/skills/scientific-citation-checker/SKILL.md +12 -0
- package/src/.github/skills/scientific-clinical-decision-support/SKILL.md +14 -0
- package/src/.github/skills/scientific-deep-research/SKILL.md +15 -0
- package/src/.github/skills/scientific-disease-research/SKILL.md +14 -0
- package/src/.github/skills/scientific-drug-repurposing/SKILL.md +14 -0
- package/src/.github/skills/scientific-drug-target-profiling/SKILL.md +14 -0
- package/src/.github/skills/scientific-environmental-ecology/SKILL.md +295 -0
- package/src/.github/skills/scientific-epidemiology-public-health/SKILL.md +332 -0
- package/src/.github/skills/scientific-grant-writing/SKILL.md +12 -0
- package/src/.github/skills/scientific-graph-neural-networks/SKILL.md +12 -0
- package/src/.github/skills/scientific-immunoinformatics/SKILL.md +341 -0
- package/src/.github/skills/scientific-infectious-disease/SKILL.md +342 -0
- package/src/.github/skills/scientific-meta-analysis/SKILL.md +11 -0
- package/src/.github/skills/scientific-metabolomics/SKILL.md +13 -0
- package/src/.github/skills/scientific-microbiome-metagenomics/SKILL.md +349 -0
- package/src/.github/skills/scientific-multi-omics/SKILL.md +13 -0
- package/src/.github/skills/scientific-network-analysis/SKILL.md +13 -0
- package/src/.github/skills/scientific-pharmacovigilance/SKILL.md +15 -0
- package/src/.github/skills/scientific-population-genetics/SKILL.md +336 -0
- package/src/.github/skills/scientific-precision-oncology/SKILL.md +14 -0
- package/src/.github/skills/scientific-protein-design/SKILL.md +13 -0
- package/src/.github/skills/scientific-protein-structure-analysis/SKILL.md +13 -0
- package/src/.github/skills/scientific-sequence-analysis/SKILL.md +13 -0
- package/src/.github/skills/scientific-single-cell-genomics/SKILL.md +361 -0
- package/src/.github/skills/scientific-spatial-transcriptomics/SKILL.md +281 -0
- package/src/.github/skills/scientific-survival-clinical/SKILL.md +12 -0
- package/src/.github/skills/scientific-systems-biology/SKILL.md +310 -0
- package/src/.github/skills/scientific-text-mining-nlp/SKILL.md +358 -0
- package/src/.github/skills/scientific-variant-interpretation/SKILL.md +14 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scientific-single-cell-genomics
|
|
3
|
+
description: |
|
|
4
|
+
シングルセルゲノミクス解析スキル。scRNA-seq データの品質管理・正規化・
|
|
5
|
+
次元削減(PCA/UMAP)・クラスタリング(Leiden)・差次発現遺伝子(DEG)同定・
|
|
6
|
+
セルタイプアノテーション・RNA velocity・細胞間コミュニケーション推定パイプライン。
|
|
7
|
+
Scanpy / AnnData フレームワークに準拠。
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Scientific Single-Cell Genomics
|
|
11
|
+
|
|
12
|
+
scRNA-seq / snRNA-seq データを対象に、QC → 正規化 → 高変動遺伝子選択 →
|
|
13
|
+
次元削減 → クラスタリング → DEG → セルタイプアノテーションの標準パイプラインを提供する。
|
|
14
|
+
CELLxGENE Census・HCA データポータルとの連携も組み込む。
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
- scRNA-seq / snRNA-seq データの解析パイプラインが必要なとき
|
|
19
|
+
- セルタイプのクラスタリングとアノテーションを行うとき
|
|
20
|
+
- クラスタ間の差次発現遺伝子を同定するとき
|
|
21
|
+
- RNA velocity による細胞分化軌跡を解析するとき
|
|
22
|
+
- CellChat / CellPhoneDB による細胞間コミュニケーション推定を行うとき
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
## 1. QC・前処理パイプライン
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
import scanpy as sc
|
|
32
|
+
import numpy as np
|
|
33
|
+
import pandas as pd
|
|
34
|
+
|
|
35
|
+
def sc_qc_preprocessing(adata, min_genes=200, max_genes=5000,
|
|
36
|
+
max_pct_mito=20, min_cells=3):
|
|
37
|
+
"""
|
|
38
|
+
scRNA-seq 標準 QC パイプライン。
|
|
39
|
+
|
|
40
|
+
QC メトリクス:
|
|
41
|
+
- n_genes_by_counts: 細胞あたり検出遺伝子数
|
|
42
|
+
- total_counts: 細胞あたり総 UMI カウント
|
|
43
|
+
- pct_counts_mt: ミトコンドリア遺伝子比率(%)
|
|
44
|
+
|
|
45
|
+
フィルタリング基準:
|
|
46
|
+
- min_genes ≤ n_genes ≤ max_genes
|
|
47
|
+
- pct_mito ≤ max_pct_mito
|
|
48
|
+
- 遺伝子は min_cells 以上の細胞で発現
|
|
49
|
+
"""
|
|
50
|
+
# ミトコンドリア遺伝子のアノテーション
|
|
51
|
+
adata.var["mt"] = adata.var_names.str.startswith(("MT-", "mt-"))
|
|
52
|
+
sc.pp.calculate_qc_metrics(adata, qc_vars=["mt"], inplace=True)
|
|
53
|
+
|
|
54
|
+
n_before = adata.n_obs
|
|
55
|
+
# 細胞フィルタ
|
|
56
|
+
sc.pp.filter_cells(adata, min_genes=min_genes)
|
|
57
|
+
adata = adata[adata.obs["n_genes_by_counts"] <= max_genes].copy()
|
|
58
|
+
adata = adata[adata.obs["pct_counts_mt"] <= max_pct_mito].copy()
|
|
59
|
+
# 遺伝子フィルタ
|
|
60
|
+
sc.pp.filter_genes(adata, min_cells=min_cells)
|
|
61
|
+
|
|
62
|
+
n_after = adata.n_obs
|
|
63
|
+
print(f" QC: {n_before} → {n_after} cells ({n_before - n_after} removed)")
|
|
64
|
+
|
|
65
|
+
return adata
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def sc_normalize(adata, target_sum=1e4, n_top_genes=2000):
|
|
69
|
+
"""
|
|
70
|
+
正規化・HVG 選択パイプライン。
|
|
71
|
+
|
|
72
|
+
手順:
|
|
73
|
+
1. Library size normalization (target_sum)
|
|
74
|
+
2. Log1p 変換
|
|
75
|
+
3. Highly Variable Gene (HVG) 選択 (Seurat v3 法)
|
|
76
|
+
"""
|
|
77
|
+
adata.layers["counts"] = adata.X.copy()
|
|
78
|
+
sc.pp.normalize_total(adata, target_sum=target_sum)
|
|
79
|
+
sc.pp.log1p(adata)
|
|
80
|
+
adata.layers["log_normalized"] = adata.X.copy()
|
|
81
|
+
sc.pp.highly_variable_genes(adata, n_top_genes=n_top_genes, flavor="seurat_v3",
|
|
82
|
+
layer="counts")
|
|
83
|
+
print(f" HVG: {adata.var['highly_variable'].sum()} genes selected")
|
|
84
|
+
return adata
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 2. 次元削減・クラスタリング
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
def sc_clustering(adata, n_pcs=50, n_neighbors=15, resolution=1.0,
|
|
91
|
+
random_state=42):
|
|
92
|
+
"""
|
|
93
|
+
PCA → 近傍グラフ → UMAP → Leiden クラスタリング。
|
|
94
|
+
|
|
95
|
+
Parameters:
|
|
96
|
+
n_pcs: PCA 主成分数
|
|
97
|
+
n_neighbors: k-NN グラフの近傍数
|
|
98
|
+
resolution: Leiden クラスタリングの解像度
|
|
99
|
+
"""
|
|
100
|
+
sc.pp.scale(adata, max_value=10)
|
|
101
|
+
sc.tl.pca(adata, n_comps=n_pcs, random_state=random_state)
|
|
102
|
+
|
|
103
|
+
# Elbow plot 用の分散説明率
|
|
104
|
+
variance_ratio = adata.uns["pca"]["variance_ratio"]
|
|
105
|
+
cumvar = np.cumsum(variance_ratio)
|
|
106
|
+
n_pcs_use = int(np.argmax(cumvar >= 0.9)) + 1
|
|
107
|
+
n_pcs_use = max(n_pcs_use, 15)
|
|
108
|
+
print(f" PCA: using {n_pcs_use} PCs (cumulative variance ≥ 90%)")
|
|
109
|
+
|
|
110
|
+
sc.pp.neighbors(adata, n_pcs=n_pcs_use, n_neighbors=n_neighbors,
|
|
111
|
+
random_state=random_state)
|
|
112
|
+
sc.tl.umap(adata, random_state=random_state)
|
|
113
|
+
sc.tl.leiden(adata, resolution=resolution, random_state=random_state)
|
|
114
|
+
|
|
115
|
+
n_clusters = adata.obs["leiden"].nunique()
|
|
116
|
+
print(f" Leiden: {n_clusters} clusters (resolution={resolution})")
|
|
117
|
+
return adata
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 3. 差次発現遺伝子(DEG)同定
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
def sc_deg_analysis(adata, groupby="leiden", method="wilcoxon",
|
|
124
|
+
n_genes=200, min_logfc=0.25, max_pval=0.05):
|
|
125
|
+
"""
|
|
126
|
+
クラスタ間の差次発現遺伝子を同定する。
|
|
127
|
+
|
|
128
|
+
method:
|
|
129
|
+
- "wilcoxon": Wilcoxon rank-sum test(推奨)
|
|
130
|
+
- "t-test_overestim_var": Welch's t-test(高速)
|
|
131
|
+
- "logreg": Logistic regression
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
DataFrame with top DEGs per cluster
|
|
135
|
+
"""
|
|
136
|
+
sc.tl.rank_genes_groups(adata, groupby=groupby, method=method, n_genes=n_genes)
|
|
137
|
+
|
|
138
|
+
deg_results = []
|
|
139
|
+
for cluster in adata.obs[groupby].unique():
|
|
140
|
+
df = sc.get.rank_genes_groups_df(adata, group=cluster)
|
|
141
|
+
df["cluster"] = cluster
|
|
142
|
+
df_sig = df[(df["logfoldchanges"].abs() >= min_logfc) &
|
|
143
|
+
(df["pvals_adj"] < max_pval)]
|
|
144
|
+
deg_results.append(df_sig)
|
|
145
|
+
|
|
146
|
+
deg_df = pd.concat(deg_results, ignore_index=True)
|
|
147
|
+
print(f" DEG: {len(deg_df)} significant genes across {adata.obs[groupby].nunique()} clusters")
|
|
148
|
+
return deg_df
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## 4. セルタイプアノテーション
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
def annotate_celltypes_marker(adata, marker_dict, groupby="leiden",
|
|
155
|
+
threshold=0.5):
|
|
156
|
+
"""
|
|
157
|
+
マーカー遺伝子ベースのセルタイプアノテーション。
|
|
158
|
+
|
|
159
|
+
marker_dict 例:
|
|
160
|
+
{
|
|
161
|
+
"T cells": ["CD3D", "CD3E", "CD8A", "CD4"],
|
|
162
|
+
"B cells": ["CD19", "MS4A1", "CD79A"],
|
|
163
|
+
"Monocytes": ["CD14", "LYZ", "FCGR3A"],
|
|
164
|
+
"NK cells": ["NKG7", "GNLY", "KLRD1"],
|
|
165
|
+
"Dendritic": ["FCER1A", "CST3", "CLEC10A"],
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
各クラスタのマーカー遺伝子発現スコアを計算し、最も高いスコアに対応する
|
|
169
|
+
セルタイプをアサインする。
|
|
170
|
+
"""
|
|
171
|
+
sc.tl.score_genes(adata, gene_list=[], score_name="_dummy")
|
|
172
|
+
|
|
173
|
+
scores = {}
|
|
174
|
+
for cell_type, markers in marker_dict.items():
|
|
175
|
+
valid_markers = [m for m in markers if m in adata.var_names]
|
|
176
|
+
if valid_markers:
|
|
177
|
+
score_name = f"score_{cell_type.replace(' ', '_')}"
|
|
178
|
+
sc.tl.score_genes(adata, gene_list=valid_markers, score_name=score_name)
|
|
179
|
+
scores[cell_type] = score_name
|
|
180
|
+
|
|
181
|
+
# クラスタごとに最高スコアのセルタイプを割り当て
|
|
182
|
+
cluster_annotations = {}
|
|
183
|
+
for cluster in adata.obs[groupby].unique():
|
|
184
|
+
mask = adata.obs[groupby] == cluster
|
|
185
|
+
best_type = "Unknown"
|
|
186
|
+
best_score = -np.inf
|
|
187
|
+
for cell_type, score_col in scores.items():
|
|
188
|
+
mean_score = adata.obs.loc[mask, score_col].mean()
|
|
189
|
+
if mean_score > best_score and mean_score > threshold:
|
|
190
|
+
best_score = mean_score
|
|
191
|
+
best_type = cell_type
|
|
192
|
+
cluster_annotations[cluster] = best_type
|
|
193
|
+
|
|
194
|
+
adata.obs["cell_type"] = adata.obs[groupby].map(cluster_annotations)
|
|
195
|
+
print(f" Annotation: {len(set(cluster_annotations.values()))} cell types assigned")
|
|
196
|
+
return adata, cluster_annotations
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## 5. RNA Velocity
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
def rna_velocity_analysis(adata_loom_path, adata, basis="umap"):
|
|
203
|
+
"""
|
|
204
|
+
scVelo による RNA velocity 解析。
|
|
205
|
+
|
|
206
|
+
RNA velocity は、スプライシング状態(unspliced/spliced)の比率から
|
|
207
|
+
遺伝子発現の時間的変化方向を推定する。
|
|
208
|
+
|
|
209
|
+
Modes:
|
|
210
|
+
- stochastic: 確率的モデル(推奨、高速)
|
|
211
|
+
- dynamical: 動的モデル(精度高、低速)
|
|
212
|
+
"""
|
|
213
|
+
import scvelo as scv
|
|
214
|
+
|
|
215
|
+
# 前処理
|
|
216
|
+
scv.pp.filter_and_normalize(adata, min_shared_counts=20, n_top_genes=2000)
|
|
217
|
+
scv.pp.moments(adata, n_pcs=30, n_neighbors=30)
|
|
218
|
+
|
|
219
|
+
# Velocity 推定
|
|
220
|
+
scv.tl.velocity(adata, mode="stochastic")
|
|
221
|
+
scv.tl.velocity_graph(adata)
|
|
222
|
+
|
|
223
|
+
# 可視化
|
|
224
|
+
scv.pl.velocity_embedding_stream(adata, basis=basis,
|
|
225
|
+
save="figures/velocity_stream.png")
|
|
226
|
+
|
|
227
|
+
# Latent time(擬似時間)
|
|
228
|
+
scv.tl.latent_time(adata)
|
|
229
|
+
print(f" Velocity: latent time range [{adata.obs['latent_time'].min():.3f}, "
|
|
230
|
+
f"{adata.obs['latent_time'].max():.3f}]")
|
|
231
|
+
|
|
232
|
+
return adata
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## 6. 細胞間コミュニケーション推定
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
def cell_communication_analysis(adata, groupby="cell_type",
|
|
239
|
+
database="CellChatDB.human"):
|
|
240
|
+
"""
|
|
241
|
+
CellChat によるリガンド-レセプター相互作用解析。
|
|
242
|
+
|
|
243
|
+
パイプライン:
|
|
244
|
+
1. L-R ペアデータベースのロード
|
|
245
|
+
2. 発現ベースのコミュニケーション確率計算
|
|
246
|
+
3. シグナリングネットワーク推定
|
|
247
|
+
4. 経路レベル集約
|
|
248
|
+
"""
|
|
249
|
+
import cellchat
|
|
250
|
+
|
|
251
|
+
cc = cellchat.CellChat(adata, groupby=groupby)
|
|
252
|
+
cc.preprocess()
|
|
253
|
+
cc.identify_overexpressed_genes()
|
|
254
|
+
cc.identify_overexpressed_interactions()
|
|
255
|
+
|
|
256
|
+
cc.compute_communication_prob(database=database)
|
|
257
|
+
cc.filter_communication(min_cells=10)
|
|
258
|
+
cc.compute_communication_prob_pathway()
|
|
259
|
+
|
|
260
|
+
# ネットワーク可視化
|
|
261
|
+
cc.aggregate_net()
|
|
262
|
+
cc.net_analysis()
|
|
263
|
+
|
|
264
|
+
# 結果取得
|
|
265
|
+
lr_pairs = cc.get_significant_interactions()
|
|
266
|
+
print(f" CellChat: {len(lr_pairs)} significant L-R interactions")
|
|
267
|
+
|
|
268
|
+
return cc, lr_pairs
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## 7. 可視化
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
def sc_visualization_panel(adata, deg_df=None, save_dir="figures"):
|
|
275
|
+
"""
|
|
276
|
+
シングルセル解析結果の可視化パネル。
|
|
277
|
+
|
|
278
|
+
生成図:
|
|
279
|
+
1. QC violin plot (n_genes, total_counts, pct_mito)
|
|
280
|
+
2. UMAP — leiden clusters
|
|
281
|
+
3. UMAP — cell types
|
|
282
|
+
4. DEG dot plot (top markers per cluster)
|
|
283
|
+
5. Marker heatmap
|
|
284
|
+
"""
|
|
285
|
+
import matplotlib.pyplot as plt
|
|
286
|
+
import os
|
|
287
|
+
os.makedirs(save_dir, exist_ok=True)
|
|
288
|
+
|
|
289
|
+
# 1. QC violin
|
|
290
|
+
sc.pl.violin(adata, ["n_genes_by_counts", "total_counts", "pct_counts_mt"],
|
|
291
|
+
jitter=0.4, multi_panel=True, save="_qc.png")
|
|
292
|
+
|
|
293
|
+
# 2. UMAP — clusters
|
|
294
|
+
sc.pl.umap(adata, color="leiden", legend_loc="on data",
|
|
295
|
+
title="Leiden Clusters", save="_leiden.png")
|
|
296
|
+
|
|
297
|
+
# 3. UMAP — cell types
|
|
298
|
+
if "cell_type" in adata.obs.columns:
|
|
299
|
+
sc.pl.umap(adata, color="cell_type",
|
|
300
|
+
title="Cell Type Annotation", save="_celltypes.png")
|
|
301
|
+
|
|
302
|
+
# 4. DEG dot plot
|
|
303
|
+
if deg_df is not None:
|
|
304
|
+
top_markers = deg_df.groupby("cluster").head(5)["names"].unique().tolist()
|
|
305
|
+
sc.pl.dotplot(adata, var_names=top_markers[:30],
|
|
306
|
+
groupby="leiden", save="_markers.png")
|
|
307
|
+
|
|
308
|
+
# 5. Stacked violin
|
|
309
|
+
if deg_df is not None:
|
|
310
|
+
top5 = deg_df.groupby("cluster").head(3)["names"].unique().tolist()[:20]
|
|
311
|
+
sc.pl.stacked_violin(adata, var_names=top5,
|
|
312
|
+
groupby="leiden", save="_stacked.png")
|
|
313
|
+
|
|
314
|
+
print(f" Figures saved to {save_dir}/")
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## References
|
|
318
|
+
|
|
319
|
+
### Output Files
|
|
320
|
+
|
|
321
|
+
| ファイル | 形式 |
|
|
322
|
+
|---|---|
|
|
323
|
+
| `results/sc_qc_summary.json` | JSON |
|
|
324
|
+
| `results/sc_deg_results.csv` | CSV |
|
|
325
|
+
| `results/sc_celltype_annotations.json` | JSON |
|
|
326
|
+
| `results/sc_velocity_summary.json` | JSON |
|
|
327
|
+
| `results/sc_cellchat_interactions.csv` | CSV |
|
|
328
|
+
| `figures/umap_leiden.png` | PNG |
|
|
329
|
+
| `figures/umap_celltypes.png` | PNG |
|
|
330
|
+
| `figures/velocity_stream.png` | PNG |
|
|
331
|
+
| `figures/deg_dotplot.png` | PNG |
|
|
332
|
+
|
|
333
|
+
### 利用可能ツール
|
|
334
|
+
|
|
335
|
+
> [ToolUniverse](https://github.com/mims-harvard/ToolUniverse) SMCP 経由で利用可能な外部ツール。
|
|
336
|
+
|
|
337
|
+
| カテゴリ | 主要ツール | 用途 |
|
|
338
|
+
|---|---|---|
|
|
339
|
+
| CELLxGENE | `CELLxGENE_get_expression_data` | シングルセル発現データ取得 |
|
|
340
|
+
| CELLxGENE | `CELLxGENE_get_cell_metadata` | 細胞メタデータ取得 |
|
|
341
|
+
| CELLxGENE | `CELLxGENE_get_gene_metadata` | 遺伝子メタデータ取得 |
|
|
342
|
+
| CELLxGENE | `CELLxGENE_get_presence_matrix` | 遺伝子存在マトリクス |
|
|
343
|
+
| CELLxGENE | `CELLxGENE_get_embeddings` | 埋め込みベクトル取得 |
|
|
344
|
+
| CELLxGENE | `CELLxGENE_download_h5ad` | H5AD ファイルダウンロード |
|
|
345
|
+
| HCA | `hca_search_projects` | Human Cell Atlas プロジェクト検索 |
|
|
346
|
+
| HCA | `hca_get_file_manifest` | HCA ファイルマニフェスト取得 |
|
|
347
|
+
| HPA | `HPA_get_rna_expression_by_source` | 組織別 RNA 発現データ |
|
|
348
|
+
|
|
349
|
+
### 参照スキル
|
|
350
|
+
|
|
351
|
+
| スキル | 連携内容 |
|
|
352
|
+
|---|---|
|
|
353
|
+
| [scientific-bioinformatics](../scientific-bioinformatics/SKILL.md) | 遺伝子アノテーション・パスウェイ解析 |
|
|
354
|
+
| [scientific-multi-omics](../scientific-multi-omics/SKILL.md) | マルチオミクス統合 |
|
|
355
|
+
| [scientific-network-analysis](../scientific-network-analysis/SKILL.md) | 遺伝子制御ネットワーク |
|
|
356
|
+
| [scientific-deep-learning](../scientific-deep-learning/SKILL.md) | scVI / scGPT 等の深層学習モデル |
|
|
357
|
+
| [scientific-pca-tsne](../scientific-pca-tsne/SKILL.md) | 次元削減手法 |
|
|
358
|
+
|
|
359
|
+
#### 依存パッケージ
|
|
360
|
+
|
|
361
|
+
- scanpy, anndata, scvelo, cellchat, leidenalg, umap-learn
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scientific-spatial-transcriptomics
|
|
3
|
+
description: |
|
|
4
|
+
空間トランスクリプトミクス解析スキル。10x Visium / MERFISH / Slide-seq データの
|
|
5
|
+
前処理・空間的遺伝子発現パターン検出(Moran's I / SpatialDE)・
|
|
6
|
+
空間ドメイン同定(BayesSpace / STAGATE)・細胞-細胞近接解析・
|
|
7
|
+
Deconvolution(cell2location)パイプライン。Squidpy フレームワーク準拠。
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Scientific Spatial Transcriptomics
|
|
11
|
+
|
|
12
|
+
空間トランスクリプトミクス技術(10x Visium, MERFISH, Slide-seq, STARmap 等)で
|
|
13
|
+
取得したデータの空間的遺伝子発現解析パイプラインを提供する。
|
|
14
|
+
空間統計・空間ドメイン検出・deconvolution・リガンド-レセプター空間共発現を扱う。
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
- Visium / MERFISH 等の空間トランスクリプトミクスデータの解析が必要なとき
|
|
19
|
+
- 空間的に変動する遺伝子(SVG: Spatially Variable Genes)を同定するとき
|
|
20
|
+
- 組織内の空間ドメインを自動検出するとき
|
|
21
|
+
- スポットの細胞型 deconvolution を行うとき
|
|
22
|
+
- 空間的なリガンド-レセプター相互作用を評価するとき
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
## 1. 空間データ前処理
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
import scanpy as sc
|
|
32
|
+
import squidpy as sq
|
|
33
|
+
import numpy as np
|
|
34
|
+
import pandas as pd
|
|
35
|
+
|
|
36
|
+
def spatial_preprocessing(adata, min_counts=500, min_genes=200,
|
|
37
|
+
max_pct_mito=25, n_top_genes=3000):
|
|
38
|
+
"""
|
|
39
|
+
空間トランスクリプトミクス前処理パイプライン。
|
|
40
|
+
|
|
41
|
+
手順:
|
|
42
|
+
1. QC メトリクス計算
|
|
43
|
+
2. 低品質スポット/セルフィルタリング
|
|
44
|
+
3. 正規化 + log1p
|
|
45
|
+
4. HVG 選択
|
|
46
|
+
5. 空間近傍グラフ構築
|
|
47
|
+
"""
|
|
48
|
+
# ミトコンドリア遺伝子
|
|
49
|
+
adata.var["mt"] = adata.var_names.str.startswith(("MT-", "mt-"))
|
|
50
|
+
sc.pp.calculate_qc_metrics(adata, qc_vars=["mt"], inplace=True)
|
|
51
|
+
|
|
52
|
+
n_before = adata.n_obs
|
|
53
|
+
sc.pp.filter_cells(adata, min_counts=min_counts)
|
|
54
|
+
sc.pp.filter_cells(adata, min_genes=min_genes)
|
|
55
|
+
adata = adata[adata.obs["pct_counts_mt"] <= max_pct_mito].copy()
|
|
56
|
+
sc.pp.filter_genes(adata, min_cells=10)
|
|
57
|
+
print(f" QC: {n_before} → {adata.n_obs} spots")
|
|
58
|
+
|
|
59
|
+
# 正規化
|
|
60
|
+
adata.layers["counts"] = adata.X.copy()
|
|
61
|
+
sc.pp.normalize_total(adata, target_sum=1e4)
|
|
62
|
+
sc.pp.log1p(adata)
|
|
63
|
+
sc.pp.highly_variable_genes(adata, n_top_genes=n_top_genes, flavor="seurat_v3",
|
|
64
|
+
layer="counts")
|
|
65
|
+
|
|
66
|
+
# 空間近傍グラフ
|
|
67
|
+
sq.gr.spatial_neighbors(adata, coord_type="grid", n_neighs=6)
|
|
68
|
+
print(f" Spatial neighbors: {adata.obsp['spatial_connectivities'].nnz} edges")
|
|
69
|
+
|
|
70
|
+
return adata
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 2. 空間的変動遺伝子(SVG)検出
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
def spatially_variable_genes(adata, method="moran", n_perms=100,
|
|
77
|
+
fdr_threshold=0.05):
|
|
78
|
+
"""
|
|
79
|
+
空間的に変動する遺伝子を同定する。
|
|
80
|
+
|
|
81
|
+
method:
|
|
82
|
+
- "moran": Moran's I 空間自己相関統計量
|
|
83
|
+
I = (N / W) * Σᵢ Σⱼ wᵢⱼ (xᵢ - x̄)(xⱼ - x̄) / Σᵢ (xᵢ - x̄)²
|
|
84
|
+
- "sepal": SEPAL(拡散ベース)
|
|
85
|
+
|
|
86
|
+
Moran's I:
|
|
87
|
+
- I ≈ 1: 強い正の空間自己相関(同値クラスタリング)
|
|
88
|
+
- I ≈ 0: ランダム分布
|
|
89
|
+
- I ≈ -1: 負の空間自己相関(チェッカーボード)
|
|
90
|
+
"""
|
|
91
|
+
if method == "moran":
|
|
92
|
+
sq.gr.spatial_autocorr(adata, mode="moran", n_perms=n_perms, n_jobs=-1)
|
|
93
|
+
svg_df = adata.uns["moranI"].copy()
|
|
94
|
+
svg_df["significant"] = svg_df["pval_norm_fdr_bh"] < fdr_threshold
|
|
95
|
+
svg_df = svg_df.sort_values("I", ascending=False)
|
|
96
|
+
elif method == "sepal":
|
|
97
|
+
sq.gr.spatial_autocorr(adata, mode="geary", n_perms=n_perms, n_jobs=-1)
|
|
98
|
+
svg_df = adata.uns["gearyC"].copy()
|
|
99
|
+
svg_df["significant"] = svg_df["pval_norm_fdr_bh"] < fdr_threshold
|
|
100
|
+
|
|
101
|
+
n_sig = svg_df["significant"].sum()
|
|
102
|
+
print(f" SVG ({method}): {n_sig} significant spatially variable genes")
|
|
103
|
+
return svg_df
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 3. 空間ドメイン検出
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
def spatial_domain_detection(adata, n_domains=7, method="leiden", resolution=0.8):
|
|
110
|
+
"""
|
|
111
|
+
空間ドメイン(組織領域)を自動検出する。
|
|
112
|
+
|
|
113
|
+
method:
|
|
114
|
+
- "leiden": 空間グラフベース Leiden クラスタリング
|
|
115
|
+
- "bayesspace": BayesSpace(ベイズモデル、Visium 特化)
|
|
116
|
+
|
|
117
|
+
空間的制約付きクラスタリングにより、遺伝子発現が類似し空間的にも
|
|
118
|
+
隣接するスポットを同一ドメインにグループ化する。
|
|
119
|
+
"""
|
|
120
|
+
sc.pp.scale(adata, max_value=10)
|
|
121
|
+
sc.tl.pca(adata, n_comps=30)
|
|
122
|
+
|
|
123
|
+
if method == "leiden":
|
|
124
|
+
# 空間近傍グラフを利用
|
|
125
|
+
sc.tl.leiden(adata, resolution=resolution, adjacency=adata.obsp["spatial_connectivities"])
|
|
126
|
+
adata.obs["spatial_domain"] = adata.obs["leiden"]
|
|
127
|
+
elif method == "bayesspace":
|
|
128
|
+
from bayesspace import BayesSpace
|
|
129
|
+
bs = BayesSpace(adata, n_clusters=n_domains)
|
|
130
|
+
bs.fit()
|
|
131
|
+
adata.obs["spatial_domain"] = bs.labels_.astype(str)
|
|
132
|
+
|
|
133
|
+
n_domains_found = adata.obs["spatial_domain"].nunique()
|
|
134
|
+
print(f" Domains: {n_domains_found} spatial domains detected ({method})")
|
|
135
|
+
return adata
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 4. Cell-type Deconvolution
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
def spatial_deconvolution(adata_spatial, adata_sc, cell_type_col="cell_type",
|
|
142
|
+
method="cell2location"):
|
|
143
|
+
"""
|
|
144
|
+
空間スポットの細胞型組成を scRNA-seq 参照データから推定する。
|
|
145
|
+
|
|
146
|
+
method:
|
|
147
|
+
- "cell2location": Bayesian 推定(推奨、高精度)
|
|
148
|
+
- "rctd": RCTD(ロバスト deconvolution)
|
|
149
|
+
|
|
150
|
+
cell2location モデル:
|
|
151
|
+
y_s ~ NB(μ_s, α)
|
|
152
|
+
μ_s = Σ_f w_sf * g_f
|
|
153
|
+
w_sf: スポット s における細胞型 f の存在量
|
|
154
|
+
g_f: 細胞型 f の遺伝子発現シグネチャ
|
|
155
|
+
"""
|
|
156
|
+
import cell2location
|
|
157
|
+
|
|
158
|
+
# リファレンスシグネチャの学習
|
|
159
|
+
cell2location.models.RegressionModel.setup_anndata(adata_sc, labels_key=cell_type_col)
|
|
160
|
+
ref_model = cell2location.models.RegressionModel(adata_sc)
|
|
161
|
+
ref_model.train(max_epochs=250)
|
|
162
|
+
inf_aver = ref_model.export_posterior(adata_sc)
|
|
163
|
+
|
|
164
|
+
# Spatial mapping
|
|
165
|
+
cell2location.models.Cell2location.setup_anndata(adata_spatial)
|
|
166
|
+
mod = cell2location.models.Cell2location(adata_spatial,
|
|
167
|
+
cell_state_df=inf_aver)
|
|
168
|
+
mod.train(max_epochs=30000)
|
|
169
|
+
|
|
170
|
+
adata_spatial = mod.export_posterior(adata_spatial)
|
|
171
|
+
print(f" Deconvolution: {len(inf_aver.columns)} cell types mapped to "
|
|
172
|
+
f"{adata_spatial.n_obs} spots")
|
|
173
|
+
return adata_spatial
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## 5. 空間リガンド-レセプター解析
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
def spatial_ligand_receptor(adata, cluster_key="spatial_domain",
|
|
180
|
+
n_perms=1000, fdr_threshold=0.01):
|
|
181
|
+
"""
|
|
182
|
+
空間的に隣接するクラスタ間のリガンド-レセプター相互作用を検定する。
|
|
183
|
+
|
|
184
|
+
Squidpy の permutation test:
|
|
185
|
+
各 L-R ペアについて、空間的に隣接するスポット間の共発現が
|
|
186
|
+
ランダム置換と比較して有意に高いかを検定する。
|
|
187
|
+
"""
|
|
188
|
+
sq.gr.ligrec(adata, n_perms=n_perms, cluster_key=cluster_key,
|
|
189
|
+
copy=False, use_raw=False, transmitter_params={"categories": "ligand"},
|
|
190
|
+
receiver_params={"categories": "receptor"})
|
|
191
|
+
|
|
192
|
+
lr_results = adata.uns["ligrec"]
|
|
193
|
+
pvals = lr_results["pvalues"]
|
|
194
|
+
sig_count = (pvals < fdr_threshold).sum().sum()
|
|
195
|
+
print(f" L-R analysis: {sig_count} significant spatial interactions")
|
|
196
|
+
return lr_results
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## 6. 空間可視化
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
def spatial_visualization_panel(adata, svg_df=None, save_dir="figures"):
|
|
203
|
+
"""
|
|
204
|
+
空間トランスクリプトミクス可視化パネル。
|
|
205
|
+
|
|
206
|
+
生成図:
|
|
207
|
+
1. 空間遺伝子発現マップ(top SVG)
|
|
208
|
+
2. 空間ドメインマップ
|
|
209
|
+
3. Deconvolution 結果マップ
|
|
210
|
+
4. Spatial autocorrelation ヒートマップ
|
|
211
|
+
"""
|
|
212
|
+
import matplotlib.pyplot as plt
|
|
213
|
+
import os
|
|
214
|
+
os.makedirs(save_dir, exist_ok=True)
|
|
215
|
+
|
|
216
|
+
# 1. 空間上の遺伝子発現
|
|
217
|
+
if svg_df is not None:
|
|
218
|
+
top_svgs = svg_df[svg_df["significant"]].head(6).index.tolist()
|
|
219
|
+
sq.pl.spatial_scatter(adata, color=top_svgs, ncols=3,
|
|
220
|
+
save=f"{save_dir}/spatial_svgs.png")
|
|
221
|
+
|
|
222
|
+
# 2. 空間ドメイン
|
|
223
|
+
if "spatial_domain" in adata.obs.columns:
|
|
224
|
+
sq.pl.spatial_scatter(adata, color="spatial_domain",
|
|
225
|
+
save=f"{save_dir}/spatial_domains.png")
|
|
226
|
+
|
|
227
|
+
# 3. Moran's I 分布
|
|
228
|
+
if svg_df is not None:
|
|
229
|
+
fig, ax = plt.subplots(figsize=(8, 4))
|
|
230
|
+
ax.hist(svg_df["I"], bins=50, color="steelblue", alpha=0.7)
|
|
231
|
+
ax.axvline(x=0, color="red", linestyle="--", label="Random (I=0)")
|
|
232
|
+
ax.set_xlabel("Moran's I")
|
|
233
|
+
ax.set_ylabel("Count")
|
|
234
|
+
ax.set_title("Distribution of Spatial Autocorrelation")
|
|
235
|
+
ax.legend()
|
|
236
|
+
plt.tight_layout()
|
|
237
|
+
plt.savefig(f"{save_dir}/morans_i_dist.png", dpi=300, bbox_inches="tight")
|
|
238
|
+
plt.close()
|
|
239
|
+
|
|
240
|
+
print(f" Figures saved to {save_dir}/")
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## References
|
|
244
|
+
|
|
245
|
+
### Output Files
|
|
246
|
+
|
|
247
|
+
| ファイル | 形式 |
|
|
248
|
+
|---|---|
|
|
249
|
+
| `results/svg_results.csv` | CSV |
|
|
250
|
+
| `results/spatial_domains.json` | JSON |
|
|
251
|
+
| `results/deconvolution_proportions.csv` | CSV |
|
|
252
|
+
| `results/ligrec_results.json` | JSON |
|
|
253
|
+
| `figures/spatial_svgs.png` | PNG |
|
|
254
|
+
| `figures/spatial_domains.png` | PNG |
|
|
255
|
+
| `figures/morans_i_dist.png` | PNG |
|
|
256
|
+
|
|
257
|
+
### 利用可能ツール
|
|
258
|
+
|
|
259
|
+
> [ToolUniverse](https://github.com/mims-harvard/ToolUniverse) SMCP 経由で利用可能な外部ツール。
|
|
260
|
+
|
|
261
|
+
| カテゴリ | 主要ツール | 用途 |
|
|
262
|
+
|---|---|---|
|
|
263
|
+
| CELLxGENE | `CELLxGENE_get_expression_data` | 参照シングルセルデータ取得 |
|
|
264
|
+
| CELLxGENE | `CELLxGENE_get_cell_metadata` | 細胞メタデータ参照 |
|
|
265
|
+
| CELLxGENE | `CELLxGENE_download_h5ad` | H5AD データダウンロード |
|
|
266
|
+
| HCA | `hca_search_projects` | HCA 空間データ検索 |
|
|
267
|
+
| HPA | `HPA_get_rna_expression_by_source` | 組織発現参照データ |
|
|
268
|
+
|
|
269
|
+
### 参照スキル
|
|
270
|
+
|
|
271
|
+
| スキル | 連携内容 |
|
|
272
|
+
|---|---|
|
|
273
|
+
| [scientific-single-cell-genomics](../scientific-single-cell-genomics/SKILL.md) | scRNA-seq 参照データ・deconvolution |
|
|
274
|
+
| [scientific-bioinformatics](../scientific-bioinformatics/SKILL.md) | 遺伝子アノテーション・パスウェイ濃縮 |
|
|
275
|
+
| [scientific-image-analysis](../scientific-image-analysis/SKILL.md) | 組織画像処理・セグメンテーション |
|
|
276
|
+
| [scientific-network-analysis](../scientific-network-analysis/SKILL.md) | 空間近傍ネットワーク解析 |
|
|
277
|
+
| [scientific-bayesian-statistics](../scientific-bayesian-statistics/SKILL.md) | BayesSpace ドメイン検出 |
|
|
278
|
+
|
|
279
|
+
#### 依存パッケージ
|
|
280
|
+
|
|
281
|
+
- squidpy, scanpy, anndata, cell2location, bayesspace, SpatialDE
|
|
@@ -233,6 +233,18 @@ def bayesian_sequential_update(successes_list, trials_list,
|
|
|
233
233
|
| `figures/cox_ph_forest.png` | PNG |
|
|
234
234
|
| `figures/bayesian_update.png` | PNG |
|
|
235
235
|
|
|
236
|
+
### 利用可能ツール
|
|
237
|
+
|
|
238
|
+
> [ToolUniverse](https://github.com/mims-harvard/ToolUniverse) SMCP 経由で利用可能な外部ツール。
|
|
239
|
+
|
|
240
|
+
| カテゴリ | 主要ツール | 用途 |
|
|
241
|
+
|---|---|---|
|
|
242
|
+
| ClinicalTrials | `search_clinical_trials` | 臨床試験検索 |
|
|
243
|
+
| ClinicalTrials | `clinical_trials_get_details` | 試験詳細取得 |
|
|
244
|
+
| FAERS | `FAERS_count_reactions_by_drug_event` | 有害事象データ |
|
|
245
|
+
| GDC | `GDC_search_cases` | TCGA 臨床データ |
|
|
246
|
+
| PubMed | `PubMed_search_articles` | 臨床文献検索 |
|
|
247
|
+
|
|
236
248
|
#### 参照実験
|
|
237
249
|
|
|
238
250
|
- **Exp-03**: Kaplan-Meier + Cox PH(がん生存解析)
|