IRootLab
An Open-Source MATLAB toolbox for vibrational biospectroscopy
gencode.m
Go to the documentation of this file.
1 %> @file
2 %> @ingroup codegen
3 
4 %> @ingroup codegen
5 %> @brief MATLAB code generation to create, boot, train and use blocks.
6 %>
7 %> @sa objtool.m, datatool.m, do_blockmenu.m
8 %>
9 classdef gencode < handle
10  properties
11  refblock;
12  classname;
13  dsnames = [];
14  params;
15  blockname;
16  flag_leave_block = 1;
17  end;
18 
19  properties(SetAccess=protected)
20  soutname1;
21  soutname2;
22  flag_started;
23  flag_data;
24  flag_handle; % whether the data is a handle class, just in case
25 
26  %> Whether the "u" object is in the workspace
27  flag_u = 0;
28  %> generated code
29  code = {};
30  %> Also generated code, but does not get emptied by @c execute()
31  allcode = {};
32  %> Name of the variable that the block has in the base workspace.
33  varname;
34  end;
35 
36  methods
37  function set.classname(o, z)
38  o.classname = z;
39  o.flag_started = 0;
40  end;
41 
42  function set.dsnames(o, z)
43  o.dsnames = z;
44  o.flag_started = 0;
45  end;
46 
47  function set.params(o, z)
48  o.params = z;
49  o.flag_started = 0;
50  end;
51 
52  function z = get.varname(o)
53  if o.flag_u
54  z = 'u';
55  else
56  z = o.blockname;
57  end;
58  end;
59  end;
60 
61  methods (Access=protected)
62  function o = assert_started(o)
63  if ~o.flag_started
64  o.start();
65  o.flag_started = 1;
66  end;
67  end;
68 
69 
70  %> Makes a string to represent the input data.
71  function sds = get_sds(o)
72  if o.refblock.flag_multiin
73  sds = '[';
74  for i = 1:length(o.dsnames);
75  if i > 1; sds = cat(2, sds, ', '); end;
76  sds = cat(2, sds, o.dsnames{i});
77  end;
78  sds = strcat(sds, ']');
79  else
80  sds = o.dsnames{1};
81  end;
82  end;
83 
84  %> Adds code
85  function o = add_code(o, code)
86  o.code{end+1} = code;
87  o.allcode{end+1} = code;
88  end;
89 
90 
91  %> Executes accumulated code
92  %> @param flag_finish Whether the execution is the last of a series (will add an extra LineFeed if so)
93  function o = execute(o, flag_finish)
94  if nargin < 2
95  flag_finish = 0;
96  end;
97  if numel(o.code) > 0
98 % temp = char(o.code);
99  ircode_eval(sprintf('%s', o.code{:}));
100  o.code = {};
101  end;
102 
103  if flag_finish
104  ircode_add(char(10));
105  end;
106  end;
107  end;
108 
109 
110  methods
111  function o = start(o)
112  if ~isempty(o.classname)
113  o.refblock = eval(o.classname); % instantializes the class in order to find out a few things
114  elseif ~isempty(o.blockname)
115  o.refblock = evalin('base', [o.blockname, ';']);
116  else
117  irerror('Cannot start: neither classname nor blockname set');
118  end;
119 
120  o.flag_data = ~isempty(o.dsnames);
121 
122 
123  o.code = {}; % Clears generated code
124  o.allcode = {};
125  o.flag_u = 0;
126 
127  o.add_code('');
128 % o.add_code(['% -- @ ', datestr(now), 10]);
129  end;
130 
131 
132  %> Generates code that creates new block
133  function o = m_create(o)
134  o.assert_started();
135 
136  o.add_code(sprintf('u = %s();\n', o.classname)); % C O D E - creates o.refblock
137  o.flag_u = 1;
138  if ~isempty(o.params)
139  o.add_code(params2str(o.params, 1)); % C O D E - sets parameters
140  end;
141 
142  o = o.execute();
143 
144  if o.flag_leave_block && o.flag_u
145  o.blockname = find_varname([o.classname]); % Name for the block
146  o = o.add_code(sprintf('%s = u;\n', o.blockname));
147  o.flag_u = 0;
148  o = o.execute();
149  end;
150  end;
151 
152  %> Generates code that boots the block
153  function o = m_boot(o)
154  o.assert_started();
155  if o.refblock.flag_bootable
156  o = o.add_code(sprintf('%s = %s.boot();\n', o.varname, o.varname));
157  end;
158  end;
159 
160 
161  %> Generates code that trains the block
162  function o = m_train(o)
163  o.assert_started();
164 
165  if ~o.flag_data
166  irerror('Cannot apply block: dataset names not provided!');
167  end;
168 
169  if o.refblock.flag_trainable > 0
170  o = o.add_code(sprintf('%s = %s.train(%s);\n', o.varname, o.varname, o.get_sds()));
171  end;
172  end;
173 
174  %> Generate code that uses the block
175  function o = m_use(o)
176  o.assert_started();
177 
178  if ~o.flag_data
179  irerror('Cannot apply block: dataset names not provided!');
180  end;
181 
182  sds = o.get_sds();
183 
184  if isa(o.refblock, 'vis') && o.refblock.flag_graphics
185  o = o.add_code(sprintf('figure;\n'));
186  end;
187 
188 
189  if o.refblock.flag_out
190  o = o.add_code(sprintf('out = %s.use(%s);\n', o.varname, sds));
191  o = extract_output(o);
192 
193  if isa(o.refblock, 'irreport')
194  o = o.open_in_browser();
195  end;
196  else
197  o = o.add_code(sprintf('%s.use(%s);\n', o.varname, sds));
198  end;
199  end;
200 
201 
202  %> Executes "generic" method from the block. Does not not pass any parameter to the block, i.e., it is assumed
203  %> that the block can execute the method using its own properties previously assigned.
204  function o = m_generic(o, what)
205  o.assert_started();
206 
207 % if ~o.flag_data
208 % irerror('Cannot apply block: dataset names not provided!');
209 % end;
210 
211 % sds = o.get_sds();
212 
213 % o = o.add_code(sprintf('out = %s.%s(%s);', o.varname, what, sds));
214 
215  o = o.add_code(sprintf('out = %s.%s();\n', o.varname, what));
216 
217  o = extract_output(o);
218  end;
219 
220  function o = extract_output(o)
221  o = o.assert_started();
222  o = o.execute(); %
223 
224  out = evalin('base', 'out;');
225  flag_cell = iscell(out);
226 
227  if o.flag_data
228  data = evalin('base', [o.dsnames{1}, ';']);
229 % o.flag_handle = isa(data, 'handle');
230  end;
231 
232 
233  if flag_cell
234  [ni, nj] = size(out);
235  else
236  ni = 1; nj = 1;
237  end;
238  for i = 1:ni
239  for j = 1:nj
240  if flag_cell
241  outij = out{i, j};
242  sij = sprintf('{%d, %d}', i, j);
243  else
244  outij = out;
245  sij = '';
246  end;
247 
248  if isa(outij, 'irdata')
249  suffix = get_suffix(class(o.refblock));
250  if o.flag_data
251  if o.refblock.flag_multiin
252  outname = find_varname([class(data) '_' suffix]);
253  else
254  outname = find_varname([o.dsnames{1} '_' suffix]);
255  end;
256  else
257  outname = find_varname([class(outij), '_', suffix]);
258  end;
259 
260  if numel(outij) > 1
261  for k = 1:numel(outij)
262  o = o.add_code(sprintf('%s_%02d = out%s(%d);\n', outname, k, sij, k));
263  end;
264  else
265  o = o.add_code(sprintf('%s = out%s;\n', outname, sij));
266  end;
267 
268  else
269  % Anything else than datasets will be made into a decent name, but not extracted if it is an array.
270 
271  suffix = get_suffix(class(o.refblock));
272  outname = find_varname([class(outij), '_', suffix]);
273  o = o.add_code(sprintf('%s = out%s;\n', outname, sij));
274 
275  end;
276 
277  o = o.execute();
278  end;
279  end;
280  end;
281 
282 
283  function o = open_in_browser(o)
284  o = o.add_code(sprintf('out.open_in_browser();\n'));
285  end;
286 
287  function o = finish(o)
288  o = o.execute(1);
289  end;
290  end;
291 end
function irerror(in s)
function objtool(in varargin)
function params2str(in params, in flag_o)
Visualization base class.
Definition: vis.m:4
Base Block class.
Definition: block.m:2
function get_suffix(in clname, in no_trim)
function ircode_add(in s, in title)
function ircode_eval(in s, in title)
function do_blockmenu(in classname, in dsnames, in flag_leave_block)
Report base class.
Definition: irreport.m:8
function find_varname(in prefix)
MATLAB code generation to create, boot, train and use blocks.
Definition: gencode.m:9