@nahisaho/satori 0.20.0 → 0.22.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 (30) hide show
  1. package/README.md +70 -39
  2. package/package.json +1 -1
  3. package/src/.github/skills/scientific-biothings-idmapping/SKILL.md +4 -0
  4. package/src/.github/skills/scientific-cellxgene-census/SKILL.md +257 -0
  5. package/src/.github/skills/scientific-clingen-curation/SKILL.md +258 -0
  6. package/src/.github/skills/scientific-clinical-nlp/SKILL.md +250 -0
  7. package/src/.github/skills/scientific-clinical-pharmacology/SKILL.md +361 -0
  8. package/src/.github/skills/scientific-clinical-standards/SKILL.md +444 -0
  9. package/src/.github/skills/scientific-crispr-design/SKILL.md +369 -0
  10. package/src/.github/skills/scientific-drug-repurposing/SKILL.md +4 -0
  11. package/src/.github/skills/scientific-environmental-ecology/SKILL.md +5 -0
  12. package/src/.github/skills/scientific-epidemiology-public-health/SKILL.md +5 -0
  13. package/src/.github/skills/scientific-epigenomics-chromatin/SKILL.md +5 -0
  14. package/src/.github/skills/scientific-glycomics/SKILL.md +274 -0
  15. package/src/.github/skills/scientific-gtex-tissue-expression/SKILL.md +5 -2
  16. package/src/.github/skills/scientific-hgnc-nomenclature/SKILL.md +282 -0
  17. package/src/.github/skills/scientific-human-cell-atlas/SKILL.md +3 -0
  18. package/src/.github/skills/scientific-human-protein-atlas/SKILL.md +4 -0
  19. package/src/.github/skills/scientific-immunoinformatics/SKILL.md +9 -0
  20. package/src/.github/skills/scientific-lipidomics/SKILL.md +284 -0
  21. package/src/.github/skills/scientific-metabolomics/SKILL.md +3 -0
  22. package/src/.github/skills/scientific-metabolomics-network/SKILL.md +311 -0
  23. package/src/.github/skills/scientific-metagenome-assembled-genomes/SKILL.md +299 -0
  24. package/src/.github/skills/scientific-model-organism-db/SKILL.md +8 -0
  25. package/src/.github/skills/scientific-pharmacogenomics/SKILL.md +4 -0
  26. package/src/.github/skills/scientific-pharos-targets/SKILL.md +276 -0
  27. package/src/.github/skills/scientific-protein-structure-analysis/SKILL.md +4 -0
  28. package/src/.github/skills/scientific-public-health-data/SKILL.md +11 -0
  29. package/src/.github/skills/scientific-systems-biology/SKILL.md +11 -0
  30. package/src/.github/skills/scientific-variant-effect-prediction/SKILL.md +7 -0
