0001 function imdl = mk_GN_model(img, opt, lambda)
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 if ischar(img) && strcmpi(img, 'unit_test')
0029 do_unit_test();
0030 return;
0031 end
0032
0033
0034 if ~exist('lambda', 'var')
0035 lambda = [];
0036 end
0037 if strcmp(img.type, 'fwd_model')
0038 img = mk_image(img, 1);
0039 end
0040 fmdl = img.fwd_model;
0041 imdl = select_imdl( fmdl,{'Basic GN dif'});
0042
0043
0044 opt = parse_options(opt,fmdl,imdl);
0045
0046
0047 if ~isfield(img,'rec_model');
0048 opt.do_coarse2fine = 0;
0049 [imdl.rec_model, imdl.fwd_model] = mk_pixel_slice(fmdl, opt.target_plane, opt);
0050 imdl.rec_model.nodes(:,3) = [];
0051
0052 imdl.rec_model.mdl_slice_mapper.y_pts = fliplr(imdl.rec_model.mdl_slice_mapper.y_pts);
0053 else
0054 imdl.rec_model = img.rec_model;
0055 end
0056
0057
0058
0059 imdl = select_imdl(imdl, {'Basic GN dif'});
0060
0061 imdl.fwd_model.coarse2fine = mk_coarse_fine_mapping(imdl.fwd_model, imdl.rec_model);
0062
0063 imdl.inv_solve.calc_solution_error = 0 ;
0064
0065 if isfield(img, 'elem_data')
0066
0067 imdl.jacobian_bkgnd.value = img.elem_data;
0068 else
0069 imdl.jacobian_bkgnd.value = 1;
0070 end
0071
0072
0073 if strcmpi(opt.RtRprior, 'laplace');
0074 imdl.RtR_prior = @prior_laplace;
0075 elseif strcmpi(opt.RtRprior, 'noser');
0076 imdl.RtR_prior = @prior_noser;
0077 imdl.prior_use_fwd_not_rec = true;
0078 elseif strcmpi(opt.RtRprior, 'tikhonov');
0079 imdl.RtR_prior = @prior_tikhonov;
0080 else
0081 error(['undefined prior: ', opt.RtRprior]);
0082 end
0083
0084
0085 if ~isempty(opt.meas_icov)
0086 imdl.meas_icov = opt.meas_icov;
0087 end
0088
0089
0090 if ~isempty(opt.noise_figure)
0091
0092
0093 xyz_elems = interp_mesh( imdl.fwd_model );
0094 ctr_elems = mean(xyz_elems, 1);
0095 ctr_elems(3) = opt.target_plane;
0096 xyz_elems = xyz_elems - ones(size(xyz_elems,1),1)*ctr_elems;
0097 d_elems = sqrt( sum( xyz_elems.^2, 2 ));
0098 [~, e_idx] = sort(d_elems);
0099
0100 imdl.hyperparameter.tgt_elems = e_idx(1:4);
0101 imdl.hyperparameter.noise_figure = opt.noise_figure;
0102
0103 sv_log = eidors_msg('log_level'); eidors_msg('log_level', 2);
0104 imdl.hyperparameter.value = choose_noise_figure( imdl );
0105 eidors_msg('log_level', sv_log);
0106 elseif ~isempty(opt.image_SNR)
0107 imdl.hyperparameter.image_SNR = opt.image_SNR;
0108 imdl.hyperparameter.value = choose_image_SNR(imdl);
0109 else
0110 imdl.hyperparameter.value = lambda;
0111 end
0112
0113 end
0114
0115
0116 function opt = parse_options(opt,fmdl,imdl)
0117
0118 if ~isfield(opt, 'imgsz'), opt.imgsz = [32 32]; end
0119 if ~isfield(opt, 'square_pixels')
0120 opt.square_pixels = 0;
0121 end
0122
0123 if isfield(imdl,'rec_model') && ~isempty(imdl.rec_model)
0124
0125 opt.imgsz(1) = numel(unique(imdl.rec_model.nodes(:,1)))-1;
0126 opt.imgsz(2) = numel(unique(imdl.rec_model.nodes(:,2)))-1;
0127 end
0128
0129 if ~isfield(opt, 'noise_figure'), opt.noise_figure = []; end
0130
0131 if ~isfield(opt, 'meas_icov'), opt.meas_icov = []; end
0132
0133 if ~isfield(opt, 'image_SNR'), opt.image_SNR = []; end
0134
0135
0136 if ~isfield(opt, 'RtRprior')
0137 opt.RtRprior = 'laplace';
0138 end
0139
0140
0141 Nelecs = length(fmdl.electrode);
0142 for i=1:Nelecs
0143 enodesi = fmdl.electrode(i).nodes;
0144 elec_loc(i,:) = mean( fmdl.nodes( enodesi,:),1 );
0145 end
0146 opt.elec_loc = elec_loc;
0147
0148 try
0149 opt.normalize = fmdl.normalize_measurements;
0150 catch
0151 opt.normalize = 0;
0152 eidors_msg('mk_GN_model: fmdl.normalize_measurements not specified, assuming 0');
0153 end
0154
0155
0156 if ~isfield(opt, 'target_plane')
0157 opt.target_plane = mean(elec_loc(:,3));
0158 else
0159 t = opt.target_plane;
0160 minnode = min(fmdl.nodes);
0161 maxnode = max(fmdl.nodes);
0162 if t<minnode(3) || t>maxnode(3)
0163 warning('options.target_plane is outside the model!');
0164 eidors_msg('mk_GN_model: Resorting to default target_plane');
0165 opt.target_plane = mean(elec_loc(:,3));
0166 end
0167 end
0168
0169 end
0170
0171
0172 function do_unit_test()
0173
0174
0175 fmdl = mk_library_model('cylinder_16x1el_fine');
0176 fmdl.nodes = fmdl.nodes/15;
0177 fmdl.stimulation = mk_stim_patterns(16,1,[0,1],[0,1],{'no_meas_current'}, 1);
0178 opt.noise_figure = 1.0;
0179 imdl_gr = mk_GREIT_model(fmdl, 0.2, [], opt);
0180
0181 opt = struct();
0182 opt.noise_figure = 1.0;
0183 imdl_gn_lap = mk_GN_model(fmdl, opt);
0184
0185 opt = struct();
0186 opt.noise_figure = 1.0;
0187 opt.RtRprior = 'tikhonov';
0188 imdl_gn_tik = mk_GN_model(fmdl, opt);
0189
0190 test_performance( { imdl_gr, imdl_gn_lap, imdl_gn_tik}, fmdl );
0191
0192 end