How to wrap a Fieldtrip matlab function

The following section is a brief introduction on how to wrap a matlab function included in a desired package.

This example script creates an Interface wrapping a function of FieldTrip to apply a bipolar montage to depth electrodes (see Time-frequency analysis on sEEG data Section).

Note

This section is based on the nipype documentation on how to wrap a matlab script.

Define Interface

The first step is to define an Interface wrapping MATLAB code. In Nipype, interfaces are python modules that allow you to use external package even if they themselves are written in another programming language than python. Here we define an interface wrapping a MATLAB script that call the interfaces function of FieldTrip to apply a bipolar montage to sEEG electrodes.

import os
from nipype.interfaces.base import traits, TraitedSpec
from nipype.interfaces.matlab import MatlabCommand, MatlabInputSpec


class ReferenceInputSpec(MatlabInputSpec):
    data_file = traits.File(exists=True,
                            desc='FieldTrip data structure .mat',
                            mandatory=True)
    ft_path = traits.String('', desc='FieldTrip path', mandatory=True)
    channels = traits.String('', desc='channel names')
    refmethod = traits.String('', desc='reference type (avg, bipolar)', mandatory=True)


class ReferenceOutputSpec(TraitedSpec):
    matlab_output = traits.Str()
    data_output = traits.Str('', desc='data structure .mat')


class Reference(MatlabCommand):
    """
    Apply the specified reference

    Inputs
    ------

    data_file : str
        data structure .mat (matlab format)
    ft_path : str
        path of FieldTrip package
    channels : str
        channels name to include in the reference process
    updatesens : bool
        update sensors information
    refmethod : str
        kind of reference (avg, bipolar)

    Outputs
    -------

    matlab_output : str
        file path of new FieldTrip data structure
    data_output : str
        fieldtrip data structure in .mat containing the rereferce data
    """
    input_spec = ReferenceInputSpec
    output_spec = ReferenceOutputSpec

    def _bipolar_reference(self):
        """call FieldTrip function to Apply a bipolar montage to the depth
        electrodes"""
        script = """
        fpath = '%s'
        addpath(fpath)
        disp(fpath)
        ft_defaults
        load('%s');
        depths = %s;
        for d = 1:numel(depths)
            cfg             = [];
            cfg.channel     = ft_channelselection(depths{d}, data.label);
            cfg.reref       = 'yes';
            cfg.refchannel  = 'all';
            cfg.refmethod   = '%s';
            cfg.updatesens  = 'yes';
            reref_depths{d} = ft_preprocessing(cfg, data);
        end
        cfg            = [];
        cfg.appendsens = 'yes';
        reref_data = ft_appenddata(cfg, reref_depths{:});
        save('%s', 'reref_data')
        """ % (self.inputs.ft_path, self.inputs.data_file,
            self.inputs.channels, self.inputs.refmethod, self.data_output)
        return script

    def run(self, **inputs):
        # Inject your script
        self.data_output = os.path.abspath('reref_data.mat')

        print('*** APPLY {} montage'.format(self.inputs.refmethod))
        self.inputs.script = self._bipolar_reference()

        results = super(MatlabCommand, self).run(**inputs)
        stdout = results.runtime.stdout
        # Attach stdout to outputs to access matlab results
        results.outputs.matlab_output = stdout
        print(stdout)
        return results

    def _list_outputs(self):
        outputs = self._outputs().get()
        outputs['data_output'] = self.data_output
        return outputs

Call interface

The code below shows how to use the Reference interface.

Let us fetch the data first (it is around 200 MB download) and specify the interface input variables. We use the iEEG data available here.

import os.path as op
import ephypype
from ephypype.nodes.FT_tools import Reference
from ephypype.datasets import fetch_ieeg_dataset

base_path = op.join(op.dirname(ephypype.__file__), '..', 'examples')
data_path = fetch_ieeg_dataset(base_path)

Now, we create the reference interface and set all its inputs.

Note

The code needs the FieldTrip package installed, with path properly setup, for this example to run.

ft_path = '/usr/local/MATLAB/R2018a/toolbox/MEEG/fieldtrip-20200327/'
refmethod = 'bipolar'
channels_name = '{\'RAM*\', \'RHH*\', \'RTH*\', \'ROC*\', \'LAM*\',\'LHH*\', \'LTH*\'}'

reference_if = Reference()
reference_if.inputs.data_file = op.join(data_path, 'SubjectUCI29_data.mat')
reference_if.inputs.channels = channels_name
reference_if.inputs.ft_path = ft_path
reference_if.inputs.refmethod = refmethod
reference_if.inputs.script = ''

out = reference_if.run()

print('Rereferenced data saved at {}'.format(out.outputs.data_output))

Note

In Time-frequency analysis on sEEG data Section there is an example on how to create a workflow connecting a node that wraps a desired function of a Matlab toolbo (FieldTrip) with a Node that wraps a function of a python toolbox (MNE).

Download Python source code: FT_tools.py

Download Python source code: plot_run_FT_IF.py