@@ -0,0 +1,361 @@
1
+ ---
2
+ name: scientific-clinical-pharmacology
3
+ description: |
4
+ 臨床薬理学モデリングスキル。PopPK (NLME 混合効果モデル)・
5
+ PBPK シミュレーション・TDM 投与量最適化・
6
+ Emax/Sigmoid PD モデリング・薬物間相互作用予測・
7
+ 臨床薬理パイプライン。
8
+ TU 外スキル (Python + nlmixr2/mrgsolve ラッパー)。
9
+ ---
10
+
11
+ # Scientific Clinical Pharmacology
12
+
13
+ 母集団薬物動態 (PopPK)・生理学的薬物動態 (PBPK)・
14
+ 薬力学 (PD) モデリングを統合した臨床薬理学
15
+ 解析パイプラインを提供する。
16
+
17
+ ## When to Use
18
+
19
+ - 母集団 PK (PopPK) の NLME 解析を行うとき
20
+ - PBPK モデルで薬物動態をシミュレーションするとき
21
+ - TDM (Therapeutic Drug Monitoring) 投与量を最適化するとき
22
+ - Emax/Sigmoid PD モデルを当てはめるとき
23
+ - 薬物間相互作用 (DDI) の影響を予測するとき
24
+ - 小児・腎障害・肝障害の用量調節を検討するとき
25
+
26
+ ---
27
+
28
+ ## Quick Start
29
+
30
+ ## 1. コンパートメント PK モデル
31
+
32
+ ```python
33
+ import numpy as np
34
+ import pandas as pd
35
+ from scipy.integrate import odeint
36
+ from scipy.optimize import minimize
37
+
38
+
39
+ def one_compartment_iv(y, t, cl, v):
40
+ """1-コンパートメント IV ボーラス ODE。"""
41
+ return [-cl / v * y[0]]
42
+
43
+
44
+ def two_compartment_iv(y, t, cl, v1, q, v2):
45
+ """2-コンパートメント IV ボーラス ODE。"""
46
+ c1 = y[0] / v1
47
+ c2 = y[1] / v2
48
+ dy1 = -cl * c1 - q * (c1 - c2)
49
+ dy2 = q * (c1 - c2)
50
+ return [dy1, dy2]
51
+
52
+
53
+ def simulate_pk(dose, model="1cmt",
54
+ params=None,
55
+ times=None):
56
+ """
57
+ PK モデルシミュレーション。
58
+
59
+ Parameters:
60
+ dose: float — 投与量 (mg)
61
+ model: str — "1cmt" or "2cmt"
62
+ params: dict — PK パラメータ
63
+ 1cmt: {cl, v}
64
+ 2cmt: {cl, v1, q, v2}
65
+ times: array — 時間点 (h)
66
+ """
67
+ if times is None:
68
+ times = np.linspace(0, 24, 241)
69
+ if params is None:
70
+ params = ({"cl": 5.0, "v": 50.0}
71
+ if model == "1cmt"
72
+ else {"cl": 5.0, "v1": 50.0,
73
+ "q": 2.0, "v2": 30.0})
74
+
75
+ if model == "1cmt":
76
+ y0 = [dose]
77
+ sol = odeint(one_compartment_iv, y0,
78
+ times,
79
+ args=(params["cl"],
80
+ params["v"]))
81
+ conc = sol[:, 0] / params["v"]
82
+ else:
83
+ y0 = [dose, 0.0]
84
+ sol = odeint(two_compartment_iv, y0,
85
+ times,
86
+ args=(params["cl"],
87
+ params["v1"],
88
+ params["q"],
89
+ params["v2"]))
90
+ conc = sol[:, 0] / params["v1"]
91
+
92
+ df = pd.DataFrame({
93
+ "time": times, "concentration": conc})
94
+ cmax = conc.max()
95
+ t_half = 0.693 * params.get(
96
+ "v", params.get("v1", 50)) / params["cl"]
97
+ print(f"PK sim ({model}): Cmax={cmax:.2f}, "
98
+ f"t1/2={t_half:.1f}h")
99
+ return df
100
+ ```
101
+
102
+ ## 2. 母集団 PK (PopPK) 推定
103
+
104
+ ```python
105
+ def popk_estimation(data, model="1cmt"):
106
+ """
107
+ 母集団 PK パラメータ推定 (簡易 NLME)。
108
+
109
+ Parameters:
110
+ data: pd.DataFrame — 個体別濃度データ
111
+ columns: [id, time, dv, dose, (covariates)]
112
+ model: str — "1cmt" or "2cmt"
113
+ """
114
+ subjects = data["id"].unique()
115
+
116
+ def _objective(theta):
117
+ """集団目的関数 (OFV)。"""
118
+ tv_cl = np.exp(theta[0])
119
+ tv_v = np.exp(theta[1])
120
+ omega_cl = np.exp(theta[2])
121
+ omega_v = np.exp(theta[3])
122
+ sigma = np.exp(theta[4])
123
+
124
+ ofv = 0.0
125
+ for subj in subjects:
126
+ sdata = data[data["id"] == subj]
127
+ dose = sdata["dose"].iloc[0]
128
+ times = sdata["time"].values
129
+ obs = sdata["dv"].values
130
+
131
+ # 個体パラメータ (EBE 近似)
132
+ eta_cl = 0.0
133
+ eta_v = 0.0
134
+ cl_i = tv_cl * np.exp(eta_cl)
135
+ v_i = tv_v * np.exp(eta_v)
136
+
137
+ pred = dose / v_i * np.exp(
138
+ -cl_i / v_i * times)
139
+ pred = np.maximum(pred, 1e-10)
140
+
141
+ # OFV 要素
142
+ residual = np.log(obs + 1e-10) - np.log(
143
+ pred)
144
+ ofv += np.sum(
145
+ residual**2 / sigma**2
146
+ + np.log(sigma**2))
147
+
148
+ return ofv
149
+
150
+ # 初期値
151
+ x0 = [np.log(5), np.log(50),
152
+ np.log(0.3), np.log(0.3),
153
+ np.log(0.2)]
154
+
155
+ result = minimize(_objective, x0,
156
+ method="Nelder-Mead",
157
+ options={"maxiter": 5000})
158
+
159
+ estimates = {
160
+ "tv_cl": round(np.exp(result.x[0]), 3),
161
+ "tv_v": round(np.exp(result.x[1]), 3),
162
+ "omega_cl": round(np.exp(result.x[2]), 3),
163
+ "omega_v": round(np.exp(result.x[3]), 3),
164
+ "sigma": round(np.exp(result.x[4]), 3),
165
+ "ofv": round(result.fun, 2),
166
+ "converged": result.success,
167
+ }
168
+
169
+ print(f"PopPK: CL={estimates['tv_cl']} L/h, "
170
+ f"V={estimates['tv_v']} L, "
171
+ f"OFV={estimates['ofv']}")
172
+ return estimates
173
+ ```
174
+
175
+ ## 3. TDM 投与量最適化
176
+
177
+ ```python
178
+ def tdm_dose_optimization(
179
+ current_conc, current_dose,
180
+ target_range, pk_params,
181
+ interval=12):
182
+ """
183
+ TDM ベース投与量最適化。
184
+
185
+ Parameters:
186
+ current_conc: float — 現在トラフ濃度
187
+ current_dose: float — 現在投与量 (mg)
188
+ target_range: tuple — 目標濃度範囲 (min, max)
189
+ pk_params: dict — {cl, v} PK パラメータ
190
+ interval: float — 投与間隔 (h)
191
+ """
192
+ cl = pk_params["cl"]
193
+ v = pk_params["v"]
194
+ ke = cl / v
195
+ target_mid = (target_range[0]
196
+ + target_range[1]) / 2
197
+
198
+ # 線形 PK 仮定: 用量比例
199
+ ratio = target_mid / max(current_conc, 0.01)
200
+ new_dose = current_dose * ratio
201
+
202
+ # シミュレーション検証
203
+ times = np.linspace(0, interval, 100)
204
+ conc_profile = (new_dose / v
205
+ * np.exp(-ke * times))
206
+ cmax = conc_profile[0]
207
+ ctrough = conc_profile[-1]
208
+
209
+ in_range = (target_range[0] <= ctrough
210
+ <= target_range[1])
211
+
212
+ result = {
213
+ "current_dose": current_dose,
214
+ "current_trough": current_conc,
215
+ "recommended_dose": round(new_dose, 1),
216
+ "predicted_cmax": round(cmax, 2),
217
+ "predicted_trough": round(ctrough, 2),
218
+ "target_range": target_range,
219
+ "in_target": in_range,
220
+ }
221
+
222
+ status = "✓" if in_range else "✗"
223
+ print(f"TDM: {current_dose}mg → "
224
+ f"{new_dose:.1f}mg "
225
+ f"(trough {ctrough:.2f}) {status}")
226
+ return result
227
+ ```
228
+
229
+ ## 4. Emax PD モデル
230
+
231
+ ```python
232
+ def emax_model(conc, emax, ec50, hill=1):
233
+ """Emax / Sigmoid Emax モデル。"""
234
+ return emax * conc**hill / (
235
+ ec50**hill + conc**hill)
236
+
237
+
238
+ def fit_emax(conc_data, effect_data,
239
+ sigmoid=False):
240
+ """
241
+ Emax モデルフィッティング。
242
+
243
+ Parameters:
244
+ conc_data: array — 濃度データ
245
+ effect_data: array — 薬効データ
246
+ sigmoid: bool — Sigmoid (Hill) モデル
247
+ """
248
+ from scipy.optimize import curve_fit
249
+
250
+ conc = np.array(conc_data)
251
+ effect = np.array(effect_data)
252
+
253
+ if sigmoid:
254
+ def _model(c, emax, ec50, hill):
255
+ return emax_model(c, emax, ec50, hill)
256
+ p0 = [max(effect), np.median(conc), 1.0]
257
+ bounds = ([0, 0, 0.1], [np.inf, np.inf, 10])
258
+ else:
259
+ def _model(c, emax, ec50):
260
+ return emax_model(c, emax, ec50, 1)
261
+ p0 = [max(effect), np.median(conc)]
262
+ bounds = ([0, 0], [np.inf, np.inf])
263
+
264
+ popt, pcov = curve_fit(
265
+ _model, conc, effect, p0=p0,
266
+ bounds=bounds, maxfev=5000)
267
+
268
+ perr = np.sqrt(np.diag(pcov))
269
+
270
+ result = {
271
+ "emax": round(popt[0], 3),
272
+ "ec50": round(popt[1], 3),
273
+ "emax_se": round(perr[0], 3),
274
+ "ec50_se": round(perr[1], 3),
275
+ }
276
+ if sigmoid:
277
+ result["hill"] = round(popt[2], 3)
278
+ result["hill_se"] = round(perr[2], 3)
279
+
280
+ print(f"PD fit: Emax={result['emax']}, "
281
+ f"EC50={result['ec50']}"
282
+ + (f", Hill={result['hill']}"
283
+ if sigmoid else ""))
284
+ return result
285
+ ```
286
+
287
+ ## 5. 臨床薬理統合パイプライン
288
+
289
+ ```python
290
+ def clinical_pharmacology_pipeline(
291
+ pk_data, pd_data=None,
292
+ target_range=(10, 20),
293
+ output_dir="results"):
294
+ """
295
+ 臨床薬理学統合パイプライン。
296
+
297
+ Parameters:
298
+ pk_data: pd.DataFrame — PK 濃度データ
299
+ pd_data: pd.DataFrame | None — PD 効果データ
300
+ target_range: tuple — 目標トラフ範囲
301
+ output_dir: str — 出力ディレクトリ
302
+ """
303
+ from pathlib import Path
304
+ out = Path(output_dir)
305
+ out.mkdir(parents=True, exist_ok=True)
306
+
307
+ # 1) PopPK 推定
308
+ pk_est = popk_estimation(pk_data)
309
+
310
+ # 2) TDM 最適化 (最新トラフがあれば)
311
+ latest = pk_data.sort_values("time").iloc[-1]
312
+ tdm = tdm_dose_optimization(
313
+ latest["dv"], latest["dose"],
314
+ target_range,
315
+ {"cl": pk_est["tv_cl"],
316
+ "v": pk_est["tv_v"]})
317
+
318
+ # 3) PD モデル (データがあれば)
319
+ pd_result = None
320
+ if pd_data is not None:
321
+ pd_result = fit_emax(
322
+ pd_data["concentration"],
323
+ pd_data["effect"],
324
+ sigmoid=True)
325
+
326
+ # 4) シミュレーション
327
+ sim = simulate_pk(
328
+ tdm["recommended_dose"],
329
+ params={"cl": pk_est["tv_cl"],
330
+ "v": pk_est["tv_v"]})
331
+ sim.to_csv(out / "pk_simulation.csv",
332
+ index=False)
333
+
334
+ print(f"Clinical PK pipeline → {out}")
335
+ return {
336
+ "popk": pk_est,
337
+ "tdm": tdm,
338
+ "pd": pd_result,
339
+ "simulation": sim,
340
+ }
341
+ ```
342
+
343
+ ---
344
+
345
+ ## パイプライン統合
346
+
347
+ ```
348
+ admet-pharmacokinetics → clinical-pharmacology → pharmacogenomics
349
+ (ADMET 予測) (臨床 PK/PD) (遺伝薬理学)
350
+ │ │ ↓
351
+ drug-repurposing ────────────┘ clinical-decision-support
352
+ (薬剤リパーパシング) (臨床意思決定)
353
+ ```
354
+
355
+ ## パイプライン出力
356
+
357
+ | ファイル | 説明 | 次スキル |
358
+ |---------|------|---------|
359
+ | `pk_simulation.csv` | PK シミュレーション | → dose-response |
360
+ | `popk_estimates.json` | PopPK パラメータ | → pharmacogenomics |
361
+ | `tdm_recommendation.json` | TDM 推奨用量 | → clinical-decision |