mk_thorax_model

PURPOSE ^

MK_THORAX_MODEL FEM models of the thorax

SYNOPSIS ^

function out = mk_thorax_model(str, varargin)

DESCRIPTION ^

MK_THORAX_MODEL FEM models of the thorax

 MK_THORAX_MODEL provides a shorthand to predefined thorax FEMs and 
 for using contributed models with PLACE_ELEC_ON_SURF. You may be asked
 to download missing files. 

 MK_THORAX_MODEL(shapestr,elec_pos, elec_shape, maxh) where:
  shapestr    - a string specifying the underlying model.
                Run MK_THORAX_MODEL('list_shapes') for a list.
  elec_pos    - a vector specifying electrode positions.
                See PLACE_ELEC_ON_SURF for details.
  elec_shape  - a vector specifying electrode shapes.
                See PLACE_ELEC_ON_SURF for details.
  This usage returns a fwd_model structure.

 MK_THORAX_MODEL(modelstr) provides quick access to predefined models.
 Run MK_THORAX_MODEL('list') for a list. This usage returns either a 
 fwd_model or an image structure.

 MK_THORAX_MODEL('list_shapes') lists available thorax shapes without 
  electrodes.

 MK_THORAX_MODEL('list') lists available predefined models.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function out = mk_thorax_model(str, varargin)
