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 5289 2016-11-02 08:43:12Z fab-b $
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    load(fname);
0103    out = fmdl;
0104 end
0105 
0106 function store_model(fmdl,fname)
0107 fname = [get_path '/' fname '.mat'];
0108 save(fname,'fmdl');
0109 
0110 function out = build_if_needed(cmd,str)
0111 out = load_stored_model(str);
0112 if isempty(out)
0113    if ~iscell(cmd)
0114       cmd = {cmd};
0115    end 
0116    for i = 1:length(cmd)
0117       if i ==1
0118          eval(['out = ' cmd{i} ';']);
0119       else
0120          eval(cmd{i});
0121       end
0122    end
0123    store_model(out,str);
0124 end
0125 
0126 %%%%%
0127 % Lists predefined models (append when adding)
0128 function out = list_predef_model_strings
0129 out = {
0130     'adult_male_16el';
0131     'adult_male_32el';
0132     'adult_male_16el_lungs';
0133     'adult_male_32el_lungs';
0134     'adult_male_grychtol2016a_1x32';
0135     'adult_male_grychtol2016a_2x16';
0136     'cylinder_16x1el_coarse';
0137     'cylinder_16x1el_fine';
0138     'cylinder_16x1el_vfine';   
0139     'cylinder_16x2el_coarse';
0140     'cylinder_16x2el_fine';
0141     'cylinder_16x2el_vfine';
0142     'neonate_16el';
0143     'neonate_32el';
0144     'neonate_16el_lungs';
0145     'neonate_32el_lungs';
0146     'pig_23kg_16el';
0147     'pig_23kg_32el';
0148     'pig_23kg_16el_lungs';
0149     'pig_23kg_32el_lungs';
0150     'lamb_newborn_16el';
0151     'lamb_newborn_32el';
0152     'lamb_newborn_16el_organs';
0153 %     'lamb_newborn_32el_organs';
0154     'beagle_16el';
0155     'beagle_32el';
0156     'beagle_16el_lungs';
0157     'beagle_32el_lungs';
0158     'beagle_16el_rectelec';
0159     'beagle_32el_rectelec';
0160     'beagle_16el_lungs_rectelec';
0161     'beagle_32el_lungs_rectelec';
0162     };
0163 
0164 %%%%%
0165 % Use predefined model
0166 function out = predef_model(str)
0167 switch str
0168     case 'adult_male_16el'
0169         out = mk_library_model({'adult_male','boundary'},...
0170             [16 1 0.5],[0.05],0.08);
0171     case 'adult_male_32el'
0172         out = mk_library_model({'adult_male','boundary'},...
0173             [32 1 0.5],[0.05],0.08);
0174     case 'adult_male_16el_lungs'
0175         out = mk_library_model({'adult_male','boundary','left_lung','right_lung'},...
0176             [16 1 0.5],[0.05],0.08);
0177     case 'adult_male_32el_lungs'
0178         out = mk_library_model({'adult_male','boundary','left_lung','right_lung'},...
0179             [32 1 0.5],[0.05],0.08);
0180     case 'adult_male_grychtol2016a_1x32'
0181         out = mk_thorax_model_grychtol2016a('1x32_ring');
0182         out = out.fwd_model;
0183     case 'adult_male_grychtol2016a_2x16'
0184         out = mk_thorax_model_grychtol2016a('2x16_planar');
0185         out = out.fwd_model;
0186         
0187     case 'cylinder_16x1el_coarse'
0188        out = build_if_needed(...
0189           'ng_mk_cyl_models([10,15],[16,5],[0.5,0,0.18])', str);
0190     case 'cylinder_16x1el_fine' 
0191        out = build_if_needed(...
0192           'ng_mk_cyl_models([10,15,1.1],[16,5],[0.5,0,0.15])',str);
0193     case 'cylinder_16x1el_vfine' 
0194         out = build_if_needed(...
0195            'ng_mk_cyl_models([10,15,0.8],[16,5],[0.5,0,0.08])',str);
0196     case 'cylinder_16x2el_coarse' 
0197         out = build_if_needed(...
0198            'ng_mk_cyl_models([30,15],[16,10,20],[0.5,0,0.18])',str);
0199     case 'cylinder_16x2el_fine'  
0200         out = build_if_needed(...
0201            'ng_mk_cyl_models([30,15,1.5],[16,10,20],[0.5,0,0.15])',str);
0202     case 'cylinder_16x2el_vfine' 
0203         out = build_if_needed(...
0204            'ng_mk_cyl_models([30,15,0.8],[16,10,20],[0.5,0,0.08])',str);
0205         
0206         
0207     case 'neonate_16el'
0208         out = mk_library_model({'neonate','boundary'},[16 1 0.5],[0.1 0 -1 0 60],0.08,49);
0209     case 'neonate_32el'
0210         out = mk_library_model({'neonate','boundary'},[32 1 0.5],[0.06 0 -1 0 60],0.08,49);
0211     case 'neonate_16el_lungs'
0212         out = mk_library_model({'neonate','boundary','left_lung','right_lung'},[16 1 0.5],[0.1 0 -1 0 60],0.08,49);
0213     case 'neonate_32el_lungs'
0214         out = mk_library_model({'neonate','boundary','left_lung','right_lung'},[32 1 0.5],[0.06 0 -1 0 60],0.08,49);
0215         
0216     case 'pig_23kg_16el'
0217         out = mk_library_model({'pig_23kg','boundary'},...
0218             [16 1 0.5],[0.05 0 -1 0 60],0.08);
0219     case 'pig_23kg_32el'
0220         out = mk_library_model({'pig_23kg','boundary'},...
0221             [32 1 0.5],[0.05 0 -1 0 60],0.08);
0222     case 'pig_23kg_16el_lungs'
0223         out = mk_library_model({'pig_23kg','boundary','lungs(1:2:end,:)'},...
0224             [16 1 0.5],[0.05 0 -1 0 60],0.08);
0225     case 'pig_23kg_32el_lungs'
0226         out = mk_library_model({'pig_23kg','boundary','lungs(1:2:end,:)'},...
0227             [32 1 0.5],[0.05 0 -1 0 60],0.08);    
0228 
0229     case 'lamb_newborn_16el'
0230 %        out = build_if_needed(...
0231 %           {['ng_mk_extruded_model({208,208*',...
0232 %             'shape_library(''get'',''lamb_newborn'',''boundary'')',...
0233 %             ',0,10},[16,1.995,104],[1])'],'out.nodes = out.nodes/204;'}, ...
0234 %           str);
0235          out = mk_library_model({'lamb_newborn','boundary'},[16,1.995,104],[1],10,0,208);
0236     case 'lamb_newborn_32el'
0237          % Very sensitive to the .980 offset. This is the only I can find that works.
0238          out = mk_library_model({'lamb_newborn','boundary'},[32,1.980,104],[1],15,50,208);
0239          out.electrode = out.electrode([2:32,1]);
0240     case 'lamb_newborn_16el_organs'
0241        out = mk_library_model({'lamb_newborn','boundary','lungs','heart'},[16,1.995,104],[1],10,0,208);
0242 %     case 'lamb_newborn_32el_organs'
0243     case 'beagle_16el';
0244       scale = 49;
0245       out = mk_library_model({'beagle','boundary'}, ...
0246          [16 1 scale*0.5],[2,0,0.10],10,0,49);
0247     case 'beagle_32el';
0248       scale = 49;
0249       out = mk_library_model({'beagle','boundary'}, ...
0250          [32 1 scale*0.5],[2,0,0.10],10,0,49);
0251     case 'beagle_16el_rectelec';
0252       scale = 49;
0253       out = mk_library_model({'beagle','boundary'}, ...
0254          [16 1 scale*0.5],8*[0.25,1,0.05],10,0,49);
0255     case 'beagle_32el_rectelec';
0256       scale = 49;
0257       out = mk_library_model({'beagle','boundary'}, ...
0258          [16 1 scale*0.5],8*[0.25,1,0.05],10,0,49);
0259 
0260     case 'beagle_16el_lungs';
0261       scale = 49;
0262       out = mk_library_model({'beagle','boundary','left_lung','right_lung'}, ...
0263          [16 1 scale*0.5],[2,0,0.10],10,0,49);
0264 
0265     case 'beagle_16el_lungs_rectelec';
0266       scale = 49;
0267       out = mk_library_model({'beagle','boundary','left_lung','right_lung'}, ...
0268          [16 1 scale*0.5],8*[0.25,1,0.05],10,0,49);
0269 
0270     case 'beagle_32el_lungs';
0271       scale = 49;
0272       out = mk_library_model({'beagle','boundary','left_lung','right_lung'}, ...
0273          [32 1 scale*0.5],[2,0,0.10],10,0,49);
0274 
0275     case 'beagle_32el_lungs_rectelec';
0276       scale = 49;
0277       out = mk_library_model({'beagle','boundary','left_lung','right_lung'}, ...
0278          [32 1 scale*0.5],8*[0.25,1,0.05],10,0,49);
0279          
0280     otherwise
0281         error('No such model');
0282 end
0283 %give the model a name
0284 out.name = str;
0285 
0286 
0287 function str = make_filename(shape, elec_pos, elec_shape, ...
0288                              maxsz, nfft, scale);
0289 %at this point, shape is a cell array of strings e.g. {'pig_23kg','lungs')
0290 str = shape{1};
0291 shape(1) = []; %remove the first element
0292 shape = sort(shape); %sort the others
0293 for i = 1:numel(shape)
0294     str = [str '_' shape{i}];
0295 end
0296 str = [str '_EP'];
0297 for i = 1:numel(elec_pos)
0298     str = [str '_' num2str(elec_pos(i))];
0299 end
0300 str = [str '_ES'];
0301 if ischar(elec_shape)
0302     str = [str '_' elec_shape];
0303 else
0304     for i = 1:numel(elec_shape)
0305         str = [str '_' num2str(elec_shape(i))];
0306     end
0307 end
0308 if ~isempty(maxsz)
0309     str = [str '_maxsz_' num2str(maxsz)];
0310 end
0311 if ~isempty(nfft)
0312     str = [str '_nfft_' num2str(nfft)];
0313 end
0314 if ~isempty(scale)
0315     str = [str '_scale' num2str(scale)];
0316 end
0317 
0318 %remove colons
0319 str = strrep(str,':','-');
0320 
0321 function clean = split_var_strings(strc)
0322 for i = 1:numel(strc)
0323     [clean{1,i} clean{2,i}] = strtok(strc{i},'([{');
0324 end
0325 
0326 
0327 function out = get_path
0328 global eidors_objects
0329 out = eidors_objects.model_cache;
0330 
0331 function set_path(val)
0332 global eidors_objects
0333 eidors_objects.model_cache = val;
0334 %if folder doesn't exist, create it
0335 if ~exist(val,'dir')
0336     ver= eidors_obj('interpreter_version');
0337     if ver.ver<4 || ver.ver>=7
0338        mkdir(val);
0339     else
0340  % matlab 6.x has a stupid mkdir function
0341        system(['mkdir ',val]); 
0342     end
0343 end
0344 
0345 function out = do_unit_test
0346 models = mk_library_model('list');
0347 n_models = numel(models);
0348 sqrt_n_models = ceil(sqrt(n_models));
0349 for i = 1:numel(models)
0350     eidors_msg('\n\n\n DOING  MODEL (%s)\n\n\n',models{i},0);
0351     mdl = mk_library_model(models{i});
0352     img = mk_image(mdl,1);
0353     try   
0354         n = numel(mdl.mat_idx); 
0355     catch
0356         n =1; 
0357     end
0358     if n >1
0359         for j = 2:n
0360             img.elem_data(mdl.mat_idx{j}) = 0.25;
0361         end
0362     end
0363     subplot(sqrt_n_models, sqrt_n_models,i);
0364     show_fem(img,[0,1,0]); axis off;
0365     title(models{i},'Interpreter','none');
0366     drawnow
0367 end
0368 
0369 
0370 out = mk_library_model({'pig_23kg','boundary','lungs(1:2:end,:)'},[32 1 0.5],[0.05 0 -1 0 60],0.08);
0371

Generated on Wed 21-Jun-2017 09:29:07 by m2html © 2005