Mercurial > hg > ltpda
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 |