0001 function [obj_id, extra_out] = eidors_obj(type,name, varargin )
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 if isstruct(type)
0054 if isfield(type,'type');
0055 obj_id = type.type;
0056 else
0057 obj_id = '{non-eidors}';
0058 end
0059 return
0060 end
0061
0062 if ~ischar(type);
0063 obj_id = [];
0064 return
0065 end
0066
0067 if nargin==0
0068 error('cannot call eidors_obj with no arguments');
0069 end
0070
0071
0072 switch type
0073 case 'UNIT_TEST';
0074 do_unit_test; return
0075
0076 case 'set'
0077 obj_id= set_obj( name, varargin{:} );
0078 case 'get-cache'
0079 test_install
0080 obj_id = []; extra_out= [];
0081 if status_check(varargin{1})
0082 [obj_id, extra_out] = get_cache_obj( name, varargin{:} );
0083 end
0084
0085 case 'set-cache'
0086 test_install
0087 obj_id= [];
0088 if status_check(varargin{1})
0089 obj_id = set_cache_obj( name, varargin{:} );
0090 end
0091
0092 case 'eidors_version'
0093 obj_id= '3.12';
0094
0095 case 'eidors_path'
0096 global eidors_objects
0097 obj_id = eidors_objects.eidors_path;
0098
0099 case 'interpreter_version'
0100 obj_id= test_versions;
0101
0102
0103
0104
0105
0106 case 'cache_init'
0107 cache_init;
0108
0109 otherwise
0110 test_install
0111 obj_id= new_obj( type, name, varargin{:} );
0112 end
0113
0114 function ok = status_check(name)
0115 ok = true;
0116 switch cache_status
0117 case 0
0118 ok = false;
0119 case 0.5
0120 dbs = dbstack;
0121 if cache_status(dbs(3).name) == 0
0122 ok = false;
0123 end
0124 if strcmp(dbs(3).name,'cache_shorthand') && cache_status(dbs(5).name) == 0
0125 ok = false;
0126 end
0127 if cache_status(name) == 0
0128 ok = false;
0129 end
0130 end
0131
0132 function on = debug_status_check
0133 on = false;
0134 switch debug_status
0135 case 1
0136 on = true;
0137 case 0.5
0138 dbs = dbstack;
0139 if debug_status(dbs(3).name) == 1
0140 on = true;
0141 end
0142 end
0143
0144
0145 function out = cache_status(fname)
0146 global eidors_objects;
0147 if nargin == 0
0148 try
0149 out = eidors_objects.cache_enable;
0150 catch
0151 out = 1;
0152 end
0153 else
0154 out = ~any(strcmp(eidors_objects.cache_disabled_on,fname));
0155 end
0156
0157
0158 function out = debug_status(fname)
0159 global eidors_objects;
0160 if nargin == 0
0161 try
0162 out = eidors_objects.debug_enable;
0163 catch
0164 out = 0;
0165 end
0166 else
0167 out = ~any(strcmp(eidors_objects.debug_enabled_on,fname));
0168 end
0169
0170
0171 function test_install
0172 global eidors_objects;
0173 if isfield(eidors_objects,'max_cache_size'); return; end
0174 error('EIDORS not correctly started. Did you do ">>run /path/to/eidors/startup"');
0175
0176 function verstr = test_versions;
0177 ver= version; ver(ver=='.')=' ';
0178 ver = sscanf(ver,'%f'); ver=ver(:);
0179
0180
0181 ver(4:end) = [];
0182
0183
0184 verstr.ver = 1e-3.^(0:length(ver)-1) * ver(:);
0185
0186 if exist('OCTAVE_VERSION') == 5
0187 verstr.isoctave = 1;
0188 else
0189 verstr.isoctave = 0;
0190 end
0191
0192 cptr = computer;
0193 if strcmp(cptr(end+(-1:0)), '64')
0194 verstr.is64bit = 1;
0195 else
0196 verstr.is64bit = 0;
0197 end
0198
0199 function obj = set_obj( obj, varargin );
0200 for idx= 1:2:nargin-1
0201 obj.( varargin{idx} )= varargin{idx+1};
0202 end
0203 obj = order_fields(obj);
0204
0205 function obj = order_fields(obj)
0206 if ~isfield(obj, 'type'), return, end
0207 switch obj.type
0208 case 'fwd_model'
0209 field_order = {'type', 'name',...
0210 'nodes', 'elems', 'boundary', ...
0211 'electrode', ...
0212 'stimulation', 'meas_select', ...
0213 'solve', 'jacobian', 'system_mat', ...
0214 'normalize_measurements', 'gnd_node', ...
0215 'boundary_numbers','mat_idx', 'mat_names'};
0216 case 'inv_model'
0217 field_order = {'type', 'name',...
0218 'fwd_model', 'rec_model','jacobian_bkgnd' ...
0219 'reconst_type','solve', ...
0220 'hyperparameter'};
0221 case 'rec_model'
0222 field_order = {'type', 'name',...
0223 'nodes', 'elems'};
0224 case 'image'
0225 field_order = {'type', 'name', 'fwd_model', ...
0226 'elem_data', 'node_data'};
0227 case 'data'
0228 field_order = {'type', 'name', 'meas'};
0229 otherwise
0230 warning(['Encountered an unexpected object type: ', obj.type, ...
0231 'Please report on the eidors mailing list if it''s not your typo.'])
0232 return
0233 end
0234
0235 fnames = fieldnames(obj);
0236 [~,known_idx] = ismember(fnames,field_order);
0237 field_idx = find(known_idx);
0238 known_order = sortrows([nonzeros(known_idx), field_idx]);
0239
0240 [~, unknown_order] = sort(fnames(known_idx==0));
0241
0242 perm = zeros(numel(fnames),1);
0243 perm(1:numel(field_idx)) = known_order(:,2);
0244 perm(numel(field_idx) + unknown_order) = find(known_idx==0);
0245
0246 obj = orderfields(obj,perm);
0247
0248 try obj.fwd_model = order_fields(obj.fwd_model); end
0249 try obj.rec_model = order_fields(obj.rec_model); end
0250
0251
0252
0253 function [value, obj_id] = get_cache_obj( obj, prop )
0254 global eidors_objects
0255 DEBUG = eidors_debug('query','eidors_obj');
0256
0257 value= [];
0258 obj_id = [];
0259
0260 if DEBUG, str = sprintf('cache request: %s ',prop); end
0261
0262
0263
0264 if ~isfield(eidors_objects, 'cache')
0265 cache_init;
0266 if DEBUG, fprintf('%s: NO CACHE FIELD\n',str); end
0267 return
0268 end
0269
0270 obj_id= calc_obj_id( { obj, prop} );
0271
0272 if isempty(eidors_objects.cache.meta),
0273 if DEBUG, fprintf('%s: NO META FIELD\n',str); end
0274 return
0275 end
0276 c = eidors_objects.cache.cols;
0277
0278
0279
0280 if DEBUG, str = [str, obj_id]; end
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 if ~isfield( eidors_objects.cache, obj_id);
0293 if DEBUG, fprintf('%s: not found\n',str); end
0294 return
0295 end
0296
0297 idx = find(strcmp(obj_id, eidors_objects.cache.meta(:,c.obj_id)), 1, 'first');
0298 if DEBUG && isempty(idx), fprintf('%s: EMPTY IDX !!\n',str); end
0299 if ~isempty(idx)
0300 eidors_objects.cache.meta{idx,c.time} = now;
0301 eidors_objects.cache.meta{idx,c.count} = eidors_objects.cache.meta{idx,c.count} + 1;
0302 eidors_objects.cache.meta{idx,c.score_eff} = calc_effort_score(...
0303 eidors_objects.cache.meta{idx,c.effort}, ...
0304 eidors_objects.cache.meta{idx,c.count}, ...
0305 eidors_objects.cache.meta{idx,c.prio});
0306 end
0307 value = eidors_objects.cache.(obj_id);
0308 if DEBUG, fprintf('%s: found\n',str); end
0309
0310
0311
0312
0313
0314 function obj_id = set_cache_obj( obj, prop, value, time )
0315 global eidors_objects
0316 obj_id = [];
0317
0318 if ~cache_this( obj ) ; return ; end
0319
0320 if nargin < 4
0321 time = 1;
0322 end
0323
0324 if ~isfield(eidors_objects,'cache');
0325 init_cache;
0326 end
0327
0328 c = eidors_objects.cache.cols;
0329
0330
0331
0332
0333 obj_id = calc_obj_id( {obj, prop} );
0334
0335 prio = eidors_objects.cache_priority;
0336
0337
0338
0339 ws = whos('value');
0340 row(c.obj_id) = {obj_id};
0341 row(c.prop) = {prop};
0342 row(c.size) = {ws.bytes};
0343 row(c.score_sz) = {calc_size_score(ws.bytes)};
0344 row(c.effort) = {time};
0345 row(c.prio) = {prio};
0346 row(c.count) = {1};
0347 row(c.score_eff)= {calc_effort_score(time, 1, prio)};
0348 row(c.time) = {now};
0349
0350 if isfield(eidors_objects.cache, obj_id)
0351 idx = find(strcmp(obj_id, eidors_objects.cache.meta(:,c.obj_id)));
0352 eidors_msg('@@ replaced cache object %s { %s }', obj_id, prop,4);
0353 eidors_objects.cache.size = eidors_objects.cache.size ...
0354 - eidors_objects.cache.meta{idx,c.size};
0355
0356 else
0357 idx = size(eidors_objects.cache.meta, 1) + 1;
0358 end
0359 eidors_objects.cache.meta(idx,:) = row;
0360 eidors_objects.cache.( obj_id ) = value;
0361 eidors_objects.cache.size = eidors_objects.cache.size + ws.bytes;
0362 check_size(obj_id, prop);
0363
0364
0365
0366
0367
0368 function cache_init
0369 global eidors_objects;
0370
0371 eidors_objects.cache = struct;
0372 eidors_objects.cache.meta = cell(0);
0373 eidors_objects.cache.cols.obj_id = 1;
0374 eidors_objects.cache.cols.prop = 2;
0375 eidors_objects.cache.cols.time = 3;
0376 eidors_objects.cache.cols.size = 4;
0377 eidors_objects.cache.cols.score_sz = 5;
0378 eidors_objects.cache.cols.effort = 6;
0379 eidors_objects.cache.cols.prio = 7;
0380 eidors_objects.cache.cols.count = 8;
0381 eidors_objects.cache.cols.score_eff = 9;
0382 eidors_objects.cache.size = 0;
0383
0384 function score = calc_size_score(sz)
0385 if iscell(sz)
0386 fn = @(b) round(10*log10(b / 1024));
0387 N = numel(sz);
0388 score = num2cell(cellfun(fn, sz));
0389 else
0390 score = round(10 * log10( sz / 1024));
0391 end
0392
0393 function score = calc_effort_score( time, counts, prios)
0394 if iscell(time)
0395 score = num2cell( round(10*log10( cell2mat(time) .* cell2mat(counts))) +...
0396 cell2mat(prios));
0397 else
0398 score = round(10*log10(time .* counts)) + prios;
0399 end
0400
0401
0402 function obj= new_obj( type, name, varargin );
0403 if isstruct(name)
0404 obj= name;
0405 try
0406 name= obj.name;
0407 catch
0408 name= 'unknown';
0409 end
0410 end
0411
0412 obj.type = type;
0413 obj.name = name;
0414 obj= set_obj(obj, varargin{:} );
0415
0416
0417
0418
0419
0420 function obj_id= calc_obj_id( var )
0421 try
0422 obj_id= eidors_var_id( var );
0423 catch
0424 global eidors_objects;
0425 if ~isfield(eidors_objects,'hash_type')
0426 eidors_objects.hash_type= 1e8+1;
0427 end
0428
0429 obj_id= sprintf('id_%031d%08d', 0,eidors_objects.hash_type );
0430 eidors_objects.hash_type= eidors_objects.hash_type + 1;
0431 end
0432
0433
0434
0435
0436
0437
0438
0439 function test_for_cachdir
0440 global eidors_objects;
0441 if ~isfield(eidors_objects, 'cachedir')
0442 cachedir= 'eidors_cache';
0443 eidors_objects.cachedir= [pwd,'/',cachedir];
0444
0445 if ~exist( eidors_objects.cachedir, 'dir')
0446
0447
0448
0449 mkdir(pwd,cachedir);
0450 end
0451 end
0452
0453
0454
0455
0456 function [objlist, cachedir]= proc_obj_list( varargin );
0457 cachedir= [];
0458 if nargin==0
0459 objlist= {};
0460 elseif ischar(varargin{nargin})
0461 cachedir= varargin{nargin};
0462 objlist = varargin(1:nargin-1);
0463 else
0464 objlist = varargin(:);
0465 end
0466
0467 function retval= cache_this( obj )
0468
0469
0470
0471 if ~isstruct( obj); retval=1; return; end
0472 DONT_CACHE= {'data','image'};
0473 if any(strcmp( obj.type, DONT_CACHE));
0474 retval = 0;
0475 else
0476 retval = 1;
0477 end
0478
0479 function check_size( obj_id , prop )
0480 global eidors_objects;
0481
0482
0483 max_memory= eidors_objects.max_cache_size;
0484
0485 if eidors_objects.cache.size > max_memory
0486 eidors_cache('clear_max',floor(max_memory*.75));
0487 end
0488
0489
0490 function do_unit_test
0491 im = eidors_obj('image','','elem_data',1);
0492 et = eidors_obj(im);
0493 unit_test_cmp('type 0',et,'image');
0494
0495