@nahisaho/satori 0.15.0 → 0.17.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.
@@ -0,0 +1,315 @@
1
+ ---
2
+ name: scientific-encode-screen
3
+ description: |
4
+ ENCODE / ChIP-Atlas エピゲノムアトラススキル。ENCODE REST API
5
+ 実験・ファイル・バイオサンプル検索、SCREEN cis 制御エレメント、
6
+ ChIP-Atlas エンリッチメント解析、エピゲノムアノテーション統合。
7
+ ToolUniverse 連携: encode, chipatlas。
8
+ tu_tools:
9
+ - key: encode
10
+ name: ENCODE
11
+ description: ENCODE プロジェクトの実験・バイオサンプル・ファイルデータ検索
12
+ - key: chipatlas
13
+ name: ChIP-Atlas
14
+ description: ChIP-seq/ATAC-seq エンリッチメント解析・ピークブラウザ
15
+ ---
16
+
17
+ # Scientific ENCODE / SCREEN / ChIP-Atlas
18
+
19
+ ENCODE REST API / SCREEN / ChIP-Atlas を活用したエピゲノム
20
+ アトラス統合解析パイプラインを提供する。
21
+
22
+ ## When to Use
23
+
24
+ - ENCODE 実験データ (ChIP-seq/ATAC-seq/DNase) を検索するとき
25
+ - SCREEN cCRE (candidate cis-Regulatory Elements) を照会するとき
26
+ - ChIP-Atlas で転写因子結合・ヒストン修飾エンリッチメントを解析するとき
27
+ - バリアントの制御領域アノテーションを強化するとき
28
+ - エピゲノムデータを下流のクロマチン解析に統合するとき
29
+ - 組織/細胞型特異的エピゲノムプロファイルを比較するとき
30
+
31
+ ---
32
+
33
+ ## Quick Start
34
+
35
+ ## 1. ENCODE 実験検索・ファイル取得
36
+
37
+ ```python
38
+ import requests
39
+ import pandas as pd
40
+ import json
41
+
42
+ ENCODE_BASE = "https://www.encodeproject.org"
43
+ HEADERS = {"Accept": "application/json"}
44
+
45
+
46
+ def encode_search_experiments(assay_title=None, biosample=None,
47
+ target=None, organism="Homo sapiens",
48
+ limit=50):
49
+ """
50
+ ENCODE — 実験メタデータ検索。
51
+
52
+ Parameters:
53
+ assay_title: str — アッセイ種別 (例: "ChIP-seq", "ATAC-seq")
54
+ biosample: str — バイオサンプル (例: "K562")
55
+ target: str — ターゲット (例: "CTCF")
56
+ organism: str — 生物種
57
+ limit: int — 最大結果数
58
+ """
59
+ url = f"{ENCODE_BASE}/search/"
60
+ params = {
61
+ "type": "Experiment",
62
+ "status": "released",
63
+ "replicates.library.biosample.donor.organism.scientific_name": organism,
64
+ "limit": limit,
65
+ "format": "json",
66
+ }
67
+ if assay_title:
68
+ params["assay_title"] = assay_title
69
+ if biosample:
70
+ params["biosample_ontology.term_name"] = biosample
71
+ if target:
72
+ params["target.label"] = target
73
+
74
+ resp = requests.get(url, params=params, headers=HEADERS, timeout=30)
75
+ resp.raise_for_status()
76
+ data = resp.json()
77
+
78
+ results = []
79
+ for exp in data.get("@graph", []):
80
+ results.append({
81
+ "accession": exp.get("accession", ""),
82
+ "assay": exp.get("assay_title", ""),
83
+ "biosample": exp.get("biosample_summary", ""),
84
+ "target": exp.get("target", {}).get("label", ""),
85
+ "status": exp.get("status", ""),
86
+ "lab": exp.get("lab", {}).get("title", ""),
87
+ "date_released": exp.get("date_released", ""),
88
+ "files_count": len(exp.get("files", [])),
89
+ })
90
+
91
+ df = pd.DataFrame(results)
92
+ print(f"ENCODE: {len(df)} experiments found")
93
+ return df
94
+
95
+
96
+ def encode_get_files(experiment_accession, file_type="bigWig",
97
+ output_type="signal p-value", assembly="GRCh38"):
98
+ """
99
+ ENCODE — 実験ファイル URL 取得。
100
+
101
+ Parameters:
102
+ experiment_accession: str — 実験アクセッション
103
+ file_type: str — ファイルタイプ
104
+ output_type: str — 出力タイプ
105
+ assembly: str — アセンブリ
106
+ """
107
+ url = f"{ENCODE_BASE}/search/"
108
+ params = {
109
+ "type": "File",
110
+ "dataset": f"/experiments/{experiment_accession}/",
111
+ "file_format": file_type,
112
+ "output_type": output_type,
113
+ "assembly": assembly,
114
+ "status": "released",
115
+ "format": "json",
116
+ }
117
+ resp = requests.get(url, params=params, headers=HEADERS, timeout=30)
118
+ resp.raise_for_status()
119
+ data = resp.json()
120
+
121
+ files = []
122
+ for f in data.get("@graph", []):
123
+ files.append({
124
+ "accession": f.get("accession", ""),
125
+ "file_format": f.get("file_format", ""),
126
+ "output_type": f.get("output_type", ""),
127
+ "assembly": f.get("assembly", ""),
128
+ "href": ENCODE_BASE + f.get("href", ""),
129
+ "file_size": f.get("file_size", 0),
130
+ "biological_replicate": f.get("biological_replicates", []),
131
+ })
132
+
133
+ df = pd.DataFrame(files)
134
+ print(f"ENCODE files ({experiment_accession}): {len(df)} files")
135
+ return df
136
+ ```
137
+
138
+ ## 2. SCREEN cCRE 検索
139
+
140
+ ```python
141
+ SCREEN_BASE = "https://api.wenglab.org/screen/v2"
142
+
143
+
144
+ def screen_ccre_search(gene=None, region=None, biosample=None,
145
+ assembly="GRCh38"):
146
+ """
147
+ SCREEN — candidate cis-Regulatory Element 検索。
148
+
149
+ Parameters:
150
+ gene: str — 遺伝子名 (例: "TP53")
151
+ region: str — ゲノム領域 (例: "chr17:7668421-7687490")
152
+ biosample: str — バイオサンプル名
153
+ assembly: str — アセンブリ
154
+ """
155
+ url = f"{SCREEN_BASE}/search"
156
+ query = {"assembly": assembly}
157
+
158
+ if gene:
159
+ query["gene"] = gene
160
+ if region:
161
+ chrom, pos = region.split(":")
162
+ start, end = pos.split("-")
163
+ query["coordinates"] = {
164
+ "chromosome": chrom,
165
+ "start": int(start),
166
+ "end": int(end),
167
+ }
168
+
169
+ resp = requests.post(url, json=query, timeout=30)
170
+ resp.raise_for_status()
171
+ data = resp.json()
172
+
173
+ ccres = []
174
+ for cre in data.get("data", []):
175
+ ccres.append({
176
+ "accession": cre.get("accession", ""),
177
+ "chromosome": cre.get("chrom", ""),
178
+ "start": cre.get("start", 0),
179
+ "end": cre.get("end", 0),
180
+ "ccre_class": cre.get("group", ""),
181
+ "dnase_zscore": cre.get("dnase_zscore", None),
182
+ "h3k4me3_zscore": cre.get("h3k4me3_zscore", None),
183
+ "h3k27ac_zscore": cre.get("h3k27ac_zscore", None),
184
+ "ctcf_zscore": cre.get("ctcf_zscore", None),
185
+ })
186
+
187
+ df = pd.DataFrame(ccres)
188
+ print(f"SCREEN cCREs: {len(df)} elements")
189
+ return df
190
+ ```
191
+
192
+ ## 3. ChIP-Atlas エンリッチメント解析
193
+
194
+ ```python
195
+ CHIPATLAS_BASE = "https://chip-atlas.org/api"
196
+
197
+
198
+ def chipatlas_enrichment(gene_list, cell_type=None,
199
+ antigen_class="TFs and others",
200
+ genome="hg38", threshold=5):
201
+ """
202
+ ChIP-Atlas — 遺伝子リストのエンリッチメント解析。
203
+
204
+ Parameters:
205
+ gene_list: list[str] — 遺伝子リスト
206
+ cell_type: str — 細胞型 (None = 全細胞型)
207
+ antigen_class: str — 抗原クラス
208
+ genome: str — ゲノムアセンブリ
209
+ threshold: int — 距離閾値 (kb)
210
+ """
211
+ url = f"{CHIPATLAS_BASE}/enrichment"
212
+ payload = {
213
+ "genome": genome,
214
+ "geneList": gene_list,
215
+ "antigenClass": antigen_class,
216
+ "distanceThreshold": threshold * 1000,
217
+ }
218
+ if cell_type:
219
+ payload["cellType"] = cell_type
220
+
221
+ resp = requests.post(url, json=payload, timeout=60)
222
+ resp.raise_for_status()
223
+ data = resp.json()
224
+
225
+ results = []
226
+ for hit in data.get("results", []):
227
+ results.append({
228
+ "antigen": hit.get("antigen", ""),
229
+ "cell_type": hit.get("cellType", ""),
230
+ "experiment_id": hit.get("experimentId", ""),
231
+ "p_value": hit.get("pValue", 1.0),
232
+ "log_p": hit.get("logPValue", 0),
233
+ "overlap_genes": hit.get("overlapGenes", 0),
234
+ "total_peaks": hit.get("totalPeaks", 0),
235
+ })
236
+
237
+ df = pd.DataFrame(results)
238
+ df = df.sort_values("p_value")
239
+ print(f"ChIP-Atlas enrichment: {len(df)} TF/antigen hits")
240
+ return df
241
+ ```
242
+
243
+ ## 4. ENCODE + SCREEN + ChIP-Atlas 統合パイプライン
244
+
245
+ ```python
246
+ def encode_epigenome_pipeline(gene_name, biosample="K562",
247
+ output_dir="results"):
248
+ """
249
+ ENCODE/SCREEN/ChIP-Atlas エピゲノム統合パイプライン。
250
+
251
+ Parameters:
252
+ gene_name: str — 遺伝子名
253
+ biosample: str — バイオサンプル
254
+ output_dir: str — 出力ディレクトリ
255
+ """
256
+ from pathlib import Path
257
+ output_dir = Path(output_dir)
258
+ output_dir.mkdir(parents=True, exist_ok=True)
259
+
260
+ # 1) SCREEN cCRE
261
+ ccres = screen_ccre_search(gene=gene_name)
262
+ ccres.to_csv(output_dir / "screen_ccres.csv", index=False)
263
+
264
+ # 2) ENCODE 実験
265
+ experiments = encode_search_experiments(
266
+ assay_title="ChIP-seq",
267
+ biosample=biosample,
268
+ target="H3K27ac",
269
+ )
270
+ experiments.to_csv(output_dir / "encode_experiments.csv", index=False)
271
+
272
+ # 3) ChIP-Atlas エンリッチメント
273
+ enrichment = chipatlas_enrichment(
274
+ gene_list=[gene_name],
275
+ cell_type=biosample,
276
+ )
277
+ enrichment.to_csv(output_dir / "chipatlas_enrichment.csv", index=False)
278
+
279
+ print(f"ENCODE epigenome pipeline: {output_dir}")
280
+ return {
281
+ "ccres": ccres,
282
+ "experiments": experiments,
283
+ "enrichment": enrichment,
284
+ }
285
+ ```
286
+
287
+ ---
288
+
289
+ ## ToolUniverse 連携
290
+
291
+ | TU Key | ツール名 | 連携内容 |
292
+ |--------|---------|---------|
293
+ | `encode` | ENCODE | 実験・バイオサンプル・ファイル検索 |
294
+ | `chipatlas` | ChIP-Atlas | 転写因子エンリッチメント解析 |
295
+
296
+ ## パイプライン統合
297
+
298
+ ```
299
+ regulatory-genomics → encode-screen → epigenomics-chromatin
300
+ (RegulomeDB/ReMap) (ENCODE/SCREEN) (ChIP/ATAC bulk)
301
+ │ │ ↓
302
+ variant-interpretation ───┘ scatac-signac
303
+ (ACMG バリアント) │ (scATAC-seq)
304
+
305
+ gene-regulatory-network
306
+ (GRN 推定)
307
+ ```
308
+
309
+ ## パイプライン出力
310
+
311
+ | ファイル | 説明 | 次スキル |
312
+ |---------|------|---------|
313
+ | `results/screen_ccres.csv` | cCRE アノテーション | → variant-interpretation |
314
+ | `results/encode_experiments.csv` | ENCODE 実験メタデータ | → epigenomics-chromatin |
315
+ | `results/chipatlas_enrichment.csv` | TF エンリッチメント | → gene-regulatory-network |
@@ -0,0 +1,255 @@
1
+ ---
2
+ name: scientific-environmental-geodata
3
+ description: |
4
+ 環境地理空間データスキル。SoilGrids REST API による土壌特性
5
+ 取得、WorldClim/CHELSA 気候データ、生物多様性-環境モデリング
6
+ 統合。直接 REST API 連携 (TU 外)。
7
+ tu_tools: []
8
+ ---
9
+
10
+ # Scientific Environmental Geodata
11
+
12
+ SoilGrids・WorldClim 等の地球観測/環境データ API を活用した
13
+ 生態学的環境モデリングパイプラインを提供する。
14
+
15
+ ## When to Use
16
+
17
+ - グローバル土壌特性 (pH, SOC, 粘土含量) を取得するとき
18
+ - バイオクリマティック変数 (BIO1-BIO19) を取得するとき
19
+ - 種分布モデル (SDM) の環境変数を準備するとき
20
+ - 気候変動シナリオの生息地適性を評価するとき
21
+ - 環境ニッチモデリングを実施するとき
22
+ - 土壌-植生-気候の相互作用を解析するとき
23
+
24
+ ---
25
+
26
+ ## Quick Start
27
+
28
+ ## 1. SoilGrids 土壌特性取得
29
+
30
+ ```python
31
+ import requests
32
+ import pandas as pd
33
+ import numpy as np
34
+
35
+ SOILGRIDS_BASE = "https://rest.isric.org/soilgrids/v2.0"
36
+
37
+
38
+ def soilgrids_get_properties(lat, lon, properties=None,
39
+ depths=None, values=None):
40
+ """
41
+ SoilGrids — 地点の土壌特性取得。
42
+
43
+ Parameters:
44
+ lat: float — 緯度
45
+ lon: float — 経度
46
+ properties: list[str] — 土壌特性 (例: ["phh2o", "soc", "clay"])
47
+ depths: list[str] — 深度 (例: ["0-5cm", "5-15cm"])
48
+ values: list[str] — 値の種類 (例: ["mean", "Q0.05", "Q0.95"])
49
+ """
50
+ if properties is None:
51
+ properties = ["phh2o", "soc", "clay", "sand", "nitrogen",
52
+ "bdod", "cec", "ocd"]
53
+ if depths is None:
54
+ depths = ["0-5cm", "5-15cm", "15-30cm", "30-60cm"]
55
+ if values is None:
56
+ values = ["mean", "Q0.05", "Q0.95"]
57
+
58
+ url = f"{SOILGRIDS_BASE}/properties/query"
59
+ params = {
60
+ "lat": lat,
61
+ "lon": lon,
62
+ "property": properties,
63
+ "depth": depths,
64
+ "value": values,
65
+ }
66
+ resp = requests.get(url, params=params, timeout=30)
67
+ resp.raise_for_status()
68
+ data = resp.json()
69
+
70
+ results = []
71
+ for layer in data.get("properties", {}).get("layers", []):
72
+ prop_name = layer.get("name", "")
73
+ unit = layer.get("unit_measure", {})
74
+ conversion = unit.get("mapped_units", "")
75
+ for depth_info in layer.get("depths", []):
76
+ row = {
77
+ "property": prop_name,
78
+ "depth": depth_info.get("label", ""),
79
+ "unit": conversion,
80
+ }
81
+ for val_key, val_val in depth_info.get("values", {}).items():
82
+ row[val_key] = val_val
83
+ results.append(row)
84
+
85
+ df = pd.DataFrame(results)
86
+ print(f"SoilGrids ({lat}, {lon}): {len(df)} records, "
87
+ f"{len(properties)} properties")
88
+ return df
89
+ ```
90
+
91
+ ## 2. WorldClim バイオクリマティック変数
92
+
93
+ ```python
94
+ import rasterio
95
+ from rasterio.sample import sample_gen
96
+
97
+
98
+ def worldclim_get_bioclim(lat, lon, resolution="2.5m",
99
+ data_dir="worldclim"):
100
+ """
101
+ WorldClim — バイオクリマティック変数取得。
102
+
103
+ Parameters:
104
+ lat: float — 緯度
105
+ lon: float — 経度
106
+ resolution: str — 空間解像度 ("30s", "2.5m", "5m", "10m")
107
+ data_dir: str — WorldClim データディレクトリ
108
+ """
109
+ from pathlib import Path
110
+ bio_dir = Path(data_dir) / f"wc2.1_{resolution}_bio"
111
+
112
+ bioclim_names = {
113
+ 1: "Annual Mean Temperature",
114
+ 2: "Mean Diurnal Range",
115
+ 3: "Isothermality",
116
+ 4: "Temperature Seasonality",
117
+ 5: "Max Temperature Warmest Month",
118
+ 6: "Min Temperature Coldest Month",
119
+ 7: "Temperature Annual Range",
120
+ 8: "Mean Temperature Wettest Quarter",
121
+ 9: "Mean Temperature Driest Quarter",
122
+ 10: "Mean Temperature Warmest Quarter",
123
+ 11: "Mean Temperature Coldest Quarter",
124
+ 12: "Annual Precipitation",
125
+ 13: "Precipitation Wettest Month",
126
+ 14: "Precipitation Driest Month",
127
+ 15: "Precipitation Seasonality",
128
+ 16: "Precipitation Wettest Quarter",
129
+ 17: "Precipitation Driest Quarter",
130
+ 18: "Precipitation Warmest Quarter",
131
+ 19: "Precipitation Coldest Quarter",
132
+ }
133
+
134
+ results = []
135
+ for bio_num, bio_name in bioclim_names.items():
136
+ tif_path = bio_dir / f"wc2.1_{resolution}_bio_{bio_num}.tif"
137
+ if not tif_path.exists():
138
+ continue
139
+ with rasterio.open(tif_path) as src:
140
+ vals = list(sample_gen(src, [(lon, lat)]))
141
+ value = vals[0][0] if vals else None
142
+ results.append({
143
+ "variable": f"BIO{bio_num}",
144
+ "name": bio_name,
145
+ "value": value,
146
+ })
147
+
148
+ df = pd.DataFrame(results)
149
+ print(f"WorldClim ({lat}, {lon}): {len(df)} bioclim variables")
150
+ return df
151
+ ```
152
+
153
+ ## 3. 種分布モデル環境変数統合
154
+
155
+ ```python
156
+ def sdm_environmental_stack(occurrences_df, lat_col="latitude",
157
+ lon_col="longitude", buffer_deg=0.5):
158
+ """
159
+ SDM — 種の出現記録に対する環境変数スタック生成。
160
+
161
+ Parameters:
162
+ occurrences_df: pd.DataFrame — 種出現記録
163
+ lat_col: str — 緯度カラム名
164
+ lon_col: str — 経度カラム名
165
+ buffer_deg: float — バッファ距離 (度)
166
+ """
167
+ results = []
168
+ for _, row in occurrences_df.iterrows():
169
+ lat, lon = row[lat_col], row[lon_col]
170
+
171
+ # SoilGrids
172
+ soil = soilgrids_get_properties(lat, lon,
173
+ properties=["phh2o", "soc", "clay"])
174
+ soil_mean = {}
175
+ for _, s in soil.iterrows():
176
+ if s.get("depth") == "0-5cm":
177
+ soil_mean[f"soil_{s['property']}"] = s.get("mean", None)
178
+
179
+ # WorldClim (if available)
180
+ bioclim = {}
181
+ try:
182
+ bio_df = worldclim_get_bioclim(lat, lon)
183
+ bioclim = {r["variable"]: r["value"]
184
+ for _, r in bio_df.iterrows()}
185
+ except Exception:
186
+ pass
187
+
188
+ combined = {
189
+ lat_col: lat,
190
+ lon_col: lon,
191
+ **soil_mean,
192
+ **bioclim,
193
+ }
194
+ results.append(combined)
195
+
196
+ df = pd.DataFrame(results)
197
+ print(f"SDM env stack: {len(df)} points, {len(df.columns)} variables")
198
+ return df
199
+ ```
200
+
201
+ ## 4. 環境地理空間統合パイプライン
202
+
203
+ ```python
204
+ def environmental_geodata_pipeline(occurrences_csv, output_dir="results"):
205
+ """
206
+ 環境地理空間統合パイプライン。
207
+
208
+ Parameters:
209
+ occurrences_csv: str — 種出現記録 CSV パス
210
+ output_dir: str — 出力ディレクトリ
211
+ """
212
+ from pathlib import Path
213
+ output_dir = Path(output_dir)
214
+ output_dir.mkdir(parents=True, exist_ok=True)
215
+
216
+ occ = pd.read_csv(occurrences_csv)
217
+ print(f"Occurrences: {len(occ)} records")
218
+
219
+ # 環境変数スタック
220
+ env_df = sdm_environmental_stack(occ)
221
+ env_df.to_csv(output_dir / "env_stack.csv", index=False)
222
+
223
+ # 環境空間要約
224
+ summary = env_df.describe().T
225
+ summary.to_csv(output_dir / "env_summary.csv")
226
+
227
+ print(f"Environmental pipeline: {output_dir}")
228
+ return {"occurrences": occ, "env_stack": env_df, "summary": summary}
229
+ ```
230
+
231
+ ---
232
+
233
+ ## ToolUniverse 連携
234
+
235
+ 直接 REST API 使用 (SoilGrids, WorldClim は ToolUniverse 外)。
236
+
237
+ ## パイプライン統合
238
+
239
+ ```
240
+ environmental-ecology → environmental-geodata → marine-ecology
241
+ (GBIF/iNaturalist) (SoilGrids/WorldClim) (OBIS/WoRMS)
242
+ │ │ ↓
243
+ phylogenetics ───────────────┘ biodiversity-indices
244
+ (系統情報) │ (多様性指標)
245
+
246
+ species-distribution-model
247
+ (SDM 統合)
248
+ ```
249
+
250
+ ## パイプライン出力
251
+
252
+ | ファイル | 説明 | 次スキル |
253
+ |---------|------|---------|
254
+ | `results/env_stack.csv` | 環境変数スタック | → species-distribution-model |
255
+ | `results/env_summary.csv` | 環境空間要約 | → environmental-ecology |