0002 %MK_THORAX_MODEL FEM models of the thorax
0003 %
0004 % MK_THORAX_MODEL provides a shorthand to predefined thorax FEMs and
0005 % for using contributed models with PLACE_ELEC_ON_SURF. You may be asked
0006 % to download missing files.
0007 %
0008 % MK_THORAX_MODEL(shapestr,elec_pos, elec_shape, maxh) where:
0009 %  shapestr    - a string specifying the underlying model.
0010 %                Run MK_THORAX_MODEL('list_shapes') for a list.
0011 %  elec_pos    - a vector specifying electrode positions.
0012 %                See PLACE_ELEC_ON_SURF for details.
0013 %  elec_shape  - a vector specifying electrode shapes.
0014 %                See PLACE_ELEC_ON_SURF for details.
0015 %  This usage returns a fwd_model structure.
0016 %
0017 % MK_THORAX_MODEL(modelstr) provides quick access to predefined models.
0018 % Run MK_THORAX_MODEL('list') for a list. This usage returns either a
0019 % fwd_model or an image structure.
0020 %
0021 % MK_THORAX_MODEL('list_shapes') lists available thorax shapes without
0022 %  electrodes.
0023 %
0024 % MK_THORAX_MODEL('list') lists available predefined models.
0025 %
0026 
0027 %
0028 % See also: PLACE_ELEC_ON_SURF, MK_LIBRARY_MODEL
0029 
0030 % (C) 2015-2016 Bartlomiej Grychtol. License: GPL version 2 or 3
0031 % $Id: mk_thorax_model.m 6453 2022-12-04 21:32:20Z bgrychtol $
0032 
0033 if nargin>0 && ischar(str) 
0034    switch(str)
0035       case 'UNIT_TEST';
0036          do_unit_test; return;
0037       case 'list_shapes'
0038          out = list_basic_shapes; return;
0039       case 'list'
0040          out = list_predef_models; return;
0041    end
0042 end
0043 
0044 opt.fstr = 'mk_thorax_model';
0045 out = eidors_cache(@do_mk_thorax_model,[{str}, varargin(:)'],opt);
0046 
0047 end
0048 
0049 function out = do_mk_thorax_model(str, elec_pos, elec_shape, maxh)
0050 
0051 if ismember(str,list_predef_models)
0052    out = build_predef_model(str);
0053    return
0054 end
0055 
0056 if ~ismember(str, list_basic_shapes)
0057    error('Shape str "%s" not understood.',str);
0058 end
0059 
0060 
0061 
0062 out = build_basic_model(str);
0063 if nargin > 1
0064    out = place_elec_on_surf(out,elec_pos,elec_shape,[],maxh);
0065    out = fix_boundary(out);
0066 end
0067 
0068 end
0069 
0070 function ls = list_basic_shapes
0071    ls = {'male','female'};
0072 end
0073 
0074 function out = build_basic_model(str)
0075 switch(str)
0076    case {'male', 'female'}
0077       out = eidors_cache(@remesh_at_model, {str});
0078 end
0079 end
0080 
0081 function out = remesh_at_model(str)
0082    tmpnm  = tempname;
0083    
0084    stlfile = [tmpnm '.stl'];
0085    volfile = [tmpnm '.vol'];
0086    
0087    contrib = 'at-thorax-mesh'; file =  sprintf('%s_t_mdl.mat',str);
0088    load(get_contrib_data(contrib,file));
0089    if strcmp(str,'male')
0090       fmdl.nodes = fmdl.nodes - 10; % center the model
0091    end
0092    fmdl = fix_boundary(fmdl);
0093    STL.vertices = fmdl.nodes;
0094    STL.faces    = fmdl.boundary;
0095    stl_write(STL,stlfile);
0096    opt.stloptions.yangle = 55;
0097    opt.stloptions.edgecornerangle = 5;
0098    opt.meshoptions.fineness = 6;
0099    opt.options.meshsize = 30;
0100    opt.options.minmeshsize = 10;
0101    opt.stloptions.resthsurfcurvfac = 2;
0102    opt.stloptions.resthsurfcurvenable = 1;
0103    opt.stloptions.chartangle = 30;
0104    opt.stloptions.outerchartangle = 90;
0105    ng_write_opt(opt);
0106    call_netgen(stlfile,volfile);
0107    out=ng_mk_fwd_model(volfile,[],[],[],[]);
0108    delete(stlfile);
0109    delete(volfile);
0110    delete('ng.opt');
0111    
0112    out = rmfield(out,...
0113       {'mat_idx','np_fwd_solve','boundary_numbers'});
0114    
0115 end
0116 
0117 function mdl = fix_boundary(mdl)
0118     opt.elem2face  = 1;
0119     opt.boundary_face = 1;
0120     opt.inner_normal = 1;
0121     mdl = fix_model(mdl,opt);
0122     flip = mdl.elem2face(logical(mdl.boundary_face(mdl.elem2face).*mdl.inner_normal));
0123     mdl.faces(flip,:) = mdl.faces(flip,[1 3 2]);
0124     mdl.normals(flip,:) = -mdl.normals(flip,:);
0125     mdl.boundary = mdl.faces(mdl.boundary_face,:);
0126 end
0127 
0128 function ls = list_predef_models
0129    ls = {'adult_male_grychtol2016a_1x32'
0130          'adult_male_grychtol2016a_2x16'};
0131 end
0132 
0133 function out = build_predef_model(str)
0134    switch str
0135       case 'adult_male_grychtol2016a_1x32'
0136          out = mk_thorax_model_grychtol2016a('1x32_ring');
0137          
0138       case 'adult_male_grychtol2016a_2x16'
0139          out = mk_thorax_model_grychtol2016a('2x16_planar');
0140    end
0141 end
0142 
0143 
0144 function do_unit_test
0145    subplot(221)
0146    show_fem(mk_thorax_model('male'));
0147    
0148    subplot(222)
0149    show_fem(mk_thorax_model('female'));
0150 
0151    subplot(223)
0152    eth16 = 360*cumsum([0.2 0.4*ones(1,7) 0.5 0.4*ones(1,7)])/6.5 - 90; eth16 = eth16';
0153    eth32 = 360*cumsum([0.1 0.2*ones(1,15) 0.25 0.2*ones(1,15)])/6.45 - 90; eth32 = eth32';
0154    ep = eth16; ep(:,2) = 150;
0155    ep(17:48,1) = eth32; ep(17:48,2) = 175;
0156    ep(49:64,1) = eth16; ep(49:64,2) = 200;
0157    mdl = mk_thorax_model('male',ep,[5 0 .5],10);
0158    show_fem(mdl);
0159 
0160    subplot(224)
0161    mdl = mk_thorax_model('female',ep,[5 0 .5],10);
0162    show_fem(mdl);
0163 
0164    % This doens't work with mk_thorax_model
0165 %  ng_write_opt('MSZCYLINDER',[0,0,50,0,0,60,180,5]);
0166 %  show_fem(mk_thorax_model('male'));
0167    
0168 end

Generated on Fri 30-Dec-2022 19:44:54 by m2html © 2005