@nahisaho/satori 0.9.0 → 0.11.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 +188 -39
  2. package/package.json +1 -1
  3. package/src/.github/skills/scientific-clinical-trials-analytics/SKILL.md +340 -0
  4. package/src/.github/skills/scientific-computational-materials/SKILL.md +353 -0
  5. package/src/.github/skills/scientific-environmental-ecology/SKILL.md +295 -0
  6. package/src/.github/skills/scientific-epidemiology-public-health/SKILL.md +332 -0
  7. package/src/.github/skills/scientific-epigenomics-chromatin/SKILL.md +567 -0
  8. package/src/.github/skills/scientific-gene-expression-transcriptomics/SKILL.md +330 -0
  9. package/src/.github/skills/scientific-immunoinformatics/SKILL.md +341 -0
  10. package/src/.github/skills/scientific-infectious-disease/SKILL.md +342 -0
  11. package/src/.github/skills/scientific-lab-data-management/SKILL.md +334 -0
  12. package/src/.github/skills/scientific-microbiome-metagenomics/SKILL.md +349 -0
  13. package/src/.github/skills/scientific-neuroscience-electrophysiology/SKILL.md +400 -0
  14. package/src/.github/skills/scientific-pharmacogenomics/SKILL.md +342 -0
  15. package/src/.github/skills/scientific-population-genetics/SKILL.md +336 -0
  16. package/src/.github/skills/scientific-proteomics-mass-spectrometry/SKILL.md +401 -0
  17. package/src/.github/skills/scientific-regulatory-science/SKILL.md +256 -0
  18. package/src/.github/skills/scientific-scientific-schematics/SKILL.md +336 -0
  19. package/src/.github/skills/scientific-single-cell-genomics/SKILL.md +361 -0
  20. package/src/.github/skills/scientific-spatial-transcriptomics/SKILL.md +281 -0
  21. package/src/.github/skills/scientific-systems-biology/SKILL.md +310 -0
  22. package/src/.github/skills/scientific-text-mining-nlp/SKILL.md +358 -0
