0001 function [inv_mdl,opt_out]= select_imdl( mdl, options )
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 if ischar(mdl) && strcmp(mdl,'UNIT_TEST'); do_unit_test; return; end
0037
0038 if nargin == 1; options = {}; end
0039
0040 switch mdl.type
0041 case 'inv_model'; inv_mdl = mdl;
0042 case 'fwd_model'; inv_mdl = basic_imdl( mdl );
0043 case 'image'; inv_mdl = basic_imdl( mdl.fwd_model, mdl.elem_data );
0044 otherwise; error('select_imdl: expects inv_model or fwd_model input');
0045 end
0046
0047 opt_out = struct();
0048 if ischar(options); options = {options}; end
0049 for i=1:length(options);
0050
0051
0052
0053
0054
0055
0056
0057 opt= regexp(options{i},'(.[^=:]*)[=:]?(.*)','tokens'); opt= opt{1};
0058 switch opt{1}
0059 case 'NOSER dif'; inv_mdl = NOSER_dif( inv_mdl );
0060 case 'Basic GN dif'; inv_mdl = Basic_GN_Dif( inv_mdl );
0061 case 'Basic GN abs'; inv_mdl = Basic_GN_Abs( inv_mdl );
0062 case 'Nodal GN dif'; inv_mdl = Nodal_GN_Dif( inv_mdl );
0063 case 'TV solve dif'; inv_mdl = TV_solve_Dif( inv_mdl );
0064 case 'Elec Move GN'; inv_mdl = Elec_Move_GN( inv_mdl );
0065 case 'Choose NF'; inv_mdl = Choose_NF( inv_mdl, str2num(opt{2}) );
0066 case 'GREIT'; [inv_mdl,opt_out] = GREIT(inv_mdl, opt{2});
0067
0068 otherwise; error('option {%s} not understood', options{i});
0069 end
0070 end
0071
0072
0073 inv_mdl = eidors_obj('inv_model',inv_mdl);
0074
0075
0076 valid_inv_model(inv_mdl);
0077
0078
0079 function imdl = basic_imdl( fmdl, elem_data );
0080 if nargin<=1; elem_data = 1; end
0081 imdl.name= 'Basic imdl from select_imdl';
0082 imdl.type= 'inv_model';
0083
0084 imdl.solve= 'eidors_default';
0085 imdl.hyperparameter.value = .01;
0086 imdl.RtR_prior = 'eidors_default';
0087 imdl.jacobian_bkgnd.value = elem_data;
0088 imdl.reconst_type= 'difference';
0089 imdl.fwd_model = fmdl;
0090
0091 function imdl = NOSER_dif( imdl );
0092 imdl.RtR_prior = @prior_noser;
0093 try; imdl = rmfield(imdl,'R_prior'); end
0094 imdl.hyperparameter.value = .03;
0095 imdl.solve= @inv_solve_diff_GN_one_step;
0096 imdl.reconst_type= 'difference';
0097
0098 function imdl = Basic_GN_Dif( imdl );
0099 imdl.RtR_prior = @prior_laplace;
0100 try; imdl = rmfield(imdl,'R_prior'); end
0101 imdl.solve= @inv_solve_diff_GN_one_step;
0102 imdl.reconst_type= 'difference';
0103
0104 function imdl = Basic_GN_Abs( imdl );
0105 imdl.RtR_prior = @prior_laplace;
0106 try; imdl = rmfield(imdl,'R_prior'); end
0107 imdl.solve= @inv_solve_gn;
0108 imdl.inv_solve_gn.max_iterations= 10;
0109 imdl.reconst_type= 'absolute';
0110
0111 function imdl = TV_solve_Dif( imdl );
0112 imdl.R_prior = @prior_TV;
0113 try; imdl = rmfield(imdl,'RtR_prior'); end
0114 imdl.solve= @inv_solve_TV_pdipm;
0115 imdl.reconst_type= 'difference';
0116 imdl.inv_solve.max_iterations= 15;
0117 imdl.hyperparameter.value = 1e-1;
0118 imdl.inv_solve.term_tolerance = 1e-3;
0119
0120 function imdl = Elec_Move_GN( imdl );
0121
0122 imdl.fwd_model.conductivity_jacobian = imdl.fwd_model.jacobian;
0123 imdl.fwd_model.jacobian = @jacobian_movement;
0124
0125
0126 try
0127 imdl.prior_movement.RegC.func = imdl.RtR_prior;
0128 catch
0129 imdl.prior_movement.RegC.func = @prior_laplace;
0130
0131 end
0132
0133 imdl.RtR_prior = @prior_movement;
0134 MV_prior = 1./mean( std( imdl.fwd_model.nodes ));
0135 imdl.prior_movement.parameters = MV_prior;
0136
0137 imdl.solve= @inv_solve_diff_GN_one_step;
0138
0139
0140 try
0141 hp = imdl.hyperparameter.value;
0142 catch
0143 hp = 0.03;
0144 end
0145 imdl.hyperparameter.value = hp;
0146
0147 try
0148 n_elems = size(imdl.rec_model.coarse2fine,2);
0149 catch
0150 n_elems = size(imdl.fwd_model.elems,1);
0151 end
0152 imdl.inv_solve.select_parameters = 1:n_elems;
0153
0154 imdl.prior_use_fwd_not_rec = 1;
0155
0156 function imdl = Nodal_GN_Dif( imdl );
0157 imdl.solve = @nodal_solve;
0158
0159 function [imdl,opt] = GREIT(inv_mdl, opts)
0160 opt.square_pixels = true;
0161 opt.noise_figure = 0.5;
0162 opt.imgsz = [32 32];
0163
0164 opt.keep_model_components = true;
0165 radius = 0.2;
0166
0167 vrange = 0.2;
0168 matches = regexp(opts,'\S+','match');
0169 for i=1:length(matches); mi = matches{i};
0170 tok= regexp(mi,'NF=([\d\.]+)','tokens');
0171 if ~isempty(tok);
0172 opt.noise_figure = str2num(tok{1}{1});
0173 end
0174
0175 tok= regexp(mi,'rad=([\d\.]+)','tokens');
0176 if ~isempty(tok);
0177 radius = str2num(tok{1}{1});
0178 end
0179
0180 tok= regexp(mi,'vrange=([\d\.]+)','tokens');
0181 if ~isempty(tok);
0182 vrange = str2num(tok{1}{1});
0183 end
0184
0185 tok= regexp(mi,'(\d+)x(\d+)','tokens');
0186 if ~isempty(tok);
0187 opt.imgsz = [str2num(tok{1}{1}), str2num(tok{1}{2})];
0188 end
0189
0190
0191 tok= regexp(mi,'(\d+)x(\d+)x(\d+)','tokens');
0192 if ~isempty(tok);
0193 tokA=str2num(tok{1}{1});
0194 tokB=str2num(tok{1}{2});
0195 tokC=str2num(tok{1}{3});
0196 [minf,maxf] = bounds(inv_mdl.fwd_model.nodes);
0197 vctr = mean([minf(3),maxf(3)]);
0198 mrad = max( maxf(1:2) - minf(1:2) );
0199
0200 vopt.imgsz = [tokA, tokB];
0201 vopt.square_pixels = true;
0202 vopt.zvec = linspace(-1,1,tokC+1)*mrad*vrange + vctr;
0203 vopt.save_memory = 2;
0204
0205
0206 [inv_mdl,opt.distr] = GREIT3D_distribution(inv_mdl, vopt);
0207 end
0208 end
0209
0210 imdl= mk_GREIT_model(inv_mdl, radius, [], opt);
0211
0212
0213 function imdl = Choose_NF( imdl, NF_req );
0214 if ~strcmp(imdl.reconst_type, 'difference');
0215 error('Choose NF only works for difference solvers right now');
0216 end
0217
0218
0219 xyz_elems = interp_mesh( imdl.fwd_model );
0220 ctr_elems = mean(xyz_elems, 1);
0221 xyz_elems = xyz_elems - ones(size(xyz_elems,1),1)*ctr_elems;
0222 d_elems = sqrt( sum( xyz_elems.^2, 2 ));
0223 [jnk, e_idx] = sort(d_elems);
0224
0225 imdl.hyperparameter.tgt_elems = e_idx(1:4);
0226 imdl.hyperparameter.noise_figure = NF_req;
0227
0228 sv_log = eidors_msg('log_level'); eidors_msg('log_level', 1);
0229 HP = choose_noise_figure( imdl );
0230 eidors_msg('log_level', sv_log);
0231
0232 imdl.hyperparameter.value = HP;
0233
0234
0235 function do_unit_test
0236
0237 load montreal_data_1995;
0238 imdl = mk_common_model('b2t3',16);
0239
0240 i=0;while true; i=i+1;
0241 vh = zc_resp(:,1); vi= zc_resp(:,23);
0242 fprintf('solver #%d\n',i);
0243 switch i
0244 case 01;
0245 imdl0 = select_imdl( imdl );
0246 case 02;
0247 imdl0 = select_imdl( imdl.fwd_model );
0248 case 03;
0249 imdl0 = select_imdl( imdl, {'NOSER dif'} );
0250 case 04;
0251 imdl0 = select_imdl( imdl, {'NOSER dif','Choose NF=1.1'});
0252 case 05;
0253 imdl0 = select_imdl( imdl, {'Basic GN dif'} );
0254 case 06;
0255 imdl0 = select_imdl( imdl, {'TV solve dif'} );
0256 case 07;
0257 imdl0 = select_imdl( imdl.fwd_model, {'Basic GN dif','Elec Move GN'} );
0258 case 08;
0259 imdl0 = select_imdl( imdl.fwd_model, {'Basic GN dif','Elec Move GN','Choose NF=0.5'} );
0260 case 09;
0261 imdl0 = select_imdl( imdl, {'Elec Move GN'} );
0262 case 10;
0263 imdl0 = mk_common_model('b2C2',16);
0264 imdl0 = select_imdl( imdl0, {'Elec Move GN'} );
0265 case 11;
0266 imdl0 = select_imdl( imdl, {'Nodal GN dif'} );
0267 case 12;
0268 imdl0 = select_imdl( imdl, {'Nodal GN dif', 'Choose NF=0.50'} );
0269 case 13;
0270 fmdl = mk_library_model('adult_male_16el');
0271 [stim,msel] = mk_stim_patterns(16,1,[0,1],[0,1],{},1);
0272 fmdl.stimulation = stim;
0273 fmdl.meas_select = msel;
0274 imdl0 = select_imdl( fmdl, 'GREIT');
0275
0276 case 14;
0277 imdl0 = mk_common_model('b2C2',16);
0278 imdl0 = select_imdl( imdl0, {'Basic GN dif', 'TV solve dif'} );
0279 imdl0.inv_solve.max_iterations= 2;
0280 imdl0 = select_imdl( imdl0, {'Choose NF=0.8'} );
0281 [vh,vi] = simulate_movement(mk_image(imdl0), [0;0.5;0.35]);
0282 case 15;
0283 imdl0 = mk_common_model('b2C2',16);
0284 imdl0 = select_imdl( imdl0, {'Nodal GN dif', 'Choose NF=0.50'} );
0285 [vh,vi] = simulate_movement(mk_image(imdl0), [0;0.5;0.05]);
0286 case 16;
0287 imdl0 = mk_common_model('b2C2',16);
0288 imdl0 = select_imdl( imdl0, {'Basic GN abs'} );
0289 [vh,vi] = simulate_movement(mk_image(imdl0), [0;0.5;0.05]);
0290 case 17;
0291 imdl = mk_common_model('n3r2',[16,2]); fmdl = imdl.fwd_model;
0292 fmdl.nodes(:,3) = fmdl.nodes(:,3) - 1.5;
0293 imdl0= select_imdl(fmdl,{'GREIT:NF=0.3 64x64 rad=0.25'});
0294 img = mk_image(fmdl,1); vh = fwd_solve(img);
0295 img.elem_data(fmdl.demo_targ_elems.A) = 1.2;
0296 img.elem_data(fmdl.demo_targ_elems.B) = 0.8;
0297 vi = fwd_solve(img);
0298
0299 case 18;
0300 imdl = mk_common_model('n3r2',[16,2]); fmdl = imdl.fwd_model;
0301 fmdl.nodes(:,3) = fmdl.nodes(:,3) - 1.5;
0302 imdl0= select_imdl(fmdl,{'GREIT:NF=0.3 32x32 rad=0.25'});
0303 img = mk_image(fmdl,1); vh = fwd_solve(img);
0304 img.elem_data(fmdl.demo_targ_elems.A) = 1.2;
0305 img.elem_data(fmdl.demo_targ_elems.B) = 0.8;
0306 vi = fwd_solve(img);
0307
0308 otherwise; break
0309 end;
0310
0311
0312 if strcmp( imdl0.reconst_type, 'absolute')
0313 imgr = inv_solve( imdl0, vi);
0314 else
0315 imgr = inv_solve( imdl0, vh, vi);
0316 end
0317 subplot(4,5,i); show_slices( imgr, [inf,inf,0] );
0318 end