


EIDORS_OBJ: 'constructor' to create a eidors structure
USAGE: to get eidors_version
version = eidors_obj('eidors_version')
USAGE: as a constructor
obj = eidors_obj(type,name,prop1,value1, prop1, value2, ...)
type: obj type: fwd_model, inv_model, data, image
name: text string identifier for model (may be '')
prop1, value1, etc: properites and values for object
example: fwd_mdl = ...
eidors_obj('fwd_model','My FWD MODEL', ...
'nodes', NODES, 'elems', ELEMS, ...
OR construct from structure
obj = eidors_obj(type,obj);
example: fwd_mdl.nodes = NODES; .... %etc
fwd_mdl = eidors_obj('fwd_model',fwd_mdl);
All constructors will set the appropriate default
values for each type: image, fwd_model, inv_model, data
USAGE: to set values
obj = eidors_obj('set',obj,prop1,value1, prop1, value2, ...)
this will set the values of properties of the object. At the
same time, any cached values will be erased (because they may
depend on older properties of the model)
example:
eidors_obj('set',fwd_mdl, 'nodes', NEW_NODES);
USAGE: to cache values
eidors_obj('set-cache',obj, cachename,value1, dep_objs, ...)
obj= eidors_obj('get-cache',obj, cachename, dep_objs, ...)
this will get or set the values of cached properties of the object.
example: % set jacobian
eidors_obj('set-cache',fwd_mdl, 'jacobian', J):
example: % get jacobian or '[]' if not set
J= eidors_obj('get-cache',fwd_mdl, 'jacobian'):
However, in some cases, such as the Jacobian, the value depends
on other objects, such as the image background. In this case, use
example: % set jacobian
eidors_obj('set-cache',fwd_mdl, 'jacobian', J, homg_img):
example: % get jacobian or '[]' if not set
J= eidors_obj('get-cache',fwd_mdl, 'jacobian', homg_img):


0001 function obj_id= eidors_obj(type,name, varargin ); 0002 % EIDORS_OBJ: 'constructor' to create a eidors structure 0003 % USAGE: to get eidors_version 0004 % version = eidors_obj('eidors_version') 0005 % 0006 % USAGE: as a constructor 0007 % obj = eidors_obj(type,name,prop1,value1, prop1, value2, ...) 0008 % 0009 % type: obj type: fwd_model, inv_model, data, image 0010 % name: text string identifier for model (may be '') 0011 % prop1, value1, etc: properites and values for object 0012 % 0013 % example: fwd_mdl = ... 0014 % eidors_obj('fwd_model','My FWD MODEL', ... 0015 % 'nodes', NODES, 'elems', ELEMS, ... 0016 % 0017 % OR construct from structure 0018 % obj = eidors_obj(type,obj); 0019 % 0020 % example: fwd_mdl.nodes = NODES; .... %etc 0021 % fwd_mdl = eidors_obj('fwd_model',fwd_mdl); 0022 % 0023 % All constructors will set the appropriate default 0024 % values for each type: image, fwd_model, inv_model, data 0025 % 0026 % USAGE: to set values 0027 % obj = eidors_obj('set',obj,prop1,value1, prop1, value2, ...) 0028 % 0029 % this will set the values of properties of the object. At the 0030 % same time, any cached values will be erased (because they may 0031 % depend on older properties of the model) 0032 % 0033 % example: 0034 % eidors_obj('set',fwd_mdl, 'nodes', NEW_NODES); 0035 % 0036 % USAGE: to cache values 0037 % eidors_obj('set-cache',obj, cachename,value1, dep_objs, ...) 0038 % obj= eidors_obj('get-cache',obj, cachename, dep_objs, ...) 0039 % 0040 % this will get or set the values of cached properties of the object. 0041 % 0042 % example: % set jacobian 0043 % eidors_obj('set-cache',fwd_mdl, 'jacobian', J): 0044 % 0045 % example: % get jacobian or '[]' if not set 0046 % J= eidors_obj('get-cache',fwd_mdl, 'jacobian'): 0047 % 0048 % However, in some cases, such as the Jacobian, the value depends 0049 % on other objects, such as the image background. In this case, use 0050 % 0051 % example: % set jacobian 0052 % eidors_obj('set-cache',fwd_mdl, 'jacobian', J, homg_img): 0053 % 0054 % example: % get jacobian or '[]' if not set 0055 % J= eidors_obj('get-cache',fwd_mdl, 'jacobian', homg_img): 0056 0057 0058 % (C) 2005-10 Andy Adler. License: GPL version 2 or version 3 0059 % $Id: eidors_obj.m 4054 2013-05-24 11:35:25Z bgrychtol $ 0060 0061 if nargin==0 || ~ischar(type) 0062 error('cannot call eidors_obj with no arguments'); 0063 end 0064 0065 switch type 0066 case 'set' 0067 obj_id= set_obj( name, varargin{:} ); 0068 case 'get-cache' 0069 test_install 0070 obj_id = []; 0071 if status_check 0072 obj_id= get_cache_obj( name, varargin{:} ); 0073 end 0074 0075 case 'set-cache' 0076 test_install 0077 obj_id= []; 0078 if status_check 0079 set_cache_obj( name, varargin{:} ); 0080 end 0081 0082 case 'eidors_version' 0083 obj_id= '3.7.1'; % Update for New eidors version 0084 0085 case 'interpreter_version' 0086 obj_id= test_versions; 0087 % TODO: Add these functions 0088 % case 'eidors_path' 0089 % case 'eidors_dev_path' 0090 % case 'eidors_cache_path' 0091 otherwise 0092 test_install 0093 obj_id= new_obj( type, name, varargin{:} ); 0094 end 0095 0096 function ok = status_check 0097 ok = true; 0098 switch cache_status 0099 case 0 0100 ok = false; 0101 case 0.5 0102 dbs = dbstack; 0103 if cache_status(dbs(3).name) == 0 0104 ok = false; 0105 end 0106 if strcmp(dbs(3).name,'cache_shorthand') && cache_status(dbs(5).name) == 0 0107 ok = false; 0108 end 0109 end 0110 0111 function on = debug_status_check 0112 on = false; 0113 switch debug_status 0114 case 1 0115 on = true; 0116 case 0.5 0117 dbs = dbstack; 0118 if debug_status(dbs(3).name) == 1 0119 on = true; 0120 end 0121 end 0122 0123 0124 function out = cache_status(fname) 0125 global eidors_objects; 0126 if nargin == 0 0127 try 0128 out = eidors_objects.cache_enable; 0129 catch 0130 out = 1; 0131 end 0132 else 0133 out = ~any(strcmp(eidors_objects.cache_disabled_on,fname)); 0134 end 0135 0136 0137 function out = debug_status(fname) 0138 global eidors_objects; 0139 if nargin == 0 0140 try 0141 out = eidors_objects.debug_enable; 0142 catch 0143 out = 0; 0144 end 0145 else 0146 out = ~any(strcmp(eidors_objects.debug_enabled_on,fname)); 0147 end 0148 0149 0150 function test_install 0151 global eidors_objects; 0152 if isfield(eidors_objects,'max_cache_size'); return; end % OK 0153 error('EIDORS not correctly started. Did you do ">>run /path/to/eidors/startup"'); 0154 0155 function verstr = test_versions; 0156 ver= version; ver(ver=='.')=' '; 0157 ver = sscanf(ver,'%f'); ver=ver(:); 0158 0159 % Convert 7.8.1 to 7.008001 0160 verstr.ver = 1e-3.^(0:length(ver)-1) * ver(:); 0161 0162 if exist('OCTAVE_VERSION') == 5 0163 verstr.isoctave = 1; 0164 else 0165 verstr.isoctave = 0; 0166 end 0167 0168 cptr = computer; 0169 if strcmp(cptr(end+(-1:0)), '64') 0170 verstr.is64bit = 1; 0171 else 0172 verstr.is64bit = 0; 0173 end 0174 0175 function obj = set_obj( obj, varargin ); 0176 global eidors_objects 0177 0178 % eidors_objects.( obj_id ) = obj; 0179 % eidors_objects.( obj_id ).cache= []; %clear cache 0180 % 0181 0182 for idx= 1:2:nargin-1 0183 % obj.( obj_id ).( varargin{idx} )= varargin{idx+1}; 0184 % for matlab 6.1 compatibility 0185 eval(sprintf('obj.%s=varargin{%d};', varargin{idx},idx+1 )); 0186 end 0187 0188 % val= get_cache_obj( obj, prop, dep_obj1, dep_obj2, ..., cachename ); 0189 function value= get_cache_obj( obj, prop, varargin ); 0190 global eidors_objects 0191 value= []; 0192 0193 % We don't do this since cache directories aren't defined (yet) 0194 % [objlist, cachename]= proc_obj_list( varargin{:} ); 0195 0196 obj_id= calc_obj_id( obj ); % recalculate in case obj changed 0197 0198 if nargin==3 0199 objlist = varargin; 0200 for dep_obj = objlist{:} 0201 prop= [prop,'_', calc_obj_id(dep_obj)]; 0202 end 0203 end 0204 0205 % if cachename is specified, then cache to that file, rather 0206 % than to the standard eidors_objects location 0207 % TODO: fixthis - use ( ) for matlab > 6.0 0208 % if ~isempty( cachename ) 0209 % test_for_cachdir; 0210 % filename= [ eidors_objects.cachedir, '/' , prop, '_' cachename '.mat' ]; 0211 % if exist( filename, 'file') 0212 % load(filename); %variable 'value' should be there 0213 % end 0214 % else 0215 try 0216 value= eidors_objects.( obj_id ).cache.( prop ); 0217 % value= eval(sprintf('eidors_objects.%s.cache.%s;',obj_id,prop)); 0218 update_timestamp_and_check_size(obj_id); 0219 end 0220 % end 0221 0222 function set_cache_obj( obj, prop, value, varargin ) 0223 global eidors_objects 0224 if ~cache_this( obj ) ; return ; end 0225 0226 % Cache directories aren't defined, yet 0227 % [objlist, cachename]= proc_obj_list( varargin{:} ); 0228 0229 obj_id = calc_obj_id( obj ); 0230 0231 if nargin>=4 0232 objlist = varargin; 0233 for dep_obj = objlist{:} 0234 prop= [prop,'_', calc_obj_id(dep_obj)]; 0235 end 0236 end 0237 0238 % if isempty(cachename) 0239 eidors_objects.( obj_id ).cache.( prop ) = value; 0240 eidors_objects.( obj_id ).priority = eidors_objects.cache_priority; 0241 update_timestamp_and_check_size(obj_id); 0242 % else 0243 % filename= [ eidors_objects.cachedir, '/' , prop, '_' cachename '.mat' ]; 0244 % save(filename, 'value'); 0245 % end 0246 0247 function obj= new_obj( type, name, varargin ); 0248 global eidors_objects 0249 0250 if isstruct(name) 0251 obj= name; 0252 try 0253 name= obj.name; 0254 catch 0255 name= 'unknown'; 0256 end 0257 end 0258 0259 obj.type = type; 0260 obj.name = name; 0261 obj= set_obj(obj, varargin{:} ); 0262 0263 % This function hashes the value of the variable var 0264 % to create an obj_id. The goal is to allow proper caching 0265 % of calculated matrices, by detecting when a previous 0266 % calculation with same parameters has been made 0267 function obj_id= calc_obj_id( var ) 0268 try 0269 obj_id= eidors_var_id( var ); 0270 catch 0271 global eidors_objects; 0272 if ~isfield(eidors_objects,'hash_type') 0273 eidors_objects.hash_type= 1e8+1; 0274 end 0275 %if hashing code is unavailable, then disable caching function 0276 obj_id= sprintf('id_%08d', eidors_objects.hash_type ); 0277 eidors_objects.hash_type= eidors_objects.hash_type + 1; 0278 end 0279 0280 % Test whether the cachedir field has been set. This is 0281 % where eidors will store cached calculations. If it has 0282 % not been set, then create it as 'eidors_cache' in the 0283 % current directory 0284 % 0285 % NOTE: This code is not (yet) used 0286 function test_for_cachdir 0287 global eidors_objects; 0288 if ~isfield(eidors_objects, 'cachedir') 0289 cachedir= 'eidors_cache'; 0290 eidors_objects.cachedir= [pwd,'/',cachedir]; 0291 0292 if ~exist( eidors_objects.cachedir, 'dir') 0293 % Now we need to ensure that cachedir exists. Because the 0294 % STUPID!!! matlab has a completely useless and nonstandard 0295 % mkdir function, we try this 0296 mkdir(pwd,cachedir); 0297 end 0298 end 0299 0300 % Test whether a cachedir function has been provided 0301 % (by testing whether the last entry is a string). If so, 0302 % return it in objlist, otherwise return [] 0303 function [objlist, cachedir]= proc_obj_list( varargin ); 0304 cachedir= []; 0305 if nargin==0 0306 objlist= {}; 0307 elseif ischar(varargin{nargin}) 0308 cachedir= varargin{nargin}; 0309 objlist = varargin(1:nargin-1); 0310 else 0311 objlist = varargin(:); 0312 end 0313 0314 function retval= cache_this( obj ) 0315 % we choose not to cache data and images because this will 0316 % tend to fill up the workspace. 0317 % TODO: make the DONT_CACHE list use configuable 0318 if ~isstruct( obj); retval=1; return; end 0319 DONT_CACHE= {'data','image'}; 0320 if any(strcmp( obj.type, DONT_CACHE)); 0321 retval = 0; 0322 else 0323 retval = 1; 0324 end 0325 0326 function update_timestamp_and_check_size( obj_id ) 0327 global eidors_objects; 0328 0329 eidors_objects.( obj_id ).last_used = now; 0330 0331 max_memory= eidors_objects.max_cache_size; 0332 ww= whos('eidors_objects'); 0333 if ww.bytes > max_memory 0334 eidors_cache('clear_max',floor(max_memory*.75)); 0335 end 0336