Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
f618b70
[broken] Rename folder matlab_tools -> +simnibsMATLAB
SeSodesa Nov 11, 2025
2cb78d7
simnibsMATLAB.expand_to_center_surround: fully qualify two MATLAB fun…
SeSodesa Nov 11, 2025
344ff70
get_data_and_scaleLimits: fully qualify SimNIBS-related MATLAB functi…
SeSodesa Nov 11, 2025
be3e824
subject_atlas.m: fully qualify SimNIBS matlab function calls
SeSodesa Nov 11, 2025
c9842fa
get_fields_at_coordinates.m: fully qualify SimNIBS MATLAB function calls
SeSodesa Nov 11, 2025
452babf
mesh_extract_regions: fully qualify parse_input call
SeSodesa Nov 11, 2025
200b6c6
mesh_get_fieldpeaks_and_focality: fully qualify SimNIBS MATLAB functi…
SeSodesa Nov 11, 2025
e606e79
mesh_get_histogram: fully qualify MATLAB function calls
SeSodesa Nov 11, 2025
61cb8fb
mesh_get_node_areas: fully qualify MATLAB function call
SeSodesa Nov 11, 2025
ae561fc
mesh_get_simulation_result: fully qualify MATLAB function calls
SeSodesa Nov 11, 2025
2a3b79d
mesh_get_surf_extrema_and_percentiles: fully qualify only mesh_get_tr…
SeSodesa Nov 11, 2025
7f79a28
mesh_show_surface: fully qualify MATLAB function calls
SeSodesa Nov 11, 2025
adc8487
mni2subject_coilpos: fully qualify simnibs_cli_call
SeSodesa Nov 11, 2025
6900092
mni2subject_coords: fully qualify simnibs_cli_call
SeSodesa Nov 11, 2025
65a4585
run_simnibs: fully qualify simnibs_cli_call
SeSodesa Nov 11, 2025
0887123
mesh_load_fssurf: qualify SimNIBS function and gifti class constructo…
SeSodesa Nov 11, 2025
7615c58
Start implementing a proper constructor for the gifti class
SeSodesa Nov 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions simnibs/+simnibsMATLAB/@gifti/gifti.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
classdef gifti
% GIfTI Geometry file format class
% Geometry format under the Neuroimaging Informatics Technology Initiative
% (NIfTI):
% http://www.nitrc.org/projects/gifti/
% http://nifti.nimh.nih.gov/
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

properties

metadata (1,1) struct = struct % TODO: short documentation here.

label (1,1) struct = struct % TODO: short documentation here.

data (1,:) cell = struct % TODO: short documentation here.

mat % TODO: add size, class and default value restrictions here.

faces % TODO: add size, class and default value restrictions here.

vertices % TODO: add size, class and default value restrictions here.

cdata (1,1) struct = struct % TODO: short documentation here.

indices % TODO: add size, class and default value restrictions here.

end % properties

methods

function this = gifti(varargin)
% GIfTI Geometry file format class
% Geometry format under the Neuroimaging Informatics Technology Initiative
% (NIfTI):
% http://www.nitrc.org/projects/gifti/
% http://nifti.nimh.nih.gov/
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Guillaume Flandin
% $Id: gifti.m 7621 2019-06-20 16:58:59Z guillaume $

switch nargin

case 0

this = simnibsMATLAB.gifti(giftistruct) ;

case 1
if isa(varargin{1},'simnibsMATLAB.gifti')
this = varargin{1};

elseif isstruct(varargin{1})
f = {'faces', 'face', 'tri' 'vertices', 'vert', 'pnt', 'cdata', 'indices'};
ff = {'faces', 'faces', 'faces', 'vertices', 'vertices', 'vertices', 'cdata', 'indices'};
[c, ia] = intersect(f,fieldnames(varargin{1}));
if ~isempty(c)

for i=1:length(c)
fieldName = ff{ia(i)} ;
this.(fieldName) = varargin{1}.(c{i}) ;
end
if isfield(varargin{1},'mat')
this.mat = varargin{1}.mat ;
end
elseif isempty(setxor(fieldnames(varargin{1}), {'metadata','label','data'}))
this = this ;
else
error('[GIFTI] Invalid structure.');
end

