mk_library_model

PURPOSE ^

MK_LIBRARY_MODEL - FEM models based on library shapes

SYNOPSIS ^

function out = mk_library_model(shape,elec_pos,elec_shape,maxsz,nfft,scale)

DESCRIPTION ^

MK_LIBRARY_MODEL - FEM models based on library shapes 

 MK_LIBRARY_MODEL(shape,elec_pos,elec_shape,maxsz,nfft) where:
   shape -  a cell array of strings and
     shape{1} is the shape_library model used
          (run shape_libary('list') to get a list
     shape{2} is the the boundary. If absent, 'boundary' is assumed.
     shape{3..} are strings specifying additional inclusions (such as
     lungs)
   elec_pos - a vector specifying electrode positions. See
     NG_MK_EXTRUDED_MODEL for details. To use the electrode positions
     stored in the 'electrode' field in the shape_libary, specify elec_pos
     as 'original'
   elec_shape - a vector specifying electrode shapes. See
     NG_MK_EXTRUDED_MODEL for details.
   maxsz - maximum FEM size (default: course mesh)
   nfft  - number of points to create along the boundary (default: 50)
     If nfft==0, no interpolation takes place.
   scale - avoids some Netgen issues by scaling the contours before 
     calling netgen and scaling the resulting model back afterwards
     (default: 1). Note that electrode and maxh specifications are not
     scaled.

 QUICK ACCESS TO COMMON MODELS:
   MK_LIBRARY_MODEL(str) where str is a single string specifying a model.
   Use MK_LIBRARY_MODEL('list') to obtain a list of available models.

 PATH TO LIBRARY MODELS
   'LIBRARY_PATH' - get or set library path

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function out = mk_library_model(shape,elec_pos,elec_shape,maxsz,nfft,scale)
0002 %MK_LIBRARY_MODEL - FEM models based on library shapes
0003 %
0004 % MK_LIBRARY_MODEL(shape,elec_pos,elec_shape,maxsz,nfft) where:
0005 %   shape -  a cell array of strings and
0006 %     shape{1} is the shape_library model used
0007 %          (run shape_libary('list') to get a list
0008 %     shape{2} is the the boundary. If absent, 'boundary' is assumed.
0009 %     shape{3..} are strings specifying additional inclusions (such as
0010 %     lungs)
0011 %   elec_pos - a vector specifying electrode positions. See
0012 %     NG_MK_EXTRUDED_MODEL for details. To use the electrode positions
0013 %     stored in the 'electrode' field in the shape_libary, specify elec_pos
0014 %     as 'original'
0015 %   elec_shape - a vector specifying electrode shapes. See
0016 %     NG_MK_EXTRUDED_MODEL for details.
0017 %   maxsz - maximum FEM size (default: course mesh)
0018 %   nfft  - number of points to create along the boundary (default: 50)
0019 %     If nfft==0, no interpolation takes place.
0020 %   scale - avoids some Netgen issues by scaling the contours before
0021 %     calling netgen and scaling the resulting model back afterwards
0022 %     (default: 1). Note that electrode and maxh specifications are not
0023 %     scaled.
0024 %
0025 % QUICK ACCESS TO COMMON MODELS:
0026 %   MK_LIBRARY_MODEL(str) where str is a single string specifying a model.
0027 %   Use MK_LIBRARY_MODEL('list') to obtain a list of available models.
0028 %
0029 % PATH TO LIBRARY MODELS
0030 %   'LIBRARY_PATH' - get or set library path
0031 
0032 % (C) 2011 Bartlomiej Grychtol. License: GPL version 2 or version 3
0033 % $Id: mk_library_model.m 6034 2019-12-30 17:52:08Z aadler $
0034 
0035 % Fill in defaults:
0036 if nargin < 6; scale = 1;          end
0037 if nargin < 5; nfft = 50;          end
0038 
0039 if ischar(shape)
0040     switch shape
0041         case 'LIBRARY_PATH'
0042             switch nargin
0043                 case 1
0044                     out = get_path;
0045                 case 2
0046                     set_path(elec_pos);
0047             end
0048         case 'list'
0049             out = list_predef_model_strings;
0050         case 'UNIT_TEST'
0051             out = do_unit_test; return;
0052         otherwise
0053             out = predef_model(shape);
0054             out = mdl_normalize(out, 0); % not normalized by default
0055     end
0056 else
0057    if ~iscell(shape)
0058       shape = {shape, 'boundary'};
0059    elseif numel(shape) == 1
0060       shape{2} = 'boundary';
0061    end
0062    fname = make_filename(shape,elec_pos,elec_shape,maxsz, nfft, scale);
0063    out = load_stored_model(fname);
0064    if ~isempty(out)
0065       return
0066    end
0067    s_shape = split_var_strings(shape(2:end));
0068    shapes = shape_library('get',shape{1},s_shape(1,:));
0069    if ~iscell(shapes), shapes = {shapes}; end
0070    %apply any indeces specified
0071    for i = 1:numel(shapes)
0072       eval(sprintf('shapes{i} = %f*shapes{i}%s;',scale,s_shape{2,i}));
0073    end
0074    if ischar(elec_pos) && strcmp(elec_pos,'original')
0075       el = shape_library('get',shape{1},'electrodes');
0076       electh= atan2(el(:,2),el(:,1))*180/pi;
0077       elec_pos = [electh,0.5*ones(size(electh))];
0078    end
0079    
0080    if nfft > 0
0081       [fmdl, mat_idx] = ng_mk_extruded_model({scale,shapes,[4,nfft],maxsz},...
0082          elec_pos,elec_shape);
0083    else
0084       [fmdl, mat_idx] = ng_mk_extruded_model({scale,shapes,0,maxsz},...
0085          elec_pos,elec_shape);
0086    end
0087    fmdl.nodes = fmdl.nodes/scale;
0088    fmdl.mat_idx = mat_idx;
0089    store_model(fmdl,fname)
0090    out = fmdl;
0091    out = mdl_normalize(out, 0); % not normalized by default
0092 end
0093 
0094 
0095 
0096 
0097 function out = load_stored_model(fname)
0098 out = [];
0099 fname = [get_path '/' fname '.mat'];
0100 if exist(fname,'file')
0101    eidors_msg('MK_LIBRARY_MODEL: Using stored model');
0102    if exist('OCTAVE_VERSION');
0103       load(file_in_loadpath(fname));
0104    else
0105       load(fname);
0106    end
0107    out = fmdl;
0108 end
0109 
0110 function store_model(fmdl,fname)
0111    fname = [get_path '/' fname '.mat'];
0112    if exist('OCTAVE_VERSION');
0113       savver = '-v7';
0114    else
0115       savver = '-v7.3';  
0116    end
0117    save(fname,savver,'fmdl');
0118 
0119 function out = build_if_needed(cmd,str)
0120 out = load_stored_model(str);
0121 if isempty(out)
0122    if ~iscell(cmd)
0123       cmd = {cmd};
0124    end 
0125    for i = 1:length(cmd)
0126       if i ==1
0127          eval(['out = ' cmd{i} ';']);
0128       else
0129          eval(cmd{i});
0130       end
0131    end
0132    store_model(out,str);
0133 end
0134 
0135 %%%%%
0136 % Lists predefined models (append when adding)
0137 function out = list_predef_model_strings
0138 out = {
0139     'adult_male_16el';
0140     'adult_male_32el';
0141     'adult_male_16el_lungs';
0142     'adult_male_32el_lungs';
0143     'adult_male_grychtol2016a_1x32';
0144     'adult_male_grychtol2016a_2x16';
0145     'cylinder_16x1el_coarse';
0146     'cylinder_16x1el_fine';
0147     'cylinder_16x1el_vfine';   
0148     'cylinder_16x2el_coarse';
0149     'cylinder_16x2el_fine';
0150     'cylinder_16x2el_vfine';
0151     'neonate_16el';
0152     'neonate_32el';
0153     'neonate_16el_lungs';
0154     'neonate_32el_lungs';
0155     'pig_23kg_16el';
0156     'pig_23kg_32el';
0157     'pig_23kg_16el_lungs';
0158     'pig_23kg_32el_lungs';
0159     'lamb_newborn_16el';
0160     'lamb_newborn_32el';
0161     'lamb_newborn_16el_organs';
0162 %     'lamb_newborn_32el_organs';
0163     'beagle_16el';
0164     'beagle_32el';
0165     'beagle_16el_lungs';
0166     'beagle_32el_lungs';
0167     'beagle_16el_rectelec';
0168     'beagle_32el_rectelec';
0169     'beagle_16el_lungs_rectelec';
0170     'beagle_32el_lungs_rectelec';
0171     };
0172 
0173 %%%%%
0174 % Use predefined model
0175 function out = predef_model(str)
0176 switch str
0177     case 'adult_male_16el'
0178         out = mk_library_model({'adult_male','boundary'},...
0179             [16 1 0.5],[0.05],0.08);
0180     case 'adult_male_32el'
0181         out = mk_library_model({'adult_male','boundary'},...
0182             [32 1 0.5],[0.05],0.08);
0183     case 'adult_male_16el_lungs'
0184         out = mk_library_model({'adult_male','boundary','left_lung','right_lung'},...
0185             [16 1 0.5],[0.05],0.08);
0186     case 'adult_male_32el_lungs'
0187         out = mk_library_model({'adult_male','boundary','left_lung','right_lung'},...
0188             [32 1 0.5],[0.05],0.08);
0189     case 'adult_male_grychtol2016a_1x32'
0190         out = mk_thorax_model_grychtol2016a('1x32_ring');
0191         out = out.fwd_model;
0192     case 'adult_male_grychtol2016a_2x16'
0193         out = mk_thorax_model_grychtol2016a('2x16_planar');
0194         out = out.fwd_model;
0195         
0196     case 'cylinder_16x1el_coarse'
0197        out = build_if_needed(...
0198           'ng_mk_cyl_models([10,15],[16,5],[0.5,0,0.18])', str);
0199     case 'cylinder_16x1el_fine' 
0200        out = build_if_needed(...
0201           'ng_mk_cyl_models([10,15,1.1],[16,5],[0.5,0,0.15])',str);
0202     case 'cylinder_16x1el_vfine' 
0203         out = build_if_needed(...
0204            'ng_mk_cyl_models([10,15,0.8],[16,5],[0.5,0,0.08])',str);
0205     case 'cylinder_16x2el_coarse' 
0206         out = build_if_needed(...
0207            'ng_mk_cyl_models([30,15],[16,10,20],[0.5,0,0.18])',str);
0208     case 'cylinder_16x2el_fine'  
0209         out = build_if_needed(...
0210            'ng_mk_cyl_models([30,15,1.5],[16,10,20],[0.5,0,0.15])',str);
0211     case 'cylinder_16x2el_vfine' 
0212         out = build_if_needed(...
0213            'ng_mk_cyl_models([30,15,0.8],[16,10,20],[0.5,0,0.08])',str);
0214         
0215         
0216     case 'neonate_16el'
0217         out = mk_library_model({'neonate','boundary'},[16 1 0.5],[0.1 0 -1 0 60],0.08,49);
0218     case 'neonate_32el'
0219         out = mk_library_model({'neonate','boundary'},[32 1 0.5],[0.06 0 -1 0 60],0.08,49);
0220     case 'neonate_16el_lungs'
0221         out = mk_library_model({'neonate','boundary','left_lung','right_lung'},[16 1 0.5],[0.1 0 -1 0 60],0.08,49);
0222     case 'neonate_32el_lungs'
0223         out = mk_library_model({'neonate','boundary','left_lung','right_lung'},[32 1 0.5],[0.06 0 -1 0 60],0.08,49);
0224         
0225     case 'pig_23kg_16el'
0226         out = mk_library_model({'pig_23kg','boundary'},...
0227             [16 1 0.5],[0.05 0 -1 0 60],0.08);
0228     case 'pig_23kg_32el'
0229         out = mk_library_model({'pig_23kg','boundary'},...
0230             [32 1 0.5],[0.05 0 -1 0 60],0.08);
0231     case 'pig_23kg_16el_lungs'
0232         out = mk_library_model({'pig_23kg','boundary','lungs(1:2:end,:)'},...
0233             [16 1 0.5],[0.05 0 -1 0 60],0.08);
0234     case 'pig_23kg_32el_lungs'
0235         out = mk_library_model({'pig_23kg','boundary','lungs(1:2:end,:)'},...
0236             [32 1 0.5],[0.05 0 -1 0 60],0.08);    
0237 
0238     case 'lamb_newborn_16el'
0239 %        out = build_if_needed(...
0240 %           {['ng_mk_extruded_model({208,208*',...
0241 %             'shape_library(''get'',''lamb_newborn'',''boundary'')',...
0242 %             ',0,10},[16,1.995,104],[1])'],'out.nodes = out.nodes/204;'}, ...
0243 %           str);
0244          out = mk_library_model({'lamb_newborn','boundary'},[16,1.995,104],[1],10,0,208);
0245     case 'lamb_newborn_32el'
0246          % Very sensitive to the .980 offset. This is the only I can find that works.
0247          out = mk_library_model({'lamb_newborn','boundary'},[32,1.980,104],[1],15,50,208);
0248          out.electrode = out.electrode([2:32,1]);
0249     case 'lamb_newborn_16el_organs'
0250        out = mk_library_model({'lamb_newborn','boundary','lungs','heart'},[16,1.995,104],[1],10,0,208);
0251 %     case 'lamb_newborn_32el_organs'
0252     case 'beagle_16el';
0253       scale = 49;
0254       out = mk_library_model({'beagle','boundary'}, ...
0255          [16 1 scale*0.5],[2,0,0.10],10,0,49);
0256     case 'beagle_32el';
0257       scale = 49;
0258       out = mk_library_model({'beagle','boundary'}, ...
0259          [32 1 scale*0.5],[2,0,0.10],10,0,49);
0260     case 'beagle_16el_rectelec';
0261       scale = 49;
0262       out = mk_library_model({'beagle','boundary'}, ...
0263          [16 1 scale*0.5],8*[0.25,1,0.05],10,0,49);
0264     case 'beagle_32el_rectelec';
0265       scale = 49;
0266       out = mk_library_model({'beagle','boundary'}, ...
0267          [16 1 scale*0.5],8*[0.25,1,0.05],10,0,49);
0268 
0269     case 'beagle_16el_lungs';
0270       scale = 49;
0271       out = mk_library_model({'beagle','boundary','left_lung','right_lung'}, ...
0272          [16 1 scale*0.5],[2,0,0.10],10,0,49);
0273 
0274     case 'beagle_16el_lungs_rectelec';
0275       scale = 49;
0276       out = mk_library_model({'beagle','boundary','left_lung','right_lung'}, ...
0277          [16 1 scale*0.5],8*[0.25,1,0.05],10,0,49);
0278 
0279     case 'beagle_32el_lungs';
0280       scale = 49;
0281       out = mk_library_model({'beagle','boundary','left_lung','right_lung'}, ...
0282          [32 1 scale*0.5],[2,0,0.10],10,0,49);
0283 
0284     case 'beagle_32el_lungs_rectelec';
0285       scale = 49;
0286       out = mk_library_model({'beagle','boundary','left_lung','right_lung'}, ...
0287          [32 1 scale*0.5],8*[0.25,1,0.05],10,0,49);
0288          
0289     otherwise
0290         error('No such model');
0291 end
0292 %give the model a name
0293 out.name = str;
0294 
0295 
0296 function str = make_filename(shape, elec_pos, elec_shape, ...
0297                              maxsz, nfft, scale);
0298 %at this point, shape is a cell array of strings e.g. {'pig_23kg','lungs')
0299 str = shape{1};
0300 shape(1) = []; %remove the first element
0301 shape = sort(shape); %sort the others
0302 for i = 1:numel(shape)
0303     str = [str '_' shape{i}];
0304 end
0305 str = [str '_EP'];
0306 for i = 1:numel(elec_pos)
0307     str = [str '_' num2str(elec_pos(i))];
0308 end
0309 str = [str '_ES'];
0310 if ischar(elec_shape)
0311     str = [str '_' elec_shape];
0312 else
0313     for i = 1:numel(elec_shape)
0314         str = [str '_' num2str(elec_shape(i))];
0315     end
0316 end
0317 if ~isempty(maxsz)
0318     str = [str '_maxsz_' num2str(maxsz)];
0319 end
0320 if ~isempty(nfft)
0321     str = [str '_nfft_' num2str(nfft)];
0322 end
0323 if ~isempty(scale)
0324     str = [str '_scale' num2str(scale)];
0325 end
0326 
0327 %remove colons
0328 str = strrep(str,':','-');
0329 
0330 function clean = split_var_strings(strc)
0331 for i = 1:numel(strc)
0332     [clean{1,i} clean{2,i}] = strtok(strc{i},'([{');
0333 end
0334 
0335 
0336 function out = get_path
0337 global eidors_objects
0338 out = eidors_objects.model_cache;
0339 
0340 function set_path(val)
0341 global eidors_objects
0342 eidors_objects.model_cache = val;
0343 %if folder doesn't exist, create it
0344 if ~exist(val,'dir')
0345     ver= eidors_obj('interpreter_version');
0346     if ver.ver<4 || ver.ver>=7
0347        mkdir(val);
0348     else
0349  % matlab 6.x has a stupid mkdir function
0350        system(['mkdir ',val]); 
0351     end
0352 end
0353 
0354 function out = do_unit_test
0355 models = mk_library_model('list');
0356 n_models = numel(models);
0357 sqrt_n_models = ceil(sqrt(n_models));
0358 for i = 1:numel(models)
0359     eidors_msg('\n\n\n DOING  MODEL (%s)\n\n\n',models{i},0);
0360     mdl = mk_library_model(models{i});
0361     img = mk_image(mdl,1);
0362     try   
0363         n = numel(mdl.mat_idx); 
0364     catch
0365         n =1; 
0366     end
0367     if n >1
0368         for j = 2:n
0369             img.elem_data(mdl.mat_idx{j}) = 0.25;
0370         end
0371     end
0372     subplot(sqrt_n_models, sqrt_n_models,i);
0373     show_fem(img,[0,1,0]); axis off;
0374     title(models{i},'Interpreter','none');
0375     drawnow
0376 end
0377 
0378 
0379 out = mk_library_model({'pig_23kg','boundary','lungs(1:2:end,:)'},[32 1 0.5],[0.05 0 -1 0 60],0.08);
0380

Generated on Tue 31-Dec-2019 17:03:26 by m2html © 2005