ng_tank_find_elec

PURPOSE ^

[elec,sels, electrodes] = ng_tank_find_elec(srf,vtx,fc,centres);

SYNOPSIS ^

function [elec,sels, electrodes] = ng_tank_find_elec(srf,vtx,fc,centres)

DESCRIPTION ^

[elec,sels, electrodes] = ng_tank_find_elec(srf,vtx,fc,centres);

 This function Tries to find the electrdes given the x y x coords of their centres.

 Version 5.0
 B.D.Grieve - 13/02/2002 + modyfication by lmazurk
 WRBL added default as prevous choice 20/1/2004
 WRBL deleted ground plane 05/12/2005
 WRBL derived automatic version ditto
 AA   speedup and fix to not output zeros
 AA  add ability to define electrodes with a function

 srf      = The boundary surfaces
 vtx      = The vertices matrix
 fc       = A one column matrix containing the face numbers
 elsrf    = Cell array of indices matrices mapping into vtx each electrode face
 sels     = The indices into the srf matrix of the selected electrode faces
 elec     = The EIDORS-3D electrode matrix of dimensions NxM, where 
            where N: no. of electrodes, M: 3 * max no. of faces per electrode
            [ kept for backward compatibility. Use electrodes output instead]
 centres(k,:)=[ x,y,z ] of kth electrode
  OR 
 centres = struct where centres(k).centre is electrode centre and
             centres(k).fcn = fcn of vtx and ctr which is
             zero outside and one inside electrode
    example: ctr_fcn = inline( 'sum((vtx-ones(size(vtx,1),1)*ctr).^2,2)<1', ...
                               'vtx','ctr');
            [ctr_param(1:nn).fcn]     = deal( ctr_fcn );
             centres=  mat2cell( [x(:),y(:),z(:)], ones(nn,1),3);
            [ctr_param(1:nn).centre] = deal( centres{:} );
    this form allows for more complicated electrode shapes
          
 electrodes = EIDORS V3.x electrodes structure

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [elec,sels, electrodes] = ng_tank_find_elec(srf,vtx,fc,centres)
0002 %[elec,sels, electrodes] = ng_tank_find_elec(srf,vtx,fc,centres);
0003 %
0004 % This function Tries to find the electrdes given the x y x coords of their centres.
0005 %
0006 % Version 5.0
0007 % B.D.Grieve - 13/02/2002 + modyfication by lmazurk
0008 % WRBL added default as prevous choice 20/1/2004
0009 % WRBL deleted ground plane 05/12/2005
0010 % WRBL derived automatic version ditto
0011 % AA   speedup and fix to not output zeros
0012 % AA  add ability to define electrodes with a function
0013 %
0014 % srf      = The boundary surfaces
0015 % vtx      = The vertices matrix
0016 % fc       = A one column matrix containing the face numbers
0017 % elsrf    = Cell array of indices matrices mapping into vtx each electrode face
0018 % sels     = The indices into the srf matrix of the selected electrode faces
0019 % elec     = The EIDORS-3D electrode matrix of dimensions NxM, where
0020 %            where N: no. of electrodes, M: 3 * max no. of faces per electrode
0021 %            [ kept for backward compatibility. Use electrodes output instead]
0022 % centres(k,:)=[ x,y,z ] of kth electrode
0023 %  OR
0024 % centres = struct where centres(k).centre is electrode centre and
0025 %             centres(k).fcn = fcn of vtx and ctr which is
0026 %             zero outside and one inside electrode
0027 %    example: ctr_fcn = inline( 'sum((vtx-ones(size(vtx,1),1)*ctr).^2,2)<1', ...
0028 %                               'vtx','ctr');
0029 %            [ctr_param(1:nn).fcn]     = deal( ctr_fcn );
0030 %             centres=  mat2cell( [x(:),y(:),z(:)], ones(nn,1),3);
0031 %            [ctr_param(1:nn).centre] = deal( centres{:} );
0032 %    this form allows for more complicated electrode shapes
0033 %
0034 % electrodes = EIDORS V3.x electrodes structure
0035 
0036 % WARNING! the 'fc' variable in this function is what everywhere else is
0037 % called 'bc', and that's how it should be used.
0038 
0039 % (C) 2002-2006. Licenced under the GPL
0040 % $Id: ng_tank_find_elec.m 6045 2019-12-31 20:09:02Z aadler $
0041 
0042 if  isstruct(centres)
0043    % Calc centre of each surface
0044    for d=1:size(vtx,2)
0045       srfctr(:,d) = mean(reshape( vtx(srf,d), size(srf) ),2);
0046    end
0047    for e=1:length(centres)
0048       inside = feval(centres(e).fcn,srfctr,centres(e).centre);
0049       this_el = srf(inside,:);
0050       electrodes(e).nodes     = unique( this_el(:) )';
0051       electrodes(e).z_contact = 0.1; % set placeholder value
0052    end
0053    elec= NaN; sels= NaN; % No backward compatible for this mode
0054 elseif size(centres,2)==3;
0055    [elec,sels, electrodes] = find_elec_centres(srf,vtx,fc,centres);
0056 else
0057    error('don`t understand format of centres');
0058 end
0059 
0060 
0061 function [elec,sels, electrodes] = find_elec_centres(srf,vtx,fc,centres);
0062 
0063 for loop1 = 1:max(fc)
0064     % Create a logical array (lgelfc) to determine which faces are electrodes
0065     lgelfc(loop1) = logical(0);
0066     
0067 %   [fcsrf,fci] = ng_extract_face(srf,vtx,fc,loop1);
0068     fci  = find( fc == loop1 );
0069     fcsrf= srf(fci,:); % should be vertex numbers for this face
0070     fcsrf= unique(fcsrf); fcsrf= fcsrf(fcsrf>0);
0071     coordsforthisface= vtx(fcsrf,:);
0072     face_coords{loop1}= coordsforthisface;
0073     ttlfcsrf(loop1) = {fcsrf};
0074     
0075 end
0076 
0077 
0078 [sels,lgelfc] = find_selected_face(centres, face_coords, lgelfc);
0079 
0080 
0081 
0082 % Extract from the total face indices matrix (ttlfcsrf) the
0083 % faces which are electrodes and store them in the cell
0084 % array (elsrf)
0085 elsrf = ttlfcsrf(lgelfc);
0086 
0087 if 0
0088    % Display each electrode in turn as a wire mesh
0089    figure
0090    set(gcf,'Name','Wire Mesh Electrode Faces')
0091    for loop1 = 1:size(elsrf,2)
0092        trimesh(elsrf{loop1},vtx(:,1),vtx(:,2),vtx(:,3),'EdgeColor','red')
0093        title(['Electrode ' num2str(loop1) ': red'])
0094        axis equal
0095        axis(mshaxs)
0096        view(45,10)
0097        hidden off
0098        hold on
0099        pause(0.75)
0100    end
0101    title('Electrodes: red,')
0102    hidden off
0103    pause(2)
0104 end
0105 % Convert elsrf into the EIDORS-3D matrix electrode matrix format
0106 
0107 nmel = size(elsrf,2); 
0108 for loop1 = 1:nmel
0109     nmfc(loop1) = size(elsrf{loop1},1);
0110 end
0111 % Initiate electrode matrix (elec) & pad with zeros
0112 elec = zeros(nmel,3*max(nmfc));
0113 % Put electrode surface information into elec
0114 for loop1 = 1:nmel
0115     el_idx= sels(loop1);
0116     this_el= ttlfcsrf{el_idx}';
0117     l_this_el= prod(size(this_el));
0118     elec(loop1, 1:l_this_el) = this_el(:)';
0119 
0120     electrodes(loop1).nodes     = unique( this_el(:) )';
0121     electrodes(loop1).z_contact = 0.1; % set placeholder value
0122 end
0123 
0124 
0125 % Find the electrode node which is closest to the specified point
0126 function [sels,lgelfc] = find_selected_face(centres, face_coords, lgelfc) 
0127    sels = [];
0128    elecn_idx= [];   
0129    elecnodes= [];   
0130    for i=1:length(face_coords)
0131        elecn_idx = [elecn_idx; i*ones(length(face_coords{i}),1)];
0132        elecnodes = [elecnodes; face_coords{i}];
0133    end
0134    elecsep = sum(min(abs(diff(centres))));
0135    for ielec = 1:size(centres,1)
0136    % Find the distance from the centre of faces to this electrode
0137        dists =  (elecnodes(:,1) - centres(ielec,1)).^2 + ...
0138                 (elecnodes(:,2) - centres(ielec,2)).^2 + ...
0139                 (elecnodes(:,3) - centres(ielec,3)).^2;
0140        dmin = min(dists); %iface is closest face to this electrode.
0141        % take the first, closest ones
0142        iface = find(dmin + elecsep >= dists);
0143        if length(iface)>1 % found electrode and background. Take smallest
0144           tryfaces = unique( elecn_idx(iface));
0145           ff=[]; for i=1:length(tryfaces)
0146             ff(i) = max( dists( elecn_idx == tryfaces(i)));
0147           end
0148           [~, i] = min(ff);
0149           iface = tryfaces(i);
0150        else
0151           iface = elecn_idx(iface);
0152        end
0153        lgelfc(iface) = true;
0154        if sum(lgelfc) ~= ielec
0155 %           disp(ielec);
0156           error('Electrode #%d not found', ielec);
0157        end
0158        sels(ielec)= iface;
0159    %   disp([ielec, iface, d]);
0160    %   now remove that face so we dont use it again
0161        ff = find(elecn_idx == iface);
0162        elecn_idx(ff,:) = [];
0163        elecnodes(ff,:) = [];
0164    end
0165 
0166 function [sels,lgelfc] = find_selected_face_old(centres, face_coords, lgelfc) 
0167    sels = [];
0168    for i=1:length(face_coords)
0169        centreofface(i,:)= mean(face_coords{i});
0170    end
0171    for ielec = 1:size(centres,1)
0172    % Find the distance from the centre of faces to this electrode
0173        dists =  (centreofface(:,1) - centres(ielec,1)).^2 + ...
0174                 (centreofface(:,2) - centres(ielec,2)).^2 + ...
0175                 (centreofface(:,3) - centres(ielec,3)).^2;
0176        [d,iface] = min(dists); %iface is closest face to this electrode.
0177        lgelfc(iface) = logical(1);
0178        if sum(lgelfc) ~= ielec
0179           disp(ielec);
0180           error('Electrode #%d not found', ielec);
0181        end
0182        sels(ielec)= iface;
0183    %   disp([ielec, iface, d]);
0184    end

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