@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,430 @@
|
|
|
1
|
+
# fNIRS QC Reference
|
|
2
|
+
|
|
3
|
+
Comprehensive guide for QC of functional near-infrared spectroscopy (fNIRS) data.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
1. [Signal Quality Metrics](#signal-quality-metrics)
|
|
7
|
+
2. [Channel-Level QC](#channel-level-qc)
|
|
8
|
+
3. [Motion Artifact Detection](#motion-artifact-detection)
|
|
9
|
+
4. [Subject-Level Exclusion](#subject-level-exclusion)
|
|
10
|
+
5. [Population Considerations](#population-considerations)
|
|
11
|
+
6. [Python Examples](#python-examples)
|
|
12
|
+
|
|
13
|
+
## Signal Quality Metrics
|
|
14
|
+
|
|
15
|
+
### Scalp Coupling Index (SCI)
|
|
16
|
+
|
|
17
|
+
**Definition**: Measure of optode-scalp coupling quality based on cardiac pulsation detection.
|
|
18
|
+
|
|
19
|
+
**Interpretation:**
|
|
20
|
+
- Range: 0-1 (higher = better coupling)
|
|
21
|
+
- Threshold: SCI > 0.7-0.8 typically acceptable
|
|
22
|
+
- Based on correlation between wavelengths at cardiac frequency
|
|
23
|
+
|
|
24
|
+
**Calculation principle:**
|
|
25
|
+
- Good coupling → visible cardiac pulsation in signal
|
|
26
|
+
- Poor coupling → no cardiac signal, likely hair/poor contact
|
|
27
|
+
|
|
28
|
+
### Peak Spectral Power (PSP)
|
|
29
|
+
|
|
30
|
+
**Definition**: Power at cardiac frequency relative to total power.
|
|
31
|
+
|
|
32
|
+
**Interpretation:**
|
|
33
|
+
- Higher values indicate clear cardiac signal (good coupling)
|
|
34
|
+
- Low PSP suggests poor signal quality
|
|
35
|
+
|
|
36
|
+
### Coefficient of Variation (CV)
|
|
37
|
+
|
|
38
|
+
**Definition**: Standard deviation / mean of raw signal intensity.
|
|
39
|
+
|
|
40
|
+
**Interpretation:**
|
|
41
|
+
- Low CV (<10%): Stable signal
|
|
42
|
+
- High CV (>10-15%): Variable signal, potential motion/coupling issues
|
|
43
|
+
|
|
44
|
+
### Signal-to-Noise Ratio (SNR)
|
|
45
|
+
|
|
46
|
+
**Calculation:**
|
|
47
|
+
```
|
|
48
|
+
SNR = mean(signal) / std(noise)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Interpretation:**
|
|
52
|
+
- Higher is better
|
|
53
|
+
- Compare across channels within subject
|
|
54
|
+
|
|
55
|
+
## Channel-Level QC
|
|
56
|
+
|
|
57
|
+
### Bad Channel Indicators
|
|
58
|
+
|
|
59
|
+
1. **Saturated signal**: Intensity at detector limit
|
|
60
|
+
2. **Zero/flat signal**: No light detected
|
|
61
|
+
3. **Excessive noise**: High variance unrelated to task
|
|
62
|
+
4. **Poor SCI**: SCI < 0.7
|
|
63
|
+
5. **Negative values**: After optical density conversion (physically impossible)
|
|
64
|
+
|
|
65
|
+
### Channel Rejection Criteria
|
|
66
|
+
|
|
67
|
+
| Metric | Reject Threshold | Notes |
|
|
68
|
+
|--------|-----------------|-------|
|
|
69
|
+
| SCI | < 0.7 | Coupling quality |
|
|
70
|
+
| CV | > 15% | Signal stability |
|
|
71
|
+
| Heart rate detectability | Not detected | Coupling validation |
|
|
72
|
+
| Negative OD values | Any | Data integrity |
|
|
73
|
+
| SNR | < sample mean - 2 SD | Relative quality |
|
|
74
|
+
|
|
75
|
+
### Maximum Acceptable Channel Loss
|
|
76
|
+
|
|
77
|
+
**Guidelines:**
|
|
78
|
+
- <20% of channels: Acceptable for most analyses
|
|
79
|
+
- 20-40%: Consider with caution, limit spatial inferences
|
|
80
|
+
- >40%: May need to exclude subject or use reduced channel set
|
|
81
|
+
|
|
82
|
+
## Motion Artifact Detection
|
|
83
|
+
|
|
84
|
+
### Motion Artifact Characteristics
|
|
85
|
+
|
|
86
|
+
- **Spikes**: Rapid, large amplitude changes
|
|
87
|
+
- **Baseline shifts**: Step changes in signal level
|
|
88
|
+
- **Slow drifts**: Gradual changes from optode movement
|
|
89
|
+
|
|
90
|
+
### Detection Methods
|
|
91
|
+
|
|
92
|
+
**1. Threshold-based:**
|
|
93
|
+
- Detect samples exceeding amplitude threshold
|
|
94
|
+
- Flag abrupt changes (derivative threshold)
|
|
95
|
+
|
|
96
|
+
**2. Moving window:**
|
|
97
|
+
- Calculate local statistics
|
|
98
|
+
- Flag windows with anomalous values
|
|
99
|
+
|
|
100
|
+
**3. Wavelet-based:**
|
|
101
|
+
- Decompose signal into frequency bands
|
|
102
|
+
- Identify motion-related components
|
|
103
|
+
|
|
104
|
+
### Correction Strategies
|
|
105
|
+
|
|
106
|
+
**1. Rejection:**
|
|
107
|
+
- Remove contaminated time segments
|
|
108
|
+
- Simple but loses data
|
|
109
|
+
|
|
110
|
+
**2. Spline interpolation:**
|
|
111
|
+
- Interpolate over short artifacts
|
|
112
|
+
- Preserves data length
|
|
113
|
+
|
|
114
|
+
**3. Wavelet filtering:**
|
|
115
|
+
- Remove motion-related wavelet components
|
|
116
|
+
- Preserves more data
|
|
117
|
+
|
|
118
|
+
**4. Principal Component Analysis (PCA):**
|
|
119
|
+
- Remove motion-related components
|
|
120
|
+
- Global artifact removal
|
|
121
|
+
|
|
122
|
+
**5. Targeted PCA / tPCA:**
|
|
123
|
+
- More targeted motion artifact removal
|
|
124
|
+
|
|
125
|
+
### Homer3 Motion Correction Functions
|
|
126
|
+
|
|
127
|
+
| Function | Description | Use Case |
|
|
128
|
+
|----------|-------------|----------|
|
|
129
|
+
| `hmrR_MotionArtifact` | Detect motion artifacts | Initial detection |
|
|
130
|
+
| `hmrR_MotionCorrectSpline` | Spline interpolation | Short artifacts |
|
|
131
|
+
| `hmrR_MotionCorrectWavelet` | Wavelet filtering | Broader correction |
|
|
132
|
+
| `hmrR_MotionCorrectPCArecurse` | Recursive PCA | Persistent artifacts |
|
|
133
|
+
|
|
134
|
+
## Subject-Level Exclusion
|
|
135
|
+
|
|
136
|
+
### Exclusion Criteria
|
|
137
|
+
|
|
138
|
+
**Quantitative:**
|
|
139
|
+
- >40% channels rejected
|
|
140
|
+
- >50% of data contaminated by motion
|
|
141
|
+
- Insufficient task trials after artifact rejection
|
|
142
|
+
- Technical failures (optode disconnection, recording errors)
|
|
143
|
+
|
|
144
|
+
**Qualitative:**
|
|
145
|
+
- Unable to achieve adequate optode placement (thick/dark hair)
|
|
146
|
+
- Persistent artifacts not correctable
|
|
147
|
+
- Subject non-compliance
|
|
148
|
+
|
|
149
|
+
### QC Checklist
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
□ Raw signal inspection (all channels)
|
|
153
|
+
□ Scalp coupling index check
|
|
154
|
+
□ Motion artifact detection
|
|
155
|
+
□ Channel pruning (bad channels removed)
|
|
156
|
+
□ Motion correction applied
|
|
157
|
+
□ Final signal quality assessment
|
|
158
|
+
□ Task-related segments verified
|
|
159
|
+
□ Hemodynamic response plausibility check
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Population Considerations
|
|
163
|
+
|
|
164
|
+
### Infants
|
|
165
|
+
|
|
166
|
+
**Unique considerations:**
|
|
167
|
+
- Different optode configurations (smaller head)
|
|
168
|
+
- More motion expected
|
|
169
|
+
- Hair less of an issue (less/finer hair)
|
|
170
|
+
- Different hemodynamic response characteristics
|
|
171
|
+
|
|
172
|
+
**Adjusted criteria:**
|
|
173
|
+
- More lenient motion thresholds
|
|
174
|
+
- Shorter usable segments acceptable
|
|
175
|
+
- Visual inspection critical
|
|
176
|
+
|
|
177
|
+
### Clinical Populations
|
|
178
|
+
|
|
179
|
+
**Considerations:**
|
|
180
|
+
- Altered hemodynamics (stroke, vascular disease)
|
|
181
|
+
- Medication effects
|
|
182
|
+
- Potential structural abnormalities affecting light propagation
|
|
183
|
+
- May have compliance challenges
|
|
184
|
+
|
|
185
|
+
## Python Examples (MNE-NIRS)
|
|
186
|
+
|
|
187
|
+
### Basic Signal Quality Check
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
import mne
|
|
191
|
+
import mne_nirs
|
|
192
|
+
import numpy as np
|
|
193
|
+
|
|
194
|
+
def check_fnirs_quality(raw):
|
|
195
|
+
"""
|
|
196
|
+
Basic fNIRS signal quality assessment.
|
|
197
|
+
"""
|
|
198
|
+
# Get data
|
|
199
|
+
data = raw.get_data()
|
|
200
|
+
|
|
201
|
+
qc_results = {
|
|
202
|
+
'n_channels': len(raw.ch_names),
|
|
203
|
+
'duration_sec': raw.times[-1],
|
|
204
|
+
'sfreq': raw.info['sfreq'],
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
# Calculate per-channel statistics
|
|
208
|
+
channel_stats = []
|
|
209
|
+
for i, ch_name in enumerate(raw.ch_names):
|
|
210
|
+
ch_data = data[i, :]
|
|
211
|
+
stats = {
|
|
212
|
+
'channel': ch_name,
|
|
213
|
+
'mean': np.mean(ch_data),
|
|
214
|
+
'std': np.std(ch_data),
|
|
215
|
+
'cv': np.std(ch_data) / np.abs(np.mean(ch_data)) * 100,
|
|
216
|
+
'min': np.min(ch_data),
|
|
217
|
+
'max': np.max(ch_data),
|
|
218
|
+
}
|
|
219
|
+
channel_stats.append(stats)
|
|
220
|
+
|
|
221
|
+
qc_results['channel_stats'] = channel_stats
|
|
222
|
+
|
|
223
|
+
return qc_results
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def calculate_sci(raw, cardiac_freq_range=(0.5, 2.5)):
|
|
227
|
+
"""
|
|
228
|
+
Calculate Scalp Coupling Index for fNIRS channels.
|
|
229
|
+
|
|
230
|
+
SCI based on correlation between wavelengths at cardiac frequency.
|
|
231
|
+
"""
|
|
232
|
+
from scipy import signal
|
|
233
|
+
|
|
234
|
+
# This is a simplified SCI calculation
|
|
235
|
+
# Full implementation would pair wavelengths by source-detector
|
|
236
|
+
|
|
237
|
+
sfreq = raw.info['sfreq']
|
|
238
|
+
data = raw.get_data()
|
|
239
|
+
|
|
240
|
+
sci_values = []
|
|
241
|
+
|
|
242
|
+
# For each channel, calculate cardiac power ratio
|
|
243
|
+
for i in range(data.shape[0]):
|
|
244
|
+
ch_data = data[i, :]
|
|
245
|
+
|
|
246
|
+
# Calculate PSD
|
|
247
|
+
freqs, psd = signal.welch(ch_data, fs=sfreq, nperseg=int(4*sfreq))
|
|
248
|
+
|
|
249
|
+
# Find cardiac band
|
|
250
|
+
cardiac_mask = (freqs >= cardiac_freq_range[0]) & (freqs <= cardiac_freq_range[1])
|
|
251
|
+
|
|
252
|
+
if np.any(cardiac_mask):
|
|
253
|
+
cardiac_power = np.max(psd[cardiac_mask])
|
|
254
|
+
total_power = np.sum(psd)
|
|
255
|
+
psp = cardiac_power / total_power
|
|
256
|
+
else:
|
|
257
|
+
psp = 0
|
|
258
|
+
|
|
259
|
+
# SCI approximation (would need paired wavelengths for true SCI)
|
|
260
|
+
sci_values.append(psp)
|
|
261
|
+
|
|
262
|
+
return np.array(sci_values)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Motion Artifact Detection
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
def detect_motion_artifacts(raw, threshold_std=3.0, window_sec=1.0):
|
|
269
|
+
"""
|
|
270
|
+
Detect motion artifacts using threshold-based method.
|
|
271
|
+
"""
|
|
272
|
+
data = raw.get_data()
|
|
273
|
+
sfreq = raw.info['sfreq']
|
|
274
|
+
n_samples = data.shape[1]
|
|
275
|
+
window_samples = int(window_sec * sfreq)
|
|
276
|
+
|
|
277
|
+
# Calculate global signal variance
|
|
278
|
+
global_std = np.std(data)
|
|
279
|
+
threshold = threshold_std * global_std
|
|
280
|
+
|
|
281
|
+
# Detect artifacts (samples where derivative exceeds threshold)
|
|
282
|
+
diff_data = np.diff(data, axis=1)
|
|
283
|
+
artifacts = np.zeros(n_samples, dtype=bool)
|
|
284
|
+
|
|
285
|
+
for i in range(data.shape[0]):
|
|
286
|
+
ch_artifacts = np.abs(diff_data[i, :]) > threshold
|
|
287
|
+
# Expand to include surrounding samples
|
|
288
|
+
for j in np.where(ch_artifacts)[0]:
|
|
289
|
+
start = max(0, j - window_samples)
|
|
290
|
+
end = min(n_samples, j + window_samples)
|
|
291
|
+
artifacts[start:end] = True
|
|
292
|
+
|
|
293
|
+
artifact_pct = 100 * np.sum(artifacts) / n_samples
|
|
294
|
+
|
|
295
|
+
return artifacts, artifact_pct
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def prune_bad_channels(raw, sci_threshold=0.7, cv_threshold=15):
|
|
299
|
+
"""
|
|
300
|
+
Identify and mark bad channels based on quality metrics.
|
|
301
|
+
"""
|
|
302
|
+
qc = check_fnirs_quality(raw)
|
|
303
|
+
sci = calculate_sci(raw)
|
|
304
|
+
|
|
305
|
+
bad_channels = []
|
|
306
|
+
|
|
307
|
+
for i, stats in enumerate(qc['channel_stats']):
|
|
308
|
+
ch_name = stats['channel']
|
|
309
|
+
|
|
310
|
+
# Check CV
|
|
311
|
+
if stats['cv'] > cv_threshold:
|
|
312
|
+
bad_channels.append(ch_name)
|
|
313
|
+
continue
|
|
314
|
+
|
|
315
|
+
# Check SCI
|
|
316
|
+
if sci[i] < sci_threshold:
|
|
317
|
+
bad_channels.append(ch_name)
|
|
318
|
+
continue
|
|
319
|
+
|
|
320
|
+
# Check for negative values (if optical density)
|
|
321
|
+
if stats['min'] < 0:
|
|
322
|
+
bad_channels.append(ch_name)
|
|
323
|
+
|
|
324
|
+
return bad_channels
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Complete QC Pipeline
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
def fnirs_qc_pipeline(raw_path, output_dir=None):
|
|
331
|
+
"""
|
|
332
|
+
Complete fNIRS QC pipeline.
|
|
333
|
+
"""
|
|
334
|
+
import os
|
|
335
|
+
|
|
336
|
+
# Load data
|
|
337
|
+
raw = mne.io.read_raw_snirf(raw_path, preload=True)
|
|
338
|
+
|
|
339
|
+
# Basic quality check
|
|
340
|
+
qc_results = check_fnirs_quality(raw)
|
|
341
|
+
|
|
342
|
+
# Calculate SCI
|
|
343
|
+
sci_values = calculate_sci(raw)
|
|
344
|
+
qc_results['sci_mean'] = np.mean(sci_values)
|
|
345
|
+
qc_results['sci_min'] = np.min(sci_values)
|
|
346
|
+
qc_results['n_low_sci'] = np.sum(sci_values < 0.7)
|
|
347
|
+
|
|
348
|
+
# Detect motion artifacts
|
|
349
|
+
artifacts, artifact_pct = detect_motion_artifacts(raw)
|
|
350
|
+
qc_results['artifact_pct'] = artifact_pct
|
|
351
|
+
|
|
352
|
+
# Identify bad channels
|
|
353
|
+
bad_channels = prune_bad_channels(raw)
|
|
354
|
+
qc_results['n_bad_channels'] = len(bad_channels)
|
|
355
|
+
qc_results['bad_channels'] = bad_channels
|
|
356
|
+
qc_results['bad_channel_pct'] = 100 * len(bad_channels) / qc_results['n_channels']
|
|
357
|
+
|
|
358
|
+
# Determine inclusion
|
|
359
|
+
include = True
|
|
360
|
+
reasons = []
|
|
361
|
+
|
|
362
|
+
if qc_results['bad_channel_pct'] > 40:
|
|
363
|
+
include = False
|
|
364
|
+
reasons.append(f"Bad channels: {qc_results['bad_channel_pct']:.1f}% > 40%")
|
|
365
|
+
|
|
366
|
+
if qc_results['artifact_pct'] > 50:
|
|
367
|
+
include = False
|
|
368
|
+
reasons.append(f"Motion artifacts: {qc_results['artifact_pct']:.1f}% > 50%")
|
|
369
|
+
|
|
370
|
+
qc_results['include'] = include
|
|
371
|
+
qc_results['exclusion_reasons'] = reasons
|
|
372
|
+
|
|
373
|
+
return qc_results
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### QC Report Generation
|
|
377
|
+
|
|
378
|
+
```python
|
|
379
|
+
def generate_fnirs_report(qc_results, output_path):
|
|
380
|
+
"""Generate fNIRS QC report."""
|
|
381
|
+
|
|
382
|
+
report = f"""
|
|
383
|
+
fNIRS Quality Control Report
|
|
384
|
+
============================
|
|
385
|
+
|
|
386
|
+
Recording Information
|
|
387
|
+
---------------------
|
|
388
|
+
Channels: {qc_results['n_channels']}
|
|
389
|
+
Duration: {qc_results['duration_sec']:.1f} seconds
|
|
390
|
+
Sampling rate: {qc_results['sfreq']} Hz
|
|
391
|
+
|
|
392
|
+
Signal Quality
|
|
393
|
+
--------------
|
|
394
|
+
Mean SCI: {qc_results.get('sci_mean', 'N/A'):.3f}
|
|
395
|
+
Min SCI: {qc_results.get('sci_min', 'N/A'):.3f}
|
|
396
|
+
Channels with low SCI: {qc_results.get('n_low_sci', 'N/A')}
|
|
397
|
+
|
|
398
|
+
Channel Quality
|
|
399
|
+
---------------
|
|
400
|
+
Bad channels: {qc_results['n_bad_channels']} ({qc_results['bad_channel_pct']:.1f}%)
|
|
401
|
+
Bad channel names: {', '.join(qc_results['bad_channels']) if qc_results['bad_channels'] else 'None'}
|
|
402
|
+
|
|
403
|
+
Motion Artifacts
|
|
404
|
+
----------------
|
|
405
|
+
Data affected by motion: {qc_results['artifact_pct']:.1f}%
|
|
406
|
+
|
|
407
|
+
Inclusion Decision
|
|
408
|
+
------------------
|
|
409
|
+
Include: {'Yes' if qc_results['include'] else 'No'}
|
|
410
|
+
"""
|
|
411
|
+
|
|
412
|
+
if not qc_results['include']:
|
|
413
|
+
report += f"Exclusion reasons:\n"
|
|
414
|
+
for reason in qc_results['exclusion_reasons']:
|
|
415
|
+
report += f" - {reason}\n"
|
|
416
|
+
|
|
417
|
+
if output_path:
|
|
418
|
+
with open(output_path, 'w') as f:
|
|
419
|
+
f.write(report)
|
|
420
|
+
|
|
421
|
+
return report
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## Key References
|
|
425
|
+
|
|
426
|
+
- Pollonini L et al. (2014). Auditory cortex activation to natural speech and simulated cochlear implant speech measured with functional near-infrared spectroscopy. Hearing Research 309:84-93. (SCI metric)
|
|
427
|
+
- Hocke LM et al. (2018). Automated Processing of fNIRS Data—A Visual Guide to the Pitfalls and Consequences. Algorithms 11(5):67.
|
|
428
|
+
- Brigadoi S et al. (2014). Motion artifacts in functional near-infrared spectroscopy: A comparison of motion correction techniques applied to real cognitive data. NeuroImage 85:181-191.
|
|
429
|
+
- Yücel MA et al. (2021). Best practices for fNIRS publications. Neurophotonics 8(1):012101.
|
|
430
|
+
- Santosa H et al. (2018). The NIRS Brain AnalyzIR Toolbox. Algorithms 11(5):73.
|