@nahisaho/satori 0.9.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 +123 -4
- package/package.json +1 -1
- 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-immunoinformatics/SKILL.md +341 -0
- package/src/.github/skills/scientific-infectious-disease/SKILL.md +342 -0
- package/src/.github/skills/scientific-microbiome-metagenomics/SKILL.md +349 -0
- package/src/.github/skills/scientific-population-genetics/SKILL.md +336 -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-systems-biology/SKILL.md +310 -0
- package/src/.github/skills/scientific-text-mining-nlp/SKILL.md +358 -0
|
@@ -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
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scientific-systems-biology
|
|
3
|
+
description: |
|
|
4
|
+
システム生物学解析スキル。動的モデリング(ODE / SBML)・
|
|
5
|
+
代謝フラックス解析(FBA / pFBA)・遺伝子制御ネットワーク推定(GRN)・
|
|
6
|
+
シグナル伝達経路モデリング・パラメータ推定・感度解析・
|
|
7
|
+
BioModels/Reactome/KEGG/BiGG 統合パイプライン。
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Scientific Systems Biology
|
|
11
|
+
|
|
12
|
+
システム生物学の定量的モデリングパイプラインを提供する。
|
|
13
|
+
ODE ベースの動的モデル、フラックスバランス解析(FBA)、
|
|
14
|
+
遺伝子制御ネットワーク(GRN)推定、パラメータ推定・感度解析を扱い、
|
|
15
|
+
BioModels・Reactome・KEGG・BiGG の統合的活用を支援する。
|
|
16
|
+
|
|
17
|
+
## When to Use
|
|
18
|
+
|
|
19
|
+
- 生物学的パスウェイの動的モデリング(ODE)が必要なとき
|
|
20
|
+
- 代謝ネットワークのフラックスバランス解析(FBA)を行うとき
|
|
21
|
+
- 遺伝子制御ネットワーク(GRN)を推定するとき
|
|
22
|
+
- BioModels / SBML モデルの取得・シミュレーションを行うとき
|
|
23
|
+
- モデルパラメータの推定・感度解析を行うとき
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
## 1. SBML モデルシミュレーション
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
import numpy as np
|
|
33
|
+
import pandas as pd
|
|
34
|
+
|
|
35
|
+
def simulate_sbml_model(sbml_file, duration=100, n_points=1000):
|
|
36
|
+
"""
|
|
37
|
+
SBML モデルのシミュレーション。
|
|
38
|
+
|
|
39
|
+
SBML (Systems Biology Markup Language):
|
|
40
|
+
生物学的モデルの標準交換フォーマット。BioModels DB に 1,000+ モデル収録。
|
|
41
|
+
|
|
42
|
+
手順:
|
|
43
|
+
1. SBML → RoadRunner ロード
|
|
44
|
+
2. 初期条件設定
|
|
45
|
+
3. 時間発展シミュレーション
|
|
46
|
+
4. 結果抽出・可視化
|
|
47
|
+
|
|
48
|
+
対応モデル:
|
|
49
|
+
- ODE ベース(決定論的)
|
|
50
|
+
- Stochastic(Gillespie SSA)
|
|
51
|
+
- Hybrid
|
|
52
|
+
"""
|
|
53
|
+
import roadrunner
|
|
54
|
+
|
|
55
|
+
rr = roadrunner.RoadRunner(sbml_file)
|
|
56
|
+
result = rr.simulate(0, duration, n_points)
|
|
57
|
+
|
|
58
|
+
df = pd.DataFrame(result, columns=result.colnames)
|
|
59
|
+
species = [c for c in df.columns if c != "time"]
|
|
60
|
+
|
|
61
|
+
print(f" SBML: {len(species)} species simulated over t=[0, {duration}]")
|
|
62
|
+
print(f" Species: {', '.join(species[:5])}{'...' if len(species) > 5 else ''}")
|
|
63
|
+
return df, rr
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def steady_state_analysis(rr):
|
|
67
|
+
"""
|
|
68
|
+
定常状態解析。
|
|
69
|
+
|
|
70
|
+
定常状態: dx/dt = f(x, p) = 0
|
|
71
|
+
ヤコビアン J の固有値 → 安定性判定:
|
|
72
|
+
- Re(λᵢ) < 0 ∀i: 安定平衡点
|
|
73
|
+
- ∃i: Re(λᵢ) > 0: 不安定
|
|
74
|
+
"""
|
|
75
|
+
rr.steadyState()
|
|
76
|
+
species_ids = rr.getFloatingSpeciesIds()
|
|
77
|
+
ss_values = rr.getFloatingSpeciesConcentrations()
|
|
78
|
+
|
|
79
|
+
# ヤコビアン
|
|
80
|
+
jac = rr.getFullJacobian()
|
|
81
|
+
eigenvalues = np.linalg.eigvals(jac)
|
|
82
|
+
stable = all(np.real(eigenvalues) < 0)
|
|
83
|
+
|
|
84
|
+
ss_dict = dict(zip(species_ids, ss_values))
|
|
85
|
+
ss_dict["stable"] = stable
|
|
86
|
+
ss_dict["eigenvalues"] = eigenvalues.tolist()
|
|
87
|
+
|
|
88
|
+
print(f" Steady state: {'Stable' if stable else 'Unstable'}")
|
|
89
|
+
return ss_dict
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 2. フラックスバランス解析(FBA)
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
def flux_balance_analysis(model_path, objective="biomass", method="fba"):
|
|
96
|
+
"""
|
|
97
|
+
代謝フラックスバランス解析。
|
|
98
|
+
|
|
99
|
+
FBA 定式化:
|
|
100
|
+
max c^T · v (目的関数、通常 biomass)
|
|
101
|
+
s.t. S · v = 0 (定常状態制約)
|
|
102
|
+
vₘᵢₙ ≤ v ≤ vₘₐₓ (フラックス範囲制約)
|
|
103
|
+
|
|
104
|
+
method:
|
|
105
|
+
- "fba": 標準 FBA — LP で最適フラックス分布を求める
|
|
106
|
+
- "pfba": Parsimonious FBA — 最小総フラックスで最適化
|
|
107
|
+
- "fva": Flux Variability Analysis — 各反応の許容フラックス範囲
|
|
108
|
+
- "loopless": ループフリー FBA
|
|
109
|
+
|
|
110
|
+
入力: SBML / JSON / YAML 形式のゲノムスケール代謝モデル(GEM)
|
|
111
|
+
BiGG Models DB: 100+ 生物種の GEM を収録
|
|
112
|
+
"""
|
|
113
|
+
import cobra
|
|
114
|
+
|
|
115
|
+
model = cobra.io.read_sbml_model(model_path)
|
|
116
|
+
print(f" Model: {model.id} — {len(model.reactions)} reactions, "
|
|
117
|
+
f"{len(model.metabolites)} metabolites, {len(model.genes)} genes")
|
|
118
|
+
|
|
119
|
+
if method == "fba":
|
|
120
|
+
solution = model.optimize()
|
|
121
|
+
elif method == "pfba":
|
|
122
|
+
solution = cobra.flux_analysis.pfba(model)
|
|
123
|
+
elif method == "fva":
|
|
124
|
+
fva_result = cobra.flux_analysis.flux_variability_analysis(
|
|
125
|
+
model, fraction_of_optimum=0.9)
|
|
126
|
+
return fva_result
|
|
127
|
+
|
|
128
|
+
# 結果
|
|
129
|
+
objective_value = solution.objective_value
|
|
130
|
+
fluxes = solution.fluxes
|
|
131
|
+
|
|
132
|
+
# Essential genes (single gene knockouts)
|
|
133
|
+
essential = []
|
|
134
|
+
for gene in model.genes:
|
|
135
|
+
with model:
|
|
136
|
+
gene.knock_out()
|
|
137
|
+
ko_sol = model.optimize()
|
|
138
|
+
if ko_sol.objective_value < 0.01 * objective_value:
|
|
139
|
+
essential.append(gene.id)
|
|
140
|
+
|
|
141
|
+
print(f" FBA: objective={objective_value:.4f}, "
|
|
142
|
+
f"{len(essential)} essential genes")
|
|
143
|
+
|
|
144
|
+
result = {
|
|
145
|
+
"objective_value": objective_value,
|
|
146
|
+
"n_active_reactions": (fluxes.abs() > 1e-6).sum(),
|
|
147
|
+
"n_essential_genes": len(essential),
|
|
148
|
+
"essential_genes": essential,
|
|
149
|
+
}
|
|
150
|
+
return result, fluxes
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## 3. 遺伝子制御ネットワーク推定(GRN)
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
def infer_grn(expression_matrix, method="genie3", n_top=1000):
|
|
157
|
+
"""
|
|
158
|
+
遺伝子制御ネットワーク(GRN)推定。
|
|
159
|
+
|
|
160
|
+
method:
|
|
161
|
+
- "genie3": GENIE3 — Random Forest ベース
|
|
162
|
+
各遺伝子 gⱼ を他の全遺伝子で回帰し、
|
|
163
|
+
特徴量重要度を制御関係の重みとする。
|
|
164
|
+
- "scenic": SCENIC — cis-regulatory 解析統合
|
|
165
|
+
- "granger": Granger 因果性 — 時系列データ向け
|
|
166
|
+
|
|
167
|
+
GENIE3 原理:
|
|
168
|
+
For each target gene gⱼ:
|
|
169
|
+
Train RF: gⱼ = f(g₁, ..., gⱼ₋₁, gⱼ₊₁, ..., gₚ)
|
|
170
|
+
Weight wᵢⱼ = importance of gᵢ for predicting gⱼ
|
|
171
|
+
"""
|
|
172
|
+
from arboreto.algo import genie3
|
|
173
|
+
|
|
174
|
+
# GENIE3
|
|
175
|
+
if method == "genie3":
|
|
176
|
+
network = genie3(expression_matrix.values,
|
|
177
|
+
gene_names=expression_matrix.columns.tolist())
|
|
178
|
+
network = network.sort_values("importance", ascending=False).head(n_top)
|
|
179
|
+
|
|
180
|
+
# ネットワーク構築
|
|
181
|
+
import networkx as nx
|
|
182
|
+
G = nx.DiGraph()
|
|
183
|
+
for _, row in network.iterrows():
|
|
184
|
+
G.add_edge(row["TF"], row["target"], weight=row["importance"])
|
|
185
|
+
|
|
186
|
+
# ハブ TF(高出次数)
|
|
187
|
+
out_degrees = sorted(G.out_degree(), key=lambda x: x[1], reverse=True)
|
|
188
|
+
top_tfs = out_degrees[:10]
|
|
189
|
+
|
|
190
|
+
print(f" GRN: {G.number_of_nodes()} nodes, {G.number_of_edges()} edges")
|
|
191
|
+
print(f" Top TFs: {', '.join([tf for tf, _ in top_tfs[:5]])}")
|
|
192
|
+
return G, network
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## 4. パラメータ推定・感度解析
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from scipy.optimize import differential_evolution
|
|
199
|
+
from SALib.sample import saltelli
|
|
200
|
+
from SALib.analyze import sobol
|
|
201
|
+
|
|
202
|
+
def parameter_estimation(model_func, data, param_bounds, method="de"):
|
|
203
|
+
"""
|
|
204
|
+
ODE モデルパラメータ推定。
|
|
205
|
+
|
|
206
|
+
method:
|
|
207
|
+
- "de": Differential Evolution(グローバル最適化)
|
|
208
|
+
- "mcmc": MCMC — pymc/emcee(事後分布推定)
|
|
209
|
+
|
|
210
|
+
目的関数: Σ (y_data - y_model)² / σ² → minimize
|
|
211
|
+
"""
|
|
212
|
+
def objective(params):
|
|
213
|
+
y_pred = model_func(params)
|
|
214
|
+
residuals = (data["y_obs"] - y_pred) ** 2
|
|
215
|
+
return np.sum(residuals / data.get("sigma", 1) ** 2)
|
|
216
|
+
|
|
217
|
+
if method == "de":
|
|
218
|
+
result = differential_evolution(objective, bounds=param_bounds,
|
|
219
|
+
seed=42, maxiter=1000, tol=1e-8)
|
|
220
|
+
return {
|
|
221
|
+
"params": result.x,
|
|
222
|
+
"cost": result.fun,
|
|
223
|
+
"success": result.success,
|
|
224
|
+
"message": result.message,
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def global_sensitivity_analysis(model_func, param_names, param_bounds,
|
|
229
|
+
n_samples=1024):
|
|
230
|
+
"""
|
|
231
|
+
Sobol グローバル感度解析。
|
|
232
|
+
|
|
233
|
+
指標:
|
|
234
|
+
- S1: 一次感度指標(主効果)
|
|
235
|
+
- ST: 全次感度指標(主効果+交互作用全て)
|
|
236
|
+
- S2: 二次感度指標(ペアワイズ交互作用)
|
|
237
|
+
|
|
238
|
+
S1 + 交互作用 = ST
|
|
239
|
+
ΣS1 < 1 の場合、交互作用効果が存在する。
|
|
240
|
+
"""
|
|
241
|
+
problem = {
|
|
242
|
+
"num_vars": len(param_names),
|
|
243
|
+
"names": param_names,
|
|
244
|
+
"bounds": param_bounds,
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
param_values = saltelli.sample(problem, n_samples)
|
|
248
|
+
Y = np.array([model_func(p) for p in param_values])
|
|
249
|
+
|
|
250
|
+
Si = sobol.analyze(problem, Y)
|
|
251
|
+
|
|
252
|
+
sa_df = pd.DataFrame({
|
|
253
|
+
"parameter": param_names,
|
|
254
|
+
"S1": Si["S1"],
|
|
255
|
+
"S1_conf": Si["S1_conf"],
|
|
256
|
+
"ST": Si["ST"],
|
|
257
|
+
"ST_conf": Si["ST_conf"],
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
print(f" Sensitivity: top parameter = {sa_df.loc[sa_df['ST'].idxmax(), 'parameter']} "
|
|
261
|
+
f"(ST={sa_df['ST'].max():.3f})")
|
|
262
|
+
return sa_df, Si
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## References
|
|
266
|
+
|
|
267
|
+
### Output Files
|
|
268
|
+
|
|
269
|
+
| ファイル | 形式 |
|
|
270
|
+
|---|---|
|
|
271
|
+
| `results/simulation_timecourse.csv` | CSV |
|
|
272
|
+
| `results/fba_fluxes.csv` | CSV |
|
|
273
|
+
| `results/grn_network.csv` | CSV |
|
|
274
|
+
| `results/sensitivity_analysis.csv` | CSV |
|
|
275
|
+
| `results/parameter_estimates.json` | JSON |
|
|
276
|
+
| `figures/timecourse_plot.png` | PNG |
|
|
277
|
+
| `figures/flux_map.png` | PNG |
|
|
278
|
+
| `figures/grn_graph.png` | PNG |
|
|
279
|
+
|
|
280
|
+
### 利用可能ツール
|
|
281
|
+
|
|
282
|
+
> [ToolUniverse](https://github.com/mims-harvard/ToolUniverse) SMCP 経由で利用可能な外部ツール。
|
|
283
|
+
|
|
284
|
+
| カテゴリ | 主要ツール | 用途 |
|
|
285
|
+
|---|---|---|
|
|
286
|
+
| BioModels | `biomodels_search` | SBML モデル検索 |
|
|
287
|
+
| BioModels | `BioModels_get_model` | モデル詳細取得 |
|
|
288
|
+
| BioModels | `BioModels_download_model` | モデルダウンロード |
|
|
289
|
+
| Reactome | `Reactome_get_pathway` | パスウェイ情報取得 |
|
|
290
|
+
| Reactome | `Reactome_get_pathway_reactions` | 反応一覧取得 |
|
|
291
|
+
| Reactome | `Reactome_map_uniprot_to_pathways` | UniProt→パスウェイ |
|
|
292
|
+
| BiGG | `BiGG_search` | 代謝モデル検索 |
|
|
293
|
+
| BiGG | `BiGG_get_model` | GEM モデル取得 |
|
|
294
|
+
| BiGG | `BiGG_get_reaction` | 反応詳細取得 |
|
|
295
|
+
| KEGG | `kegg_get_pathway_info` | KEGG パスウェイ |
|
|
296
|
+
| KEGG | `kegg_get_gene_info` | KEGG 遺伝子情報 |
|
|
297
|
+
|
|
298
|
+
### 参照スキル
|
|
299
|
+
|
|
300
|
+
| スキル | 連携内容 |
|
|
301
|
+
|---|---|
|
|
302
|
+
| [scientific-network-analysis](../scientific-network-analysis/SKILL.md) | GRN ネットワーク解析 |
|
|
303
|
+
| [scientific-multi-omics](../scientific-multi-omics/SKILL.md) | マルチオミクスデータ統合 |
|
|
304
|
+
| [scientific-bayesian-statistics](../scientific-bayesian-statistics/SKILL.md) | ベイズパラメータ推定 |
|
|
305
|
+
| [scientific-doe](../scientific-doe/SKILL.md) | 実験設計・感度解析 |
|
|
306
|
+
| [scientific-metabolomics](../scientific-metabolomics/SKILL.md) | 代謝フラックス-メタボローム統合 |
|
|
307
|
+
|
|
308
|
+
#### 依存パッケージ
|
|
309
|
+
|
|
310
|
+
- cobra (cobrapy), roadrunner (libroadrunner), arboreto, SALib, scipy, networkx
|