-
Notifications
You must be signed in to change notification settings - Fork 17
/
bids_importcoordsystemfile.m
141 lines (126 loc) · 5.09 KB
/
bids_importcoordsystemfile.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
% BIDS_IMPORTCOORDSYSTEMFILE - import coordinate information
%
% Usage:
% [EEG, bids] = bids_importcoordsystemfile(EEG, coordfile, 'key', value)
%
% Inputs:
% 'EEG' - [struct] the EEG structure to which event information will be imported
% coordfile - [string] path to the coordsystem.json file.
% e.g. ~/BIDS_EXPORT/sub-01/ses-01/eeg/sub-01_ses-01_task-GoNogo_coordsystem.json
%
% Optional inputs:
% 'bids' - [struct] structure that saves imported BIDS information. Default is []
%
% Outputs:
% EEG - [struct] the EEG structure with event info imported
% bids - [struct] structure that saves BIDS information with event information
%
% Authors: Arnaud Delorme, 2022
function [EEG, bids] = bids_importcoordsystemfile(EEG, coordfile, varargin)
if nargin < 2
help bids_importcoordsystemfile;
return;
end
g = finputcheck(varargin, {'bids' 'struct' [] struct([]) }, 'eeg_importcoordsystemfiles', 'ignore');
if isstr(g), error(g); end
bids = g.bids;
% coordinate information
bids(1).coordsystem = bids_importjson(coordfile, '_coordsystem.json'); %bids_loadfile( coordfile, '');
if ~isfield(EEG.chaninfo, 'nodatchans')
EEG.chaninfo.nodatchans = [];
end
EEG.chaninfo.BIDS = bids(1).coordsystem;
% import anatomical landmark
% --------------------------
if isfield(bids.coordsystem, 'AnatomicalLandmarkCoordinates') && ~isempty(bids.coordsystem.AnatomicalLandmarkCoordinates)
factor = checkunit(EEG.chaninfo, 'AnatomicalLandmarkCoordinateUnits');
fieldNames = fieldnames(bids.coordsystem.AnatomicalLandmarkCoordinates);
for iField = 1:length(fieldNames)
EEG.chaninfo.nodatchans(end+1).labels = fieldNames{iField};
EEG.chaninfo.nodatchans(end).type = 'FID';
EEG.chaninfo.nodatchans(end).X = bids.coordsystem.AnatomicalLandmarkCoordinates.(fieldNames{iField})(1)*factor;
EEG.chaninfo.nodatchans(end).Y = bids.coordsystem.AnatomicalLandmarkCoordinates.(fieldNames{iField})(2)*factor;
EEG.chaninfo.nodatchans(end).Z = bids.coordsystem.AnatomicalLandmarkCoordinates.(fieldNames{iField})(3)*factor;
end
EEG.chaninfo.nodatchans = convertlocs(EEG.chaninfo.nodatchans);
end
% import head position
% --------------------
if isfield(bids.coordsystem, 'DigitizedHeadPoints') && ~isempty(bids.coordsystem.DigitizedHeadPoints)
factor = checkunit(EEG.chaninfo, 'DigitizedHeadPointsCoordinateUnits');
try
headpos = readlocs(bids.coordsystem.DigitizedHeadPoints, 'filetype', 'sfp');
for iPoint = 1:length(headpos)
EEG.chaninfo.nodatchans(end+1).labels = headpos{iField};
EEG.chaninfo.nodatchans(end).type = 'HeadPoint';
EEG.chaninfo.nodatchans(end).X = headpos(iPoint).X*factor;
EEG.chaninfo.nodatchans(end).Y = headpos(iPoint).Y*factor;
EEG.chaninfo.nodatchans(end).Z = headpos(iPoint).Z*factor;
end
EEG.chaninfo.nodatchans = convertlocs(EEG.chaninfo.nodatchans);
catch
if ischar(bids.coordsystem.DigitizedHeadPoints)
fprintf('Could not read head points file %s\n', bids.coordsystem.DigitizedHeadPoints);
end
end
end
% coordinate transform factor
% ---------------------------
function factor = checkunit(chaninfo, field)
factor = 1;
if isfield(chaninfo, 'BIDS') && isfield(chaninfo.BIDS, field) && isfield(chaninfo, 'unit')
if isequal(chaninfo.BIDS.(field), 'mm') && isequal(chaninfo.unit, 'cm')
factor = 1/10;
elseif isequal(chaninfo.BIDS.(field), 'mm') && isequal(chaninfo.unit, 'm')
factor = 1/1000;
elseif isequal(chaninfo.BIDS.(field), 'cm') && isequal(chaninfo.unit, 'mm')
factor = 10;
elseif isequal(chaninfo.BIDS.(field), 'cm') && isequal(chaninfo.unit, 'm')
factor = 1/10;
elseif isequal(chaninfo.BIDS.(field), 'm') && isequal(chaninfo.unit, 'cm')
factor = 100;
elseif isequal(chaninfo.BIDS.(field), 'm') && isequal(chaninfo.unit, 'mm')
factor = 1000;
elseif isequal(chaninfo.BIDS.(field), chaninfo.unit)
factor = 1;
else
error('Unit not supported')
end
end
function nameout = cleanvarname(namein)
% Routine to remove unallowed characters from strings
% nameout can be use as a variable or field in a structure
% custom change
if strcmp(namein,'#')
namein = 'nb';
end
% 1st char must be a letter
for l=1:length(namein)
if isletter(namein(l))
nameout = namein(l:end);
break % exist for loop
end
end
% remove usual suspects
stringcheck = [strfind(namein,'('), ...
strfind(namein,')') ...
strfind(namein,'[') ...
strfind(namein,']') ...
strfind(namein,'{') ...
strfind(namein,'}') ...
strfind(namein,'-') ...
strfind(namein,'+') ...
strfind(namein,'*') ...
strfind(namein,'/') ...
strfind(namein,'#') ...
strfind(namein,'%') ...
strfind(namein,'&') ...
strfind(namein,'@') ...
];
if ~isempty(stringcheck)
nameout(stringcheck) = [];
end
% last check
if ~isvarname(nameout)
error('the variable name to use is still invalid, check chars to remove')
end