@@ -0,0 +1,400 @@
1
+ ---
2
+ name: scientific-neuroscience-electrophysiology
3
+ description: |
4
+ 神経科学・電気生理学解析スキル。Neuropixels/マルチ電極アレイの
5
+ スパイクソーティング (SpikeInterface + Kilosort4)、品質指標 (SNR/ISI 違反率)、
6
+ EEG マイクロステート・事象関連電位 (MNE-Python)、ECG HRV 解析、
7
+ EDA 皮膚コンダクタンス応答、EMG 筋活動解析 (NeuroKit2)、
8
+ 脳結合性解析 (機能的/実効的) を統合した神経科学パイプライン。
9
+ ---
10
+
11
+ # Scientific Neuroscience & Electrophysiology
12
+
13
+ Neuropixels 高密度電極記録・EEG・ECG・EMG・EDA 等の神経生理信号を対象に、
14
+ スパイクソーティング→品質管理→特徴抽出→統計解析の
15
+ 標準パイプラインを提供する。SpikeInterface + NeuroKit2 + MNE-Python ベース。
16
+
17
+ ## When to Use
18
+
19
+ - Neuropixels/MEA のスパイクソーティングパイプラインが必要なとき
20
+ - EEG マイクロステート・事象関連電位 (ERP) 解析を行うとき
21
+ - ECG からの心拍変動 (HRV) 解析・自律神経系評価が必要なとき
22
+ - EDA (皮膚電気活動) の交感神経応答解析を行うとき
23
+ - 脳結合性 (機能的/実効的) の推定が必要なとき
24
+
25
+ ---
26
+
27
+ ## Quick Start
28
+
29
+ ## 1. Neuropixels スパイクソーティング (SpikeInterface)
30
+
31
+ ```python
32
+ import numpy as np
33
+ import spikeinterface.full as si
34
+
35
+
36
+ def neuropixels_preprocessing(recording_path, probe_type="NP1",
37
+ output_dir="results/neuroscience"):
38
+ """
39
+ Neuropixels 記録の前処理パイプライン (SpikeInterface)。
40
+
41
+ 1. SpikeGLX/OpenEphys ファイル読み込み
42
+ 2. バンドパスフィルタ (300-6000 Hz)
43
+ 3. 位相シフト補正 (ADC multiplexing)
44
+ 4. CMR (Common Median Reference) ノイズ除去
45
+ 5. ドリフト補正 (Motion correction)
46
+ """
47
+ import os
48
+ os.makedirs(output_dir, exist_ok=True)
49
+
50
+ # 記録読み込み
51
+ recording = si.read_spikeglx(recording_path)
52
+ print(f" Probe: {probe_type}")
53
+ print(f" Channels: {recording.get_num_channels()}")
54
+ print(f" Sampling rate: {recording.get_sampling_frequency()} Hz")
55
+ print(f" Duration: {recording.get_total_duration():.1f} sec")
56
+
57
+ # 前処理チェーン
58
+ rec_filt = si.bandpass_filter(recording, freq_min=300, freq_max=6000)
59
+ rec_shift = si.phase_shift(rec_filt) # ADC 位相補正
60
+ rec_cmr = si.common_reference(rec_shift, reference="global",
61
+ operator="median")
62
+
63
+ # モーション補正 (非剛体)
64
+ motion_info = si.correct_motion(
65
+ rec_cmr, preset="nonrigid_accurate",
66
+ output_motion_info=True
67
+ )
68
+
69
+ print(f" Preprocessing complete: filter → phase_shift → CMR → motion")
70
+
71
+ return rec_cmr
72
+
73
+
74
+ def spike_sorting_kilosort4(recording, output_dir="results/spike_sorting"):
75
+ """
76
+ Kilosort4 によるスパイクソーティング。
77
+
78
+ SpikeInterface wrapper を使用。
79
+ """
80
+ import os
81
+ os.makedirs(output_dir, exist_ok=True)
82
+
83
+ sorting = si.run_sorter(
84
+ sorter_name="kilosort4",
85
+ recording=recording,
86
+ output_folder=output_dir,
87
+ verbose=True,
88
+ )
89
+
90
+ print(f" Kilosort4 results:")
91
+ print(f" Units found: {len(sorting.get_unit_ids())}")
92
+
93
+ return sorting
94
+
95
+
96
+ def spike_sorting_quality_metrics(sorting, recording,
97
+ output_dir="results/spike_sorting"):
98
+ """
99
+ スパイクソーティング品質指標。
100
+
101
+ ENCODE/Allen Institute 基準:
102
+ - SNR ≥ 5: 高品質ユニット
103
+ - ISI violation rate < 0.5%: 良好な分離
104
+ - Presence ratio > 0.9: 安定した記録
105
+ - Amplitude cutoff < 0.1
106
+ """
107
+ we = si.extract_waveforms(recording, sorting, folder=f"{output_dir}/waveforms")
108
+ metrics = si.compute_quality_metrics(we)
109
+
110
+ # Allen Institute 基準フィルタ
111
+ good_units = metrics[
112
+ (metrics["snr"] >= 5) &
113
+ (metrics["isi_violations_ratio"] < 0.005) &
114
+ (metrics["presence_ratio"] > 0.9) &
115
+ (metrics["amplitude_cutoff"] < 0.1)
116
+ ]
117
+
118
+ print(f" Quality metrics computed for {len(metrics)} units")
119
+ print(f" Good units (Allen criteria): {len(good_units)} / {len(metrics)}")
120
+ print(f" Mean SNR: {metrics['snr'].mean():.1f}")
121
+ print(f" Mean ISI violation rate: {metrics['isi_violations_ratio'].mean():.4f}")
122
+ print(f" Mean firing rate: {metrics['firing_rate'].mean():.1f} Hz")
123
+
124
+ return metrics, good_units
125
+ ```
126
+
127
+ ## 2. EEG 解析 (MNE-Python)
128
+
129
+ ```python
130
+ import numpy as np
131
+ import mne
132
+
133
+
134
+ def eeg_preprocessing(raw_file, montage="standard_1020",
135
+ l_freq=1.0, h_freq=40.0):
136
+ """
137
+ EEG 前処理パイプライン (MNE-Python)。
138
+
139
+ 1. ファイル読み込み (BDF/EDF/FIF/BrainVision)
140
+ 2. モンタージュ設定
141
+ 3. バンドパスフィルタ (1-40 Hz)
142
+ 4. ICA によるアーティファクト除去 (眼球運動, 心拍)
143
+ 5. 再参照 (平均参照)
144
+ """
145
+ raw = mne.io.read_raw(raw_file, preload=True)
146
+ raw.set_montage(montage)
147
+
148
+ print(f" Channels: {len(raw.ch_names)}")
149
+ print(f" Sampling rate: {raw.info['sfreq']} Hz")
150
+ print(f" Duration: {raw.times[-1]:.1f} sec")
151
+
152
+ # バンドパスフィルタ
153
+ raw.filter(l_freq=l_freq, h_freq=h_freq, fir_design="firwin")
154
+
155
+ # ICA アーティファクト除去
156
+ ica = mne.preprocessing.ICA(n_components=20, random_state=42)
157
+ ica.fit(raw)
158
+
159
+ # EOG/ECG コンポーネント自動検出
160
+ eog_indices, eog_scores = ica.find_bads_eog(raw)
161
+ ica.exclude = eog_indices
162
+ raw_clean = ica.apply(raw.copy())
163
+
164
+ print(f" ICA components excluded: {len(eog_indices)} (EOG artifacts)")
165
+
166
+ # 平均参照
167
+ raw_clean.set_eeg_reference("average")
168
+
169
+ return raw_clean
170
+
171
+
172
+ def eeg_erp_analysis(raw, events, event_id, tmin=-0.2, tmax=0.8,
173
+ baseline=(-0.2, 0)):
174
+ """
175
+ 事象関連電位 (ERP) 解析。
176
+
177
+ Parameters:
178
+ events: MNE events 配列
179
+ event_id: イベント辞書 (e.g., {"target": 1, "standard": 2})
180
+ """
181
+ epochs = mne.Epochs(raw, events, event_id,
182
+ tmin=tmin, tmax=tmax,
183
+ baseline=baseline,
184
+ reject=dict(eeg=100e-6),
185
+ preload=True)
186
+
187
+ print(f" Epochs: {len(epochs)} / {len(events)} (after rejection)")
188
+
189
+ evokeds = {}
190
+ for condition in event_id:
191
+ evoked = epochs[condition].average()
192
+ evokeds[condition] = evoked
193
+
194
+ # ピーク検出
195
+ ch_name, latency, amplitude = evoked.get_peak(
196
+ ch_type="eeg", tmin=0.05, tmax=0.5
197
+ )
198
+ print(f" {condition}: peak at {latency*1000:.0f} ms, "
199
+ f"{amplitude*1e6:.1f} µV ({ch_name})")
200
+
201
+ return epochs, evokeds
202
+
203
+
204
+ def eeg_microstate_analysis(raw, n_states=4):
205
+ """
206
+ EEG マイクロステート解析。
207
+
208
+ 脳の準安定状態 (4-7 マイクロステート A-G) を GFP ピークから同定。
209
+ 各マイクロステートの出現頻度・持続時間・遷移確率を算出。
210
+ """
211
+ from sklearn.cluster import KMeans
212
+
213
+ # GFP (Global Field Power) 計算
214
+ data = raw.get_data(picks="eeg")
215
+ gfp = np.std(data, axis=0)
216
+
217
+ # GFP ピーク抽出
218
+ from scipy.signal import find_peaks
219
+ peaks, _ = find_peaks(gfp, height=np.percentile(gfp, 50))
220
+
221
+ # K-means クラスタリング
222
+ peak_maps = data[:, peaks].T
223
+ kmeans = KMeans(n_clusters=n_states, random_state=42, n_init=50)
224
+ labels = kmeans.fit_predict(peak_maps)
225
+
226
+ # 各マイクロステートの統計
227
+ print(f" Microstate analysis ({n_states} states):")
228
+ for i in range(n_states):
229
+ ms_label = chr(65 + i) # A, B, C, D, ...
230
+ count = np.sum(labels == i)
231
+ pct = count / len(labels)
232
+ print(f" State {ms_label}: {pct:.1%} occurrence")
233
+
234
+ return kmeans, labels
235
+ ```
236
+
237
+ ## 3. ECG 心拍変動解析 (NeuroKit2)
238
+
239
+ ```python
240
+ import numpy as np
241
+ import pandas as pd
242
+ import neurokit2 as nk
243
+
244
+
245
+ def ecg_hrv_analysis(ecg_signal, sampling_rate=1000):
246
+ """
247
+ ECG からの心拍変動 (HRV) 解析パイプライン。
248
+
249
+ 1. R ピーク検出
250
+ 2. RR 間隔算出
251
+ 3. 時間領域 HRV (SDNN, RMSSD, pNN50)
252
+ 4. 周波数領域 HRV (VLF, LF, HF, LF/HF 比)
253
+ 5. 非線形 HRV (SD1, SD2, ApEn, SampEn)
254
+ """
255
+ # ECG 前処理 + R ピーク検出
256
+ ecg_cleaned = nk.ecg_clean(ecg_signal, sampling_rate=sampling_rate)
257
+ signals, info = nk.ecg_process(ecg_cleaned, sampling_rate=sampling_rate)
258
+
259
+ r_peaks = info["ECG_R_Peaks"]
260
+ print(f" R-peaks detected: {len(r_peaks)}")
261
+ print(f" Mean HR: {signals['ECG_Rate'].mean():.1f} bpm")
262
+
263
+ # HRV 解析 (時間 + 周波数 + 非線形)
264
+ hrv_time = nk.hrv_time(signals, sampling_rate=sampling_rate)
265
+ hrv_freq = nk.hrv_frequency(signals, sampling_rate=sampling_rate)
266
+ hrv_nonlinear = nk.hrv_nonlinear(signals, sampling_rate=sampling_rate)
267
+
268
+ hrv_results = pd.concat([hrv_time, hrv_freq, hrv_nonlinear], axis=1)
269
+
270
+ print(f" Time-domain HRV:")
271
+ print(f" SDNN: {hrv_results['HRV_SDNN'].values[0]:.1f} ms")
272
+ print(f" RMSSD: {hrv_results['HRV_RMSSD'].values[0]:.1f} ms")
273
+ print(f" pNN50: {hrv_results['HRV_pNN50'].values[0]:.1f}%")
274
+ print(f" Frequency-domain HRV:")
275
+ print(f" LF/HF ratio: {hrv_results['HRV_LFHF'].values[0]:.2f}")
276
+
277
+ return hrv_results, signals
278
+
279
+
280
+ def eda_sympathetic_analysis(eda_signal, sampling_rate=1000):
281
+ """
282
+ EDA (皮膚電気活動) 解析 — 交感神経系応答。
283
+
284
+ 1. トニック成分 (Skin Conductance Level, SCL) 分離
285
+ 2. ファジック成分 (Skin Conductance Response, SCR) 検出
286
+ 3. SCR ピーク振幅・潜時・回復時間
287
+ """
288
+ eda_cleaned = nk.eda_clean(eda_signal, sampling_rate=sampling_rate)
289
+ signals, info = nk.eda_process(eda_cleaned, sampling_rate=sampling_rate)
290
+
291
+ scr_peaks = info["SCR_Peaks"]
292
+ print(f" SCR peaks detected: {len(scr_peaks)}")
293
+ print(f" Mean SCL (tonic): {signals['EDA_Tonic'].mean():.3f} µS")
294
+ if len(scr_peaks) > 0:
295
+ print(f" Mean SCR amplitude: {signals['SCR_Amplitude'].dropna().mean():.3f} µS")
296
+
297
+ return signals, info
298
+ ```
299
+
300
+ ## 4. 脳機能結合性解析
301
+
302
+ ```python
303
+ import numpy as np
304
+ import pandas as pd
305
+
306
+
307
+ def functional_connectivity(epochs, method="wpli2_debiased",
308
+ fmin=8, fmax=13):
309
+ """
310
+ EEG/MEG 脳機能的結合性の推定。
311
+
312
+ Methods:
313
+ - coh: Coherence
314
+ - imcoh: Imaginary Coherence
315
+ - plv: Phase Locking Value
316
+ - wpli: Weighted Phase Lag Index
317
+ - wpli2_debiased: Debiased Squared WPLI (推奨)
318
+ """
319
+ from mne_connectivity import spectral_connectivity_epochs
320
+
321
+ con = spectral_connectivity_epochs(
322
+ epochs, method=method,
323
+ fmin=fmin, fmax=fmax,
324
+ faverage=True, n_jobs=-1
325
+ )
326
+
327
+ conn_matrix = con.get_data(output="dense")[:, :, 0]
328
+
329
+ print(f" Connectivity method: {method}")
330
+ print(f" Frequency band: {fmin}-{fmax} Hz")
331
+ print(f" Matrix shape: {conn_matrix.shape}")
332
+ print(f" Mean connectivity: {np.mean(conn_matrix[np.triu_indices_from(conn_matrix, k=1)]):.3f}")
333
+
334
+ return conn_matrix, con
335
+
336
+
337
+ def graph_theory_brain_network(conn_matrix, ch_names, threshold=0.3):
338
+ """
339
+ 脳ネットワークのグラフ理論的解析。
340
+
341
+ - Global efficiency
342
+ - Clustering coefficient
343
+ - Small-world index
344
+ - Hub 同定 (degree centrality)
345
+ """
346
+ import networkx as nx
347
+
348
+ n = conn_matrix.shape[0]
349
+ G = nx.Graph()
350
+ for i in range(n):
351
+ G.add_node(ch_names[i])
352
+ for j in range(i + 1, n):
353
+ if conn_matrix[i, j] > threshold:
354
+ G.add_edge(ch_names[i], ch_names[j],
355
+ weight=conn_matrix[i, j])
356
+
357
+ # グラフ指標
358
+ eff = nx.global_efficiency(G)
359
+ cc = nx.average_clustering(G, weight="weight")
360
+ degree = dict(G.degree(weight="weight"))
361
+ top_hubs = sorted(degree.items(), key=lambda x: x[1], reverse=True)[:5]
362
+
363
+ print(f" Brain network: {G.number_of_nodes()} nodes, {G.number_of_edges()} edges")
364
+ print(f" Global efficiency: {eff:.3f}")
365
+ print(f" Clustering coefficient: {cc:.3f}")
366
+ print(f" Top hubs: {[h[0] for h in top_hubs]}")
367
+
368
+ return G
369
+ ```
370
+
371
+ ## References
372
+
373
+ ### Output Files
374
+
375
+ | ファイル | 形式 |
376
+ |---|---|
377
+ | `results/spike_sorting/sorting_results.npz` | NPZ |
378
+ | `results/spike_sorting/quality_metrics.csv` | CSV |
379
+ | `results/eeg/erp_evokeds.fif` | FIF |
380
+ | `results/eeg/microstates.csv` | CSV |
381
+ | `results/ecg/hrv_results.csv` | CSV |
382
+ | `results/eda/scr_peaks.csv` | CSV |
383
+ | `results/connectivity/conn_matrix.csv` | CSV |
384
+ | `figures/spike_rasters.png` | PNG |
385
+ | `figures/erp_waveforms.png` | PNG |
386
+ | `figures/hrv_poincare.png` | PNG |
387
+
388
+ ### 参照スキル
389
+
390
+ | スキル | 関連 |
391
+ |---|---|
392
+ | `scientific-biosignal-processing` | 汎用生体信号処理 |
393
+ | `scientific-spectral-signal` | スペクトル・周波数解析 |
394
+ | `scientific-time-series` | 時系列分解・予測 |
395
+ | `scientific-network-analysis` | グラフ理論・ネットワーク指標 |
396
+ | `scientific-deep-learning` | DL ベーススパイク分類 |
397
+
398
+ ### 依存パッケージ
399
+
400
+ `spikeinterface`, `mne`, `mne-connectivity`, `neurokit2`, `numpy`, `pandas`, `scipy`, `scikit-learn`, `networkx`