@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.
- package/LICENSE +21 -0
- package/README.md +98 -0
- package/cli.js +272 -0
- package/install.py +240 -0
- package/package.json +44 -0
- package/skills/bidsapp-nidm-standards/SKILL.md +202 -0
- package/skills/bidsapp-nidm-standards/references/babs_config.md +20 -0
- package/skills/bidsapp-nidm-standards/references/cli_arguments.md +76 -0
- package/skills/bidsapp-nidm-standards/references/container_patterns.md +53 -0
- package/skills/bidsapp-nidm-standards/references/nidm_integration.md +403 -0
- package/skills/bidsapp-nidm-standards/references/repo_structure.md +121 -0
- package/skills/bidsapp-nidm-standards/references/testing_patterns.md +82 -0
- package/skills/dicom2fmriprep/SKILL.md +377 -0
- package/skills/dicom2fmriprep/evals/evals.json +26 -0
- package/skills/dicom2fmriprep/references/babs-details.md +407 -0
- package/skills/dicom2fmriprep/references/fmriprep-details.md +250 -0
- package/skills/dicom2fmriprep/references/heudiconv-details.md +243 -0
- package/skills/fmri-ssm/SKILL.md +317 -0
- package/skills/fmri-ssm/references/code_templates.md +1570 -0
- package/skills/fmri-ssm/references/downstream_analysis.md +680 -0
- package/skills/fmri-ssm/references/group_inference.md +608 -0
- package/skills/fmri-ssm/references/hrf_modeling.md +447 -0
- package/skills/fmri-ssm/references/model_catalog.md +436 -0
- package/skills/fmri-ssm/references/paradigm_guide.md +406 -0
- package/skills/fmri-ssm/references/preprocessing.md +614 -0
- package/skills/fmri-ssm.zip +0 -0
- package/skills/neuroimaging-qc/SKILL.md +203 -0
- package/skills/neuroimaging-qc/references/eeg_qc.md +400 -0
- package/skills/neuroimaging-qc/references/fmri_qc.md +343 -0
- package/skills/neuroimaging-qc/references/fnirs_qc.md +430 -0
- package/skills/neuroimaging-qc/references/structural_qc.md +454 -0
- package/skills/neuroimaging-qc/scripts/parse_fmriprep_confounds.py +153 -0
- package/skills/neuroimaging-qc/scripts/parse_mriqc.py +114 -0
- package/skills/neuroimaging-qc/scripts/qc_report.py +295 -0
- package/skills/scientific-writer/SKILL.md +202 -0
- package/skills/scientific-writer/references/citation_styles.md +163 -0
- package/skills/scientific-writer/references/field_conventions.md +245 -0
- package/skills/scientific-writer/references/figures_tables.md +225 -0
- package/skills/scientific-writer/references/reporting_guidelines.md +225 -0
- 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
|