@nahisaho/satori 0.12.0 → 0.14.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.
Files changed (22) hide show
  1. package/README.md +150 -54
  2. package/package.json +1 -1
  3. package/src/.github/skills/scientific-biomedical-pubtator/SKILL.md +331 -0
  4. package/src/.github/skills/scientific-biothings-idmapping/SKILL.md +298 -0
  5. package/src/.github/skills/scientific-cell-line-resources/SKILL.md +258 -0
  6. package/src/.github/skills/scientific-compound-screening/SKILL.md +245 -0
  7. package/src/.github/skills/scientific-ebi-databases/SKILL.md +280 -0
  8. package/src/.github/skills/scientific-genome-sequence-tools/SKILL.md +304 -0
  9. package/src/.github/skills/scientific-healthcare-ai/SKILL.md +273 -0
  10. package/src/.github/skills/scientific-human-protein-atlas/SKILL.md +244 -0
  11. package/src/.github/skills/scientific-metabolic-modeling/SKILL.md +288 -0
  12. package/src/.github/skills/scientific-noncoding-rna/SKILL.md +262 -0
  13. package/src/.github/skills/scientific-ontology-enrichment/SKILL.md +340 -0
  14. package/src/.github/skills/scientific-pharmacology-targets/SKILL.md +323 -0
  15. package/src/.github/skills/scientific-phylogenetics/SKILL.md +297 -0
  16. package/src/.github/skills/scientific-preprint-archive/SKILL.md +476 -0
  17. package/src/.github/skills/scientific-public-health-data/SKILL.md +322 -0
  18. package/src/.github/skills/scientific-rare-disease-genetics/SKILL.md +327 -0
  19. package/src/.github/skills/scientific-regulatory-genomics/SKILL.md +274 -0
  20. package/src/.github/skills/scientific-reinforcement-learning/SKILL.md +280 -0
  21. package/src/.github/skills/scientific-structural-proteomics/SKILL.md +317 -0
  22. package/src/.github/skills/scientific-symbolic-mathematics/SKILL.md +277 -0
