Modify BIDS path to instead load list of .fif files

Apologies for posting back to back!

I am working through the NIRS group GLM tutorial. Due to preprocessing issues necessitating me saving my files as .fif files instead of .snirf files, instead of loading a directory of subjects I now have all of my data files loaded as a list() in .fif format. Does anyone have suggestions as to how best to I modify the following code?

def individual_analysis(bids_path, ID):

raw_intensity = read_raw_bids(bids_path=bids_path, verbose=False)

# Convert signal to haemoglobin and resample
raw_od = optical_density(raw_intensity)
raw_haemo = beer_lambert_law(raw_od, ppf=0.1)
raw_haemo.resample(0.6)

# Cut out just the short channels for creating a GLM repressor
sht_chans = get_short_channels(raw_haemo)
raw_haemo = get_long_channels(raw_haemo)

# Create a design matrix
design_matrix = make_first_level_design_matrix(raw_haemo, stim_dur=5.0)

# Append short channels mean to design matrix
design_matrix["ShortHbO"] = np.mean(sht_chans.copy().pick(picks="hbo").get_data(), axis=0)
design_matrix["ShortHbR"] = np.mean(sht_chans.copy().pick(picks="hbr").get_data(), axis=0)

# Run GLM
glm_est = run_glm(raw_haemo, design_matrix)

# Define channels in each region of interest
# List the channel pairs manually
left = [[4, 3], [1, 3], [3, 3], [1, 2], [2, 3], [1, 1]]
right = [[8, 7], [5, 7], [7, 7], [5, 6], [6, 7], [5, 5]]
# Then generate the correct indices for each pair
groups = dict(
    Left_Hemisphere=picks_pair_to_idx(raw_haemo, left, on_missing='ignore'),
    Right_Hemisphere=picks_pair_to_idx(raw_haemo, right, on_missing='ignore'))

# Extract channel metrics
cha = glm_est.to_dataframe()

# Compute region of interest results from channel data
roi = glm_est.to_dataframe_region_of_interest(groups,
                                              design_matrix.columns,
                                              demographic_info=True)

# Define left vs right tapping contrast
contrast_matrix = np.eye(design_matrix.shape[1])
basic_conts = dict([(column, contrast_matrix[i])
                    for i, column in enumerate(design_matrix.columns)])
contrast_LvR = basic_conts['Tapping_Left'] - basic_conts['Tapping_Right']

# Compute defined contrast
contrast = glm_est.compute_contrast(contrast_LvR)
con = contrast.to_dataframe()

# Add the participant ID to the dataframes
roi["ID"] = cha["ID"] = con["ID"] = ID

# Convert to uM for nicer plotting below.
cha["theta"] = [t * 1.e6 for t in cha["theta"]]
roi["theta"] = [t * 1.e6 for t in roi["theta"]]
con["effect"] = [t * 1.e6 for t in con["effect"]]

return raw_haemo, roi, cha, con

It seems structured to iterate through directories instead of a list and I’ve had no luck so far trying to get it to accept a list instead.

As a second point of clarification, I am also trying to modify this part of the analysis to iterate based on list item instead of subj.

for sub in subjects: # Loop from first to fifth subject

# Create path to file based on experiment info
bids_path = dataset.update(subject=sub)

# Analyse data and return both ROI and channel results
raw_haemo, roi, channel, con = individual_analysis(bids_path, sub)

# Append individual results to all participants
df_roi = pd.concat([df_roi, roi], ignore_index=True)
df_cha = pd.concat([df_cha, channel], ignore_index=True)
df_con = pd.concat([df_con, con], ignore_index=True)

I similarly have been unable to figure out how to get it to accept a list.

Any help is greatly appreciated! Thank you so much!

Okay I figured out how to do this so I’m posting in hope that it may help someone else. This is probably some of the ugliest code I have ever written in my life but it does work. You will have to iterate through your files by hand however as any attempt to use a loop seemed to break my computer. If your processor doesn’t hate you though, you may be able to loop this—see the solutions posted by other people in my other help thread for that.

This is basically the NIRS group GLM tutorial verbatim but with my edits to handle .fif files:

#Group GLM with .fif files

#make your data frames to store your group level results
df_roi = pd.DataFrame()  # To store region of interest results
df_cha = pd.DataFrame()  # To store channel level results
df_con = pd.DataFrame()  # To store channel level contrast results

#lets do this b*tch manually 
#(you will have to personally change the file name/subj ID each time)

#everything below this comment, copy/paste and run for as many files as you want to load for your group analysis, changing your file name/ID each time
file_name = '/Users/in65/Desktop/GroupGLM/subj05_raw.fif'
ID='subj05' #this is whatever your subj ID is

#load raw .fif file
raw_intensity = read_raw_fif(file_name, preload=True)

# Convert signal to haemoglobin and resample
raw_od = optical_density(raw_intensity)
raw_haemo = beer_lambert_law(raw_od, ppf=0.1)
raw_haemo.resample(0.6)

# Cut out just the short channels for creating a GLM repressor
sht_chans = get_short_channels(raw_haemo)
raw_haemo = get_long_channels(raw_haemo)

# Create a design matrix
design_matrix = make_first_level_design_matrix(raw_haemo, stim_dur=5.0)

# Append short channels mean to design matrix
design_matrix["ShortHbO"] = np.mean(sht_chans.copy().pick(picks="hbo").get_data(), axis=0)
design_matrix["ShortHbR"] = np.mean(sht_chans.copy().pick(picks="hbr").get_data(), axis=0)

# Run GLM
glm_est = run_glm(raw_haemo, design_matrix)

# Define channels in each region of interest
# List the channel pairs manually
left = [[4, 3], [1, 3], [3, 3], [1, 2], [2, 3], [1, 1]]
right = [[8, 7], [5, 7], [7, 7], [5, 6], [6, 7], [5, 5]]
# Then generate the correct indices for each pair
groups = dict(
    Left_Hemisphere=picks_pair_to_idx(raw_haemo, left, on_missing='ignore'),
    Right_Hemisphere=picks_pair_to_idx(raw_haemo, right, on_missing='ignore'))

# Extract channel metrics
cha = glm_est.to_dataframe()

# Compute region of interest results from channel data
roi = glm_est.to_dataframe_region_of_interest(groups,
                                              design_matrix.columns,
                                              demographic_info=True)

# Define left vs right tapping contrast
contrast_matrix = np.eye(design_matrix.shape[1])
basic_conts = dict([(column, contrast_matrix[I])
                    for i, column in enumerate(design_matrix.columns)])
contrast_LvR = basic_conts['left_tapping'] - basic_conts['right_tapping']

# Compute defined contrast
contrast = glm_est.compute_contrast(contrast_LvR)
con = contrast.to_dataframe()

# Add the participant ID to the dataframes
roi["ID"] = cha["ID"] = con["ID"] = ID

# Convert to uM for nicer plotting below.
cha["theta"] = [t * 1.e6 for t in cha["theta"]]
roi["theta"] = [t * 1.e6 for t in roi["theta"]]
con["effect"] = [t * 1.e6 for t in con["effect"]]


# Append individual results to all participants
df_roi = pd.concat([df_roi, roi], ignore_index=True)
df_cha = pd.concat([df_cha, cha], ignore_index=True)
df_con = pd.concat([df_con, con], ignore_index=True)

Hope this helps someone else!

1 Like