elseif ishandle(varargin{1})

this = struct('vertices',get(varargin{1},'Vertices'), ...
'faces', get(varargin{1},'Faces'));
if ~isempty(get(varargin{1},'FaceVertexCData'))
this.cdata = get(varargin{1},'FaceVertexCData');
end
this = simnibsMATLAB.gifti(this);

elseif isnumeric(varargin{1})

this = simnibsMATLAB.gifti;
this.cdata = varargin{1};

elseif iscell(varargin{1}) && numel(varargin{1}) == 1 && isnumeric(varargin{1}{1})
this = simnibsMATLAB.gifti;
for i=1:size(varargin{1}{1},2)
this.data{i}.metadata = struct([]);
this.data{i}.space = [];
this.data{i}.attributes.Intent = 'NIFTI_INTENT_NONE';
this.data{i}.attributes.DataType = 'NIFTI_TYPE_FLOAT32';
this.data{i}.attributes.Dim = size(varargin{1}{1},1);
this.data{i}.data = single(varargin{1}{1}(:,i));
end

elseif ischar(varargin{1})

if size(varargin{1},1)>1
this = simnibsMATLAB.gifti(cellstr(varargin{1}));
return;
end
[~,~,e] = fileparts(varargin{1});
if strcmpi(e,'.mat')
try
this = simnibsMATLAB.gifti(load(varargin{1}));
catch
error('[GIFTI] Loading of file %s failed.', varargin{1});
end
elseif ismember(lower(e),{'.asc','.srf','.mgh','.mgz','.pial',...
'.white','.inflated','.nofix','.orig','.smoothwm',...
'.sphere','.reg','.surf','.curv','.area','.sulc','.annot'})
this = freesurfer_read(varargin{1});
this = simnibsMATLAB.gifti(this);
elseif strcmpi(e,'.vtk')
this = mvtk_read(varargin{1});
this = simnibsMATLAB.gifti(this);
elseif strcmpi(e,'.obj')
this = obj_read(varargin{1});
this = simnibsMATLAB.gifti(this);
elseif strcmpi(e,'.ply')
this = ply_read(varargin{1});
this = simnibsMATLAB.gifti(this);
elseif strcmpi(e,'.off')
this = off_read(varargin{1});
this = simnibsMATLAB.gifti(this);
elseif strcmpi(e,'.stl')
this = stl_read(varargin{1});
this = simnibsMATLAB.gifti(this);
elseif strcmpi(e,'.mz3')
this = mz3_read(varargin{1});
this = simnibsMATLAB.gifti(this);
else
this = gifti_read(varargin{1},giftistruct);
this = simnibsMATLAB.gifti(this);
end

elseif iscellstr(varargin{1})
fnames = varargin{1};
this(numel(fnames)) = simnibsMATLAB.gifti(giftistruct);
for i=1:numel(fnames)
this(i) = simnibsMATLAB.gifti(fnames{i});
end

else
error('[GIFTI] Invalid object construction.');
end

otherwise
error('[GIFTI] Invalid object construction.');
end % switch
end % function
end % methods
end % classdef

%==========================================================================
function s = giftistruct
s = struct(...
'metadata', ...
struct(...
'name', {}, ...
'value', {} ...
), ...
'label', ...
struct(...
'name', {}, ...
'index', {} ...
), ...
'data', ...
struct(...
'attributes', {}, ...
'metadata', struct('name',{}, 'value',{}), ...
'space', {}, ...
'data', {} ...
) ...
);

end % function
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@
s.N=[];
s.multichannel=[];
s.phis_surround=[];
s=parse_input(s,varargin{:});
s=simnibsMATLAB.parse_input(s,varargin{:});

fn_in = [tempname,'.mat'];
fn_out = [tempname,'.mat'];
save(fn_in,'-struct','tdcslist', '-v7')

