comparison m-toolbox/classes/@smodel/fromDatafile.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 % FROMDATAFILE Construct smodel object from filename AND parameter list
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % FUNCTION: fromDatafile
5 %
6 % DESCRIPTION: Construct smodel object from filename AND parameter list
7 %
8 % CALL: a = fromFilenameAndPlist(a, pli)
9 %
10 % PARAMETER: a: empty ltpda-model-object
11 % pli: plist-object (must contain the filename)
12 %
13 % FORMAT: The text file must have the following format:
14 %
15 % - Blank lines are ignored
16 % - Lines starting with a hash (#) are ignored
17 % (* see description part
18 % - The first continuous comment block will be put into the
19 % description field
20 % - The values for the model are defined with some keywords
21 % - Use only one line for a value
22 % - A colon after a keyword can be optionally inserted
23 % - The following keywords (inside the quotes) are mandatory
24 % and must be at the beginning of a line.
25 % 'expr' - the expression of the model
26 % 'params' - parameters which are used in the model
27 % 'values' - default values for the parameters
28 % 'xvar' - X-variable
29 % - The following keywords are optional
30 % 'xunits' - units of the x-axis
31 % 'yunits' - units of the y-axis
32 % 'xvals' - values for the X-variable
33 % - It is possible to read more than one model from a file.
34 % Use for this the indeces behind the keywords. For example
35 % expr(1,2): ...
36 % expr(3) ...
37 % - It is necessary that each mandatory keyword have an entry
38 % for each index. If a keyword have only one entry then will
39 % be this enty copied to all other models.
40 %
41 % VERSION: $Id: fromDatafile.m,v 1.2 2011/08/15 13:12:17 hewitson Exp $
42 %
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44
45 function mdl = fromDatafile(mdlin, pli)
46
47 utils.helper.msg(utils.const.msg.PROC1, 'constructing from filename and/or plist');
48
49 VERSION = '$Id: fromDatafile.m,v 1.2 2011/08/15 13:12:17 hewitson Exp $';
50
51 % get ltpda-model info
52 mi = smodel.getInfo('smodel', 'From ASCII File');
53
54 % Set the method version string in the minfo object
55 mi.setMversion([VERSION '-->' mi.mversion]);
56
57 % Get filename
58 file_name = find(pli, 'filename');
59
60 [pathstr, f_name, ext] = fileparts(file_name);
61
62 %%%%%%%%%% Get default parameter list %%%%%%%%%%
63 dpl = smodel.getDefaultPlist('From ASCII File');
64 pl = applyDefaults(dpl, pli);
65
66 pl = pset(pl, 'filename', [f_name ext]);
67 pl = pset(pl, 'filepath', pathstr);
68
69 dxunits = pl.find('xunits');
70 dyunits = pl.find('yunits');
71 dxvals = pl.find('xvals');
72 ddesc = pl.find('description');
73
74 %%%%%%%%%% read file %%%%%%%%%%
75 [fid,msg] = fopen (file_name, 'r');
76 if (fid < 0)
77 error ('### can not open file: %s \n### error msg: %s',file_name, msg);
78 end
79
80 firstCommentBlock = true;
81
82 desc = '';
83 expr = {};
84 params = {};
85 xvar = {};
86 values = {};
87
88 xvals = {};
89 xunits = {};
90 yunits = {};
91
92 while ~feof(fid)
93
94 fline = fgetl(fid);
95 fline = strtrim(fline);
96
97 if isempty(fline)
98 firstCommentBlock = isFirstCommentBlock(desc);
99 elseif fline(1) == '#'
100 if firstCommentBlock && ~isempty(strtrim(fline(2:end)))
101 desc = [desc, strtrim(fline(2:end)), '\n'];
102 end
103
104 elseif strcmpi(fline(1:4), 'expr')
105 firstCommentBlock = isFirstCommentBlock(desc);
106 [i,j,txt] = parseLine(fline, 'expr');
107 expr{i,j} = txt;
108
109 elseif strcmpi(fline(1:6), 'params')
110 firstCommentBlock = isFirstCommentBlock(desc);
111 [i,j,txt] = parseLine(fline, 'params');
112 params{i,j} = txt;
113
114 elseif strcmpi(fline(1:4), 'xvar')
115 firstCommentBlock = isFirstCommentBlock(desc);
116 [i,j,txt] = parseLine(fline, 'xvar');
117 xvar{i,j} = txt;
118
119 elseif strcmpi(fline(1:6), 'values')
120 firstCommentBlock = isFirstCommentBlock(desc);
121 [i,j,txt] = parseLine(fline, 'values');
122 values{i,j} = txt;
123
124 elseif strcmpi(fline(1:5), 'xvals')
125 firstCommentBlock = isFirstCommentBlock(desc);
126 [i,j,txt] = parseLine(fline, 'xvals');
127 xvals{i,j} = txt;
128
129 elseif strcmpi(fline(1:6), 'xunits')
130 firstCommentBlock = isFirstCommentBlock(desc);
131 [i,j,txt] = parseLine(fline, 'xunits');
132 xunits{i,j} = txt;
133
134 elseif strcmpi(fline(1:6), 'yunits')
135 firstCommentBlock = isFirstCommentBlock(desc);
136 [i,j,txt] = parseLine(fline, 'yunits');
137 yunits{i,j} = txt;
138
139 end
140
141 end
142 fclose(fid);
143
144 % Get maximum size of the smodel matrix
145 maxi = max([size(expr,1), size(params,1), size(xvar,1), size(values,1), size(xvals,1), size(xunits,1), size(yunits,1)]);
146 maxj = max([size(expr,2), size(params,2), size(xvar,2), size(values,2), size(xvals,2), size(xunits,2), size(yunits,2)]);
147
148 % Make some plausibly checks
149 % 1) Replicate the array to the maximum size of the used indices if the
150 % array have only one input.
151 % 2) The array must have the same size as the used indices.
152 if isempty(xunits)
153 xunits = {dxunits};
154 end
155 if isempty(yunits)
156 yunits = {dyunits};
157 end
158 if isempty(xvals)
159 xvals = {dxvals};
160 end
161 if ~isempty(ddesc)
162 desc = ddesc;
163 end
164 expr = checkArray(expr, maxi, maxj);
165 params = checkArray(params, maxi, maxj);
166 xvar = checkArray(xvar, maxi, maxj);
167 values = checkArray(values, maxi, maxj);
168 xvals = checkArray(xvals, maxi, maxj);
169 xunits = checkArray(xunits, maxi, maxj);
170 yunits = checkArray(yunits, maxi, maxj);
171
172 mdl = smodel.newarray([maxi, maxj]);
173
174 % Check mandatory fields
175 if isempty(expr) || isempty(params) || isempty(xvar) || isempty(values)
176 error('### At least one of the mandatory fields (''expr'', ''params'', ''xvar'', ''values'') is empty.');
177 end
178
179 % Create Object
180 for ii = 1:numel(mdl)
181
182 % mandatory fields
183 mdl(ii).expr = expr{ii};
184 mdl(ii).params = regexp(strtrim(params{ii}), ',', 'split');
185 mdl(ii).xvar = xvar{ii};
186 mdl(ii).values = cellfun(@str2num, regexp(strtrim(values{ii}), ',', 'split'));
187
188 % Optional fields
189 if ~isempty(xvals)
190 if ischar(xvals{ii})
191 mdl(ii).xvals = eval(xvals{ii});
192 else
193 mdl(ii).xvals = xvals{ii};
194 end
195 end
196 if ~isempty(xunits)
197 mdl(ii).xunits = xunits{ii};
198 end
199 if ~isempty(yunits)
200 mdl(ii).yunits = yunits{ii};
201 end
202 mdl(ii).description = desc(1:end-2); % remove the last break
203 mdl(ii).addHistory(mi, pl, [], []);
204
205 end
206
207 end
208
209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 % Local Functions %
211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
212
213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214 %
215 % FUNCTION: fromDatafile
216 %
217 % DESCRIPTION:
218 %
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 function flag = isFirstCommentBlock(desc)
221 if isempty(desc)
222 flag = true;
223 else
224 flag = false;
225 end
226 end
227
228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229 %
230 % FUNCTION: getIndex
231 %
232 % DESCRIPTION: Returns the index of the input string.
233 % '(3,2)' -> i=3, j=2
234 % '(3)' -> i=3, default: j=1
235 % '()' -> default i=1, default: j=1
236 % '' -> default i=1, default: j=1
237 %
238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
239 function [i,j] = getIndex(token)
240 ij = regexp(token, '\d*', 'match');
241 if numel(ij) == 2
242 i = eval(ij{1});
243 j = eval(ij{2});
244 elseif numel(ij) == 1
245 i = eval(ij{1});
246 j = 1;
247 else
248 i = 1;
249 j = 1;
250 end
251 end
252
253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254 %
255 % FUNCTION: parseLine
256 %
257 % DESCRIPTION: Returns the indices i,j and the remaining value for the
258 % given field.
259 %
260 % Example: expr: a+b*t -> i=1, j=1, txt=a+b*t
261 % expr a+b*t -> i=1, j=1, txt=a+b*t
262 % expr(3) a+b*t -> i=3, j=1, txt=a+b*t
263 % expr(3,2): a+b*t -> i=3, j=2, txt=a+b*t
264 %
265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 function [i,j,txt] = parseLine(lineIn, field)
267 exp = [field '(?<idx>\(\d*(,\d*)?\))?:? *'];
268 idx = regexp(lineIn, exp, 'end');
269 ij = regexp(lineIn, exp, 'names');
270 [i,j] = getIndex(ij(1).idx);
271 txt = lineIn(idx+1:end);
272 end
273
274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275 %
276 % FUNCTION: checkArray
277 %
278 % DESCRIPTION: There are the following rules
279 % 1) If the array have only one input then replicate this
280 % input to the maximum size of the used indices.
281 % 2) Throw an error if the inputs are more than one but not so
282 % much as the maximum of the used indices.
283 %
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285 function array = checkArray(array, maxi, maxj)
286 if numel(array) == 0
287 % Do nothing
288 elseif numel(array) == 1
289 array = repmat(array, maxi, maxj);
290 elseif size(array,1) ~= maxi || size(array,2) ~= maxj
291 error('### One model is not well defined. Max (i,j) = (%d,%d) but only used (%d,%d)', maxi, maxj, size(array,1), size(array,2));
292 end
293 end
294