Getting Started
The HRfunc tool can be used to estimate latent hemodynamic response functions and neural activity in functional near infrared spectroscopy (fNIRS). Estimate neural activity in each subject and a group level hemodynamic response function (HRF) through Python and MNE following these steps. Check the Q & A or reach out if you have any questions.
- Prepare raw fNIRS scans and events
- Estimate subject level estimates for each subject
- Generate a subject pool HRF distribution
- Estimate channel-wise neural activity for each subject
Video guide of how to use HRfunc to estimate HRFs and neural activity...
To first estimate subject level HRFs, initialize a
hrfunc.montage()
object with one of your scans loaded into an MNE object to orient the hrfunc.montage()
to your NIRX montage setup. Then iterate through each of your raw scans passing them into the
montage.estimate_hrf()
function. The HRfunc tool will automatically preprocess them for deconvolution, which is distinctly different than standard
hemoglobin preprocessing. The lmbda
(lambda) variable can be tuned to increase and decrease noise suppresion
within the signal.
import hrfunc as hrf
# Load in NIRX scans
raw_scan = mne.io.read_raw_nirx("path/to/your/nirx/scan/")
# Load in events and format as a list of 0's and 1's representing an event sequence in NIRX sampling space
with open("path/to/events.txt", "r") as file: # Or however you save/load events
events = [int(line.split('/n')[0]) for line in file.readlines()]
# Load a hrfunc montage
montage = hrf.montage(raw_scan)
# Iterate through each of your MNE NIRX scans and estimate an HRF for it
for scan in raw_scans:
montage.estimate_hrf(scan, events, duration = 30.0, lmbda = 1.0)
Once each scan has been passed into your montage to have HRFs estimated, you can now average across subject estimates to generate a subject-pool wide HRF estimate for each channel.
# Generate subject pool wide distribution
montage.generate_distribution()
montage.save('study_HRFs.json')
After generating a subject-pool wide HRF distribution for each NIRX channel, an HRF estimate will be attached to each of your hrf montage channel nodes for use in estimating neural activity. Save the object as a json object to use with other study analysis, share with collaborators, or share with the wider neuroimaging community. Now using our estimated HRFs we can estimate neural activity!
To accomplish this you must iterate through each of your scans and pass them into your
montage.estimate_activity(raw)
. This will replace channel
hemoglobin data in place using using MNEs raw.apply_function() to each channel using
you're estimated channel HRF.
# Load previously estimated HRF montage
montage = hrf.load_montage('study_HRFs.json')
# Estimate neural activity in place and save the nirx object
for scan in raw_scans:
scan = montage.estimate_activity(scan)
scan.save('sub-123_deconvolved.fif')