% Run expand_to_center_surround
cmdstr = [simnibs_cli_call('expand_to_center_surround') ...
cmdstr = [simnibsMATLAB.simnibs_cli_call('expand_to_center_surround') ...
' -S ' fn_in ' -p ' subpath ' -F ' fn_out ];
fn = fieldnames(s);
for k=1:numel(fn)
Expand Down Expand Up @@ -76,4 +76,3 @@
S_out = load(fn_out);
delete(fn_in);
delete(fn_out);

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
function [data, name, scaleLimits, varargout] = get_data_and_scaleLimits(m,field_idx,datatype,scaleLimits)
% returns the data, the field name and fills in the scaleLimits (if they
% are empty); optionally, also the element sizes are returned
%
%
% USAGE:
% [data, name, scaleLimits] = get_data_and_scaleLimits(m,field_idx,datatype,scaleLimits)
% [data, name, scaleLimits, elemsizes] = get_data_and_scaleLimits(m,field_idx,datatype,scaleLimits)
% [data, name, scaleLimits] = simnibsMATLAB.get_data_and_scaleLimits(m,field_idx,datatype,scaleLimits)
% [data, name, scaleLimits, elemsizes] = simnibsMATLAB.get_data_and_scaleLimits(m,field_idx,datatype,scaleLimits)
%
% The scale limits are determined as follows:
% [0 absmax] for positive-only data;
Expand Down Expand Up @@ -33,18 +33,18 @@
if isempty(scaleLimits)||(nargout>3)
if strcmpi(datatype,'tet')
% tet volumes
elemsizes=mesh_get_tetrahedron_sizes(m);
elemsizes=simnibsMATLAB.mesh_get_tetrahedron_sizes(m);
elseif strcmpi(datatype,'tri')
% triangle areas
elemsizes=mesh_get_triangle_sizes(m);
elemsizes=simnibsMATLAB.mesh_get_triangle_sizes(m);
else % node data
if ~isempty(m.triangles)&&~isempty(m.tetrahedra)
disp('Both tets and triangles found: Ambiguity to assign sizes to nodes')
error('mesh has to contain either tets or triangles, not both');
end
if isempty(m.triangles)
% use tet volumes to get node sizes
elemsizes=mesh_get_tetrahedron_sizes(m);
elemsizes=simnibsMATLAB.mesh_get_tetrahedron_sizes(m);
elemsizes=elemsizes/4;
nodesizes=zeros(size(m.nodes,1),1);
for i=1:size(m.tetrahedra,1)
Expand All @@ -53,7 +53,7 @@
elemsizes=nodesizes;
else
% use tri areas to get node sizes
elemsizes=mesh_get_triangle_sizes(m);
elemsizes=simnibsMATLAB.mesh_get_triangle_sizes(m);
elemsizes=elemsizes/3;
nodesizes=zeros(size(m.nodes,1),1);
for i=1:size(m.triangles,1)
Expand All @@ -70,9 +70,9 @@
% get element postions if needed
if nargout>4
if strcmpi(datatype,'tet')
varargout{2}=mesh_get_tetrahedron_centers(m);
varargout{2}=simnibsMATLAB.mesh_get_tetrahedron_centers(m);
elseif strcmpi(datatype,'tri')
varargout{2}=mesh_get_triangle_centers(m);
varargout{2}=simnibsMATLAB.mesh_get_triangle_centers(m);
else
varargout{2}=m.nodes;
end
Expand All @@ -86,11 +86,11 @@
else
dataHlp=data;
end

idx=~isnan(dataHlp);
dataHlp=dataHlp(idx);
elemsizesHlp=elemsizes(idx);

[dataHlp,idx] = sort(dataHlp);
elemsizesHlp=elemsizesHlp(idx);
elemsizesHlp=cumsum(elemsizesHlp);
Expand All @@ -106,4 +106,4 @@
absmax=max([-dataHlp(idx) scaleLimits(2)]);
scaleLimits = [-absmax absmax];
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@
if ischar(mesh)
assert(exist(mesh, 'file') == 2, ['Could not find mesh file ' mesh])
fn_mesh = mesh;
is_temp = false;
is_temp = false;
else
is_temp = true;
fn_mesh = [tempname '.msh'];
mesh_save_gmsh4(mesh, fn_mesh)
simnibsMATLAB.mesh_save_gmsh4(mesh, fn_mesh)
end

fn_in = [tempname,'.csv'];
csvwrite(fn_in, coords);

% Run mni2subject_coords
[status,result] = system([simnibs_cli_call('get_fields_at_coordinates')...
[status,result] = system([simnibsMATLAB.simnibs_cli_call('get_fields_at_coordinates')...
' -m ' fn_mesh ' -s ' fn_in, ' --out_fill ' out_fill]);
if status ~= 0
if is_temp
Expand All @@ -60,4 +60,4 @@
end
delete(fn_in);

end
end
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
% deletes unused nodes, elment_data entries and updates the node numbers
%
% USAGE:
% m=mesh_extract_regions(m, [,'OptionName',OptionValue,...])
% m=mesh_extract_regions(m, [,'OptionName',OptionValue,...])
%
% m: input mesh
%
%
% Options are set using the option name followed by the value.
% elemtype: determines the element type to extract
% ('tri', 'tet' or 'both'; standard: 'both')
% region_idx: extracts the elements with the given region numbers
% keepAllNodes: when set to true, do not remove unused nodes and
% keepAllNodes: when set to true, do not remove unused nodes and
% do not update node numbers (standard: false)
% node_idx: indices of the nodes to keep (standard: keep all)
% tri_idx: indices of the triangles to keep
Expand All @@ -22,7 +22,7 @@
% m=mesh_extract_regions(m, 'elemtype','tet'); % delete all triangles
% m=mesh_extract_regions(m, 'region_idx', [5 1005]);
% % keep tetrahedra and triangles with region numbers 5 or 1005
%
%
% A. Thielscher 11-Apr-2018, based on prior code from M. Windhoff
% A.Thielscher: updated 03-Oct-2018, added 'node_idx', 'tri_idx' and
% 'tet_idx' options
Expand Down Expand Up @@ -57,7 +57,7 @@
if nargin<1
error('at least one argument is needed');
end
s=parse_input(s,varargin{:});
s=simnibsMATLAB.parse_input(s,varargin{:});

keepTri=false;
keepTet=false;
Expand Down Expand Up @@ -85,7 +85,7 @@
idx_kept_tri = idx_kept_tri | m.triangle_regions==s.region_idx(i);
end
end

if ~isempty(s.tri_idx)
if islogical(s.tri_idx)&&length(s.tri_idx)~=size(m.triangles,1)
error('logical index must have same length as number of triangles')
Expand All @@ -107,7 +107,7 @@
idx_kept_tet = idx_kept_tet | m.tetrahedron_regions==s.region_idx(i);
end
end

if ~isempty(s.tet_idx)
if islogical(s.tet_idx)&&length(s.tet_idx)~=size(m.tetrahedra,1)
error('logical index must have same length as number of tets')
Expand All @@ -128,7 +128,7 @@
else
idx_kept_nodes(unique(m.triangles(idx_kept_tri,:)))=true;
idx_kept_nodes(unique(m.tetrahedra(idx_kept_tet,:)))=true;

if ~isempty(s.node_idx)
if islogical(s.node_idx)&&length(s.node_idx)~=size(m.nodes,1)
error('logical index must have same length as number of nodes')
Expand All @@ -139,7 +139,7 @@
s.node_idx=idx_hlp;
end
idx_kept_nodes = idx_kept_nodes&s.node_idx;

% delete affected triangles and tets
idx_kept_tri=idx_kept_tri&(sum(idx_kept_nodes(m.triangles),2)==3);
idx_kept_tet=idx_kept_tet&(sum(idx_kept_nodes(m.tetrahedra),2)==4);
Expand Down Expand Up @@ -168,7 +168,7 @@
if ~isempty(m.element_data{i}.tridata)
m.element_data{i}.tridata=m.element_data{i}.tridata(idx_kept_tri,:);
end

if ~isempty(m.element_data{i}.tetdata)
m.element_data{i}.tetdata=m.element_data{i}.tetdata(idx_kept_tet,:);
end
Expand Down
Loading
Loading