123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- """
- readrawnix.py
- Usage:
- python readrawnix.py <nixfile>
- Arguments:
- nixfile Path to the NIX file to read.
- (Requires Python 3)
- Command line script for reading NIX files into an MNE structure (mne-python).
- NIX file should have been created using the mnetonix.py script/module. This
- reader expects certain objects relationships and names to exist in order to
- load all data and metadata successfully. Refer to the "NIX Format Layout" in
- the mnetonix.py module for details.
- To include in a script, call the 'import_nix()' and provide a NIX filename.
- """
- import os
- import sys
- import numpy as np
- import nixio as nix
- import mne
- DATA_BLOCK_NAME = "EEG Data Block"
- DATA_BLOCK_TYPE = "Recording"
- RAW_DATA_GROUP_NAME = "Raw Data Group"
- RAW_DATA_GROUP_TYPE = "EEG Channels"
- RAW_DATA_TYPE = "Raw Data"
- typemap = {
- "str": str,
- "int": int,
- "float": float,
- "bool": bool,
- "tuple": tuple,
- "list": list,
- "numpy.float64": np.float64,
- "numpy.ndarray": np.array,
- }
- def convert_prop_type(prop):
- pt = prop.type[8:-2]
- pv = prop.values
- if len(pv) == 1:
- pv = pv[0]
- return typemap[pt](pv)
- def md_to_dict(section):
- sdict = dict()
- for prop in section.props:
- sdict[prop.name] = convert_prop_type(prop)
- if section.type[8:-2] == "mne.transforms.Transform":
- to = sdict["to"]
- fro = sdict["from"]
- trans = sdict["trans"]
- trans = section.referring_data_arrays[0][:]
- return mne.Transform(fro=fro, to=to, trans=trans)
- for sec in section.sections:
- if sec.name == "chs":
- # make a list of dictionaries for the channels
- chlist = list()
- for chsec in sec.sections:
- chlist.append(md_to_dict(chsec))
- sdict[sec.name] = chlist
- else:
- sdict[sec.name] = md_to_dict(sec)
- return sdict
- def merge_data_arrays(arrays):
- rows = [a[:] for a in arrays]
- return np.array(rows)
- def create_mne_annotations(mtags):
- onset = list()
- duration = list()
- description = list()
- for mtag in mtags:
- posshape = mtag.positions.shape
- if len(posshape) == 1:
- onset.extend(mtag.positions)
- duration.extend(mtag.extents)
- else:
- onset.extend([p[1] for p in mtag.positions])
- duration.extend([e[1] for e in mtag.extents])
- description.extend(mtag.positions.dimensions[0].labels)
- return mne.Annotations(onset=onset,
- duration=duration,
- description=description)
- def import_nix(nixfilename):
- """
- Import a NIX file (generated with mnetonix.py) into an MNE Raw structure.
- :param nixfilename: Path to the NIX file to be loaded.
- :rtype: mne.io.RawArray
- """
- nixfile = nix.File(nixfilename, mode=nix.FileMode.ReadOnly)
- # root, ext = os.path.splitext(nixfilename)
- # bvfilename = root + os.extsep + "vhdr"
- # bvfile = mne.io.read_raw_brainvision(bvfilename, stim_channel=False)
- # Create MNE Info object
- infosec = nixfile.sections["Info"]
- nchan = infosec["nchan"]
- sfreq = infosec["sfreq"]
- info = mne.create_info(nchan, sfreq)
- nixinfodict = md_to_dict(infosec)
- info.update(nixinfodict)
- # Read raw data into MNE objects
- datagroup = nixfile.blocks[DATA_BLOCK_NAME].groups[RAW_DATA_GROUP_NAME]
- if len(datagroup.data_arrays) > 1:
- # Data split: One DataArray per channel. Merging
- nixrawdata = merge_data_arrays(datagroup.data_arrays)
- else:
- nixrawdata = datagroup.data_arrays[0][:]
- # Create MNE RawArray
- mnerawdata = mne.io.RawArray(nixrawdata, info)
- # Add annotations: Stimuli from MultiTags
- mtags = datagroup.multi_tags
- annotations = create_mne_annotations(mtags)
- mnerawdata.set_annotations(annotations)
- nixfile.close()
- return mnerawdata
- def main():
- if len(sys.argv) < 2:
- print("Please provide either a NIX filename as the first argument")
- sys.exit(1)
- nixfilename = sys.argv[1]
- import_nix(nixfilename)
- if __name__ == "__main__":
- main()
|