Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
arnodelorme committed Jun 26, 2018
1 parent 8958719 commit 2038e0a
Show file tree
Hide file tree
Showing 47 changed files with 4,990 additions and 0 deletions.
File renamed without changes.
Binary file added MFF-1.2.2-jar-with-dependencies.jar
Binary file not shown.
69 changes: 69 additions & 0 deletions README.txt
@@ -0,0 +1,69 @@
Known limitations to the Philips MFF import/export plugin
---------------------------------------------------------
- Timing accuracy limited to 10-50 microseconds precision. Matlab 2014b time
conversion is not as precise as Matlab 2017a conversion (we can loose 1ms
accuracy on some events in some specific rare files). With Matlab 2018a, the
difference seems to be at most 10 microseconds. In most applications,
this limitation has no consequences as event latencies are multiple of 1000
microseconds (1 ms) and the events are imported and exported perfectly.

- The plugin will not work with version of Matlab older than 2014a as the Java
JAR file cannot be properly interfaced.

- When the Java Heap Memory is at its default level, few files can be imported.
There is a special message guiding users how to increase the default settings
in Matlab in case they encounter an error. Importantly, some large files
require a computer with 16Gb of RAM or more (or Java Heap of 4Gb).

- Calibration data when present is applied to the data. However, if the file
is exported this information is lost. Impedance data and channel status also
contained in the info1.xml file is ignored.

- Importing trials of different length is not supported. This is a rare occurrence.

- Channel status and channel keys in category files are not imported

- Importing filter information and calibration information is not supported
(except gain calibration which is applied to the data when it is imported)

- When importing in standalone mode, if the file is exported, it will not
contain event keys

- Video files are not imported and expoted

- This plugin was tested on platforms using little-endian byte ordering.
Although we do not expect big-endian to be a problem, there is a small
chance there could be problem

Revision history
----------------
Version 0.96
- Add license for each file
- Clean up documentation

Version 0.95
- Fix issues when running File-io import and now importing using File-io functions direclty
- Adding licence file

Version 0.94
- Fix EEGLAB history for pop_mffimport
- Fix boundaries when encoding types
- Minor documentation changes

Version 0.93
- Now import/export data files with PNS data only
- Through the graphic interface, now allow to specify the MFF events field to
use for the EEGLAB event types.
- Now allow the plugin to function in standalone mode.
- Now check for Matlab version and issue an error for unsuported Matlab versions

Version 0.92
- Renamed all the functions
- Fix minor issue with multiple references

Version 0.91 - Difference with previous revision
- Fixed issue with info1.xml file which was missing some information

Version 0.9
- Adding support for layout and subject information

99 changes: 99 additions & 0 deletions eegplugin_mffmatlabio.m
@@ -0,0 +1,99 @@
% eegplugin_mffmatlabio() - plugin for importing and exporting MFF files
%
% Usage:
% >> eegplugin_mffmatlabio(fig, trystrs, catchstrs);
%
% Inputs:
% fig - [integer] eeglab figure.
% trystrs - [struct] "try" strings for menu callbacks.
% catchstrs - [struct] "catch" strings for menu callbacks.
%
% Main files
% ----------
% eegplugin_mffmatlabio.m - create menu in the EEGLAB interface
% pop_mffimport.m - import MFF file into EEGLAB (graphic interface)
% pop_mffexport.m - export EEGLAB structure to MFF file/folder (graphic interface)
%
% Support files
% -------------
% mff_import.m - import MFF file/folder to EEGLAB structure
% mff_importcategories.m - import 'categories.xml' file
% mff_importcoordinates.m - import 'coordinates.xml' file
% mff_importepochs.m - import 'epochs.xml' file
% mff_importevents.m - import 'eventsxxxx.xml' file(s)
% mff_importinfo.m - import 'info.xml' file
% mff_importinfon.m - import 'info1.xml' file
% mff_importpnsset.m - import PNS file
% mff_importsensorlayout.m - import 'sensorlayout.xml' file
% mff_importsignal.m - import 'signal1.bin' file
% mff_importsubject.m - import subject file
% mff_export.m - export MFF file/folder from EEGLAB structure
% mff_createmff.m - create empty MFF file/folder
% mff_exportcategories.m - export 'categories.xml' file
% mff_exportcoordinates.m - export 'coordinates.xml' file
% mff_exportepochs.m - export 'epochs.xml' file
% mff_exportevents.m - export 'events.xml' file
% mff_exportinfo.m - export 'info.xml' file
% mff_exportinfon.m - export 'info1.xml' file
% mff_exportpnsset.m - export PNS file
% mff_exportsensorlayout.m - export 'sensorlayout.xml' file
% mff_exportsignal.m - export 'signal1.bin' file
% mff_exportsubject.m - export subject file
% mff_decodetime.m - convert MFF time to Matlab time
% mff_encodetime.m - convert Matlab time to MFF time
% mff_getobj.m - convert Java object to Matlab
% mff_setobj.m - convert Matlab object to Java
% pop_mffimport.m - EEGLAB import GUI
% pop_mffexport.m - EEGLAB export GUI
% eegplugin_mffmatlabio.m - EEGLAB startup function
% eeg_compare.m - Function to compare EEGLAB sturtures
% mff_fileio_read_data.m - File-IO function to read data
% mff_fileio_read_header.m - File-IO function to read header
% mff_fileio_read_event.m - File-IO function to read event
% mff_fileio_write.m - File-IO function to write data and events

