-
Notifications
You must be signed in to change notification settings - Fork 3
/
safe_hw_from_asc.m
161 lines (122 loc) · 5.16 KB
/
safe_hw_from_asc.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
function hw = safe_hw_from_asc(fn_asc, verbose, mode)
% function hw = safe_hw_from_asc(fn_asc, verbose, mode)
%
% 2024-02-28 - FSz
% New version of funciton that is compatible with old and new hardware
% specification files. Old file format can be run in mode = 0, whereas the
% new format yields peripheral nerve stimulation parameters (PNS, mode = 1)
% or cardiac nerve stimation (CarNS, mode = 2).
if nargin < 2 || isempty(verbose)
verbose = 0;
end
if nargin < 3 || isempty(mode)
mode = -1;
end
switch mode
case {-1, 'auto'}
mode = safe_asc_fn_to_mode(fn_asc);
hw = safe_hw_from_asc(fn_asc, verbose, mode);
return
case {0, 'none'}
model = 'Peripheral';
prefix = '';
case {1, 'PNS'}
model = 'Peripheral';
prefix = '.PNS.';
case {2, 'CarNS'}
model = 'Cardiac';
prefix = '.CarNS.';
otherwise
error('Mode not recognized!')
end
[~,b,~] = fileparts(fn_asc);
hw.name = b;
hw.model = model;
hw.fn_asc = fn_asc;
STR = fileread(fn_asc);
STR = STR(~isspace(STR));
str = lower(STR);
str_list = {
'checksum=', 'checksum', '';
'$INCLUDE', 'dependency', '';
'GScaleFactorX=', 'x', 'g_scale';
'GScaleFactorY=', 'y', 'g_scale';
'GScaleFactorZ=', 'z', 'g_scale';
[prefix 'flgSWDStimulationLimitX='], 'x', 'stim_limit';
[prefix 'flgSWDStimulationLimitY='], 'y', 'stim_limit';
[prefix 'flgSWDStimulationLimitZ='], 'z', 'stim_limit';
[prefix 'flgSWDStimulationThresholdX='], 'x', 'stim_thresh';
[prefix 'flgSWDStimulationThresholdY='], 'y', 'stim_thresh';
[prefix 'flgSWDStimulationThresholdZ='], 'z', 'stim_thresh';
[prefix 'flgSWDTauX[0]='], 'x', 'tau1';
[prefix 'flgSWDTauX[1]='], 'x', 'tau2';
[prefix 'flgSWDTauX[2]='], 'x', 'tau3';
[prefix 'flgSWDTauY[0]='], 'y', 'tau1';
[prefix 'flgSWDTauY[1]='], 'y', 'tau2';
[prefix 'flgSWDTauY[2]='], 'y', 'tau3';
[prefix 'flgSWDTauZ[0]='], 'z', 'tau1';
[prefix 'flgSWDTauZ[1]='], 'z', 'tau2';
[prefix 'flgSWDTauZ[2]='], 'z', 'tau3';
[prefix 'flgSWDAX[0]='], 'x', 'a1';
[prefix 'flgSWDAX[1]='], 'x', 'a2';
[prefix 'flgSWDAX[2]='], 'x', 'a3';
[prefix 'flgSWDAY[0]='], 'y', 'a1';
[prefix 'flgSWDAY[1]='], 'y', 'a2';
[prefix 'flgSWDAY[2]='], 'y', 'a3';
[prefix 'flgSWDAZ[0]='], 'z', 'a1';
[prefix 'flgSWDAZ[1]='], 'z', 'a2';
[prefix 'flgSWDAZ[2]='], 'z', 'a3';
};
for i = 1:size(str_list, 1)
ind = strfind(str, lower([str_list{i,1}])) + length(str_list{i,1});
switch (str_list{i,1})
case 'checksum='
hw.(str_list{i,2}) = regexp( str((ind+4):end), '\d+', 'match', 'once' );
case '$INCLUDE'
hw.(str_list{i,2}) = regexp( STR(ind:end), '\w+', 'match', 'once' );
case {'GScaleFactorX=', 'GScaleFactorY=', 'GScaleFactorZ='}
% The scale factors are not explicitly attributed to PNS or CNS
% so we dont know which is which. Hopefully they are the same
% so we can just use one of them.
if numel(ind)<=1
hw.(str_list{i,2}).(str_list{i,3}) = sscanf(str(ind:end), '%g', 1);
else
for j = 1:numel(ind)
tmp(j) = sscanf(str(ind(j):end), '%g', 1);
end
if any(tmp-tmp(1))
% Here we have detected several values for the same
% parameter and we dont know for sure how to treat
% them. Remove at your own peril!
error('Several scale factors were found and the correct one cannot be determined!')
else
hw.(str_list{i,2}).(str_list{i,3}) = tmp(1);
end
end
otherwise
if numel(ind)>1
error('The string matching was not unique! DANGER! Try using specific mode 1 or 2!')
end
hw.(str_list{i,2}).(str_list{i,3}) = sscanf(str(ind:end), '%g', 1);
end
end
% At the introduction of XA20/30 systems (possibly earlier), the hardware specifications
% started having dependencies, such that the PNS parameters were taken from
% sibling systems. Therefore we attempt to complete the hw specifications
% from files that may be present in the same folder as the original
% .asc. This is a bit dangereous since it assumes a specific file structure.
if ~isempty(hw.dependency)
warning(['Reading PNS parameters from other system (' hw.name ' is based on ' hw.dependency ')'])
[a,b,c] = fileparts(fn_asc);
fn_asc_dep = [a filesep hw.dependency c];
hw_dep = safe_hw_from_asc(fn_asc_dep, verbose, mode);
hw = safe_hw_mergeIfNotEmpty(hw, hw_dep);
end
if verbose
try
safe_hw_verify(hw);
safe_hw_check(hw);
catch me
disp(me.message)
end
end