Modify annotations on raw file

:question: If you have a question or issue with MNE-Python, please include the following info:

  • MNE version: e.g. 1.3.1
  • operating system: e.g. macOS 13

I’m modifying the annotations on my data using mne.Annotations and set_annotations but this doesn’t save the modifications I’m making to the raw file so I have to reset them every time I reopen the file. Is there a way I can save the modifications to the raw data file itself so it’s just good to go? Thanks!

Hello,

Can you share a code snippet?
If you use raw.set_annotations and then save this raw, the annotations are saved alongside.

Mathieu

Hi Mathieu,

Thanks! Here is the code I’ve been using so far:

fnirs_raw_dir = os.path.join(fnirs_data_folder,‘7DCC3558-2021-11-02’);
raw_intensity = mne.io.read_raw_nirx(fnirs_raw_dir).load_data()
raw_intensity.resample(0.7)

my_annot = mne.Annotations(onset=[56.9348, 1649.8071], duration = [30, 30], description =[‘rest’, ‘rest’])
raw_intensity.set_annotations(my_annot),

Should I be using

raw.set_annotations(my_annot),
save raw

instead?

Thanks again,
Isabel

No, you named the variable raw_intensity so it looks correct to me. And then to save, raw_intensity.save(fname)?

What is the length of your raw_intensity in seconds?

Mathieu

Hi Mathieu!

The file is 2710.045 s long which I know is a very long file. When I use the raw_intensity.save(fname) command to save, it will only let me save the file as a .fif file instead of a .snirf file. Then when I go to load the participant file again, it will only load the original .snirf file and not the modified .fif file as the participant’s data.

Thank you so much for your continued help!!

Isabel

I never work with fNIRS data, but I think we found the issue.
When you save a Raw object with MNE, it is indeed saved as a .fif file. This format support all of the MNE data structures, including annotations. Thus, when you will open this saved .fif file, your annotations will be present.
Saving to another format is called exporting, you can find here the function to export Raw object, currently supporting BrainVision, EEGLAB and EDF formats.

Based on your text, it seems like you are:

  • loading the .snirf file in a Raw object
  • do some stuff one the Raw object, e.g. adding annotation
  • saving? as you can not export to .snirf, I’m guessing you are saving to .fif anyway
  • loading the original .snirf again, without the modification done in step 2, instead of loading the modified .fif

You can load the .fif file with read_raw_fif.

Code snippet:

from mne import Annotations
from mne.datasets import testing
from mne.io import read_raw_fif, read_raw_nirx


dirname = testing.data_path() / "NIRx" / "nirsport_v2" / "aurora_2021_9_6"
raw = read_raw_nirx(dirname, preload=True)
# remove existing annotations for this example
raw.set_annotations(None)
assert len(raw.annotations) == 0
# add an annotation
annotations = Annotations(onset=1, duration=1, description="test")
raw.set_annotations(annotations)

fname = "~/Downloads/test_raw.fif"
raw.save(fname)
raw_load = read_raw_fif(fname, preload=True)
assert len(raw.annotations) == 1

Mathieu

Hi Mathieu,

Thank you so much! This worked perfectly! I have one last question, if you don’t mind—I was able to run my individual subject analyses no problem by just loading the individual file with read_raw_fif but I don’t know how to load the .fif files as a directory so I can run a group GLM. The BIDSPath instructions included in the group GLM tutorial don’t seem to work and the importing data page linked doesn’t include instructions for .fif file. How would I create a group directory object with my .fif files if my files are organized like this (example linked)?

Thank you so much for all your help! I cannot tell you how much I appreciate it.
Isabel

You can load each file one by one in a sequence, e.g. a list.

raws = list()
for file in files:
    raw = read_raw_fif(file, preload=True)
    raws.append(raw)

Mathieu

Hi Mathieu,

Thank you so much! How would I indicate a root directory though? Bc specifying a folder and then iterating through it doesn’t seem to work i.e.,

fnirs_data_folder = ‘/Users/in65/Desktop/GroupGLM’;
raws = list()
for file in fnirs_data_folder:
raw = read_raw_fif(file, preload=True)
raws.append(raw)

Also read_raw_fif doesn’t load directories correct? So all of my .fif participant files would have to be in the same folder instead of individual subj folders?

Thank you again,
Isabel

You can put the file paths in a list and then iterate over it. You can do that either manually, or use functions from pathlib, e.g. pathlib.glob().

That’s what I was thinking too.

something like:

from pathlib import Path
fnirs_data_folder = Path(‘/Users/in65/Desktop/GroupGLM’)
print(fnirs_data_folder.exists())  # double check that you specified the path correctly
files = fnirs_data_folder.glob("*.fif")
# use line below to see if glob caught the files you want:
print(list(files)) # should print a list containing the files you want to load

then you should be able to use the loop suggested before.

Thank you all so much! The Path code you posted does create a list of the files I am trying to load but for whatever reason, when I try to run the actual for file in fnirs_data_folder loop, it stalls out and refuses to load. Do you have any reason why that might be? I’m not running any code not posted in this thread.

Thanks,
Isabel

Just to be safe can you caste the generator object that glob returns into a list?

so adjust the files = line to be:

files = list(fnirs_data_folder.glob("*.fif"))

and let me know if the for loop works?

It’s still freezing. When I iterate through it manually though, my data loads just fine.

hmm, well sorry that I seemed to have given you advice that didn’t help!

I’m glad that it sounds like you found a solution though.

Thank you so much for your help!!