% This file is part of mffmatlabio.
%
% mffmatlabio is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% mffmatlabio is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with mffmatlabio. If not, see <https://www.gnu.org/licenses/>.

function versionstr = eegplugin_mffmatlabio(fig, trystrs, catchstrs)

%global EEG
versionstr = '0.95';
if nargin < 3
error('eegplugin_mffmatlabio requires 3 arguments');
end;

% add amica folder to path
% -----------------------
if ~exist('mff_import')
p = which('eegplugin_mffmatlabio');
p = p(1:findstr(p,'eegplugin_mffmatlabio.m')-1);
addpath(p);
end

% find tools menu
% ---------------
menui = findobj(fig, 'tag', 'import data');
menue = findobj(fig, 'tag', 'export');

% menu callback commands
% ----------------------
comload = [ trystrs.no_check '[EEG, LASTCOM] = pop_mffimport;' catchstrs.store_and_hist ];
comwrite = [ trystrs.no_check 'LASTCOM = pop_mffexport(EEG);' catchstrs.store_and_hist ];

% create menus
% ------------
submenu = uimenu( menui, 'Label', 'Import Philips .mff file', 'separator', 'on', 'CallBack', comload);
submenu = uimenu( menue, 'Label', 'Export Philips .mff file', 'CallBack', comwrite);
61 changes: 61 additions & 0 deletions mff_createmff.m
@@ -0,0 +1,61 @@
% mff_createmff - create empty MFF file/folder
%
% Usage:
% mff_createmff(mffFile);
%
% Inputs:
% mffFile - filename/foldername for the MFF file (MFF file/folder must
% already exist)

% This file is part of mffmatlabio.
%
% mffmatlabio is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% mffmatlabio is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with mffmatlabio. If not, see <https://www.gnu.org/licenses/>.

function events = mff_createmff(mffURI)

p = fileparts(which('mff_importsignal.m'));
warning('off', 'MATLAB:Java:DuplicateClass');
javaaddpath(fullfile(p, 'MFF-1.2.2-jar-with-dependencies.jar'));
import com.egi.services.mff.api.MFFFactory;
import com.egi.services.mff.api.MFFResourceType;
import com.egi.services.mff.api.LocalMFFFactoryDelegate;
import com.egi.services.mff.utility.ResourceUnmarshalException;
import com.egi.services.mff.api.Signal;
import com.egi.services.mff.api.SignalBlock;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
warning('on', 'MATLAB:Java:DuplicateClass');

% Test script for matlab binding of Java based MFF file access library.
% The MFFFactory class is used to access all resources contained in a
% MFF package file. This example loads an event track from the example file
% and writes out information about events in that file.

% create a factory
mfffactorydelegate = javaObject('com.egi.services.mff.api.LocalMFFFactoryDelegate');
mfffactory = javaObject('com.egi.services.mff.api.MFFFactory', mfffactorydelegate); %MFFResourceType.MFFResourceTypes.
mffFileResourceType = javaObject('com.egi.services.mff.api.MFFResourceType', javaMethod('valueOf', 'com.egi.services.mff.api.MFFResourceType$MFFResourceTypes', 'kMFF_RT_MFFFile'));

if mfffactory.resourceExistsAtURI(mffURI, mffFileResourceType)
disp('The resource already exists');
else
disp('The resource does not exist');

if mfffactory.createResourceAtURI(mffURI, mffFileResourceType)
disp('Success creating MFF file.');
else
disp('An error occured creating the MFF file.');
end
end
41 changes: 41 additions & 0 deletions mff_decodetime.m
@@ -0,0 +1,41 @@
% mff_decodetime - decode EGI time format into Matlab time format
%
% Usage:
% timeout = mff_decodetime(timein);
%
% Input:
% timein - EGI time format (string)
%
% Output:
% timeout - Matlab numerical time (see datenum)

