@yibeichan/claude-skills 1.0.2

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 (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/cli.js +272 -0
  4. package/install.py +240 -0
  5. package/package.json +44 -0
  6. package/skills/bidsapp-nidm-standards/SKILL.md +202 -0
  7. package/skills/bidsapp-nidm-standards/references/babs_config.md +20 -0
  8. package/skills/bidsapp-nidm-standards/references/cli_arguments.md +76 -0
  9. package/skills/bidsapp-nidm-standards/references/container_patterns.md +53 -0
  10. package/skills/bidsapp-nidm-standards/references/nidm_integration.md +403 -0
  11. package/skills/bidsapp-nidm-standards/references/repo_structure.md +121 -0
  12. package/skills/bidsapp-nidm-standards/references/testing_patterns.md +82 -0
  13. package/skills/dicom2fmriprep/SKILL.md +377 -0
  14. package/skills/dicom2fmriprep/evals/evals.json +26 -0
  15. package/skills/dicom2fmriprep/references/babs-details.md +407 -0
  16. package/skills/dicom2fmriprep/references/fmriprep-details.md +250 -0
  17. package/skills/dicom2fmriprep/references/heudiconv-details.md +243 -0
  18. package/skills/fmri-ssm/SKILL.md +317 -0
  19. package/skills/fmri-ssm/references/code_templates.md +1570 -0
  20. package/skills/fmri-ssm/references/downstream_analysis.md +680 -0
  21. package/skills/fmri-ssm/references/group_inference.md +608 -0
  22. package/skills/fmri-ssm/references/hrf_modeling.md +447 -0
  23. package/skills/fmri-ssm/references/model_catalog.md +436 -0
  24. package/skills/fmri-ssm/references/paradigm_guide.md +406 -0
  25. package/skills/fmri-ssm/references/preprocessing.md +614 -0
  26. package/skills/fmri-ssm.zip +0 -0
  27. package/skills/neuroimaging-qc/SKILL.md +203 -0
  28. package/skills/neuroimaging-qc/references/eeg_qc.md +400 -0
  29. package/skills/neuroimaging-qc/references/fmri_qc.md +343 -0
  30. package/skills/neuroimaging-qc/references/fnirs_qc.md +430 -0
  31. package/skills/neuroimaging-qc/references/structural_qc.md +454 -0
  32. package/skills/neuroimaging-qc/scripts/parse_fmriprep_confounds.py +153 -0
  33. package/skills/neuroimaging-qc/scripts/parse_mriqc.py +114 -0
  34. package/skills/neuroimaging-qc/scripts/qc_report.py +295 -0
  35. package/skills/scientific-writer/SKILL.md +202 -0
  36. package/skills/scientific-writer/references/citation_styles.md +163 -0
  37. package/skills/scientific-writer/references/field_conventions.md +245 -0
  38. package/skills/scientific-writer/references/figures_tables.md +225 -0
  39. package/skills/scientific-writer/references/reporting_guidelines.md +225 -0
  40. package/skills.json +54 -0
@@ -0,0 +1,447 @@
1
+ # HRF Modeling for State-Space Models in fMRI
2
+
3
+ ## Table of Contents
4
+ 1. [The HRF Problem for SSMs](#the-problem)
5
+ 2. [Approach 1: Fit on BOLD Directly (No Deconvolution)](#bold-direct)
6
+ 3. [Approach 2: Deconvolve First, Then Fit SSM](#deconvolve-first)
7
+ 4. [Approach 3: HRF-Informed State Constraints](#hrf-constraints)
8
+ 5. [Approach 4: Joint HRF-State Estimation](#joint-estimation)
9
+ 6. [Approach 5: Temporal Basis Sets Within the SSM](#basis-sets)
10
+ 7. [Decision Framework](#decision-framework)
11
+ 8. [HRF Variability Across Regions and Subjects](#hrf-variability)
12
+ 9. [Interaction with TR and Temporal Resolution](#tr-effects)
13
+
14
+ ---
15
+
16
+ ## 1. The HRF Problem for SSMs {#the-problem}
17
+
18
+ The BOLD signal y(t) is approximately the convolution of underlying neural activity s(t)
19
+ with the hemodynamic response function h(t), plus noise:
20
+
21
+ y(t) = (s * h)(t) + ε(t) = ∫ s(τ) h(t - τ) dτ + ε(t)
22
+
23
+ The canonical HRF (double-gamma function) has these key properties:
24
+ - **Onset delay**: ~1-2 seconds after neural event
25
+ - **Peak**: ~5-6 seconds after neural event
26
+ - **Undershoot**: negative deflection at ~10-15 seconds
27
+ - **Total duration**: ~25-30 seconds, but main response is within 0-15 seconds
28
+ - **Temporal smoothing**: acts as a low-pass filter, attenuating high-frequency neural dynamics
29
+
30
+ **Impact on SSMs:**
31
+
32
+ For a discrete state sequence z_1, z_2, ..., z_T at the neural level:
33
+ - States shorter than ~5 seconds will not produce a full BOLD response before the next state begins
34
+ - Rapid state transitions appear as gradual BOLD transitions (ramp-up/ramp-down artifacts)
35
+ - True neural state boundaries are blurred by ~4-6 seconds in the BOLD signal
36
+ - An SSM fitted to BOLD will recover BOLD-level states, not neural-level states
37
+
38
+ This distinction is critical: **BOLD-level states ≠ neural-level states** unless states are
39
+ long enough that the HRF fully resolves between transitions (roughly >15 seconds).
40
+
41
+ For many analyses, BOLD-level states are perfectly fine — they capture recurring patterns in
42
+ the observed signal. But if you need to make claims about neural state timing (e.g., "the brain
43
+ enters state X exactly when the stimulus appears"), you must account for the HRF.
44
+
45
+ ---
46
+
47
+ ## 2. Approach 1: Fit on BOLD Directly {#bold-direct}
48
+
49
+ **When this is appropriate:**
50
+ - Resting-state analyses where you care about recurring BOLD patterns, not precise neural timing
51
+ - Block designs with long blocks (>15s) where HRF has time to reach steady state
52
+ - Analyses where state definitions are spatial (FC patterns) rather than temporal
53
+ - Most exploratory analyses as a first pass
54
+
55
+ **How to implement:**
56
+ Simply fit the SSM on the preprocessed BOLD timeseries. No special handling needed.
57
+
58
+ **Interpretation caveats:**
59
+ - State onset times are delayed by ~5s relative to neural events
60
+ - State durations in the Viterbi path include HRF onset/offset ramps
61
+ - Very short states (1-3 TRs) may reflect HRF transition periods, not true neural states
62
+ - Dwell time distributions will be biased toward longer durations due to HRF smoothing
63
+
64
+ **When this goes wrong:**
65
+ - Event-related designs with short ITIs (2-4s): successive events overlap in the BOLD response,
66
+ creating a complex mixture that does not cleanly correspond to discrete states
67
+ - Rapid state-switching paradigms: the HRF acts as a low-pass filter, attenuating the very
68
+ signal you're trying to detect
69
+ - When making precise temporal claims: "state X onsets 200ms before the button press"
70
+
71
+ ```python
72
+ # No special HRF handling — just fit on preprocessed BOLD
73
+ from hmmlearn import hmm
74
+
75
+ model = hmm.GaussianHMM(n_components=K, covariance_type='full', n_iter=200)
76
+ model.fit(bold_timeseries) # shape: (T, n_features)
77
+ states = model.predict(bold_timeseries)
78
+ ```
79
+
80
+ ---
81
+
82
+ ## 3. Approach 2: Deconvolve First, Then Fit SSM {#deconvolve-first}
83
+
84
+ The idea: undo the HRF convolution to recover an estimate of neural-level activity, then fit
85
+ the SSM on the deconvolved signal.
86
+
87
+ ### 3a. Wiener Deconvolution
88
+
89
+ Operates in the frequency domain. Divides the signal spectrum by the HRF spectrum, with
90
+ regularization to avoid amplifying noise at frequencies where the HRF has low power.
91
+
92
+ **Pros:** Fast, simple, works region-by-region
93
+ **Cons:** Assumes stationary HRF, amplifies high-frequency noise, assumes global HRF shape
94
+
95
+ ```python
96
+ import numpy as np
97
+ from scipy.signal import fftconvolve
98
+ from nilearn.glm.first_level import spm_hrf
99
+
100
+ def wiener_deconvolve(bold, tr, snr=5.0):
101
+ """Wiener deconvolution of BOLD signal to estimate neural activity.
102
+
103
+ Parameters
104
+ ----------
105
+ bold : array, shape (T, n_features)
106
+ Preprocessed BOLD timeseries
107
+ tr : float
108
+ Repetition time in seconds
109
+ snr : float
110
+ Assumed signal-to-noise ratio (regularization). Higher = less regularization.
111
+ Typical range: 2-10. Start with 5.
112
+
113
+ Returns
114
+ -------
115
+ neural_est : array, shape (T, n_features)
116
+ Estimated neural-level timeseries
117
+ """
118
+ T, p = bold.shape
119
+
120
+ # Generate canonical HRF sampled at TR
121
+ hrf_duration = 32 # seconds
122
+ hrf_times = np.arange(0, hrf_duration, tr)
123
+ hrf = spm_hrf(tr, oversampling=1)
124
+ # spm_hrf may return fewer or more points than hrf_times — clip to consistent length
125
+ n_hrf = len(hrf_times)
126
+ if len(hrf) >= n_hrf:
127
+ hrf = hrf[:n_hrf]
128
+ else:
129
+ # Pad with zeros if spm_hrf is shorter than hrf_times (e.g., very long TR)
130
+ hrf = np.pad(hrf, (0, n_hrf - len(hrf)))
131
+
132
+ # Zero-pad HRF to match signal length
133
+ hrf_padded = np.zeros(T)
134
+ hrf_padded[:len(hrf)] = hrf
135
+
136
+ # Frequency domain
137
+ H = np.fft.fft(hrf_padded)
138
+ H_conj = np.conj(H)
139
+
140
+ # Wiener filter: H* / (|H|^2 + 1/SNR^2)
141
+ wiener = H_conj / (np.abs(H)**2 + 1.0 / snr**2)
142
+
143
+ neural_est = np.zeros_like(bold)
144
+ for i in range(p):
145
+ Y = np.fft.fft(bold[:, i])
146
+ S_est = Y * wiener
147
+ neural_est[:, i] = np.real(np.fft.ifft(S_est))
148
+
149
+ return neural_est
150
+
151
+ # Usage:
152
+ neural_timeseries = wiener_deconvolve(bold_timeseries, tr=0.8, snr=5.0)
153
+ model = hmm.GaussianHMM(n_components=K, covariance_type='full', n_iter=200)
154
+ model.fit(neural_timeseries)
155
+ ```
156
+
157
+ ### 3b. FIR (Finite Impulse Response) Deconvolution
158
+
159
+ Estimates the response at each time point relative to events using a set of time-lagged
160
+ regressors. Model-free — makes no assumptions about HRF shape.
161
+
162
+ **Pros:** Does not assume HRF shape, handles variable HRF across regions
163
+ **Cons:** Requires event timing (not applicable to resting state), very noisy estimates,
164
+ needs many events for stable estimation
165
+
166
+ ```python
167
+ import numpy as np
168
+ from nilearn.glm.first_level import FirstLevelModel
169
+
170
+ def fir_deconvolve(bold_img, events_df, tr, fir_delays=range(0, 20)):
171
+ """FIR deconvolution using nilearn.
172
+
173
+ Use this when you have task event timing and want to estimate
174
+ neural-level activity without assuming an HRF shape.
175
+
176
+ Parameters
177
+ ----------
178
+ bold_img : Nifti image
179
+ 4D BOLD image
180
+ events_df : DataFrame
181
+ Columns: onset, duration, trial_type
182
+ tr : float
183
+ Repetition time
184
+ fir_delays : range
185
+ FIR delays in scans. range(0, 20) covers 0 to 20×TR seconds.
186
+
187
+ Returns
188
+ -------
189
+ residuals : array
190
+ Residual timeseries after removing task-evoked response
191
+ """
192
+ fir_model = FirstLevelModel(
193
+ t_r=tr,
194
+ hrf_model='fir',
195
+ fir_delays=list(fir_delays),
196
+ drift_model='cosine',
197
+ high_pass=0.01,
198
+ )
199
+ fir_model.fit(bold_img, events=events_df)
200
+
201
+ # Extract masked BOLD data and design matrix
202
+ bold_data = fir_model.masker_.transform(bold_img) # (T, n_voxels)
203
+ design_mat = fir_model.design_matrices_[0].values # (T, n_regressors)
204
+ n_regressors = design_mat.shape[1]
205
+
206
+ # Reconstruct fitted values: design_matrix @ beta_estimates per regressor
207
+ # (FirstLevelModel has no .predicted attribute — we compute it manually)
208
+ beta_maps = np.zeros((n_regressors, bold_data.shape[1]))
209
+ for i in range(n_regressors):
210
+ contrast = np.zeros(n_regressors)
211
+ contrast[i] = 1.0
212
+ # output_type='effect_size' returns the beta estimate (not t- or z-stat)
213
+ beta_img = fir_model.compute_contrast(contrast, output_type='effect_size')
214
+ beta_maps[i] = beta_img.get_fdata().ravel()[:bold_data.shape[1]]
215
+
216
+ fitted = design_mat @ beta_maps # (T, n_voxels)
217
+ residuals = bold_data - fitted # non-task-evoked dynamics
218
+
219
+ return residuals
220
+ ```
221
+
222
+ ### 3c. Semi-blind Deconvolution (Paradigm-Free Mapping)
223
+
224
+ Estimates both neural events and HRF jointly from the BOLD signal without task timing.
225
+ Originally proposed by Caballero Gaudes et al. Uses sparsity-promoting priors on neural events.
226
+
227
+ **Pros:** Works without event timing (applicable to resting state), data-driven
228
+ **Cons:** Computationally expensive, requires tuning of sparsity parameter, assumes
229
+ neural events are sparse (may not be appropriate for sustained states)
230
+
231
+ This approach is more research-oriented. Consider using it if:
232
+ - You have resting-state data but want neural-level timing
233
+ - You have strong reason to believe neural states produce sparse, punctate events
234
+
235
+ ---
236
+
237
+ ## 4. Approach 3: HRF-Informed State Constraints {#hrf-constraints}
238
+
239
+ For task paradigms, you know when events occur. You can use this knowledge to inform the SSM
240
+ without full deconvolution.
241
+
242
+ ### 3a. Initialize states from HRF-shifted task timing
243
+
244
+ Shift task onsets by the HRF peak delay (~5-6s) and use these shifted onsets to initialize
245
+ the state sequence before fitting.
246
+
247
+ ```python
248
+ import numpy as np
249
+
250
+ def task_informed_init(events_df, n_trs, tr, hrf_peak_delay=5.5, n_states=None,
251
+ hrf_spread_s=4.0):
252
+ """Initialize HMM state sequence from task events, shifted by HRF delay.
253
+
254
+ Parameters
255
+ ----------
256
+ events_df : DataFrame
257
+ Columns: onset (seconds), duration (seconds), trial_type
258
+ n_trs : int
259
+ Total number of TRs
260
+ tr : float
261
+ Repetition time in seconds
262
+ hrf_peak_delay : float
263
+ Assumed HRF peak delay in seconds
264
+ n_states : int or None
265
+ Number of states. If None, infer from number of unique trial_types + 1 (baseline)
266
+ hrf_spread_s : float
267
+ Extra seconds to extend each state window beyond the event duration, accounting
268
+ for HRF onset/offset ramps. Default 4.0 seconds (≈ 1 TR at TR=2s, or 2 TRs at TR=2s).
269
+
270
+ Returns
271
+ -------
272
+ init_states : array, shape (n_trs,)
273
+ Initial state labels for each TR
274
+ """
275
+ trial_types = sorted(events_df['trial_type'].unique())
276
+ if n_states is None:
277
+ n_states = len(trial_types) + 1 # +1 for baseline/rest state
278
+
279
+ type_to_state = {tt: i + 1 for i, tt in enumerate(trial_types)}
280
+
281
+ init_states = np.zeros(n_trs, dtype=int) # 0 = baseline
282
+
283
+ for _, event in events_df.iterrows():
284
+ onset_tr = int(np.round((event['onset'] + hrf_peak_delay) / tr))
285
+ duration_trs = max(1, int(np.round(event['duration'] / tr)))
286
+
287
+ # Account for HRF spreading: extend state by ~2 TRs for rise/fall
288
+ start_tr = max(0, onset_tr)
289
+ end_tr = min(n_trs, onset_tr + duration_trs + int(np.round(hrf_spread_s / tr)))
290
+
291
+ state_label = type_to_state.get(event['trial_type'], 0)
292
+ init_states[start_tr:end_tr] = state_label
293
+
294
+ return init_states
295
+ ```
296
+
297
+ ### 3b. Constrain transition probabilities using task structure
298
+
299
+ For block designs, you know approximately when state transitions should occur. Encode this
300
+ as informative priors on the transition matrix or by segmenting the data.
301
+
302
+ ---
303
+
304
+ ## 5. Approach 4: Joint HRF-State Estimation {#joint-estimation}
305
+
306
+ The most principled but most complex approach: estimate the HRF and the state sequence
307
+ simultaneously within a unified generative model.
308
+
309
+ **Model structure:**
310
+ - Neural state sequence: z_t^{neural} (at sub-TR resolution if needed)
311
+ - State-specific neural activity: s_t = μ_{z_t^{neural}}
312
+ - HRF convolution: BOLD_t = Σ_τ s_{t-τ} × h(τ)
313
+ - Observation: y_t ~ N(BOLD_t, Σ)
314
+
315
+ This requires either:
316
+ 1. Parametric HRF (e.g., double-gamma with free peak time, width) estimated jointly
317
+ 2. Semi-parametric HRF (basis set with estimated coefficients)
318
+ 3. Nonparametric HRF estimated via regularized deconvolution within the EM loop
319
+
320
+ **Existing implementations:**
321
+ - Limited off-the-shelf options. Most published work uses custom implementations.
322
+ - The `ssm` library can be extended to include HRF convolution in the emission model.
323
+ - Wu et al. (2021, NeuroImage) proposed a variational approach for HMM with HRF.
324
+
325
+ **When to consider this:**
326
+ - When precise neural-level state timing is the primary research question
327
+ - When you have evidence that HRF varies substantially across states (e.g., different
328
+ brain regions have different HRFs)
329
+ - When simpler approaches (deconvolve-then-fit or fit-on-BOLD) give unsatisfying results
330
+
331
+ **Practical recommendation:**
332
+ Unless you have strong methodological expertise, start with simpler approaches (1 or 2)
333
+ and only move to joint estimation if there's clear evidence it's needed.
334
+
335
+ ---
336
+
337
+ ## 6. Approach 5: Temporal Basis Sets Within the SSM {#basis-sets}
338
+
339
+ Instead of a single HRF, use a set of basis functions to flexibly capture the hemodynamic
340
+ response within the SSM framework.
341
+
342
+ **Common basis sets:**
343
+ - **Canonical + temporal derivative + dispersion derivative** (SPM's 3-parameter set):
344
+ Captures variations in HRF peak time and width
345
+ - **FIR basis set**: Completely flexible, no shape assumptions, but many parameters
346
+ - **Fourier basis set**: Captures the HRF in frequency domain
347
+ - **FLOBS (FMRIB's Linear Optimal Basis Set)**: Data-driven basis from a large HRF library
348
+
349
+ **How to integrate with SSM:**
350
+ The emission model becomes: y_t | z_t=k ~ N(Σ_b β_k^{(b)} × h_b(t), Σ_k)
351
+ where h_b(t) are basis functions and β_k^{(b)} are state-specific weights on each basis.
352
+
353
+ This is an intermediate approach between "ignore HRF" and "joint estimation" — it
354
+ acknowledges HRF variability without full deconvolution.
355
+
356
+ ---
357
+
358
+ ## 7. Decision Framework {#decision-framework}
359
+
360
+ Use this flowchart to pick your HRF strategy:
361
+
362
+ ```
363
+ START
364
+
365
+ ├── Is this resting-state data?
366
+ │ ├── YES → Are you interested in neural-level timing?
367
+ │ │ ├── NO → Approach 1 (fit on BOLD directly)
368
+ │ │ └── YES → Approach 2c (semi-blind deconvolution)
369
+ │ │ or Approach 1 with careful interpretation
370
+ │ │
371
+ │ └── NO → Continue...
372
+
373
+ ├── Is this task-based data?
374
+ │ ├── Block design (blocks > 15s)?
375
+ │ │ └── Approach 1 (BOLD direct) is usually fine
376
+ │ │ Optionally use Approach 3a for initialization
377
+ │ │
378
+ │ ├── Event-related design?
379
+ │ │ ├── Do you need neural-level state timing?
380
+ │ │ │ ├── YES → Approach 2a (Wiener) or 2b (FIR) + SSM
381
+ │ │ │ │ or Approach 4 (joint) if you have expertise
382
+ │ │ │ └── NO → Approach 1 + Approach 3a for initialization
383
+ │ │ │
384
+ │ │ └── Are events closely spaced (ITI < 4s)?
385
+ │ │ └── YES → Approach 2 (deconvolve) is strongly recommended
386
+ │ │ Overlapping HRFs create complex BOLD patterns
387
+ │ │
388
+ │ └── Mixed design? → Treat like event-related (more conservative)
389
+
390
+ └── Is this naturalistic data?
391
+ ├── Continuous stimulation (no discrete events)?
392
+ │ └── Approach 1 (BOLD direct) — states will be BOLD-level
393
+ │ This is the standard approach for movie-watching HMMs
394
+
395
+ └── Annotated events available (scene cuts, speech onset)?
396
+ └── Approach 3a with scene/event annotations
397
+ or Approach 1 if temporal precision isn't critical
398
+ ```
399
+
400
+ ---
401
+
402
+ ## 8. HRF Variability Across Regions and Subjects {#hrf-variability}
403
+
404
+ The canonical HRF is an average — real HRFs vary:
405
+
406
+ **Across brain regions:**
407
+ - Visual cortex: faster HRF (peak ~4-5s)
408
+ - Prefrontal cortex: slower HRF (peak ~6-7s)
409
+ - Subcortical structures: variable, often faster
410
+ - This means the same neural event appears at different times in different regions'
411
+ BOLD signals, which can create artifactual lead-lag relationships
412
+
413
+ **Across subjects:**
414
+ - Peak time varies by ~1-2 seconds across healthy adults
415
+ - Width varies by ~1-3 seconds
416
+ - Older adults tend to have slower, broader HRFs
417
+ - Clinical populations (stroke, TBI) may have severely altered hemodynamics
418
+
419
+ **Implications for SSMs:**
420
+ - Regional HRF variability can create spurious state definitions — a "state" might
421
+ simply reflect the HRF catching up in slow regions
422
+ - If using deconvolution, consider region-specific HRFs (estimate HRF per ROI from
423
+ task data, or use published region-specific parameters)
424
+ - SLDS may be more robust to HRF variability than HMM because the continuous latent
425
+ dynamics can absorb some of the temporal smoothing
426
+
427
+ ---
428
+
429
+ ## 9. Interaction with TR and Temporal Resolution {#tr-effects}
430
+
431
+ **Fast TR (< 1s, e.g., multiband):**
432
+ - Better temporal resolution to resolve HRF shape
433
+ - Deconvolution is more effective and stable
434
+ - But: also picks up more physiological noise (cardiac, respiratory)
435
+ - States can be shorter in TR-units, giving more temporal precision
436
+ - Consider higher AR orders in HMM-MAR to capture the richer temporal structure
437
+
438
+ **Standard TR (1-2s):**
439
+ - Most validated TR range for SSM-fMRI literature
440
+ - HRF is reasonably sampled (3-6 points across the main response)
441
+ - Standard deconvolution approaches work well
442
+
443
+ **Slow TR (> 2.5s):**
444
+ - HRF is poorly sampled — deconvolution is unreliable
445
+ - Approach 1 (fit on BOLD directly) is usually the only practical option
446
+ - Minimum state duration is effectively 2-3 TRs (5-7.5+ seconds)
447
+ - Older datasets with slow TRs are less suitable for fine-grained state analysis