@@ -0,0 +1,317 @@
1
+ ---
2
+ name: scientific-structural-proteomics
3
+ description: |
4
+ 構造プロテオミクス統合スキル。EMDB クライオ EM、PDBe 構造データ、
5
+ Proteins API (UniProt)、Complex Portal 複合体、DeepGO 機能予測、
6
+ EVE 変異影響評価の統合パイプライン。
7
+ ---
8
+
9
+ # Scientific Structural Proteomics
10
+
11
+ 6 つの構造・機能データベースを統合した
12
+ タンパク質構造・機能プロファイリングパイプラインを提供する。
13
+
14
+ ## When to Use
15
+
16
+ - PDB エントリの詳細構造情報 (分解能, 実験手法, 二次構造) を取得するとき
17
+ - クライオ EM マップ情報を EMDB から取得するとき
18
+ - UniProt タンパク質のドメイン・変異・ゲノムマッピングを調べるとき
19
+ - タンパク質複合体のサブユニット構成を Complex Portal で調べるとき
20
+ - DeepGO で配列ベースの GO 機能予測を行うとき
21
+ - EVE で missense 変異の病原性スコアを取得するとき
22
+
23
+ ---
24
+
25
+ ## Quick Start
26
+
27
+ ## 1. PDBe 構造データ取得
28
+
29
+ ```python
30
+ import requests
31
+ import pandas as pd
32
+
33
+ PDBE_API = "https://www.ebi.ac.uk/pdbe/api"
34
+
35
+
36
+ def get_pdbe_entry(pdb_id):
37
+ """
38
+ PDBe エントリのサマリー・品質・二次構造を取得。
39
+
40
+ Parameters:
41
+ pdb_id: str — PDB ID (e.g., "1cbs")
42
+
43
+ ToolUniverse:
44
+ pdbe_get_entry_summary(pdb_id=pdb_id)
45
+ pdbe_get_entry_quality(pdb_id=pdb_id)
46
+ pdbe_get_entry_experiment(pdb_id=pdb_id)
47
+ pdbe_get_entry_molecules(pdb_id=pdb_id)
48
+ pdbe_get_entry_secondary_structure(pdb_id=pdb_id)
49
+ pdbe_get_entry_assemblies(pdb_id=pdb_id)
50
+ pdbe_get_entry_publications(pdb_id=pdb_id)
51
+ """
52
+ pdb = pdb_id.lower()
53
+
54
+ # Summary
55
+ resp_s = requests.get(f"{PDBE_API}/pdb/entry/summary/{pdb}")
56
+ resp_s.raise_for_status()
57
+ summary = resp_s.json().get(pdb, [{}])[0]
58
+
59
+ # Quality
60
+ resp_q = requests.get(f"{PDBE_API}/pdb/entry/quality/{pdb}")
61
+ quality = (
62
+ resp_q.json().get(pdb, [{}])[0] if resp_q.status_code == 200 else {}
63
+ )
64
+
65
+ # Experiment
66
+ resp_e = requests.get(f"{PDBE_API}/pdb/entry/experiment/{pdb}")
67
+ experiment = (
68
+ resp_e.json().get(pdb, [{}])[0] if resp_e.status_code == 200 else {}
69
+ )
70
+
71
+ entry = {
72
+ "pdb_id": pdb,
73
+ "title": summary.get("title", ""),
74
+ "method": experiment.get("experimental_method", ""),
75
+ "resolution": experiment.get("resolution", ""),
76
+ "release_date": summary.get("release_date", ""),
77
+ "r_factor": quality.get("r_factor", ""),
78
+ "r_free": quality.get("r_free", ""),
79
+ }
80
+
81
+ print(f"PDBe {pdb}: {entry['method']} @ {entry['resolution']}Å")
82
+ return entry, summary, quality
83
+ ```
84
+
85
+ ## 2. EMDB クライオ EM 構造
86
+
87
+ ```python
88
+ EMDB_API = "https://www.ebi.ac.uk/emdb/api"
89
+
90
+
91
+ def get_emdb_structure(emdb_id):
92
+ """
93
+ EMDB エントリの 3D EM マップ情報を取得。
94
+
95
+ Parameters:
96
+ emdb_id: str — EMDB ID (e.g., "EMD-1234")
97
+
98
+ ToolUniverse:
99
+ EMDB_get_structure(emdb_id=emdb_id)
100
+ EMDB_get_map_info(emdb_id=emdb_id)
101
+ EMDB_get_sample_info(emdb_id=emdb_id)
102
+ EMDB_get_imaging_info(emdb_id=emdb_id)
103
+ EMDB_get_validation(emdb_id=emdb_id)
104
+ EMDB_get_publications(emdb_id=emdb_id)
105
+ EMDB_search_structures(query=query)
106
+ """
107
+ url = f"{EMDB_API}/entry/{emdb_id}"
108
+ resp = requests.get(url)
109
+ resp.raise_for_status()
110
+ data = resp.json()
111
+
112
+ admin = data.get("admin", {})
113
+ map_info = data.get("map", {})
114
+
115
+ entry = {
116
+ "emdb_id": emdb_id,
117
+ "title": admin.get("title", ""),
118
+ "resolution": map_info.get("resolution", {}).get("value", ""),
119
+ "contour_level": map_info.get("contour_level", {}).get("value", ""),
120
+ "deposition_date": admin.get("deposition_date", ""),
121
+ }
122
+
123
+ print(f"EMDB {emdb_id}: {entry['resolution']}Å resolution")
124
+ return entry, data
125
+ ```
126
+
127
+ ## 3. Proteins API (UniProt) ドメイン・変異
128
+
129
+ ```python
130
+ PROTEINS_API = "https://www.ebi.ac.uk/proteins/api"
131
+
132
+
133
+ def get_protein_features(uniprot_id):
134
+ """
135
+ Proteins API からタンパク質のドメイン・変異・修飾情報を取得。
136
+
137
+ Parameters:
138
+ uniprot_id: str — UniProt accession (e.g., "P04637")
139
+
140
+ ToolUniverse:
141
+ proteins_api_get_protein(accession=uniprot_id)
142
+ proteins_api_get_features(accession=uniprot_id)
143
+ proteins_api_get_variants(accession=uniprot_id)
144
+ proteins_api_get_xrefs(accession=uniprot_id)
145
+ proteins_api_get_genome_mappings(accession=uniprot_id)
146
+ """
147
+ headers = {"Accept": "application/json"}
148
+
149
+ # Protein info
150
+ resp_p = requests.get(
151
+ f"{PROTEINS_API}/proteins/{uniprot_id}", headers=headers
152
+ )
153
+ resp_p.raise_for_status()
154
+ protein = resp_p.json()
155
+
156
+ # Features
157
+ resp_f = requests.get(
158
+ f"{PROTEINS_API}/features/{uniprot_id}", headers=headers
159
+ )
160
+ features = resp_f.json() if resp_f.status_code == 200 else {}
161
+
162
+ feature_list = features.get("features", [])
163
+ domains = [f for f in feature_list if f.get("type") == "DOMAIN"]
164
+ variants = [f for f in feature_list if f.get("type") == "VARIANT"]
165
+
166
+ print(f"Proteins API {uniprot_id}: "
167
+ f"{len(domains)} domains, {len(variants)} variants")
168
+ return protein, feature_list
169
+ ```
170
+
171
+ ## 4. Complex Portal 複合体
172
+
173
+ ```python
174
+ def get_complex_portal(complex_id):
175
+ """
176
+ Complex Portal からタンパク質複合体の詳細を取得。
177
+
178
+ Parameters:
179
+ complex_id: str — Complex Portal ID (e.g., "CPX-1")
180
+
181
+ ToolUniverse:
182
+ ComplexPortal_get_complex(complex_id=complex_id)
183
+ ComplexPortal_search_complexes(query=query)
184
+ """
185
+ url = (
186
+ f"https://www.ebi.ac.uk/intact/complex-ws/complex/{complex_id}"
187
+ )
188
+ resp = requests.get(url, headers={"Accept": "application/json"})
189
+ resp.raise_for_status()
190
+ data = resp.json()
191
+
192
+ participants = data.get("participants", [])
193
+ subunits = []
194
+ for p in participants:
195
+ interactor = p.get("interactor", {})
196
+ subunits.append({
197
+ "identifier": interactor.get("identifier", ""),
198
+ "name": interactor.get("name", ""),
199
+ "stoichiometry": p.get("stoichiometry", ""),
200
+ })
201
+
202
+ print(f"Complex Portal {complex_id}: "
203
+ f"{data.get('name', '?')}, {len(subunits)} subunits")
204
+ return data, subunits
205
+ ```
206
+
207
+ ## 5. DeepGO 機能予測 & EVE 変異評価
208
+
209
+ ```python
210
+ def predict_deepgo_function(sequence):
211
+ """
212
+ DeepGO でタンパク質配列から GO 機能予測。
213
+
214
+ ToolUniverse:
215
+ DeepGO_predict_function(sequence=sequence)
216
+ """
217
+ url = "https://deepgo.cbrc.kaust.edu.sa/deepgo/api/create"
218
+ resp = requests.post(url, json={"data_format": "fasta", "data": sequence})
219
+ resp.raise_for_status()
220
+ data = resp.json()
221
+
222
+ predictions = data.get("predictions", [])
223
+ print(f"DeepGO: {len(predictions)} GO term predictions")
224
+ return predictions
225
+
226
+
227
+ def get_eve_variant_score(gene_name, variant=None):
228
+ """
229
+ EVE (Evolutionary model of Variant Effect) による
230
+ missense 変異の病原性スコアを取得。
231
+
232
+ ToolUniverse:
233
+ EVE_get_gene_info(gene_name=gene_name)
234
+ EVE_get_variant_score(gene_name=gene_name, variant=variant)
235
+ """
236
+ url = f"https://evemodel.org/api/proteins/{gene_name}"
237
+
238
+ if variant:
239
+ url += f"/variants/{variant}"
240
+
241
+ resp = requests.get(url)
242
+ resp.raise_for_status()
243
+ data = resp.json()
244
+
245
+ if variant:
246
+ score = data.get("eve_score", None)
247
+ classification = data.get("eve_class", "")
248
+ print(f"EVE {gene_name} {variant}: score={score}, class={classification}")
249
+ else:
250
+ print(f"EVE {gene_name}: found")
251
+
252
+ return data
253
+ ```
254
+
255
+ ## References
256
+
257
+ ### Output Files
258
+
259
+ | ファイル | 形式 |
260
+ |---|---|
261
+ | `results/pdbe_entry.json` | JSON |
262
+ | `results/emdb_structure.json` | JSON |
263
+ | `results/protein_features.json` | JSON |
264
+ | `results/complex_portal.json` | JSON |
265
+ | `results/deepgo_predictions.json` | JSON |
266
+ | `results/eve_scores.json` | JSON |
267
+
268
+ ### 利用可能ツール
269
+
270
+ | カテゴリ | 主要ツール | 用途 |
271
+ |---|---|---|
272
+ | PDBe | `pdbe_get_entry_summary` | エントリサマリー |
273
+ | PDBe | `pdbe_get_entry_quality` | 構造品質 |
274
+ | PDBe | `pdbe_get_entry_experiment` | 実験手法 |
275
+ | PDBe | `pdbe_get_entry_molecules` | 分子情報 |
276
+ | PDBe | `pdbe_get_entry_secondary_structure` | 二次構造 |
277
+ | PDBe | `pdbe_get_entry_assemblies` | 生物学的集合体 |
278
+ | PDBe | `pdbe_get_entry_publications` | 文献 |
279
+ | PDBe | `pdbe_get_entry_related_publications` | 関連文献 |
280
+ | PDBe | `pdbe_get_entry_observed_residues_ratio` | 観察残基 |
281
+ | PDBe | `pdbe_get_entry_status` | ステータス |
282
+ | EMDB | `EMDB_get_structure` | EM 構造 |
283
+ | EMDB | `EMDB_get_map_info` | マップ情報 |
284
+ | EMDB | `EMDB_get_sample_info` | サンプル情報 |
285
+ | EMDB | `EMDB_get_imaging_info` | イメージング |
286
+ | EMDB | `EMDB_get_validation` | バリデーション |
287
+ | EMDB | `EMDB_get_publications` | 文献 |
288
+ | EMDB | `EMDB_search_structures` | EM 構造検索 |
289
+ | Proteins API | `proteins_api_get_protein` | タンパク質情報 |
290
+ | Proteins API | `proteins_api_get_features` | ドメイン・特徴 |
291
+ | Proteins API | `proteins_api_get_variants` | 変異 |
292
+ | Proteins API | `proteins_api_get_xrefs` | 外部参照 |
293
+ | Proteins API | `proteins_api_get_genome_mappings` | ゲノムマッピング |
294
+ | Proteins API | `proteins_api_get_epitopes` | エピトープ |
295
+ | Proteins API | `proteins_api_get_proteomics` | プロテオミクス |
296
+ | Proteins API | `proteins_api_get_publications` | 文献 |
297
+ | Proteins API | `proteins_api_get_comments` | コメント |
298
+ | Proteins API | `proteins_api_search` | 検索 |
299
+ | Complex Portal | `ComplexPortal_get_complex` | 複合体詳細 |
300
+ | Complex Portal | `ComplexPortal_search_complexes` | 複合体検索 |
301
+ | DeepGO | `DeepGO_predict_function` | GO 機能予測 |
302
+ | EVE | `EVE_get_gene_info` | 遺伝子情報 |
303
+ | EVE | `EVE_get_variant_score` | 変異スコア |
304
+
305
+ ### 参照スキル
306
+
307
+ | スキル | 関連 |
308
+ |---|---|
309
+ | `scientific-protein-structure-analysis` | タンパク質構造 |
310
+ | `scientific-proteomics-mass-spectrometry` | プロテオミクス |
311
+ | `scientific-protein-interaction-network` | PPI |
312
+ | `scientific-molecular-docking` | ドッキング |
313
+ | `scientific-variant-interpretation` | 変異解釈 |
314
+
315
+ ### 依存パッケージ
316
+
317
+ `requests`, `pandas`
@@ -0,0 +1,277 @@
1
+ ---
2
+ name: scientific-symbolic-mathematics
3
+ description: |
4
+ 記号数学スキル。SymPy による解析的微積分・線形代数・微分方程式求解、
5
+ 記号式の LaTeX 変換、数値計算との統合、科学モデリング用
6
+ 記号計算パイプライン。
7
+ ---
8
+
9
+ # Scientific Symbolic Mathematics
10
+
11
+ SymPy を中心とした記号数学 (Computer Algebra System)
12
+ パイプラインを提供する。
13
+
14
+ ## When to Use
15
+
16
+ - 微分方程式を解析的に解くとき
17
+ - 数式の記号的微分・積分を行うとき
18
+ - 行列の固有値・固有ベクトルを記号的に求めるとき
19
+ - 科学モデルのパラメータに関する感度解析を記号的に行うとき
20
+ - 数式を LaTeX 形式に変換するとき
21
+ - 記号解と数値解を比較検証するとき
22
+
23
+ ---
24
+
25
+ ## Quick Start
26
+
27
+ ## 1. 微分方程式の解析解
28
+
29
+ ```python
30
+ import sympy as sp
31
+ from sympy import (
32
+ symbols, Function, Eq, dsolve, classify_ode,
33
+ exp, sin, cos, sqrt, pi, oo, integrate, diff,
34
+ Matrix, latex, simplify, factor, expand, solve,
35
+ Rational, Sum, Product, series,
36
+ )
37
+ import numpy as np
38
+
39
+
40
+ def solve_ode(ode_expr, dependent_var, independent_var, ics=None):
41
+ """
42
+ 常微分方程式の解析解。
43
+
44
+ Parameters:
45
+ ode_expr: sympy.Eq — ODE (e.g., Eq(f(x).diff(x, 2) + f(x), 0))
46
+ dependent_var: sympy.Function — 従属変数
47
+ independent_var: sympy.Symbol — 独立変数
48
+ ics: dict — 初期条件 {f(0): 1, f'(0): 0}
49
+
50
+ K-Dense: sympy — Symbolic mathematics
51
+ """
52
+ # Classify ODE
53
+ classification = classify_ode(ode_expr, dependent_var(independent_var))
54
+ print(f"ODE classification: {classification[:3]}")
55
+
56
+ # Solve
57
+ solution = dsolve(ode_expr, dependent_var(independent_var), ics=ics)
58
+
59
+ print(f"Solution: {solution}")
60
+ print(f"LaTeX: {latex(solution)}")
61
+ return solution
62
+
63
+
64
+ # Example: damped harmonic oscillator
65
+ x, t, omega, gamma = symbols("x t omega gamma", positive=True)
66
+ f = Function("f")
67
+
68
+ # f''(t) + 2γf'(t) + ω²f(t) = 0
69
+ damped_ode = Eq(f(t).diff(t, 2) + 2*gamma*f(t).diff(t) + omega**2*f(t), 0)
70
+ ```
71
+
72
+ ## 2. 記号的微積分
73
+
74
+ ```python
75
+ def symbolic_calculus(expr, var, operations=None):
76
+ """
77
+ 記号的微積分操作。
78
+
79
+ Parameters:
80
+ expr: sympy expression — 数式
81
+ var: sympy.Symbol — 変数
82
+ operations: list — ["diff", "integrate", "series", "limit"]
83
+ """
84
+ if operations is None:
85
+ operations = ["diff", "integrate"]
86
+
87
+ results = {}
88
+
89
+ if "diff" in operations:
90
+ deriv = diff(expr, var)
91
+ results["derivative"] = {"expr": deriv, "latex": latex(deriv)}
92
+ print(f"d/d{var}({expr}) = {deriv}")
93
+
94
+ if "integrate" in operations:
95
+ integral = integrate(expr, var)
96
+ results["integral"] = {"expr": integral, "latex": latex(integral)}
97
+ print(f"∫{expr} d{var} = {integral}")
98
+
99
+ if "series" in operations:
100
+ ser = series(expr, var, 0, n=6)
101
+ results["series"] = {"expr": ser, "latex": latex(ser)}
102
+ print(f"Taylor series: {ser}")
103
+
104
+ if "limit" in operations:
105
+ from sympy import limit as sp_limit
106
+ lim = sp_limit(expr, var, oo)
107
+ results["limit"] = {"expr": lim, "latex": latex(lim)}
108
+ print(f"lim({var}→∞) {expr} = {lim}")
109
+
110
+ return results
111
+ ```
112
+
113
+ ## 3. 線形代数 (記号的)
114
+
115
+ ```python
116
+ def symbolic_linear_algebra(matrix_data):
117
+ """
118
+ 記号的線形代数 — 固有値・固有ベクトル・行列分解。
119
+
120
+ Parameters:
121
+ matrix_data: list of lists — 行列要素 (記号含む)
122
+ """
123
+ M = Matrix(matrix_data)
124
+ print(f"Matrix ({M.rows}×{M.cols}):")
125
+ sp.pprint(M)
126
+
127
+ results = {}
128
+
129
+ # Determinant
130
+ det = M.det()
131
+ results["determinant"] = {"expr": det, "latex": latex(det)}
132
+ print(f"\nDeterminant: {det}")
133
+
134
+ # Eigenvalues & eigenvectors
135
+ eigenvals = M.eigenvals()
136
+ results["eigenvalues"] = {str(k): v for k, v in eigenvals.items()}
137
+ print(f"Eigenvalues: {eigenvals}")
138
+
139
+ eigenvects = M.eigenvects()
140
+ results["eigenvectors"] = [
141
+ {"eigenvalue": str(ev[0]), "multiplicity": ev[1],
142
+ "vectors": [str(v) for v in ev[2]]}
143
+ for ev in eigenvects
144
+ ]
145
+
146
+ # Characteristic polynomial
147
+ lam = symbols("lambda")
148
+ char_poly = M.charpoly(lam)
149
+ results["characteristic_polynomial"] = {
150
+ "expr": str(char_poly.as_expr()),
151
+ "latex": latex(char_poly.as_expr()),
152
+ }
153
+ print(f"Characteristic polynomial: {char_poly.as_expr()}")
154
+
155
+ # Inverse (if nonsingular)
156
+ if det != 0:
157
+ inv = M.inv()
158
+ results["inverse"] = {"latex": latex(inv)}
159
+ print(f"Inverse exists: {M.rows}×{M.cols}")
160
+
161
+ return results
162
+ ```
163
+
164
+ ## 4. 科学モデリング (薬物動態学 PK モデル例)
165
+
166
+ ```python
167
+ def pk_compartment_model(n_compartments=1):
168
+ """
169
+ 薬物動態学コンパートメントモデルの記号的解法。
170
+
171
+ Parameters:
172
+ n_compartments: int — 1 (1-compartment) or 2 (2-compartment)
173
+ """
174
+ t = symbols("t", positive=True)
175
+
176
+ if n_compartments == 1:
177
+ # 1-compartment: dC/dt = -ke * C
178
+ C = Function("C")
179
+ ke, C0 = symbols("k_e C_0", positive=True)
180
+ ode = Eq(C(t).diff(t), -ke * C(t))
181
+ solution = dsolve(ode, C(t), ics={C(0): C0})
182
+
183
+ # Half-life
184
+ t_half = sp.solve(Eq(solution.rhs, C0/2), t)[0]
185
+
186
+ # AUC (0→∞)
187
+ auc = integrate(solution.rhs, (t, 0, oo))
188
+
189
+ result = {
190
+ "model": "1-compartment IV bolus",
191
+ "ode": latex(ode),
192
+ "solution": latex(solution),
193
+ "half_life": latex(t_half),
194
+ "auc_inf": latex(auc),
195
+ }
196
+ print(f"PK 1-compartment: C(t) = {solution.rhs}")
197
+ print(f" t½ = {t_half}")
198
+ print(f" AUC(0→∞) = {auc}")
199
+
200
+ elif n_compartments == 2:
201
+ # 2-compartment model
202
+ C1, C2 = Function("C1"), Function("C2")
203
+ k10, k12, k21, D, V1 = symbols("k_10 k_12 k_21 D V_1", positive=True)
204
+
205
+ ode1 = Eq(C1(t).diff(t), -(k10 + k12)*C1(t) + k21*C2(t))
206
+ ode2 = Eq(C2(t).diff(t), k12*C1(t) - k21*C2(t))
207
+
208
+ system = [ode1, ode2]
209
+ solution = sp.dsolve(system, [C1(t), C2(t)])
210
+
211
+ result = {
212
+ "model": "2-compartment IV bolus",
213
+ "system": [latex(eq) for eq in system],
214
+ "solution": [latex(sol) for sol in solution],
215
+ }
216
+ print(f"PK 2-compartment system defined")
217
+ for sol in solution:
218
+ print(f" {sol}")
219
+
220
+ return result
221
+ ```
222
+
223
+ ## 5. LaTeX 数式エクスポート
224
+
225
+ ```python
226
+ def export_equations_latex(equations, output_file="equations.tex"):
227
+ """
228
+ 記号数式を LaTeX ファイルにエクスポート。
229
+
230
+ Parameters:
231
+ equations: dict — {name: sympy_expr}
232
+ output_file: str — 出力 LaTeX パス
233
+ """
234
+ lines = [
235
+ r"\documentclass{article}",
236
+ r"\usepackage{amsmath,amssymb}",
237
+ r"\begin{document}",
238
+ "",
239
+ ]
240
+
241
+ for name, expr in equations.items():
242
+ lines.append(f"% {name}")
243
+ lines.append(r"\begin{equation}")
244
+ lines.append(f" {latex(expr)}")
245
+ lines.append(r"\end{equation}")
246
+ lines.append("")
247
+
248
+ lines.append(r"\end{document}")
249
+
250
+ with open(output_file, "w") as f:
251
+ f.write("\n".join(lines))
252
+
253
+ print(f"LaTeX exported: {output_file} ({len(equations)} equations)")
254
+ return output_file
255
+ ```
256
+
257
+ ---
258
+
259
+ ## パイプライン出力
260
+
261
+ | 出力ファイル | 説明 | 連携先スキル |
262
+ |---|---|---|
263
+ | `results/symbolic_solutions.json` | 記号解 (LaTeX 形式) | → latex-formatter, academic-writing |
264
+ | `results/ode_solutions.json` | ODE 解析解 | → systems-biology, admet-pharmacokinetics |
265
+ | `equations.tex` | LaTeX 数式集 | → latex-formatter |
266
+ | `figures/symbolic_plot.png` | 記号解の可視化 | → publication-figures |
267
+
268
+ ## パイプライン統合
269
+
270
+ ```
271
+ systems-biology ──→ symbolic-mathematics ──→ latex-formatter
272
+ (SBML/ODE) (SymPy 解析解) (LaTeX 変換)
273
+
274
+ ├──→ admet-pharmacokinetics (PK モデル)
275
+ ├──→ bayesian-statistics (尤度導出)
276
+ └──→ computational-materials (バンド理論)
277
+ ```