% This file is part of mffmatlabio.
%
% mffmatlabio is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% mffmatlabio is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with mffmatlabio. If not, see <https://www.gnu.org/licenses/>.

function timeValOut = mff_decodetime(timeVal)

% remove GMT part
microSec = 0.0000000000115251168608665466308593750000000;
timeValOut = datenum(timeVal, 'yyyy-mm-ddTHH:MM:SS.FFF') + str2double(timeVal(24:26))*microSec;

% indDash = find(timeVal == '-');
% if indDash(end) > 10 else indDash = length(timeVal)+1; end;
%
% microSeconds = timeVal(indDash(end)-4:indDash(end)-1);
% microSeconds = str2double(microSeconds)/24/60/60/1000;
% fprintf('%1.20f\n', timeValOut);
% timeValOut = timeValOut+microSeconds;
% fprintf('%1.20f\n', timeValOut);

58 changes: 58 additions & 0 deletions mff_encodetime.m
@@ -0,0 +1,58 @@
% mff_encodetime - encode EGI time format from Matlab time format
%
% Usage:
% timeout = mff_encodetime(timein);
%
% Input:
% timein - EGI time format (numerical)
%
% Output:
% timeout - EGI string format time
%
% Example:
% timeValOut = mff_decodetime('2009-04-16T21:52:47.893250-08:00')
% mff_encodetime(timeValOut,'08:00')
%
% timeValOut = mff_decodetime('2009-04-16T21:52:47.893750-08:00')
% mff_encodetime(timeValOut,'08:00') % issue here

% This file is part of mffmatlabio.
%
% mffmatlabio is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% mffmatlabio is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with mffmatlabio. If not, see <https://www.gnu.org/licenses/>.

function timeValOut = mff_encodetime(timeVal, timeZone)

% remove GMT part
microSec = 0.000000000011525116860866546630859375000;

% estimate error
tmp = datestr(timeVal, 'yyyy-mm-ddTHH:MM:SS.FFF');
remain = timeVal-mff_decodetime([tmp '000']);
if remain < 0
tmp = datestr(timeVal-microSec*1000, 'yyyy-mm-ddTHH:MM:SS.FFF');
remain = timeVal-mff_decodetime([tmp '000']);
if remain < 0
error('Negative microseconds');
end
end
timeValOut = [ tmp sprintf('%.3d', round(remain/microSec/10)*10) timeZone ];


% old code
% millisec = 0.000000000011525116860866546630859375000;
%
% tmp = timeVal/millisec;
% remain = (tmp-floor(tmp))*1000;
%
% timeValOut = [ datestr(timeVal, 'yyyy-mm-ddTHH:MM:SS.FFF') sprintf('%.3d', round(remain,-1)) '-' timeZone ];
56 changes: 56 additions & 0 deletions mff_export.m
@@ -0,0 +1,56 @@
% mff_export - export EEGLAB structure to MFF file. This function calls
% all other function to create MFF structure, export
% events, channels and channel coordinates.
%
% Usage:
% mff_export(EEG, mffFile);
%
% Inputs:
% EEG - EEGLAB structure
% mffFile - filename/foldername for the MFF file (MFF file/folder must
% already exist)

% This file is part of mffmatlabio.
%
% mffmatlabio is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% mffmatlabio is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with mffmatlabio. If not, see <https://www.gnu.org/licenses/>.

function mff_export(EEG, outputFile)

matVer = ver('MATLAB');
if datenum(matVer.Date) < 735595
error('This version of Matlab is too old. Use version 2014a or later');
end

% add mff extension if not present
[filePath, fileName] = fileparts( outputFile);
outputFile = fullfile(filePath, [ fileName '.mff' ]);

% delete folder if it exist
if exist(outputFile)
rmdir(outputFile, 's');
end

mff_createmff(outputFile);
mff_exportinfo(EEG, outputFile);
mff_exportsubject(EEG, outputFile);
mff_exportinfon(EEG, outputFile);
mff_exportsignal(EEG, outputFile);
indtle = mff_exportcategories(EEG, outputFile);
EEG.event(indtle) = []; % remove time locking events
mff_exportevents(EEG, outputFile);
mff_exportcoordinates(EEG, outputFile);
mff_exportsensorlayout(EEG, outputFile);
mff_exportpnsset(EEG, outputFile);
mff_exportepochs(EEG, outputFile);
mff_exportsensorlayout(EEG, outputFile);

0 comments on commit 2038e0a

Please sign in to comment.