- MNE version: 1.8.0
- operating system: Windows 11
Hello,
I have fNIRS data where the source and detector locations follow the brainproducts-RNP-BA-128
montage. I would like to use this montage configuration with the provided code.
raw_modified = raw_intensity.copy()
raw_modified.set_montage(brainproducts)
However, an error is occurring, as shown below:
ValueError: 'S1' is not in list
Here’s a refined version:
I reviewed similar posts, such as this one, and tried to follow the suggested steps. I also checked the MNE GitHub montages directory but couldn’t find the .elc
file for BrainProducts. Therefore, I extracted the x, y, z coordinate information using the code provided below:
# Load the brainproducts standard montage
brainproducts = mne.channels.make_standard_montage('brainproducts-RNP-BA-128')
# Initialize the header of the .elc file content
elc_content = [
"# ASA electrode file",
"ReferenceLabel avg",
"UnitPosition mm",
f"NumberPositions= {len(brainproducts.dig)}", # Total number of points, including fiducials
"Positions"
]
# Extract the x, y, z coordinates for each channel in mm, including LPA, RPA, and Nasion
for pos in brainproducts.dig:
x, y, z = pos['r'] * 1000 # Convert from meters to millimeters
elc_content.append(f"{x:.4f} {y:.4f} {z:.4f}")
# Add Labels section
elc_content.append("Labels")
# Add fiducials and then channel names
fiducials = ['LPA', 'Nasion', 'RPA']
elc_content.extend(fiducials + brainproducts.ch_names)
# Save to .elc file
with open("brainproducts-RNP-BA-128-org.elc", "w") as f:
f.write("\n".join(elc_content))
Since the fNIRS channel names differ from those in the BrainProducts montage, I attempted to map the fNIRS channels to the BrainProducts channels. However, I encountered some errors. My code is provided below:
mapping = {
'S1_D1 760': 'Fp1_AFp1 760',
'S1_D1 850': 'Fp1_AFp1 850',
'S1_D3 760': 'Fp1_AFF3h 760',
'S1_D3 850': 'Fp1_AFF3h 850',
'S2_D2 760': 'AFp2_AFF2h 760',
'S2_D2 850': 'AFp2_AFF2h 850',
'S2_D1 760': 'AFp2_Fp1 760',
'S2_D1 850': 'AFp2_Fp1 850',
'S2_D5 760': 'AFp2_AFF6h 760',
'S2_D5 850': 'AFp2_AFF6h 850',
'S3_D1 760': 'AFF3h_Fp1 760',
'S3_D1 850': 'AFF3h_Fp1 850',
'S3_D3 760': 'AFF3h_AFF2h 760',
'S3_D3 850': 'AFF3h_AFF2h 850',
'S3_D4 760': 'AFF3h_AFF4h 760',
'S3_D4 850': 'AFF3h_AFF4h 850',
'S3_D6 760': 'AFF3h_AFF6h 760',
'S3_D6 850': 'AFF3h_AFF6h 850',
'S4_D4 760': 'AFF2h_AFF4h 760',
'S4_D4 850': 'AFF2h_AFF4h 850',
'S4_D5 760': 'AFF2h_AFF6h 760',
'S4_D5 850': 'AFF2h_AFF6h 850',
'S4_D7 760': 'AFF2h_AFF5h 760',
'S4_D7 850': 'AFF2h_AFF5h 850',
'S5_D2 760': 'FFC5h_Fp1 760',
'S5_D2 850': 'FFC5h_Fp1 850',
'S5_D5 760': 'FFC5h_AFF6h 760',
'S5_D5 850': 'FFC5h_AFF6h 850',
'S5_D8 760': 'FFC5h_FFC2h 760',
'S5_D8 850': 'FFC5h_FFC2h 850',
'S6_D3 760': 'FFC1h_AFF3h 760',
'S6_D3 850': 'FFC1h_AFF3h 850',
'S6_D6 760': 'FFC1h_AFF6h 760',
'S6_D6 850': 'FFC1h_AFF6h 850',
'S7_D4 760': 'FFC4h_AFF4h 760',
'S7_D4 850': 'FFC4h_AFF4h 850',
'S7_D6 760': 'FFC4h_AFF6h 760',
'S7_D6 850': 'FFC4h_AFF6h 850',
'S7_D7 760': 'FFC4h_FFC3h 760',
'S7_D7 850': 'FFC4h_FFC3h 850',
'S8_D5 760': 'FFC2h_AFF6h 760',
'S8_D5 850': 'FFC2h_AFF6h 850',
'S8_D7 760': 'FFC2h_FFC3h 760',
'S8_D7 850': 'FFC2h_FFC3h 850',
'S8_D8 760': 'FFC2h_FFC6h 760',
'S8_D8 850': 'FFC2h_FFC6h 850'
}
brainproducts_montage = mne.channels.read_custom_montage("brainproducts-RNP-BA-128.elc", head_size=None)
print(brainproducts_montage)
print(brainproducts_montage.dig)
raw_intensity_modified = raw_intensity.copy()
raw_intensity_modified.rename_channels(mapping)
# Set the channels to fnirs_cw_amplitude type
fnirs_types = {ch_name: 'fnirs_cw_amplitude' for ch_name in raw_intensity_modified.ch_names}
raw_intensity_modified.set_channel_types(fnirs_types)
raw_intensity_modified.set_montage(brainproducts_montage)
But I get this error:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[484], line 61
58 fnirs_types = {ch_name: 'fnirs_cw_amplitude' for ch_name in raw_intensity_modified.ch_names}
59 raw_intensity_modified.set_channel_types(fnirs_types)
---> 61 raw_intensity_modified.set_montage(brainproducts_montage)
63 # raw_intensity_modified.plot_sensors(kind='topomap', show_names=False)
64 # fig = raw_intensity_modified.get_montage().plot()
File <decorator-gen-22>:12, in set_montage(self, montage, match_case, match_alias, on_missing, verbose)
File c:\ProgramData\miniconda3\envs\fnirs\lib\site-packages\mne\_fiff\meas_info.py:422, in MontageMixin.set_montage(self, montage, match_case, match_alias, on_missing, verbose)
419 from ..channels.montage import _set_montage
421 info = self if isinstance(self, Info) else self.info
--> 422 _set_montage(info, montage, match_case, match_alias, on_missing)
423 return self
File c:\ProgramData\miniconda3\envs\fnirs\lib\site-packages\mne\channels\montage.py:1329, in _set_montage(***failed resolving arguments***)
1327 fnirs_picks = _picks_to_idx(info, "fnirs", allow_empty=True)
1328 if len(fnirs_picks) > 0:
-> 1329 _set_montage_fnirs(info, mnt_head)
File c:\ProgramData\miniconda3\envs\fnirs\lib\site-packages\mne\channels\montage.py:1081, in _set_montage_fnirs(info, montage)
1078 from ..preprocessing.nirs import _validate_nirs_info
1080 # Validate that the fNIRS info is correctly formatted
-> 1081 picks = _validate_nirs_info(info)
1083 # Modify info['chs'][#]['loc'] in place
1084 num_ficiduals = len(montage.dig) - len(montage.ch_names)
File c:\ProgramData\miniconda3\envs\fnirs\lib\site-packages\mne\preprocessing\nirs\nirs.py:261, in _validate_nirs_info(info, throw_errors, fnirs, which, check_bads, allow_empty)
257 if not len(pick_types(info, fnirs=fnirs)):
258 raise RuntimeError(
259 f"{which} must operate on {kind} data, but none was found."
260 )
--> 261 freqs = np.unique(_channel_frequencies(info))
262 if freqs.size > 0:
263 pair_vals = freqs
File c:\ProgramData\miniconda3\envs\fnirs\lib\site-packages\mne\preprocessing\nirs\nirs.py:73, in _channel_frequencies(info)
71 freqs = list()
72 for pick in picks:
---> 73 freqs.append(round(float(_S_D_F_RE.match(info["ch_names"][pick]).groups()[2])))
74 return np.array(freqs, int)
AttributeError: 'NoneType' object has no attribute 'groups'