0001 function img = data_mapper(img, reverse)
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 if ischar(img) && strcmp(img,'UNIT_TEST'); img = do_unit_test; return; end
0039
0040 if nargin < 2
0041 reverse = false;
0042 elseif ischar(reverse) && strcmpi(reverse, 'pack')
0043 reverse = false;
0044 else
0045 reverse = true;
0046 end
0047
0048 for i = 1:length(img)
0049 if reverse
0050 tmp(i) = unpack_params(img(i));
0051 else
0052 tmp(i) = pack_params(img(i));
0053 end
0054 end
0055 img = tmp;
0056 end
0057
0058 function img = pack_params(img);
0059
0060 flds = fieldnames(img);
0061 prms = ismember(flds, supported_params);
0062
0063 switch sum(prms)
0064 case 0
0065
0066 if ~( isfield(img,'elem_data') || isfield(img,'node_data'))
0067 error('No params, elem_data or node_data found on img');
0068 else
0069 if isfield(img,'current_params') && ~isempty(img.current_params)
0070 eidors_msg('@@@ Careful! Image already mapped. Doing nothing',4);
0071 return;
0072 end
0073
0074 eidors_msg('@@@ No params present on img. Assuming conductivity',4);
0075
0076
0077
0078 for i=1:length(img)
0079 img(i).current_params = 'conductivity';
0080 end
0081 end
0082 return
0083 case 1
0084 ph = find(prms);
0085 if isfield(img.(flds{ph}),'func')
0086
0087 img = feval(img.(flds{ph}).func, img);
0088 return
0089 else
0090 img = pack_params_using_params_str(img, flds{ph});
0091 end
0092 otherwise
0093
0094 try
0095 prms_fun = img.data_mapper;
0096 catch
0097 error('Multiple params found on img require: img.data_mapper = function or {"string","array"}');
0098 end
0099 if ~isa(prms_fun, 'function_handle') && ismember(prms_fun,flds);
0100 img = pack_params_using_params_str(img, prms_fun);
0101 else
0102 try
0103 img = feval(prms_fun,img);
0104 catch
0105 error('img.data_mapper not understood');
0106 end
0107 end
0108
0109 end
0110 end
0111
0112 function img = pack_params_using_params_str(img, prms)
0113
0114 prms_flds = fieldnames(img.(prms));
0115 for i = 1:length(prms_flds)
0116 if isfield(img, prms_flds{i})
0117 eidors_msg('@@@ Overwriting img.%s',prms_flds{i},4);
0118 warning('EIDORS:OverwritingData', 'Overwriting img.%s',prms_flds{i});
0119 end
0120
0121 if strcmp(prms_flds{i},'elem_data') && numel(img.(prms).elem_data) == 1
0122 n_elem = calc_num_elems(img.fwd_model);
0123 img.elem_data = ones(n_elem,1);
0124 img.elem_data(:) = img.(prms).elem_data;
0125 elseif strcmp(prms_flds{i},'node_data')
0126 img.node_data = ones(size(img.fwd_model.nodes,1),1);
0127 img.node_data(:) = img.(prms).node_data;
0128 else
0129 img.(prms_flds{i}) = img.(prms).(prms_flds{i});
0130 end
0131 end
0132 img.current_params = prms;
0133 end
0134
0135 function n = calc_num_elems(fmdl)
0136 if isfield(fmdl, 'coarse2fine')
0137 n = size(fmdl.coarse2fine,2);
0138 else
0139 n = length(fmdl.elems);
0140 end
0141 end
0142
0143 function img = copy_data_to_params(img, prms)
0144 prms_flds = fieldnames(img.(prms));
0145 try
0146 for i = 1:length(prms_flds)
0147 img.(prms).(prms_flds{i}) = img.(prms_flds{i});
0148 img = rmfield(img, prms_flds{i});
0149 end
0150 img = rmfield(img, 'current_params');
0151 catch
0152 error('Fields specified by img.%s missing from img.',prms);
0153 end
0154 end
0155
0156 function img = unpack_params(img)
0157 try
0158 curprms = img.current_params;
0159 catch
0160 if isfield(img,'elem_data') || isfield(img, 'node_data')
0161 return
0162 else
0163 error('img.current_params required');
0164 end
0165 end
0166 if ismember(curprms, fieldnames(img))
0167 img = copy_data_to_params(img,curprms);
0168 elseif strcmp(curprms,'conductivity')
0169
0170 if ~any(ismember(fieldnames(img),supported_params))
0171
0172
0173 img = rmfield(img, 'current_params');
0174 else
0175 error('Cannot reverse %s mapping',curprms);
0176 end
0177 else
0178 try
0179
0180 img = feval(curprms,img,1);
0181 catch
0182 error('data_mapper %s failed to reverse', curprms);
0183 end
0184 end
0185 end
0186
0187 function pass = do_unit_test
0188 pass = 1;
0189 pass = do_unit_test_legacy() && pass;
0190 pass = do_unit_test_undo() && pass;
0191 disp('');
0192 if pass
0193 disp('TEST: overall PASS');
0194 else
0195 error('TEST: overall FAIL');
0196 end
0197 end
0198
0199 function pass = do_unit_test_legacy
0200 pass = 1;
0201 ll = eidors_msg('log_level');
0202 eidors_msg('log_level',3);
0203
0204 imdl = mk_common_model('a2c2',8);
0205 c = 3*ones(length(imdl.fwd_model.elems),1);
0206 img = eidors_obj('image','test_image','fwd_model',imdl.fwd_model);
0207 img.conductivity.elem_data = c;
0208
0209 fprintf('TEST: mv img.conductivity.elem_data to img.elem_data\n');
0210 imgi = data_mapper(img, 'pack');
0211 if ~isfield(imgi, 'elem_data')
0212 imgi
0213 disp('TEST FAIL: missing elem_data');
0214 pass = 0;
0215 end
0216
0217 imgi2 = data_mapper(img, 'pack');
0218
0219 imgii = data_mapper(imgi,'unpack');
0220 if ~isequaln(imgii, img)
0221 img
0222 imgii
0223 fprintf('TEST FAIL: pack to unpack returned different result\n');
0224 pass = 0;
0225 end
0226
0227 img.resistivity.elem_data = 1./c;
0228 img.data_mapper = 'resistivity';
0229 img = data_mapper(img);
0230 if abs(img.elem_data(1) - 1/3) > 1e-4
0231 img.elem_data(1)
0232 pass = 0;
0233 disp('TEST FAIL: expected img.elem_data to be ~1/3');
0234 end
0235
0236 img.data_mapper = @unit_test_passthrough;
0237 imgf = data_mapper(img);
0238
0239 if ~isequaln(imgf, img)
0240 img
0241 imgf
0242 fprintf('TEST FAIL: pass-through function failed\n');
0243 pass = 0;
0244 end
0245
0246 eidors_msg('log_level',ll);
0247 if ~pass
0248 disp('TEST: ---------------------------------------');
0249 end
0250 end
0251
0252 function img = unit_test_passthrough(img1,rev)
0253 img = img1;
0254 end
0255
0256 function pass = do_unit_test_undo
0257 pass = 1;
0258
0259 imdl = mk_common_model('c2c', 16);
0260 img = mk_image(imdl);
0261 d = img.elem_data;
0262 img0 = rmfield(img, 'elem_data');
0263
0264 disp('TEST: img.elem_data');
0265 img = img0; img.elem_data = d;
0266 pass = test_undo(img, d, 'elem_data') && pass;
0267
0268 disp('TEST: img.node_data');
0269 img = img0; img.node_data = d;
0270 pass = test_undo(img, d, 'node_data') && pass;
0271
0272 disp('TEST: img.conductivity.elem_data');
0273 img = img0; img.conductivity.elem_data = d;
0274 pass = test_undo(img, d, 'elem_data') && pass;
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 end
0288
0289
0290 function pass = test_undo(img, d, dl)
0291 pass = 1;
0292 imgp = data_mapper(img);
0293 imgup = data_mapper(imgp,'unpack');
0294 if ~isequaln(img, imgup)
0295 img
0296 imgp
0297 imgup
0298 disp('TEST FAIL: the initial image and the image after being packed, then unpacked differ');
0299 pass = 0;
0300 end
0301 if ~isequaln(imgp.(dl), d)
0302 disp(['TEST FAIL: the packed data imgp.' dl ' seems broken']);
0303 pass = 0;
0304 end
0305 if ~pass
0306 disp('TEST: ---------------------------------------');
0307 end
0308 end