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