├── +aplot ├── addlabels.m ├── compute_reduced_indices.m ├── connections.m ├── convert_mesh.m ├── defaults.m ├── docurvature.m ├── dotemplate.m ├── drawnodes.m ├── fit_check_source2mesh.m ├── fixmesh.m ├── get_mesh.m ├── get_roi_centres.m ├── interp_template.m ├── isopen.m ├── killinterhems.m ├── makecolbar.m ├── makeodd.m ├── matrix2nodes.m ├── meshmesh.m ├── overlay.m ├── parse_labels.m ├── parse_mesh.m ├── parse_overlay.m ├── parse_plots.m ├── rescale.m ├── rw_edgenode.m ├── sort_sourcemodel.m ├── sort_template.m ├── spherefit.m ├── sym_pad_vector.m ├── symm_orthog.m ├── video.m └── vol2surf.m ├── +gty └── +gifti │ ├── Contents.m │ ├── display.m │ ├── export.m │ ├── fieldnames.m │ ├── gifti.m │ ├── isfield.m │ ├── plot.m │ ├── private │ ├── Makefile │ ├── base64decode.m │ ├── base64encode.m │ ├── getdict.m │ ├── isintent.m │ ├── miniz.c │ ├── read_freesurfer_file.m │ ├── read_gifti_file.m │ ├── zstream.c │ └── zstream.m │ ├── save.m │ ├── struct.m │ ├── subsasgn.m │ └── subsref.m ├── @gifti ├── Contents.m ├── display.m ├── export.m ├── fieldnames.m ├── gifti.m ├── isfield.m ├── plot.m ├── private │ ├── Makefile │ ├── base64decode.m │ ├── base64encode.m │ ├── getdict.m │ ├── isintent.m │ ├── miniz.c │ ├── read_freesurfer_file.m │ ├── read_gifti_file.m │ ├── zstream.c │ └── zstream.m ├── save.m ├── struct.m ├── subsasgn.m └── subsref.m ├── @xmltree ├── Contents.m ├── add.m ├── attributes.m ├── branch.m ├── char.m ├── children.m ├── convert.m ├── copy.m ├── delete.m ├── display.m ├── editor.m ├── find.m ├── flush.m ├── get.m ├── getfilename.m ├── isfield.m ├── length.m ├── move.m ├── parent.m ├── private │ ├── xml_findstr.c │ ├── xml_findstr.m │ ├── xml_findstr.mexa64 │ ├── xml_findstr.mexglx │ ├── xml_findstr.mexw32 │ ├── xml_findstr.mexw64 │ └── xml_parser.m ├── root.m ├── save.m ├── set.m ├── setfilename.m └── xmltree.m ├── EASY_RENDER_NIFTI_OVERLAY.m ├── Example_AAL90_OverlayQuick.m ├── Example_AAL90_ParcelOverlay_Curv.m ├── Example_CerebellumCortexNetwork_AAL116.m ├── Example_FunctionalVolumeRender_Parcellate.m ├── Example_HarvardOxfordCerbellum_Rendering.m ├── Example_RenderFunctionalOverCurvature.m ├── Examples ├── CompareProjectionMethodsScript.m ├── Ex_OverlayWithNetworkAndLabels.gif ├── ExampleScript_RenderAndOrthogProject2D.m ├── ExampleScriptingUsage.m ├── ExampleScriptingUsageNetwork.m ├── ExampleScriptingUsageNetworkConvertAAL.m ├── ExampleScriptingUsage_AAL116_Overlay.m ├── Example_AAL90_OverlayQuick.m ├── Example_AAL90_ParcelOverlay_Curv.m ├── Example_CerebellumCortexNetwork_AAL116.m ├── Example_FunctionalVolumeRender_Parcellate.m ├── Example_HarvardOxfordCerbellum_Rendering.m ├── Example_RenderFunctionalOverCurvature.m ├── Example_RerunOverlayFaster.m ├── Example_SPM_SourceInv_ExtractPlot.m ├── Example_Script_OverlayAndNodes.m ├── Example_SubplotsToVideo.m ├── FieldtripSegmentationUsage.m ├── MainExampleScript.m ├── NEW_RENDER_OVERLAY_FieldTrip_EXAMPLE.m └── NewExampleScript.m ├── Ext ├── .DS_Store ├── InteractiveColorbar │ ├── Examples.m │ ├── InteractiveColorbar.m │ └── license.txt ├── NIfTI │ ├── load_nii.m │ ├── load_nii_hdr.m │ ├── load_nii_img.m │ ├── make_nii.m │ ├── save_nii.m │ ├── save_nii_hdr.m │ └── xform_nii.m ├── New_AALROI_6mm.mat ├── brewermap │ ├── LICENSE.TXT │ ├── README.md │ ├── brewermap.m │ ├── brewermap_plot.m │ ├── brewermap_view.m │ └── preset_colormap.m ├── findMeshHoles │ ├── circleMeshSample.mat │ ├── demo.m │ ├── findTriMeshHoles.m │ └── license.txt ├── findthenearest.m ├── meshconn.m ├── smoothsurf.m ├── sms.m ├── spm_mesh_inflate.m ├── spm_mesh_normals.m ├── spm_mesh_smooth.m ├── spm_mesh_utils.mexmaca64 ├── stlwrite.m └── vrml.m ├── Funcs ├── .DS_Store ├── CheckCompareOverlay.m ├── CheckOrientationMesh.fig ├── CheckOrientationMesh.m ├── CompareProjectionMethods.m ├── NewMeanFilt3D.m ├── afigure.m ├── avolrender.m ├── bigimg.m ├── bluewhitered │ ├── bluewhitered.m │ └── license.txt ├── cdist.m ├── conmat2nodes.m ├── cubric_meg_palettes.m ├── exportbrains.m ├── flatten_mesh.m ├── genvol.m ├── im2vid.m ├── linksubplots.m ├── maker.m ├── maxpoints.m ├── meshnorm.m ├── pca_on_mesh_overlay.m ├── pseudoAAL.m ├── read_nifti.m ├── read_nv.m ├── rw_edgenode.m ├── slice2.m ├── slice3.m ├── slice6.m ├── spherefit.m ├── spherefit.mexa64 ├── spm │ ├── spm_mesh_adjacency.m │ ├── spm_mesh_distmtx.m │ ├── spm_unvec.m │ └── spm_vec.m ├── spm_mesh_adjacency.m ├── spm_mesh_clusters.m ├── spm_mesh_distmtx.m ├── spm_mesh_utils.m ├── spm_mesh_utils.mexa64 ├── spm_mesh_utils.mexmaci64 ├── spm_mesh_utils.mexw32 ├── spm_mesh_utils.mexw64 ├── ug.m └── volumise_points.m ├── NEW_RENDER_OVERLAY_FieldTrip_EXAMPLE.m ├── README.md ├── _config.yml ├── aJointColorbar.m ├── another_example_overlay.m ├── atemplate.asv ├── atemplate.m ├── atemplateobj.asv ├── atemplateobj.m ├── figs ├── DualRotate.gif ├── ExampleMeshRotate.gif ├── Example_HemiNetOverlayNodes.png ├── FillHolesExample.png ├── NewCurvOverlay1.gif ├── NewSourceMeshExampleFig.png ├── NodePowOnSurface.gif ├── V1_RenderRight.png ├── VideoExample.gif ├── VisGammaExample.png └── peaks_1.png ├── gui ├── SourceMeshGUI.fig └── SourceMeshGUI.m ├── lovelybrain_pasteljet_R.png ├── sourcemesh_fig1.png └── template ├── .DS_Store ├── AAL116.mat ├── AAL90DefaultWeights.mat ├── AAL_90_SOURCEMOD.mat ├── AAL_SOURCEMOD.mat ├── AAL_labels.mat ├── BrainMesh_Ch2.gii ├── BrainMesh_ICBM152.gii ├── BrainMesh_ICBM152_smoothed.nv ├── DefaultMeshCentroidsNormals.mat ├── DenseAAL.mat ├── GenSourceBrainMapping.m ├── HCP250.mat ├── HCP360.mat ├── HOA_Cerebellum.mat ├── HarvOx.mat ├── LightAAL.mat ├── MNI152.gii ├── MakeSourceModelFromNifti.m ├── MakeSourceModelFromNifti_AAL120.m ├── MakeSourceModel_HarvOx_wCerebellum.m ├── New_58cortical_AALROI_6mm.mat ├── New_AALROI_6mm.mat ├── New_AALROI_Cortical78_6mm.mat ├── Node_AAL90.node ├── PR_minimize.m ├── ROI_MNI_V4.nii ├── SaveVolumeTstats.mat ├── SuperAAL.mat ├── aal38_labels.mat ├── alexcmap.m ├── align_clouds_3d.m ├── align_clouds_3d_xyz.m ├── alignclouds.m ├── atlasdata_patchplot.m ├── avg152PD.nii ├── bh.headbrain.TPM.gii ├── compute_reduced_indices.m ├── cortex_8196.surf.gii ├── example_aal90_data.mat ├── ft_mesh_mni.mat ├── map_pos_to_aal.m ├── mni152_2009.mat ├── pastelmap.mat ├── points_to_alphashape.m ├── quickscatter3.m ├── standard_bem.mat └── vec2meshvals.m /+aplot/addlabels.m: -------------------------------------------------------------------------------- 1 | function data = addlabels(data,V,all_roi_tissueindex,thelabels) 2 | % Add labels to the plot. 3 | % 4 | % If using AAL90 sourcemodle, these are automatic. 5 | % 6 | % If using another sourcemodel: 7 | % - provide the all_roi_tissueindex from fieldtirp. This is a 8 | % 1xnum_vertices vector containing indices of rois (i,e. which verts belong 9 | % to which rois). 10 | % Also provide labels! 11 | % 12 | pos = data.sourcemodel.pos; 13 | 14 | if ( ~isempty(thelabels) && ~isempty(all_roi_tissueindex) ) &&... 15 | ( length(pos) == length(all_roi_tissueindex) ) &&... 16 | ( length(thelabels) == length(unique(all_roi_tissueindex(all_roi_tissueindex~=0))) ) 17 | 18 | labels = strrep(thelabels,'_',' '); 19 | v = aplot.get_roi_centres(pos,all_roi_tissueindex); 20 | roi = all_roi_tissueindex; 21 | 22 | elseif length(V) == 90 23 | 24 | load('AAL_labels'); 25 | labels = strrep(labels,'_',' '); 26 | v = pos*0.95; 27 | roi = 1:90; 28 | elseif (length(V) == length(thelabels)) &&... 29 | (length(V) == length(pos)) 30 | 31 | labels = strrep(thelabels,'_',' '); 32 | v = pos*0.95; 33 | roi = 1:length(V); 34 | else 35 | fprintf('Labels info not right!\n'); 36 | return 37 | end 38 | 39 | data.labels.roi = roi; 40 | data.labels.labels = labels; 41 | data.labels.centres = v; 42 | 43 | % compile list of in-use node indices 44 | %-------------------------------------------------------------------------- 45 | to = []; from = []; V(isnan(V)) = 0; 46 | for i = 1:size(V,1) 47 | ni = find(logical(V(i,:))); 48 | if any(ni) 49 | to = [to roi(ni)]; 50 | from = [from roi(repmat(i,[1,length(ni)])) ]; 51 | end 52 | end 53 | 54 | AN = unique([to,from]); 55 | AN = AN(AN~=0); 56 | off = 1.5; 57 | data.labels.in_use = AN; 58 | 59 | if sum(v(:,3)) == 0 60 | off3 = 0; 61 | else;off3 = off; 62 | end 63 | 64 | % add these to plot with offset 65 | %-------------------------------------------------------------------------- 66 | for i = 1:length(AN) 67 | L = labels{AN(i)}; 68 | switch L(end) 69 | case 'L'; 70 | t(i) = text(v(AN(i),1)-(off*5),v(AN(i),2)-(off*5),v(AN(i),3)+off3,L); 71 | case 'R'; 72 | t(i) = text(v(AN(i),1)+(off*2),+v(AN(i),2)+(off*2),v(AN(i),3)+off3,L); 73 | otherwise 74 | t(i) = text(v(AN(i),1),v(AN(i),2),v(AN(i),3),L); 75 | end 76 | end 77 | try 78 | % this fails if the network was empty! 79 | set(t,'Fontsize',14) 80 | end 81 | 82 | end -------------------------------------------------------------------------------- /+aplot/compute_reduced_indices.m: -------------------------------------------------------------------------------- 1 | 2 | function indices = compute_reduced_indices(before, after) 3 | % Compute the retained functional (colour) values after patch reduction 4 | % 5 | 6 | indices = zeros(length(after), 1); 7 | for i = 1:length(after) 8 | dotprods = (before * after(i, :)') ./ sqrt(sum(before.^2, 2)); 9 | [~, indices(i)] = max(dotprods); 10 | end 11 | end -------------------------------------------------------------------------------- /+aplot/defaults.m: -------------------------------------------------------------------------------- 1 | function [data,in] = defaults() 2 | 3 | data = struct; % main output structure 4 | in.pmesh = 1; % flag to display the mesh or not 5 | in.labels = 0; % flag to display labels on rois 6 | in.write = 0; % flag to write mesh & overlay 7 | in.fname = []; % filename for saves (e.g. for sae gifti) 8 | in.fighnd = []; % put the plot into an existing figure handle 9 | in.colbar = 1; % display colourbar 10 | in.template = 0; % register source model to a template using ICP 11 | in.orthog = 0; % orthogonalise [ignore] 12 | in.inflate = 0; % inflate the mesh [just calls spm_mesh_inflate] 13 | in.peaks = 0; % compute peaks on surface functional overlay 14 | in.components = 0; % compute local maxima on functional overlay 15 | in.pca = 0; % compute pca on surface functional overlay 16 | in.flip = 0; % ignore 17 | in.affine = 0; % supply affine transformation matrix 18 | in.netcmap = 0; % colormap for network 19 | in.method = 'raycast'; % volume to surface algorithm 20 | in.depth = []; % depth for raycasting 21 | in.all_roi_tissueindex = []; % indices of roi each voxel belongs to 22 | in.thelabels = []; % supply cell array of labels for rois 23 | in.tf_interactive = 0; % ignore 24 | in.checkori = 0; % interactively check/adjust orientation of mesh 25 | in.fillholes = 0; % fill holes in mesh 26 | in.hemi = 'both'; % hemisphere to plot 27 | in.roi = []; 28 | in.optimise = 0; 29 | in.post_parcel = []; 30 | in.thresh = []; 31 | in.open = 0; 32 | -------------------------------------------------------------------------------- /+aplot/docurvature.m: -------------------------------------------------------------------------------- 1 | function C = docurvature(M) 2 | % Computes the curvature of a mesh 3 | % 4 | % 5 | 6 | A = spm_mesh_adjacency(M); 7 | A = sparse(1:size(M.vertices,1),1:size(M.vertices,1),1./sum(A,2)) * A; 8 | 9 | C = (A-speye(size(A))) * double(M.vertices); 10 | N = spm_mesh_normals(M); 11 | C = sign(sum(N.*C,2)) .* sqrt(sum(C.*C,2)); 12 | 13 | end -------------------------------------------------------------------------------- /+aplot/dotemplate.m: -------------------------------------------------------------------------------- 1 | function atlas = dotemplate(model) 2 | % Put dense sourcemodel into an atlas space using ICP and linear 3 | % interpolation 4 | % 5 | % 6 | % 7 | 8 | if ischar(model) 9 | switch model 10 | case lower({'aal','aal90'}); load New_AALROI_6mm.mat 11 | case lower('aal58'); load New_58cortical_AALROI_6mm 12 | case lower('aal78'); load New_AALROI_Cortical78_6mm 13 | otherwise 14 | fprintf('Model not found.\n'); 15 | return; 16 | end 17 | elseif iscell(model) 18 | template_sourcemodel.pos = model{1}; 19 | all_roi_tissueindex = model{2}; 20 | AAL_Labels = []; 21 | end 22 | 23 | atlas.AAL_Labels = AAL_Labels; 24 | atlas.all_roi_tissueindex = all_roi_tissueindex; 25 | atlas.template_sourcemodel = template_sourcemodel; 26 | 27 | end -------------------------------------------------------------------------------- /+aplot/drawnodes.m: -------------------------------------------------------------------------------- 1 | function data = drawnodes(data, N) 2 | % Node plotter. N = (90,1) with 1s for nodes to plot and 0s to ignore. 3 | % 4 | % 5 | hold on; 6 | pos = data.sourcemodel.pos; 7 | %v = pos*0.9; 8 | 9 | if isfield(data.sourcemodel,'vi') 10 | % if pos is cell, it's because we've passed both a vertex set and a 11 | % vector that describes which vertex belongs to which roi 12 | v = pos; 13 | vi = data.sourcemodel.vi; 14 | n = unique(vi); 15 | for i = 1:length(n) 16 | these = find(vi==n(i)); 17 | roi(i,:) = spherefit(v(these,:)); 18 | end 19 | pos = roi; 20 | for ip = 1:length(pos) 21 | [~,this] = min(cdist(pos(ip,:),data.mesh.vertices)); 22 | pos(ip,:) = data.mesh.vertices(this,:); 23 | end 24 | end 25 | 26 | 27 | bounds = [min(data.mesh.vertices); max(data.mesh.vertices)]; 28 | offset = 0.99; 29 | for ip = 1:3 30 | pos(:,ip) = bounds(1,ip) + ((bounds(2,ip)-bounds(1,ip))) .* ... 31 | (pos(:,ip) - min(pos(:,ip)))./(max(pos(:,ip)) - min(pos(:,ip))); 32 | pos(:,ip) = pos(:,ip)*offset; 33 | end 34 | 35 | % redirect to clseast mesh point (vertex?) 36 | for ip = 1:length(pos) 37 | [~,this] = min(cdist(pos(ip,:),data.mesh.vertices)); 38 | pos(ip,:) = data.mesh.vertices(this,:); 39 | end 40 | 41 | v = pos; 42 | 43 | if size(N,1) > 1 && size(N,2) > 1 44 | cols = {'r' 'm','y','g','c','b'}; 45 | if size(size(N,2)) == 90 46 | N = N'; 47 | end 48 | 49 | for j = 1:size(N,2) 50 | ForPlot = v(find(N(:,j)),:) + (1e-2 * (2*j) ) ; 51 | s = find(N); 52 | col = cols{j}; 53 | for i = 1:length(ForPlot) 54 | scatter3(ForPlot(i,1),ForPlot(i,2),ForPlot(i,3),70,col,'filled',... 55 | 'MarkerFaceAlpha',.6,'MarkerEdgeAlpha',.6); hold on; 56 | end 57 | end 58 | 59 | elseif iscell(N) 60 | % pass a cell of length sm with color strings 61 | % e.g. N=cell(90,1); 62 | % N{1} = 'r'; 63 | ForPlot = []; 64 | for j = 1:length(N) 65 | if any(N{j}) 66 | v0 = v(j,:); 67 | ForPlot = [ForPlot v0]; 68 | scatter3(v0(1),v0(2),v0(3),150,N{j},'filled'); 69 | end 70 | end 71 | 72 | else 73 | ForPlot = v(find(N),:); 74 | %s = find(N); 75 | s = ones(length(find(N)),1)*150; 76 | for i = 1:size(ForPlot,1) 77 | col = 'r'; 78 | scatter3(ForPlot(i,1),ForPlot(i,2),ForPlot(i,3),s(i),'r','filled'); 79 | end 80 | end 81 | %RGB = makecolbar(ForPlot); 82 | %set(gcf,'DefaultAxesColorOrder',RGB); jet; 83 | colorbar 84 | 85 | data.drawnodes.data = ForPlot; 86 | 87 | end -------------------------------------------------------------------------------- /+aplot/fit_check_source2mesh.m: -------------------------------------------------------------------------------- 1 | function pos = fit_check_source2mesh(pos,g) 2 | % check box bounds of sourcemodel and mesh are matched 3 | % 4 | % pos = nx3 source model, g = mesh gifti/struct 5 | 6 | % ensure sourcemodel (pos) is around same scale as mesh boundaries 7 | m = min(g.vertices);% *1.1; 8 | M = max(g.vertices);% *1.1; 9 | 10 | % refit box boundaries 11 | V = pos - repmat(spherefit(pos),[size(pos,1),1]); 12 | V(:,1) = m(1) + ((M(1)-m(1))).*(V(:,1) - min(V(:,1)))./(max(V(:,1)) - min(V(:,1))); 13 | V(:,2) = m(2) + ((M(2)-m(2))).*(V(:,2) - min(V(:,2)))./(max(V(:,2)) - min(V(:,2))); 14 | V(:,3) = m(3) + ((M(3)-m(3))).*(V(:,3) - min(V(:,3)))./(max(V(:,3)) - min(V(:,3))); 15 | pos = V; 16 | 17 | end 18 | -------------------------------------------------------------------------------- /+aplot/fixmesh.m: -------------------------------------------------------------------------------- 1 | function newpos = fixmesh(g,pos) 2 | % plot as transparent grey gifti surface 3 | % 4 | % AS 5 | 6 | v = g.vertices; 7 | v = v - repmat(spherefit(v),[size(v,1),1]); % Centre on ~0 8 | g.vertices=v; 9 | 10 | % Centre on ~0 11 | pos = pos - repmat(spherefit(pos),[size(pos,1),1]); 12 | 13 | for i = 1:length(pos) 14 | this = pos(i,:); 15 | [t,I] = maxpoints(cdist(v,this),1,'max'); 16 | newpos(i,:) = v(I,:); 17 | end 18 | 19 | end -------------------------------------------------------------------------------- /+aplot/get_mesh.m: -------------------------------------------------------------------------------- 1 | function [mesh,data] = get_mesh(i,data) 2 | % Decide what brain we're actually using, return it 3 | 4 | try mesh = i.g; 5 | fprintf('Using user provided mesh\n'); 6 | 7 | if ischar(mesh) || isnumeric(mesh) 8 | [mesh,data] = aplot.convert_mesh(mesh,data); 9 | end 10 | 11 | catch mesh = read_nv(); 12 | fprintf('(Using template brain mesh)\n'); 13 | end 14 | 15 | % if i.inflate 16 | % try fprintf('Trying to inflate mesh\n'); 17 | % dmesh.vertices = mesh.vertices; 18 | % dmesh.faces = mesh.faces; 19 | % dmesh = spm_mesh_inflate(dmesh,100); 20 | % mesh.vertices = dmesh.vertices; 21 | % mesh.faces = dmesh.faces; 22 | % catch 23 | % fprintf('Couldnt find spm_mesh_inflate: is SPM installed?\n'); 24 | % end 25 | % end 26 | 27 | 28 | end -------------------------------------------------------------------------------- /+aplot/get_roi_centres.m: -------------------------------------------------------------------------------- 1 | function [C,verts] = get_roi_centres(pos,all_roi_tissueindex) 2 | % Find centre points of rois 3 | % 4 | % 5 | v = pos; 6 | roi = all_roi_tissueindex; 7 | 8 | i = unique(roi); 9 | i(find(i==0))=[]; 10 | 11 | fprintf('Finding centre points of ROIs for labels...'); 12 | for j = 1:length(i) 13 | vox = find(roi==i(j)); 14 | verts{j} = v(vox,:); 15 | C(j,:) = spherefit(verts{j}); 16 | end 17 | fprintf(' ... done! \n'); 18 | % % Plot the first roi, mark centre and label: 19 | % scatter3(v(:,1),v(:,2),v(:,3),'k'); hold on 20 | % scatter3(verts(:,1),verts(:,2),verts(:,3),'r') 21 | % scatter3(C(:,1),C(:,2),C(:,3),'b*') 22 | 23 | end -------------------------------------------------------------------------------- /+aplot/interp_template.m: -------------------------------------------------------------------------------- 1 | function atlas = interp_template(atlas,pos) 2 | % The Euclidean/ICP routine for atlas registration 3 | 4 | if length(atlas.pos) == length(pos) 5 | fprintf('Overlay and atlas Vectors already match!\n'); 6 | atlas.M = eye(length(pos)); 7 | return; 8 | end 9 | 10 | fprintf('Scanning points:\n'); 11 | M = zeros( length(atlas.pos), length(pos) )'; 12 | r = floor( length(atlas.pos) / length(pos) );%1; 13 | w = 1; 14 | 15 | dist = cdist(pos,atlas.pos)'; 16 | %for i = 1:length(atlas.pos) 17 | for i = 1:length(pos) 18 | if i > 1; fprintf(repmat('\b',[size(str)])); end 19 | str = sprintf('%d/%d',i,(length(pos))); 20 | fprintf(str); 21 | 22 | [junk,ind] = maxpoints(dist(:,i),r,'min'); 23 | M (i,ind) = w; 24 | end 25 | fprintf('\n'); 26 | atlas.M = M'; 27 | 28 | end -------------------------------------------------------------------------------- /+aplot/isopen.m: -------------------------------------------------------------------------------- 1 | function data = isopen(data,in) 2 | % a wrapper on atemplate for generating the same plot for the left and 3 | % right hemis separately in different sublots 4 | s(1) = subplot(121); 5 | s(2) = subplot(122); 6 | 7 | data_in = data; 8 | 9 | % Plot 1. 10 | in.hemi = 'l'; 11 | in.fighnd = s(1); 12 | data = sort_sourcemodel(data_in,in); % Sourcemodel vertices 13 | [mesh,data] = get_mesh(in,data); % Get Surface 14 | [data,in] = sort_template(data,in); % Template space? (aal90/78/58) 15 | [mesh,data] = parse_mesh(mesh,in,data); % Mesh to put stuff on 16 | data.mesh = mesh; 17 | data = parse_plots(data,in); % Overlays, networks, etc 18 | data.in = in; % Return everything 19 | data_l = data; 20 | 21 | view([90 0]); 22 | 23 | % Plot 2. 24 | in.hemi = 'r'; 25 | in.fighnd = s(2); 26 | data = sort_sourcemodel(data_in,in); % Sourcemodel vertices 27 | [mesh,data] = get_mesh(in,data); % Get Surface 28 | [data,in] = sort_template(data,in); % Template space? (aal90/78/58) 29 | [mesh,data] = parse_mesh(mesh,in,data); % Mesh to put stuff on 30 | data.mesh = mesh; 31 | data = parse_plots(data,in); % Overlays, networks, etc 32 | data.in = in; % Return everything 33 | data_r = data; 34 | 35 | view([270 0]); 36 | 37 | data = []; 38 | data.l = data_l; 39 | data.r = data_r; 40 | 41 | end -------------------------------------------------------------------------------- /+aplot/killinterhems.m: -------------------------------------------------------------------------------- 1 | function x = killinterhems(x); 2 | % kill interhemispherics, assuming a square adjacency matrix 3 | % 4 | % 5 | 6 | S = size(x); 7 | xb = (S(1)/2)+1:S(1); 8 | yb = (S(2)/2)+1:S(2); 9 | xa = 1:S(1)/2; 10 | ya = 1:S(2)/2; 11 | 12 | x(xa,yb) = 0; 13 | x(xb,ya) = 0; 14 | 15 | end -------------------------------------------------------------------------------- /+aplot/makecolbar.m: -------------------------------------------------------------------------------- 1 | function RGB = makecolbar(I,netcmap) 2 | % Register colorbar values to an overlay / T-vector 3 | % 4 | 5 | if any(any(netcmap ~= 0)) 6 | Colors = colormap(netcmap); 7 | else 8 | Colors = jet; 9 | end 10 | 11 | NoColors = length(Colors); 12 | 13 | Ireduced = (I-min(I))/(max(I)-min(I))*(NoColors-1)+1; 14 | RGB = interp1(1:NoColors,Colors,Ireduced); 15 | 16 | end -------------------------------------------------------------------------------- /+aplot/makeodd.m: -------------------------------------------------------------------------------- 1 | function y = makeodd(x) 2 | % nearest odd number 3 | % 4 | % 5 | 6 | y = 2*floor(x/2)+1; 7 | 8 | end 9 | -------------------------------------------------------------------------------- /+aplot/matrix2nodes.m: -------------------------------------------------------------------------------- 1 | function [node1,node2,strng] = matrix2nodes(A,pos) 2 | % Write node & edge files for the AAL90 atlas 3 | % Also returns node-to-node coordinates for the matrix specified. 4 | % 5 | % Input is the n-by-n connectivity matrix 6 | % Input 2 is the sourcemodel vertices, n-by-3 7 | % 8 | % AS2017 9 | 10 | 11 | 12 | node1 = []; node2 = []; strng = []; 13 | for i = 1:length(A) 14 | [ix,iy,iv] = find(A(i,:)); 15 | 16 | if ~isempty(ix) 17 | conns = max(length(ix),length(iy)); 18 | for nc = 1:conns 19 | node1 = [node1; pos(i(1),:)]; 20 | node2 = [node2; pos(iy(nc),:)]; 21 | strng = [strng; iv(nc)]; 22 | end 23 | end 24 | end 25 | 26 | end -------------------------------------------------------------------------------- /+aplot/parse_labels.m: -------------------------------------------------------------------------------- 1 | function data = parse_labels(i,data) 2 | % decide which labels to include depending on what we're plotting 3 | if i.labels 4 | if isfield(i,'A') 5 | if isnumeric(i.A) 6 | data = aplot.addlabels(data,i.A,i.all_roi_tissueindex,i.thelabels); 7 | elseif ischar(i.A) 8 | E = data.network.edge; 9 | data = aplot.addlabels(data,E,i.all_roi_tissueindex,i.thelabels); 10 | end 11 | 12 | elseif isfield(i,'N') 13 | if sum(ismember(size(i.N),[1 90])) == 2 14 | data = aplot.addlabels(data, diag(i.N),i.all_roi_tissueindex,i.thelabels); 15 | elseif sum(ismember(size(i.N),[1 90])) == 1 16 | data = aplot.addlabels(data, diag(sum(i.N,2)),i.all_roi_tissueindex,i.thelabels); 17 | end 18 | 19 | else; n = length(data.sourcemodel.pos); 20 | data = aplot.addlabels(data, ones(n,n),i.all_roi_tissueindex,i.thelabels); 21 | end 22 | end 23 | end -------------------------------------------------------------------------------- /+aplot/parse_mesh.m: -------------------------------------------------------------------------------- 1 | function [mesh,data] = parse_mesh(mesh,i,data) 2 | % Figure out whether we actually want to plot a glass brain mesh, or not 3 | 4 | % if only one hemisphere plot 5 | hemi = i.hemi; 6 | data.hemi = hemi; 7 | 8 | % if affine supplied or flip flag 9 | affine = i.affine; 10 | flip = i.flip; 11 | 12 | % if inflate, pass flag 13 | inflate = i.inflate; 14 | 15 | % check orientation? 16 | checkori = i.checkori; 17 | 18 | % fill holes during hemisphere separation? 19 | dofillholes = i.fillholes; 20 | 21 | % explicitly optimise the alignment of the cloud points? 22 | optimise = i.optimise; 23 | 24 | if i.pmesh && ~isfield(i,'T') 25 | [mesh,data.sourcemodel.pos,h,p] = meshmesh(mesh,i.write,i.fname,i.fighnd,... 26 | .3,data.sourcemodel.pos,hemi,affine,flip,inflate,checkori,dofillholes,optimise); 27 | elseif i.pmesh 28 | [mesh,data.sourcemodel.pos,h,p] = meshmesh(mesh,i.write,i.fname,i.fighnd,... 29 | .3,data.sourcemodel.pos,hemi,affine,flip,inflate,checkori,dofillholes,optimise); 30 | else 31 | h = []; 32 | p = []; 33 | end 34 | 35 | mesh.h = h; 36 | mesh.p = p; 37 | end -------------------------------------------------------------------------------- /+aplot/parse_plots.m: -------------------------------------------------------------------------------- 1 | function data = parse_plots(data,i) 2 | 3 | % unpack triggers 4 | inputs = i; 5 | 6 | % overlays 7 | if isfield(inputs,'L') 8 | % copy over overlay options 9 | data.overlay.peaks = i.peaks; 10 | data.overlay.components = i.components; 11 | data.overlay.pca = i.pca; 12 | data.overlay.method = i.method; 13 | data.overlay.depth = i.depth; 14 | data.overlay.thresh = i.thresh; 15 | data.overlay.tf_interactive = i.tf_interactive; 16 | 17 | if isfield(i,'funcaffine') 18 | data.overlay.affine = i.funcaffine; 19 | end 20 | 21 | data = aplot.overlay(data, (i.L),i.write,i.fname,i.colbar); 22 | end 23 | 24 | isover = exist('L','var') || exist('V','var'); 25 | if isover && exist('A','var') 26 | i.colbar = 0; 27 | alpha(.2); 28 | end 29 | 30 | % networks 31 | if isfield(inputs,'A') 32 | data = aplot.connections(data,i.A,i.colbar,i.write,i.fname,i.netcmap); 33 | end 34 | 35 | % tracts 36 | if isfield(inputs,'T') 37 | data = aplot.drawtracks(data,i.T,i.H); 38 | end 39 | 40 | % nodes 41 | if isfield(inputs,'N') 42 | data = aplot.drawnodes(data, i.N); 43 | end 44 | 45 | % labels 46 | data = aplot.parse_labels(i,data); 47 | 48 | % video 49 | if isfield(inputs,'V') 50 | tv = 1:size(i.V,2); 51 | try tv = i.times; end 52 | data = aplot.video(data,i.V,1,i.fpath,tv); 53 | end 54 | 55 | 56 | end -------------------------------------------------------------------------------- /+aplot/rescale.m: -------------------------------------------------------------------------------- 1 | function y = rescale(x,S) 2 | 3 | y = S(1) + (S(2)-S(1)) .* (x - min(x) ) / ... 4 | ( max(x) - min(x) ); 5 | 6 | end -------------------------------------------------------------------------------- /+aplot/rw_edgenode.m: -------------------------------------------------------------------------------- 1 | function [edge,node] = rw_edgenode(name,rw,varargin) 2 | % Read / write (AAL) edge and node files from a matrix 3 | % 4 | % usage: 5 | % read: [edge,node] = rw_edgenode('name'); 6 | % write: rw_edgenode('savename','w',A) 7 | % 8 | % where A is connectivity matrix. 9 | % 10 | % To only write a subset of nodes / edges, see write_plot_node.m 11 | % AS 12 | 13 | if nargin < 2; rw = 'r' ; end 14 | 15 | if isnumeric(name) 16 | edge = name; 17 | node = []; 18 | return; 19 | end 20 | 21 | switch rw 22 | case 'r'; 23 | [fp,f,e] = fileparts(name); 24 | if isempty(fp) 25 | node = dlmread([f '.node']); 26 | edge = dlmread([f '.edge']); 27 | else 28 | node = dlmread([fp '/' f '.node']); 29 | edge = dlmread([fp '/' f '.edge']); 30 | end 31 | 32 | case 'w'; 33 | A = varargin{1}; 34 | A(isnan(A)) = 0; 35 | conmat2nodes(A,name); 36 | end -------------------------------------------------------------------------------- /+aplot/sort_sourcemodel.m: -------------------------------------------------------------------------------- 1 | function data = sort_sourcemodel(data,i) 2 | % Sort out what source model vertices we're going to use 3 | 4 | if isfield(i,'pos') 5 | fprintf('Using supplied sourcemodel vertices\n'); 6 | pos = i.pos; 7 | 8 | elseif isfield(i,'A') && ischar(i.A) 9 | fprintf('Using coords in node-file as sourcemodel\n'); 10 | 11 | [~,pos] = rw_edgenode(i.A); 12 | pos = pos(:,1:3); 13 | 14 | % elseif isfield(i,'L') && ischar(i.L) 15 | % %IF USING A NIFTI OVERLAY AS SOURCEMODEL, NEED THIS *before* TRYING TO DO 16 | % %TEMPLATE SPACE CONVERSION! 17 | % 18 | % [mesh,data] = get_mesh(i,data); 19 | % data.mesh = mesh; 20 | % [~,data] = parse_overlay(i.L,data); 21 | % pos = data.sourcemodel.pos; 22 | 23 | else 24 | fprintf('Assuming AAL90 source vertices by default\n'); 25 | load('AAL_SOURCEMOD'); 26 | pos = template_sourcemodel.pos; 27 | end -------------------------------------------------------------------------------- /+aplot/sort_template.m: -------------------------------------------------------------------------------- 1 | function [data,i] = sort_template(data,i) 2 | % If specified a template model, register data to it and return splined data as 3 | % well as weights 4 | 5 | if ~isfield(i,'pos') 6 | i.pos = data.sourcemodel.pos; 7 | end 8 | try 9 | data.template.model = i.model; 10 | data.template.labels = i.labels; 11 | end 12 | if i.template 13 | atlas = aplot.dotemplate(i.model); 14 | rois = aplot.get_roi_centres(atlas.template_sourcemodel.pos,atlas.all_roi_tissueindex); 15 | 16 | atlas.template_sourcemodel.pos = rois; 17 | atlas = rmfield(atlas,'all_roi_tissueindex'); 18 | 19 | reg = aplot.interp_template(data.sourcemodel,rois); 20 | atlas.M = reg.M; 21 | data.atlas = atlas; 22 | NM = atlas.M; 23 | 24 | % rescale so not change amplitudes 25 | m = max(NM(:)); 26 | NM = NM/m; 27 | 28 | % update sourcemodel and labels 29 | data.sourcemodel = atlas.template_sourcemodel; 30 | if i.labels; i.thelabels = atlas.AAL_Labels; end 31 | 32 | % overlay data 33 | if isfield(i,'L') 34 | if isnumeric(i.L) && ndims(i.L) ~= 3 35 | S = [min(i.L(:)) max(i.L(:))]; 36 | NL = i.L(:)'*NM; 37 | L = S(1) + ((S(2)-S(1))).*(NL - min(NL))./(max(NL) - min(NL)); 38 | L(isnan(L))=0; 39 | i.L = L; 40 | end 41 | end 42 | 43 | % network 44 | if isfield(i,'A') 45 | if isnumeric(i.A) 46 | S = [min(i.A(:)) max(i.A(:))]; 47 | NL = NM'*i.A*NM; 48 | A = S(1) + ((S(2)-S(1))).*(NL - min(NL(:)))./(max(NL(:)) - min(NL(:))); 49 | A(isnan(A)) = 0; 50 | i.A = A; 51 | end 52 | end 53 | 54 | % video data 55 | if isfield(i,'V') 56 | S = [min(i.V(:)) max(i.V(:))]; 57 | for j = 1:size(i.V,2) % over time points 58 | NL(:,j) = i.V(:,j)'*NM; 59 | end 60 | V = S(1) + ((S(2)-S(1))).*(NL - min(NL))./(max(NL) - min(NL)); 61 | V(isnan(V))=0; 62 | if orthog 63 | % dont use this 64 | V = aplot.symm_orthog(V); 65 | end 66 | V(isnan(V))=0; 67 | i.V = V; 68 | end 69 | 70 | end 71 | 72 | end -------------------------------------------------------------------------------- /+aplot/spherefit.m: -------------------------------------------------------------------------------- 1 | function Centre = spherefit(X) 2 | % Fit sphere to centre of vertices, return centre points 3 | % 4 | % 5 | 6 | A = [mean(X(:,1).*(X(:,1)-mean(X(:,1)))), ... 7 | 2*mean(X(:,1).*(X(:,2)-mean(X(:,2)))), ... 8 | 2*mean(X(:,1).*(X(:,3)-mean(X(:,3)))); ... 9 | 0, ... 10 | mean(X(:,2).*(X(:,2)-mean(X(:,2)))), ... 11 | 2*mean(X(:,2).*(X(:,3)-mean(X(:,3)))); ... 12 | 0, ... 13 | 0, ... 14 | mean(X(:,3).*(X(:,3)-mean(X(:,3))))]; 15 | A = A+A.'; 16 | B = [mean((X(:,1).^2+X(:,2).^2+X(:,3).^2).*(X(:,1)-mean(X(:,1))));... 17 | mean((X(:,1).^2+X(:,2).^2+X(:,3).^2).*(X(:,2)-mean(X(:,2))));... 18 | mean((X(:,1).^2+X(:,2).^2+X(:,3).^2).*(X(:,3)-mean(X(:,3))))]; 19 | Centre=(A\B).'; 20 | end -------------------------------------------------------------------------------- /+aplot/sym_pad_vector.m: -------------------------------------------------------------------------------- 1 | function y = sym_pad_vector(x,n) 2 | % Symmetrically pad a vector with zeros 3 | 4 | if length(x) ~= n 5 | k = n - length(x); 6 | k = floor(k/2); 7 | y = [zeros(1,k) x zeros(1,k)]; 8 | 9 | else y = x; 10 | end 11 | 12 | end -------------------------------------------------------------------------------- /+aplot/symm_orthog.m: -------------------------------------------------------------------------------- 1 | function y = symm_orthog(x) 2 | % Efficient symmetric orthogonalisation method for matrices, using: 3 | % 4 | % y = x * real(inv(x' * x)^(1/2)); 5 | % 6 | % AS 7 | 8 | fprintf('\nOrthogonalising\n'); 9 | y = [x] * real(inv([x]' * [x])^(1/2)); 10 | y = (max(x(:)) - min(x(:))) * ( (y - min(y(:))) / (max(y(:)) - min(y(:))) ); 11 | 12 | end -------------------------------------------------------------------------------- /+gty/+gifti/Contents.m: -------------------------------------------------------------------------------- 1 | % GIfTI Class for MATLAB 2 | % 3 | % Geometry format under the Neuroimaging Informatics Technology Initiative 4 | % (NIfTI): 5 | % http://www.nitrc.org/projects/gifti/ 6 | % http://nifti.nimh.nih.gov/ 7 | % 8 | % This MATLAB class is part of SPM: 9 | % http://www.fil.ion.ucl.ac.uk/spm/ 10 | % 11 | % It relies on external libraries: 12 | % Base64, by Peter J. Acklam: 13 | % http://home.online.no/~pjacklam/ 14 | % miniz, by Rich Geldreich: 15 | % http://code.google.com/p/miniz/ 16 | % XMLTree, by Guillaume Flandin: 17 | % http://www.artefact.tk/software/matlab/xml/ 18 | %__________________________________________________________________________ 19 | % Copyright (C) 2008-2015 Wellcome Trust Centre for Neuroimaging 20 | 21 | % Guillaume Flandin 22 | % $Id: Contents.m 6404 2015-04-13 14:29:53Z guillaume $ 23 | 24 | % GIfTI file format for MATLAB (The Mathworks, Inc.). 25 | % Copyright (C) 2008-2015 Wellcome Trust Centre for Neuroimaging 26 | % 27 | % This program is free software; you can redistribute it and/or 28 | % modify it under the terms of the GNU General Public License 29 | % as published by the Free Software Foundation; either version 2 30 | % of the License, or any later version. 31 | % 32 | % This program is distributed in the hope that it will be useful, 33 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35 | % GNU General Public License for more details. 36 | % 37 | % You should have received a copy of the GNU General Public License 38 | % along with this program; if not, write to the Free Software 39 | % Foundation Inc, 59 Temple Pl. - Suite 330, Boston, MA 02111-1307, USA. -------------------------------------------------------------------------------- /+gty/+gifti/display.m: -------------------------------------------------------------------------------- 1 | function display(this) 2 | % Display method for GIfTI objects 3 | % FORMAT display(this) 4 | % this - GIfTI object 5 | %__________________________________________________________________________ 6 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 7 | 8 | % Guillaume Flandin 9 | % $Id: display.m 4182 2011-02-01 12:29:09Z guillaume $ 10 | 11 | display_name = inputname(1); 12 | if isempty(display_name) 13 | display_name = 'ans'; 14 | end 15 | 16 | if length(this) == 1 && ~isempty(this.data) 17 | eval([display_name ' = struct(this);']); 18 | eval(['display(' display_name ');']); 19 | else 20 | disp(' ') 21 | disp([display_name ' =']); 22 | disp(' '); 23 | eval([display_name ' = this;']); 24 | eval(['disp(' display_name ');']); 25 | end -------------------------------------------------------------------------------- /+gty/+gifti/export.m: -------------------------------------------------------------------------------- 1 | function s = export(this,target) 2 | % Export a GIfTI object into specific MATLAB struct 3 | % FORMAT s = export(this,target) 4 | % this - GIfTI object 5 | % target - string describing target output [default: MATLAB] 6 | % s - a structure containing public fields of the object 7 | %__________________________________________________________________________ 8 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 9 | 10 | % Guillaume Flandin 11 | % $Id: export.m 6401 2015-04-09 17:21:33Z guillaume $ 12 | 13 | if numel(this) > 1, warning('Only handle scalar objects yet.'); end 14 | 15 | if nargin <= 1, target = 'MATLAB'; end 16 | 17 | switch lower(target) 18 | case 'matlab' 19 | s = struct(this); 20 | 21 | case 'patch' 22 | if isfield(this,'vertices') 23 | s.vertices = double(subsref(this, substruct('.', 'vertices'))); 24 | end 25 | if isfield(this,'faces') 26 | s.faces = subsref(this, substruct('.', 'faces')); 27 | end 28 | if isfield(this,'cdata') 29 | s.facevertexcdata = double(subsref(this, substruct('.', 'cdata'))); 30 | end 31 | try, s; catch, s = struct([]); end 32 | 33 | case {'fieldtrip', 'ft'} 34 | s = struct('tri',[], 'pnt',[]); 35 | if isfield(this,'vertices') 36 | s.pnt = double(subsref(this, substruct('.', 'vertices'))); 37 | end 38 | if isfield(this,'faces') 39 | s.tri = double(subsref(this, substruct('.', 'faces'))); 40 | end 41 | 42 | case {'spm'} 43 | s = struct('face',[], 'vert',[]); 44 | if isfield(this,'vertices') 45 | s.vert = double(subsref(this, substruct('.', 'vertices'))); 46 | end 47 | if isfield(this,'faces') 48 | s.face = uint32(subsref(this, substruct('.', 'faces'))); 49 | end 50 | 51 | otherwise 52 | error('Unknown target ''%s''.', target); 53 | end 54 | -------------------------------------------------------------------------------- /+gty/+gifti/fieldnames.m: -------------------------------------------------------------------------------- 1 | function names = fieldnames(this) 2 | % Fieldnames method for GIfTI objects 3 | % FORMAT names = fieldnames(this) 4 | % this - GIfTI object 5 | % names - field names 6 | %__________________________________________________________________________ 7 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 8 | 9 | % Guillaume Flandin 10 | % $Id: fieldnames.m 6345 2015-02-20 12:25:50Z guillaume $ 11 | 12 | if numel(this) > 1, warning('Only handle scalar objects yet.'); end 13 | 14 | pfn = {'vertices' 'faces' 'normals' 'cdata' 'mat' 'labels' 'indices'}; 15 | 16 | names = pfn(isintent(this,pfn)); 17 | -------------------------------------------------------------------------------- /+gty/+gifti/isfield.m: -------------------------------------------------------------------------------- 1 | function tf = isfield(this,field) 2 | % Isfield method for GIfTI objects 3 | % FORMAT tf = isfield(this,field) 4 | % this - GIfTI object 5 | % field - string of cell array 6 | % tf - logical array 7 | %__________________________________________________________________________ 8 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 9 | 10 | % Guillaume Flandin 11 | % $Id: isfield.m 2076 2008-09-10 12:34:08Z guillaume $ 12 | 13 | tf = ismember(field, fieldnames(this)); -------------------------------------------------------------------------------- /+gty/+gifti/plot.m: -------------------------------------------------------------------------------- 1 | function varargout = plot(varargin) 2 | % plot method for GIfTI objects 3 | %__________________________________________________________________________ 4 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Guillaume Flandin 7 | % $Id: plot.m 5888 2014-02-19 19:54:12Z guillaume $ 8 | 9 | % if ishandle(varargin{1}) 10 | % h = figure(varargin{1}); 11 | % else 12 | % h = figure; 13 | % %axis equal; 14 | % %axis off; 15 | % %camlight; 16 | % %camlight(-80,-10); 17 | % %lighting phong; 18 | % end 19 | % cameramenu; 20 | 21 | 22 | cdata = []; 23 | ax = []; 24 | indc = 0; 25 | if nargin == 1 26 | this = varargin{1}; 27 | h = gcf; 28 | else 29 | if ishandle(varargin{1}) 30 | ax = varargin{1}; 31 | h = figure(get(ax,'parent')); 32 | this = varargin{2}; 33 | 34 | % allow pass of cdata as varargin{3} 35 | if nargin == 3; 36 | cdata = subsref(varargin{3},struct('type','.','subs','cdata')); 37 | indc = 1; 38 | end 39 | elseif strcmp(varargin{2},'fighnd') 40 | ax = varargin{3}; 41 | h = figure(get(ax,'parent')); 42 | this = varargin{1}; 43 | 44 | % allow pass of cdata as varargin{3} 45 | if nargin == 4; 46 | cdata = subsref(varargin{4},struct('type','.','subs','cdata')); 47 | indc = 1; 48 | end 49 | else 50 | this = varargin{1}; 51 | h = gcf; 52 | cdata = subsref(varargin{2},struct('type','.','subs','cdata')); 53 | end 54 | % changed in light of above 55 | if nargin > 2 && isempty(indc) 56 | indc = varargin{3}; 57 | else 58 | indc = 1; 59 | end 60 | end 61 | 62 | if isempty(ax), ax = axes('Parent',h); end 63 | 64 | % Alex add: only make size x=y if not a subplot (i.e. no handle) 65 | if ~ishandle(varargin{1}); 66 | %axis(ax,'equal'); 67 | axis(ax,'image'); 68 | end 69 | 70 | %axis(ax,'off'); 71 | hp = patch(struct(... 72 | 'vertices', subsref(this,struct('type','.','subs','vertices')),... 73 | 'faces', subsref(this,struct('type','.','subs','faces'))),... 74 | 'FaceColor', [.5 .5 .5],...%'b',... 75 | 'EdgeColor', 'none',... 76 | 'Parent',ax); 77 | 78 | if ~isempty(cdata) 79 | set(hp,'FaceVertexCData',cdata(:,indc), 'FaceColor','interp') 80 | end 81 | 82 | axes(ax); 83 | %camlight; 84 | %camlight(-80,-10); 85 | camlight left 86 | camlight right 87 | 88 | lighting phong; 89 | %axes(ax); 90 | %cameramenu; 91 | 92 | if nargout 93 | varargout{1} = hp; 94 | end 95 | -------------------------------------------------------------------------------- /+gty/+gifti/private/Makefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env make -f 2 | # GIfTI Makefile called by {SPM}/src/Makefile 3 | # 4 | # Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging 5 | # 6 | # $Id: Makefile 6402 2015-04-09 18:11:06Z guillaume $ 7 | 8 | include ../../src/Makefile.var 9 | 10 | SPMMEX = zstream.$(SUF) 11 | 12 | ifeq (mex,$(SUF)) 13 | export CFLAGS = $(shell $(MEX) -p CFLAGS) -std=c99 14 | else 15 | MEXOPTS += CFLAGS='$$CFLAGS -std=c99' 16 | endif 17 | 18 | all: $(SPMMEX) 19 | @: 20 | 21 | clean: 22 | @: 23 | 24 | distclean: clean 25 | $(DEL) $(SPMMEX) 26 | 27 | install: 28 | @: 29 | 30 | tarball: all 31 | $(TAR) cf spm_mex.tar $(SPMMEX) 32 | 33 | %.$(SUF) : %.c 34 | $(MEX) $< $(MEXEND) 35 | -------------------------------------------------------------------------------- /+gty/+gifti/private/getdict.m: -------------------------------------------------------------------------------- 1 | function d = getdict 2 | % Dictionary of GIfTI/NIfTI stuff 3 | %__________________________________________________________________________ 4 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Guillaume Flandin 7 | % $Id: getdict.m 4505 2011-09-30 11:45:58Z guillaume $ 8 | 9 | persistent dict; 10 | if ~isempty(dict) 11 | d = dict; 12 | return; 13 | end 14 | 15 | table = {... 16 | 'NIFTI_TYPE_UINT8', 'uint8', '%d', @uint8, 'uint8' 17 | 'NIFTI_TYPE_INT32', 'int32', '%d', @int32, 'int32' 18 | 'NIFTI_TYPE_FLOAT32', 'float32', '%f', @single, 'single' 19 | 'NIFTI_TYPE_FLOAT64', 'float64', '%f', @double, 'double'}; 20 | 21 | for i=1:size(table,1) 22 | dict.(table{i,1}) = cell2struct({table{i,2:end}},... 23 | {'class', 'format', 'conv', 'cast'}, 2); 24 | end 25 | 26 | d = dict; -------------------------------------------------------------------------------- /+gty/+gifti/private/read_freesurfer_file.m: -------------------------------------------------------------------------------- 1 | function this = read_freesurfer_file(filename) 2 | % Low level reader of FreeSurfer files (ASCII triangle surface file) 3 | % FORMAT this = read_freesurfer_file(filename) 4 | % filename - FreeSurfer file 5 | % 6 | % See http://wideman-one.com/gw/brain/fs/surfacefileformats.htm 7 | %__________________________________________________________________________ 8 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 9 | 10 | % Guillaume Flandin 11 | % $Id: read_freesurfer_file.m 5322 2013-03-13 15:04:14Z guillaume $ 12 | 13 | 14 | fid = fopen(filename,'rt'); 15 | if fid == -1, error('Cannot open "%s".',filename); end 16 | 17 | fgetl(fid); % #!ascii 18 | N = fscanf(fid,'%d',2); 19 | this.vertices = fscanf(fid,'%f %f %f %d',[4 N(1)])'; 20 | this.faces = fscanf(fid,'%d %d %d %d',[4 N(2)])'; 21 | 22 | fclose(fid); 23 | 24 | this.vertices = this.vertices(:,1:3); 25 | this.faces = this.faces(:,1:3) + 1; 26 | -------------------------------------------------------------------------------- /+gty/+gifti/private/zstream.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: zstream.c 6417 2015-04-21 16:03:44Z guillaume $ 3 | * Guillaume Flandin 4 | */ 5 | 6 | /* mex -O CFLAGS='$CFLAGS -std=c99' -largeArrayDims zstream.c */ 7 | 8 | /* setenv CFLAGS "`mkoctfile -p CFLAGS` -std=c99" */ 9 | /* mkoctfile --mex zstream.c */ 10 | 11 | /* miniz: http://code.google.com/p/miniz/ */ 12 | #define MINIZ_NO_STDIO 13 | #define MINIZ_NO_ARCHIVE_APIS 14 | #define MINIZ_NO_TIME 15 | #define MINIZ_NO_ZLIB_APIS 16 | #include "miniz.c" 17 | 18 | #include "mex.h" 19 | 20 | /* --- GATEWAY FUNCTION --- */ 21 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 22 | { 23 | 24 | char *action; 25 | unsigned char *IN = NULL, *OUT = NULL; 26 | size_t INlen, OUTlen; 27 | 28 | /* Check for proper number of arguments */ 29 | if (nrhs < 2) 30 | mexErrMsgTxt("Not enough input arguments."); 31 | else if (nrhs > 2) 32 | mexErrMsgTxt("Too many input arguments."); 33 | else if (nlhs > 1) 34 | mexErrMsgTxt("Too many output arguments."); 35 | 36 | /* The input ACTION must be a string */ 37 | if (!mxIsChar(prhs[0])) 38 | mexErrMsgTxt("Input ACTION must be a string."); 39 | action = mxArrayToString(prhs[0]); 40 | 41 | /* The input IN must be a real uint8 array */ 42 | if (!mxIsUint8(prhs[1]) || mxIsComplex(prhs[1])) 43 | mexErrMsgTxt("Input IN must be a real uint8 array."); 44 | 45 | INlen = mxGetNumberOfElements(prhs[1]); 46 | IN = mxGetData(prhs[1]); 47 | 48 | if (!strcmp(action,"D")) { 49 | 50 | /* Decompress data */ 51 | OUT = tinfl_decompress_mem_to_heap(IN, INlen, &OUTlen, TINFL_FLAG_PARSE_ZLIB_HEADER); 52 | 53 | if (OUT == NULL) 54 | mexErrMsgTxt("Error when decompressing data."); 55 | } 56 | else if (!strcmp(action,"C")) { 57 | /* Compress data */ 58 | OUT = tdefl_compress_mem_to_heap(IN, INlen, &OUTlen, TDEFL_WRITE_ZLIB_HEADER); 59 | 60 | if (OUT == NULL) 61 | mexErrMsgTxt("Error when compressing data."); 62 | } 63 | else { 64 | mexErrMsgTxt("Unknown ACTION type."); 65 | } 66 | 67 | /* */ 68 | plhs[0] = mxCreateNumericMatrix(OUTlen,1,mxUINT8_CLASS,mxREAL); 69 | if (plhs[0] == NULL) 70 | mexErrMsgTxt("Error when creating output variable."); 71 | 72 | memcpy(mxGetData(plhs[0]), OUT, OUTlen); 73 | 74 | mxFree(action); 75 | mz_free(OUT); 76 | 77 | } 78 | -------------------------------------------------------------------------------- /+gty/+gifti/private/zstream.m: -------------------------------------------------------------------------------- 1 | function Z = zstream(action,D) 2 | % Compress/decompress stream of bytes using Deflate/Inflate 3 | % FORMAT Z = zstream('C',D) 4 | % D - data stream to compress (converted to uint8 if needed) 5 | % Z - compressed data stream (uint8 vector) 6 | % FORMAT D = zstream('D',Z) 7 | % Z - data stream to decompress (uint8 vector) 8 | % D - decompressed data stream (uint8 vector) 9 | %__________________________________________________________________________ 10 | % 11 | % This C-MEX file relies on: 12 | % * miniz, by Rich Geldreich 13 | % http://code.google.com/p/miniz/ 14 | % Fallback Java implementation is adapted from: 15 | % * dzip/dunzip, by Michael Kleder 16 | % http://www.mathworks.com/matlabcentral/fileexchange/8899 17 | %__________________________________________________________________________ 18 | % Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging 19 | 20 | % Guillaume Flandin 21 | % $Id: zstream.m 6417 2015-04-21 16:03:44Z guillaume $ 22 | 23 | 24 | if exist('OCTAVE_VERSION','builtin') 25 | error('zstream.c not compiled - see Makefile'); 26 | end 27 | 28 | switch upper(action) 29 | case 'C' 30 | D = typecast(D(:),'uint8'); 31 | f = java.io.ByteArrayOutputStream(); 32 | g = java.util.zip.DeflaterOutputStream(f); 33 | g.write(D); 34 | g.close; 35 | Z = typecast(f.toByteArray,'uint8'); 36 | f.close; 37 | 38 | case 'D' 39 | import com.mathworks.mlwidgets.io.InterruptibleStreamCopier 40 | a = java.io.ByteArrayInputStream(D); 41 | b = java.util.zip.InflaterInputStream(a); 42 | isc = InterruptibleStreamCopier.getInterruptibleStreamCopier; 43 | c = java.io.ByteArrayOutputStream; 44 | isc.copyStream(b,c); 45 | Z = c.toByteArray; 46 | 47 | otherwise 48 | error('Unknown action "%s".',action); 49 | end 50 | -------------------------------------------------------------------------------- /+gty/+gifti/struct.m: -------------------------------------------------------------------------------- 1 | function s = struct(this) 2 | % Struct method for GIfTI objects 3 | % FORMAT s = struct(this) 4 | % this - GIfTI object 5 | % s - a structure containing public fields of the object 6 | %__________________________________________________________________________ 7 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 8 | 9 | % Guillaume Flandin 10 | % $Id: struct.m 4716 2012-04-19 11:01:32Z guillaume $ 11 | 12 | names = fieldnames(this); 13 | names = unique(names); 14 | values = cell(length(names), length(this(:))); 15 | 16 | for i=1:length(names) 17 | [values{i,:}] = subsref(this(:), substruct('.',names{i})); 18 | end 19 | s = reshape(cell2struct(values,names,1),size(this)); -------------------------------------------------------------------------------- /+gty/+gifti/subsref.m: -------------------------------------------------------------------------------- 1 | function varargout = subsref(this,subs) 2 | % Subscript referencing for GIfTI objects 3 | %__________________________________________________________________________ 4 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Guillaume Flandin 7 | % $Id: subsref.m 6345 2015-02-20 12:25:50Z guillaume $ 8 | 9 | if length(this) > 1 && ~strcmp(subs(1).type,'()') 10 | warning('Not implemented.'); 11 | for i=1:numel(this) 12 | varargout{i} = subsref(this(i),subs); 13 | end 14 | return; 15 | end 16 | 17 | switch subs(1).type 18 | case '.' 19 | [i,j] = isintent(this,subs(1).subs); 20 | if isempty(i) 21 | if strcmp(subs(1).subs,'private') 22 | varargout{1} = builtin('struct',this); 23 | else 24 | error('Reference to non-existent field ''%s''.',subs(1).subs); 25 | end 26 | else 27 | if strcmp(subs(1).subs,'mat') 28 | varargout{1} = this.data{j}.space.MatrixData; 29 | elseif strcmp(subs(1).subs,'labels') 30 | varargout{1} = this.label; 31 | else 32 | if length(j) == 1 33 | varargout{1} = this.data{j}.data; 34 | else 35 | a = [this.data{j}]; 36 | try 37 | varargout{1} = [a.data]; 38 | catch 39 | error('Data arrays are of different sizes.'); 40 | end 41 | end 42 | end 43 | end 44 | if strcmp(subs(1).subs,'faces') || strcmp(subs(1).subs,'indices') 45 | varargout{1} = varargout{1} + 1; % indices start at 1 46 | end 47 | if length(subs) > 1 48 | varargout{1} = subsref(varargout{1},subs(2:end)); 49 | end 50 | case '{}' 51 | error('Cell contents reference from a non-cell array object.'); 52 | case '()' 53 | if length(subs) == 1 54 | varargout{1} = builtin('subsref',this,subs(1)); 55 | else 56 | varargout{1} = subsref(builtin('subsref',this,subs(1)),subs(2:end)); 57 | end 58 | otherwise 59 | error('This should not happen.'); 60 | end -------------------------------------------------------------------------------- /@gifti/Contents.m: -------------------------------------------------------------------------------- 1 | % GIfTI Class for MATLAB 2 | % 3 | % Geometry format under the Neuroimaging Informatics Technology Initiative 4 | % (NIfTI): 5 | % http://www.nitrc.org/projects/gifti/ 6 | % http://nifti.nimh.nih.gov/ 7 | % 8 | % This MATLAB class is part of SPM: 9 | % http://www.fil.ion.ucl.ac.uk/spm/ 10 | % 11 | % It relies on external libraries: 12 | % Base64, by Peter J. Acklam: 13 | % http://home.online.no/~pjacklam/ 14 | % miniz, by Rich Geldreich: 15 | % http://code.google.com/p/miniz/ 16 | % XMLTree, by Guillaume Flandin: 17 | % http://www.artefact.tk/software/matlab/xml/ 18 | %__________________________________________________________________________ 19 | % Copyright (C) 2008-2015 Wellcome Trust Centre for Neuroimaging 20 | 21 | % Guillaume Flandin 22 | % $Id: Contents.m 6404 2015-04-13 14:29:53Z guillaume $ 23 | 24 | % GIfTI file format for MATLAB (The Mathworks, Inc.). 25 | % Copyright (C) 2008-2015 Wellcome Trust Centre for Neuroimaging 26 | % 27 | % This program is free software; you can redistribute it and/or 28 | % modify it under the terms of the GNU General Public License 29 | % as published by the Free Software Foundation; either version 2 30 | % of the License, or any later version. 31 | % 32 | % This program is distributed in the hope that it will be useful, 33 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35 | % GNU General Public License for more details. 36 | % 37 | % You should have received a copy of the GNU General Public License 38 | % along with this program; if not, write to the Free Software 39 | % Foundation Inc, 59 Temple Pl. - Suite 330, Boston, MA 02111-1307, USA. -------------------------------------------------------------------------------- /@gifti/display.m: -------------------------------------------------------------------------------- 1 | function display(this) 2 | % Display method for GIfTI objects 3 | % FORMAT display(this) 4 | % this - GIfTI object 5 | %__________________________________________________________________________ 6 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 7 | 8 | % Guillaume Flandin 9 | % $Id: display.m 4182 2011-02-01 12:29:09Z guillaume $ 10 | 11 | display_name = inputname(1); 12 | if isempty(display_name) 13 | display_name = 'ans'; 14 | end 15 | 16 | if length(this) == 1 && ~isempty(this.data) 17 | eval([display_name ' = struct(this);']); 18 | eval(['display(' display_name ');']); 19 | else 20 | disp(' ') 21 | disp([display_name ' =']); 22 | disp(' '); 23 | eval([display_name ' = this;']); 24 | eval(['disp(' display_name ');']); 25 | end -------------------------------------------------------------------------------- /@gifti/export.m: -------------------------------------------------------------------------------- 1 | function s = export(this,target) 2 | % Export a GIfTI object into specific MATLAB struct 3 | % FORMAT s = export(this,target) 4 | % this - GIfTI object 5 | % target - string describing target output [default: MATLAB] 6 | % s - a structure containing public fields of the object 7 | %__________________________________________________________________________ 8 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 9 | 10 | % Guillaume Flandin 11 | % $Id: export.m 6401 2015-04-09 17:21:33Z guillaume $ 12 | 13 | if numel(this) > 1, warning('Only handle scalar objects yet.'); end 14 | 15 | if nargin <= 1, target = 'MATLAB'; end 16 | 17 | switch lower(target) 18 | case 'matlab' 19 | s = struct(this); 20 | 21 | case 'patch' 22 | if isfield(this,'vertices') 23 | s.vertices = double(subsref(this, substruct('.', 'vertices'))); 24 | end 25 | if isfield(this,'faces') 26 | s.faces = subsref(this, substruct('.', 'faces')); 27 | end 28 | if isfield(this,'cdata') 29 | s.facevertexcdata = double(subsref(this, substruct('.', 'cdata'))); 30 | end 31 | try, s; catch, s = struct([]); end 32 | 33 | case {'fieldtrip', 'ft'} 34 | s = struct('tri',[], 'pnt',[]); 35 | if isfield(this,'vertices') 36 | s.pnt = double(subsref(this, substruct('.', 'vertices'))); 37 | end 38 | if isfield(this,'faces') 39 | s.tri = double(subsref(this, substruct('.', 'faces'))); 40 | end 41 | 42 | case {'spm'} 43 | s = struct('face',[], 'vert',[]); 44 | if isfield(this,'vertices') 45 | s.vert = double(subsref(this, substruct('.', 'vertices'))); 46 | end 47 | if isfield(this,'faces') 48 | s.face = uint32(subsref(this, substruct('.', 'faces'))); 49 | end 50 | 51 | otherwise 52 | error('Unknown target ''%s''.', target); 53 | end 54 | -------------------------------------------------------------------------------- /@gifti/fieldnames.m: -------------------------------------------------------------------------------- 1 | function names = fieldnames(this) 2 | % Fieldnames method for GIfTI objects 3 | % FORMAT names = fieldnames(this) 4 | % this - GIfTI object 5 | % names - field names 6 | %__________________________________________________________________________ 7 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 8 | 9 | % Guillaume Flandin 10 | % $Id: fieldnames.m 6345 2015-02-20 12:25:50Z guillaume $ 11 | 12 | if numel(this) > 1, warning('Only handle scalar objects yet.'); end 13 | 14 | pfn = {'vertices' 'faces' 'normals' 'cdata' 'mat' 'labels' 'indices'}; 15 | 16 | names = pfn(isintent(this,pfn)); 17 | -------------------------------------------------------------------------------- /@gifti/isfield.m: -------------------------------------------------------------------------------- 1 | function tf = isfield(this,field) 2 | % Isfield method for GIfTI objects 3 | % FORMAT tf = isfield(this,field) 4 | % this - GIfTI object 5 | % field - string of cell array 6 | % tf - logical array 7 | %__________________________________________________________________________ 8 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 9 | 10 | % Guillaume Flandin 11 | % $Id: isfield.m 2076 2008-09-10 12:34:08Z guillaume $ 12 | 13 | tf = ismember(field, fieldnames(this)); -------------------------------------------------------------------------------- /@gifti/plot.m: -------------------------------------------------------------------------------- 1 | function varargout = plot(varargin) 2 | % plot method for GIfTI objects 3 | %__________________________________________________________________________ 4 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Guillaume Flandin 7 | % $Id: plot.m 5888 2014-02-19 19:54:12Z guillaume $ 8 | 9 | % if ishandle(varargin{1}) 10 | % h = figure(varargin{1}); 11 | % else 12 | % h = figure; 13 | % %axis equal; 14 | % %axis off; 15 | % %camlight; 16 | % %camlight(-80,-10); 17 | % %lighting phong; 18 | % end 19 | % cameramenu; 20 | 21 | 22 | cdata = []; 23 | ax = []; 24 | indc = 0; 25 | if nargin == 1 26 | this = varargin{1}; 27 | h = gcf; 28 | else 29 | if ishandle(varargin{1}) 30 | ax = varargin{1}; 31 | h = figure(get(ax,'parent')); 32 | this = varargin{2}; 33 | 34 | % allow pass of cdata as varargin{3} 35 | if nargin == 3; 36 | cdata = subsref(varargin{3},struct('type','.','subs','cdata')); 37 | indc = 1; 38 | end 39 | elseif strcmp(varargin{2},'fighnd') 40 | ax = varargin{3}; 41 | h = figure(get(ax,'parent')); 42 | this = varargin{1}; 43 | 44 | % allow pass of cdata as varargin{3} 45 | if nargin == 4; 46 | cdata = subsref(varargin{4},struct('type','.','subs','cdata')); 47 | indc = 1; 48 | end 49 | else 50 | this = varargin{1}; 51 | h = gcf; 52 | cdata = subsref(varargin{2},struct('type','.','subs','cdata')); 53 | end 54 | % changed in light of above 55 | if nargin > 2 && isempty(indc) 56 | indc = varargin{3}; 57 | else 58 | indc = 1; 59 | end 60 | end 61 | 62 | if isempty(ax), ax = axes('Parent',h); end 63 | 64 | % Alex add: only make size x=y if not a subplot (i.e. no handle) 65 | if ~ishandle(varargin{1}); 66 | %axis(ax,'equal'); 67 | axis(ax,'image'); 68 | end 69 | 70 | %axis(ax,'off'); 71 | hp = patch(struct(... 72 | 'vertices', subsref(this,struct('type','.','subs','vertices')),... 73 | 'faces', subsref(this,struct('type','.','subs','faces'))),... 74 | 'FaceColor', [.5 .5 .5],...%'b',... 75 | 'EdgeColor', 'none',... 76 | 'Parent',ax); 77 | 78 | if ~isempty(cdata) 79 | set(hp,'FaceVertexCData',cdata(:,indc), 'FaceColor','interp') 80 | end 81 | 82 | axes(ax); 83 | %camlight; 84 | %camlight(-80,-10); 85 | 86 | c1 = camlight('left'); 87 | c2 = camlight('right'); 88 | 89 | c1.Color = [.1 .1 .1]; 90 | c2.Color = [.1 .1 .1]; 91 | 92 | 93 | lighting phong; 94 | %axes(ax); 95 | %cameramenu; 96 | 97 | if nargout 98 | varargout{1} = hp; 99 | end 100 | -------------------------------------------------------------------------------- /@gifti/private/Makefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env make -f 2 | # GIfTI Makefile called by {SPM}/src/Makefile 3 | # 4 | # Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging 5 | # 6 | # $Id: Makefile 6402 2015-04-09 18:11:06Z guillaume $ 7 | 8 | include ../../src/Makefile.var 9 | 10 | SPMMEX = zstream.$(SUF) 11 | 12 | ifeq (mex,$(SUF)) 13 | export CFLAGS = $(shell $(MEX) -p CFLAGS) -std=c99 14 | else 15 | MEXOPTS += CFLAGS='$$CFLAGS -std=c99' 16 | endif 17 | 18 | all: $(SPMMEX) 19 | @: 20 | 21 | clean: 22 | @: 23 | 24 | distclean: clean 25 | $(DEL) $(SPMMEX) 26 | 27 | install: 28 | @: 29 | 30 | tarball: all 31 | $(TAR) cf spm_mex.tar $(SPMMEX) 32 | 33 | %.$(SUF) : %.c 34 | $(MEX) $< $(MEXEND) 35 | -------------------------------------------------------------------------------- /@gifti/private/getdict.m: -------------------------------------------------------------------------------- 1 | function d = getdict 2 | % Dictionary of GIfTI/NIfTI stuff 3 | %__________________________________________________________________________ 4 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Guillaume Flandin 7 | % $Id: getdict.m 4505 2011-09-30 11:45:58Z guillaume $ 8 | 9 | persistent dict; 10 | if ~isempty(dict) 11 | d = dict; 12 | return; 13 | end 14 | 15 | table = {... 16 | 'NIFTI_TYPE_UINT8', 'uint8', '%d', @uint8, 'uint8' 17 | 'NIFTI_TYPE_INT32', 'int32', '%d', @int32, 'int32' 18 | 'NIFTI_TYPE_FLOAT32', 'float32', '%f', @single, 'single' 19 | 'NIFTI_TYPE_FLOAT64', 'float64', '%f', @double, 'double'}; 20 | 21 | for i=1:size(table,1) 22 | dict.(table{i,1}) = cell2struct({table{i,2:end}},... 23 | {'class', 'format', 'conv', 'cast'}, 2); 24 | end 25 | 26 | d = dict; -------------------------------------------------------------------------------- /@gifti/private/read_freesurfer_file.m: -------------------------------------------------------------------------------- 1 | function this = read_freesurfer_file(filename) 2 | % Low level reader of FreeSurfer files (ASCII triangle surface file) 3 | % FORMAT this = read_freesurfer_file(filename) 4 | % filename - FreeSurfer file 5 | % 6 | % See http://wideman-one.com/gw/brain/fs/surfacefileformats.htm 7 | %__________________________________________________________________________ 8 | % Copyright (C) 2013 Wellcome Trust Centre for Neuroimaging 9 | 10 | % Guillaume Flandin 11 | % $Id: read_freesurfer_file.m 5322 2013-03-13 15:04:14Z guillaume $ 12 | 13 | 14 | fid = fopen(filename,'rt'); 15 | if fid == -1, error('Cannot open "%s".',filename); end 16 | 17 | fgetl(fid); % #!ascii 18 | N = fscanf(fid,'%d',2); 19 | this.vertices = fscanf(fid,'%f %f %f %d',[4 N(1)])'; 20 | this.faces = fscanf(fid,'%d %d %d %d',[4 N(2)])'; 21 | 22 | fclose(fid); 23 | 24 | this.vertices = this.vertices(:,1:3); 25 | this.faces = this.faces(:,1:3) + 1; 26 | -------------------------------------------------------------------------------- /@gifti/private/zstream.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: zstream.c 6417 2015-04-21 16:03:44Z guillaume $ 3 | * Guillaume Flandin 4 | */ 5 | 6 | /* mex -O CFLAGS='$CFLAGS -std=c99' -largeArrayDims zstream.c */ 7 | 8 | /* setenv CFLAGS "`mkoctfile -p CFLAGS` -std=c99" */ 9 | /* mkoctfile --mex zstream.c */ 10 | 11 | /* miniz: http://code.google.com/p/miniz/ */ 12 | #define MINIZ_NO_STDIO 13 | #define MINIZ_NO_ARCHIVE_APIS 14 | #define MINIZ_NO_TIME 15 | #define MINIZ_NO_ZLIB_APIS 16 | #include "miniz.c" 17 | 18 | #include "mex.h" 19 | 20 | /* --- GATEWAY FUNCTION --- */ 21 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 22 | { 23 | 24 | char *action; 25 | unsigned char *IN = NULL, *OUT = NULL; 26 | size_t INlen, OUTlen; 27 | 28 | /* Check for proper number of arguments */ 29 | if (nrhs < 2) 30 | mexErrMsgTxt("Not enough input arguments."); 31 | else if (nrhs > 2) 32 | mexErrMsgTxt("Too many input arguments."); 33 | else if (nlhs > 1) 34 | mexErrMsgTxt("Too many output arguments."); 35 | 36 | /* The input ACTION must be a string */ 37 | if (!mxIsChar(prhs[0])) 38 | mexErrMsgTxt("Input ACTION must be a string."); 39 | action = mxArrayToString(prhs[0]); 40 | 41 | /* The input IN must be a real uint8 array */ 42 | if (!mxIsUint8(prhs[1]) || mxIsComplex(prhs[1])) 43 | mexErrMsgTxt("Input IN must be a real uint8 array."); 44 | 45 | INlen = mxGetNumberOfElements(prhs[1]); 46 | IN = mxGetData(prhs[1]); 47 | 48 | if (!strcmp(action,"D")) { 49 | 50 | /* Decompress data */ 51 | OUT = tinfl_decompress_mem_to_heap(IN, INlen, &OUTlen, TINFL_FLAG_PARSE_ZLIB_HEADER); 52 | 53 | if (OUT == NULL) 54 | mexErrMsgTxt("Error when decompressing data."); 55 | } 56 | else if (!strcmp(action,"C")) { 57 | /* Compress data */ 58 | OUT = tdefl_compress_mem_to_heap(IN, INlen, &OUTlen, TDEFL_WRITE_ZLIB_HEADER); 59 | 60 | if (OUT == NULL) 61 | mexErrMsgTxt("Error when compressing data."); 62 | } 63 | else { 64 | mexErrMsgTxt("Unknown ACTION type."); 65 | } 66 | 67 | /* */ 68 | plhs[0] = mxCreateNumericMatrix(OUTlen,1,mxUINT8_CLASS,mxREAL); 69 | if (plhs[0] == NULL) 70 | mexErrMsgTxt("Error when creating output variable."); 71 | 72 | memcpy(mxGetData(plhs[0]), OUT, OUTlen); 73 | 74 | mxFree(action); 75 | mz_free(OUT); 76 | 77 | } 78 | -------------------------------------------------------------------------------- /@gifti/private/zstream.m: -------------------------------------------------------------------------------- 1 | function Z = zstream(action,D) 2 | % Compress/decompress stream of bytes using Deflate/Inflate 3 | % FORMAT Z = zstream('C',D) 4 | % D - data stream to compress (converted to uint8 if needed) 5 | % Z - compressed data stream (uint8 vector) 6 | % FORMAT D = zstream('D',Z) 7 | % Z - data stream to decompress (uint8 vector) 8 | % D - decompressed data stream (uint8 vector) 9 | %__________________________________________________________________________ 10 | % 11 | % This C-MEX file relies on: 12 | % * miniz, by Rich Geldreich 13 | % http://code.google.com/p/miniz/ 14 | % Fallback Java implementation is adapted from: 15 | % * dzip/dunzip, by Michael Kleder 16 | % http://www.mathworks.com/matlabcentral/fileexchange/8899 17 | %__________________________________________________________________________ 18 | % Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging 19 | 20 | % Guillaume Flandin 21 | % $Id: zstream.m 6417 2015-04-21 16:03:44Z guillaume $ 22 | 23 | 24 | if exist('OCTAVE_VERSION','builtin') 25 | error('zstream.c not compiled - see Makefile'); 26 | end 27 | 28 | switch upper(action) 29 | case 'C' 30 | D = typecast(D(:),'uint8'); 31 | f = java.io.ByteArrayOutputStream(); 32 | g = java.util.zip.DeflaterOutputStream(f); 33 | g.write(D); 34 | g.close; 35 | Z = typecast(f.toByteArray,'uint8'); 36 | f.close; 37 | 38 | case 'D' 39 | import com.mathworks.mlwidgets.io.InterruptibleStreamCopier 40 | a = java.io.ByteArrayInputStream(D); 41 | b = java.util.zip.InflaterInputStream(a); 42 | isc = InterruptibleStreamCopier.getInterruptibleStreamCopier; 43 | c = java.io.ByteArrayOutputStream; 44 | isc.copyStream(b,c); 45 | Z = c.toByteArray; 46 | 47 | otherwise 48 | error('Unknown action "%s".',action); 49 | end 50 | -------------------------------------------------------------------------------- /@gifti/struct.m: -------------------------------------------------------------------------------- 1 | function s = struct(this) 2 | % Struct method for GIfTI objects 3 | % FORMAT s = struct(this) 4 | % this - GIfTI object 5 | % s - a structure containing public fields of the object 6 | %__________________________________________________________________________ 7 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 8 | 9 | % Guillaume Flandin 10 | % $Id: struct.m 4716 2012-04-19 11:01:32Z guillaume $ 11 | 12 | names = fieldnames(this); 13 | names = unique(names); 14 | values = cell(length(names), length(this(:))); 15 | 16 | for i=1:length(names) 17 | [values{i,:}] = subsref(this(:), substruct('.',names{i})); 18 | end 19 | s = reshape(cell2struct(values,names,1),size(this)); -------------------------------------------------------------------------------- /@gifti/subsref.m: -------------------------------------------------------------------------------- 1 | function varargout = subsref(this,subs) 2 | % Subscript referencing for GIfTI objects 3 | %__________________________________________________________________________ 4 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 5 | 6 | % Guillaume Flandin 7 | % $Id: subsref.m 6345 2015-02-20 12:25:50Z guillaume $ 8 | 9 | if length(this) > 1 && ~strcmp(subs(1).type,'()') 10 | warning('Not implemented.'); 11 | for i=1:numel(this) 12 | varargout{i} = subsref(this(i),subs); 13 | end 14 | return; 15 | end 16 | 17 | switch subs(1).type 18 | case '.' 19 | [i,j] = isintent(this,subs(1).subs); 20 | if isempty(i) 21 | if strcmp(subs(1).subs,'private') 22 | varargout{1} = builtin('struct',this); 23 | else 24 | error('Reference to non-existent field ''%s''.',subs(1).subs); 25 | end 26 | else 27 | if strcmp(subs(1).subs,'mat') 28 | varargout{1} = this.data{j}.space.MatrixData; 29 | elseif strcmp(subs(1).subs,'labels') 30 | varargout{1} = this.label; 31 | else 32 | if length(j) == 1 33 | varargout{1} = this.data{j}.data; 34 | else 35 | a = [this.data{j}]; 36 | try 37 | varargout{1} = [a.data]; 38 | catch 39 | error('Data arrays are of different sizes.'); 40 | end 41 | end 42 | end 43 | end 44 | if strcmp(subs(1).subs,'faces') || strcmp(subs(1).subs,'indices') 45 | varargout{1} = varargout{1} + 1; % indices start at 1 46 | end 47 | if length(subs) > 1 48 | varargout{1} = subsref(varargout{1},subs(2:end)); 49 | end 50 | case '{}' 51 | error('Cell contents reference from a non-cell array object.'); 52 | case '()' 53 | if length(subs) == 1 54 | varargout{1} = builtin('subsref',this,subs(1)); 55 | else 56 | varargout{1} = subsref(builtin('subsref',this,subs(1)),subs(2:end)); 57 | end 58 | otherwise 59 | error('This should not happen.'); 60 | end -------------------------------------------------------------------------------- /@xmltree/Contents.m: -------------------------------------------------------------------------------- 1 | % XMLTree: XML Toolbox for MATLAB and GNU Octave 2 | % Version 2.0 14-Aug-2015 3 | % 4 | % XML file I/O. 5 | % xmltree - Constructor (XML parser). 6 | % save - Save an XMLTree in a file. 7 | % 8 | % XML Tree manipulation methods. 9 | % add - Add a node in a tree. 10 | % attributes - Handle attributes of a node. 11 | % branch - Extract a subtree from a tree. 12 | % children - Return children of a node. 13 | % convert - Convert a tree in a MATLAB structure. 14 | % copy - Copy nodes within a tree. 15 | % delete - Delete a node in a tree. 16 | % find - Find nodes in a tree. 17 | % flush - Clear a subtree. 18 | % get - get node properties. 19 | % getfilename - Get filename. 20 | % isfield - Return true if a field is present in a node. 21 | % length - Return the length of a tree. 22 | % move - Move a node within a tree. 23 | % parent - Return parents of a node. 24 | % root - Return the root element of a tree. 25 | % set - Set node properties. 26 | % setfilename - Set filename. 27 | % 28 | % Graphical user interface methods (basic). 29 | % editor - Graphical display of a tree. 30 | % 31 | % Low level class methods. 32 | % char - Convert a tree into a string (for display). 33 | % display - Display a tree in the workspace. 34 | % 35 | % Private methods. 36 | % xml_parser - XML parser. 37 | % xml_findstr - Find one string within another (C-MEX file). 38 | % 39 | % Conversions struct <=> XML. 40 | % loadxml - 41 | % savexml - 42 | % mat2xml - 43 | % xml2mat - 44 | % struct2xml - 45 | % 46 | % Demos. 47 | % xmldemo1 - Create an XML tree from scratch and save it. 48 | % xmldemo2 - Read an XML file and access fields. 49 | % xmldemo3 - Read an XML file, modify some fields and save it. 50 | 51 | % Copyright 2002-2015 http://www.artefact.tk/ 52 | 53 | % Guillaume Flandin 54 | % $Id: Contents.m 6480 2015-06-13 01:08:30Z guillaume $ 55 | -------------------------------------------------------------------------------- /@xmltree/branch.m: -------------------------------------------------------------------------------- 1 | function subtree = branch(tree,uid) 2 | % XMLTREE/BRANCH Branch Method 3 | % FORMAT uid = parent(tree,uid) 4 | % 5 | % tree - XMLTree object 6 | % uid - UID of the root element of the subtree 7 | % subtree - XMLTree object (a subtree from tree) 8 | %__________________________________________________________________________ 9 | % 10 | % Return a subtree from a tree. 11 | %__________________________________________________________________________ 12 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 13 | 14 | % Guillaume Flandin 15 | % $Id: branch.m 4460 2011-09-05 14:52:16Z guillaume $ 16 | 17 | 18 | %error(nargchk(2,2,nargin)); 19 | 20 | if uid > length(tree) || ... 21 | numel(uid)~=1 || ... 22 | ~strcmp(tree.tree{uid}.type,'element') 23 | error('[XMLTree] Invalid UID.'); 24 | end 25 | 26 | subtree = xmltree; 27 | subtree = set(subtree,root(subtree),'name',tree.tree{uid}.name); 28 | %- fix by Piotr Dollar to copy attributes for the root node: 29 | subtree = set(subtree,root(subtree),'attributes',tree.tree{uid}.attributes); 30 | 31 | child = children(tree,uid); 32 | 33 | for i=1:length(child) 34 | l = length(subtree); 35 | subtree = sub_branch(tree,subtree,child(i),root(subtree)); 36 | subtree.tree{root(subtree)}.contents = [subtree.tree{root(subtree)}.contents l+1]; 37 | end 38 | 39 | %========================================================================== 40 | function tree = sub_branch(t,tree,uid,p) 41 | 42 | l = length(tree); 43 | tree.tree{l+1} = t.tree{uid}; 44 | tree.tree{l+1}.uid = l + 1; 45 | tree.tree{l+1}.parent = p; 46 | tree.tree{l+1}.contents = []; 47 | if isfield(t.tree{uid},'contents') 48 | contents = get(t,uid,'contents'); 49 | m = length(tree); 50 | for i=1:length(contents) 51 | tree.tree{l+1}.contents = [tree.tree{l+1}.contents m+1]; 52 | tree = sub_branch(t,tree,contents(i),l+1); 53 | m = length(tree); 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /@xmltree/char.m: -------------------------------------------------------------------------------- 1 | function s = char(tree) 2 | % XMLTREE/CHAR Converter function from XMLTree to a description string 3 | % FORMAT s = char(tree) 4 | % 5 | % tree - XMLTree object 6 | % s - a description string of an XMLTree 7 | %__________________________________________________________________________ 8 | % 9 | % Return a string describing the XMLTree: 10 | % 'XMLTree object (x nodes) [filename]' 11 | %__________________________________________________________________________ 12 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 13 | 14 | % Guillaume Flandin 15 | % $Id: char.m 4460 2011-09-05 14:52:16Z guillaume $ 16 | 17 | 18 | s = strcat('XMLTree object (',num2str(length(tree)),' nodes) [',getfilename(tree),']'); 19 | -------------------------------------------------------------------------------- /@xmltree/children.m: -------------------------------------------------------------------------------- 1 | function child = children(tree,uid) 2 | % XMLTREE/CHILDREN Return children's UIDs of node uid 3 | % FORMAT child = children(tree,uid) 4 | % 5 | % tree - a tree 6 | % uid - uid of the element 7 | % child - array of the UIDs of children of node uid 8 | %__________________________________________________________________________ 9 | % 10 | % Return UID's of children of node uid 11 | %__________________________________________________________________________ 12 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 13 | 14 | % Guillaume Flandin 15 | % $Id: children.m 4460 2011-09-05 14:52:16Z guillaume $ 16 | 17 | %error(nargchk(2,2,nargin)); 18 | 19 | child = []; 20 | uid = uid(:); 21 | l = length(tree); 22 | for i=1:length(uid) 23 | if uid(i) > 0 && uid(i) <= l 24 | if strcmp(tree.tree{uid(i)}.type,'element') 25 | child = [child tree.tree{uid(i)}.contents]; 26 | end 27 | else 28 | error('[XMLTree] Invalid UID.'); 29 | end 30 | end 31 | if isempty(child), child = []; end 32 | -------------------------------------------------------------------------------- /@xmltree/copy.m: -------------------------------------------------------------------------------- 1 | function tree = copy(tree,subuid,uid) 2 | % XMLTREE/COPY Copy Method (copy a subtree in another branch) 3 | % FORMAT tree = copy(tree,subuid,uid) 4 | % 5 | % tree - XMLTree object 6 | % subuid - UID of the subtree to copy 7 | % uid - UID of the element where the subtree must be duplicated 8 | %__________________________________________________________________________ 9 | % 10 | % Copy a subtree to another branch. 11 | % The tree parameter must be in input AND in output. 12 | %__________________________________________________________________________ 13 | % Copyright (C) 2002-2015 http://www.artefact.tk/ 14 | 15 | % Guillaume Flandin 16 | % $Id: copy.m 6480 2015-06-13 01:08:30Z guillaume $ 17 | 18 | 19 | %error(nargchk(2,3,nargin)); 20 | 21 | if nargin == 2 22 | uid = parent(tree,subuid); 23 | end 24 | 25 | l = length(tree); 26 | tree = sub_copy(tree,subuid,uid); 27 | tree.tree{uid}.contents = [tree.tree{uid}.contents l+1]; 28 | 29 | % to have the copy next to the original and not at the end? 30 | % contents = get(tree,parent,'contents'); 31 | % i = find(contents==uid); 32 | % tree = set(tree,parent,'contents',[contents(1:i) l+1 contents(i+1:end)]); 33 | 34 | %========================================================================== 35 | function tree = sub_copy(tree,uid,p) 36 | 37 | l = length(tree); 38 | tree.tree{l+1} = tree.tree{uid}; 39 | tree.tree{l+1}.uid = l+1; 40 | tree.tree{l+1}.parent = p; 41 | tree.tree{l+1}.contents = []; 42 | if isfield(tree.tree{uid},'contents') 43 | contents = get(tree,uid,'contents'); 44 | m = length(tree); 45 | for i=1:length(contents) 46 | tree.tree{l+1}.contents = [tree.tree{l+1}.contents m+1]; 47 | tree = sub_copy(tree,contents(i),l+1); 48 | m = length(tree); 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /@xmltree/delete.m: -------------------------------------------------------------------------------- 1 | function tree = delete(tree,uid) 2 | % XMLTREE/DELETE Delete (delete a subtree given its UID) 3 | % 4 | % tree - XMLTree object 5 | % uid - array of UID's of subtrees to be deleted 6 | %__________________________________________________________________________ 7 | % 8 | % Delete a subtree given its UID 9 | % The tree parameter must be in input AND in output 10 | %__________________________________________________________________________ 11 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 12 | 13 | % Guillaume Flandin 14 | % $Id: delete.m 4460 2011-09-05 14:52:16Z guillaume $ 15 | 16 | %error(nargchk(2,2,nargin)); 17 | 18 | uid = uid(:); 19 | for i=1:length(uid) 20 | if uid(i)==1 21 | warning('[XMLTree] Cannot delete root element.'); 22 | else 23 | p = tree.tree{uid(i)}.parent; 24 | tree = sub_delete(tree,uid(i)); 25 | tree.tree{p}.contents(find(tree.tree{p}.contents==uid(i))) = []; 26 | end 27 | end 28 | 29 | %========================================================================== 30 | function tree = sub_delete(tree,uid) 31 | if isfield(tree.tree{uid},'contents') 32 | for i=1:length(tree.tree{uid}.contents) 33 | tree = sub_delete(tree,tree.tree{uid}.contents(i)); 34 | end 35 | end 36 | tree.tree{uid} = struct('type','deleted'); 37 | -------------------------------------------------------------------------------- /@xmltree/display.m: -------------------------------------------------------------------------------- 1 | function display(tree) 2 | % XMLTREE/DISPLAY Command window display of an XMLTree 3 | % FORMAT display(tree) 4 | % 5 | % tree - XMLTree object 6 | %__________________________________________________________________________ 7 | % 8 | % This method is called when the semicolon is not used to terminate a 9 | % statement which returns an XMLTree. 10 | %__________________________________________________________________________ 11 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 12 | 13 | % Guillaume Flandin 14 | % $Id: display.m 4460 2011-09-05 14:52:16Z guillaume $ 15 | 16 | disp(' '); 17 | disp([inputname(1),' = ']); 18 | disp(' '); 19 | for i=1:numel(tree) 20 | disp([blanks(length(inputname(1))+3) char(tree(i))]); 21 | end 22 | disp(' '); 23 | -------------------------------------------------------------------------------- /@xmltree/flush.m: -------------------------------------------------------------------------------- 1 | function tree = flush(tree,uid) 2 | % XMLTREE/FLUSH Flush (Clear a subtree given its UID) 3 | % 4 | % tree - XMLTree object 5 | % uid - array of UID's of subtrees to be cleared 6 | % Default is root 7 | %__________________________________________________________________________ 8 | % 9 | % Clear a subtree given its UID (remove all the leaves of the tree) 10 | % The tree parameter must be in input AND in output 11 | %__________________________________________________________________________ 12 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 13 | 14 | % Guillaume Flandin 15 | % $Id: flush.m 4460 2011-09-05 14:52:16Z guillaume $ 16 | 17 | 18 | %error(nargchk(1,2,nargin)); 19 | 20 | if nargin == 1, 21 | uid = root(tree); 22 | end 23 | 24 | uid = uid(:); 25 | for i=1:length(uid) 26 | tree = sub_flush(tree,uid(i)); 27 | end 28 | 29 | %========================================================================== 30 | function tree = sub_flush(tree,uid) 31 | if isfield(tree.tree{uid},'contents') 32 | % contents is parsed in reverse order because each child is 33 | % deleted and the contents vector is then eventually reduced 34 | for i=length(tree.tree{uid}.contents):-1:1 35 | tree = sub_flush(tree,tree.tree{uid}.contents(i)); 36 | end 37 | end 38 | if strcmp(tree.tree{uid}.type,'chardata') ||... 39 | strcmp(tree.tree{uid}.type,'pi') ||... 40 | strcmp(tree.tree{uid}.type,'cdata') ||... 41 | strcmp(tree.tree{uid}.type,'comment') 42 | tree = delete(tree,uid); 43 | end 44 | -------------------------------------------------------------------------------- /@xmltree/get.m: -------------------------------------------------------------------------------- 1 | function value = get(tree,uid,parameter) 2 | % XMLTREE/GET Get Method (get object properties) 3 | % FORMAT value = get(tree,uid,parameter) 4 | % 5 | % tree - XMLTree object 6 | % uid - array of uid's 7 | % parameter - property name 8 | % value - property value 9 | %__________________________________________________________________________ 10 | % 11 | % Get object properties of a tree given their UIDs. 12 | %__________________________________________________________________________ 13 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 14 | 15 | % Guillaume Flandin 16 | % $Id: get.m 4460 2011-09-05 14:52:16Z guillaume $ 17 | 18 | 19 | %error(nargchk(2,3,nargin)); 20 | 21 | value = cell(size(uid)); 22 | uid = uid(:); 23 | if nargin==2 24 | for i=1:length(uid) 25 | if uid(i)<1 || uid(i)>length(tree.tree) 26 | error('[XMLTree] Invalid UID.'); 27 | end 28 | % According to the type of the node, return only some parameters 29 | % Need changes... 30 | value{i} = tree.tree{uid(i)}; 31 | end 32 | else 33 | for i=1:length(uid) 34 | try 35 | value{i} = subsref(tree.tree{uid(i)}, struct('type','.','subs',parameter)); 36 | catch 37 | error(sprintf('[XMLTree] Parameter %s not found.',parameter)); 38 | end 39 | end 40 | end 41 | if length(value)==1 42 | value = value{1}; 43 | end 44 | -------------------------------------------------------------------------------- /@xmltree/getfilename.m: -------------------------------------------------------------------------------- 1 | function filename = getfilename(tree) 2 | % XMLTREE/GETFILENAME Get filename method 3 | % FORMAT filename = getfilename(tree) 4 | % 5 | % tree - XMLTree object 6 | % filename - XML filename 7 | %__________________________________________________________________________ 8 | % 9 | % Return the filename of the XML tree if loaded from disk and an empty 10 | % string otherwise. 11 | %__________________________________________________________________________ 12 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 13 | 14 | % Guillaume Flandin 15 | % $Id: getfilename.m 4460 2011-09-05 14:52:16Z guillaume $ 16 | 17 | filename = tree.filename; 18 | -------------------------------------------------------------------------------- /@xmltree/isfield.m: -------------------------------------------------------------------------------- 1 | function F = isfield(tree,uid,parameter) 2 | % XMLTREE/ISFIELD Is parameter a field of tree{uid} ? 3 | % FORMAT F = isfield(tree,uid,parameter) 4 | % 5 | % tree - a tree 6 | % uid - uid of the element 7 | % parameter - a field of the root tree 8 | % F - 1 if present, 0 otherwise 9 | %__________________________________________________________________________ 10 | % 11 | % Is parameter a field of tree{uid} ? 12 | %__________________________________________________________________________ 13 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 14 | 15 | % Guillaume Flandin 16 | % $Id: isfield.m 4460 2011-09-05 14:52:16Z guillaume $ 17 | 18 | 19 | %error(nargchk(3,3,nargin)); 20 | 21 | F = zeros(1,length(uid)); 22 | for i=1:length(uid) 23 | if isfield(tree.tree{uid(i)},parameter) 24 | F(i) = 1; 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /@xmltree/length.m: -------------------------------------------------------------------------------- 1 | function l = length(tree,r) 2 | % XMLTREE/LENGTH Length Method 3 | % FORMAT l = length(tree,r) 4 | % 5 | % tree - XMLTree object 6 | % r - 'real' if present, returns the real number of nodes in the 7 | % tree (deleted nodes aren't populated) 8 | % l - length of the XML tree (number of nodes) 9 | %__________________________________________________________________________ 10 | % 11 | % Return the number of nodes of an XMLTree object. 12 | %__________________________________________________________________________ 13 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 14 | 15 | % Guillaume Flandin 16 | % $Id: length.m 4460 2011-09-05 14:52:16Z guillaume $ 17 | 18 | 19 | %error(nargchk(1,2,nargin)); 20 | 21 | % Return the full number of nodes once allocated 22 | l = length(tree.tree); 23 | 24 | % Substract the number of deleted nodes to the previous length 25 | if nargin == 2 26 | if strcmp(r,'real') 27 | ll = 0; 28 | for i=1:l 29 | if ~strcmp(tree.tree{i}.type,'deleted') 30 | ll = ll + 1; 31 | end 32 | end 33 | l = ll; 34 | else 35 | error('[XMLTree] Bad input argument.'); 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /@xmltree/move.m: -------------------------------------------------------------------------------- 1 | function tree = move(tree,uida, uidb) 2 | % XMLTREE/MOVE Move (move a subtree inside a tree from A to B) 3 | % 4 | % tree - XMLTree object 5 | % uida - initial position of the subtree 6 | % uidb - parent of the final position of the subtree 7 | %__________________________________________________________________________ 8 | % 9 | % Move a subtree inside a tree from A to B. 10 | % The tree parameter must be in input AND in output. 11 | %__________________________________________________________________________ 12 | % Copyright (C) 2002-2015 http://www.artefact.tk/ 13 | 14 | % Guillaume Flandin 15 | % $Id: move.m 6480 2015-06-13 01:08:30Z guillaume $ 16 | 17 | 18 | %error(nargchk(3,3,nargin)); 19 | 20 | p = tree.tree{uida}.parent; 21 | tree.tree{p}.contents(find(tree.tree{p}.contents==uida)) = []; 22 | tree.tree(uidb).contents = [tree.tree(uidb).contents uida]; 23 | -------------------------------------------------------------------------------- /@xmltree/parent.m: -------------------------------------------------------------------------------- 1 | function p = parent(tree,uid) 2 | % XMLTREE/PARENT Parent Method 3 | % FORMAT uid = parent(tree,uid) 4 | % 5 | % tree - XMLTree object 6 | % uid - UID of the lonely child 7 | % p - UID of the parent ([] if root is the child) 8 | %__________________________________________________________________________ 9 | % 10 | % Return the uid of the parent of a node. 11 | %__________________________________________________________________________ 12 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 13 | 14 | % Guillaume Flandin 15 | % $Id: parent.m 4460 2011-09-05 14:52:16Z guillaume $ 16 | 17 | p = tree.tree{uid}.parent; 18 | -------------------------------------------------------------------------------- /@xmltree/private/xml_findstr.m: -------------------------------------------------------------------------------- 1 | function k = xml_findstr(s,p,i,n) 2 | %XML_FINDSTR Find one string within another 3 | % K = XML_FINDSTR(TEXT,PATTERN) returns the starting indices of any 4 | % occurrences of the string PATTERN in the string TEXT. 5 | % 6 | % K = XML_FINDSTR(TEXT,PATTERN,INDICE) returns the starting indices 7 | % equal or greater than INDICE of occurrences of the string PATTERN 8 | % in the string TEXT. By default, INDICE equals to one. 9 | % 10 | % K = XML_FINDSTR(TEXT,PATTERN,INDICE,NBOCCUR) returns the NBOCCUR 11 | % starting indices equal or greater than INDICE of occurrences of 12 | % the string PATTERN in the string TEXT. By default, INDICE equals 13 | % to one and NBOCCUR equals to Inf. 14 | % 15 | % Examples 16 | % s = 'How much wood would a woodchuck chuck?'; 17 | % xml_findstr(s,' ') returns [4 9 14 20 22 32] 18 | % xml_findstr(s,' ',10) returns [14 20 22 32] 19 | % xml_findstr(s,' ',10,1) returns 14 20 | % 21 | % See also STRFIND, FINDSTR 22 | %__________________________________________________________________________ 23 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 24 | 25 | % Guillaume Flandin 26 | % $Id: xml_findstr.m 4460 2011-09-05 14:52:16Z guillaume $ 27 | 28 | %error(sprintf('Missing MEX-file: %s', mfilename)); 29 | 30 | persistent runonce 31 | if isempty(runonce) 32 | warning(sprintf(['xml_findstr is not compiled for your platform.\n'... 33 | 'This will result in a slowdown of the XML parsing.'])); 34 | runonce = 1; 35 | end 36 | 37 | % k = regexp(s(i:end),p,'once') + i - 1; 38 | if nargin < 3, i = 1; end 39 | if nargin < 4, n = Inf; end 40 | j = strfind(s,p); 41 | k = j(j>=i); 42 | if ~isempty(k), k = k(1:min(n,length(k))); end 43 | -------------------------------------------------------------------------------- /@xmltree/private/xml_findstr.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/@xmltree/private/xml_findstr.mexa64 -------------------------------------------------------------------------------- /@xmltree/private/xml_findstr.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/@xmltree/private/xml_findstr.mexglx -------------------------------------------------------------------------------- /@xmltree/private/xml_findstr.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/@xmltree/private/xml_findstr.mexw32 -------------------------------------------------------------------------------- /@xmltree/private/xml_findstr.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/@xmltree/private/xml_findstr.mexw64 -------------------------------------------------------------------------------- /@xmltree/root.m: -------------------------------------------------------------------------------- 1 | function uid = root(tree) 2 | % XMLTREE/ROOT Root Method 3 | % FORMAT uid = root(tree) 4 | % 5 | % tree - XMLTree object 6 | % uid - UID of the root element of tree 7 | %__________________________________________________________________________ 8 | % 9 | % Return the uid of the root element of the tree. 10 | %__________________________________________________________________________ 11 | % Copyright (C) 2002-2008 http://www.artefact.tk/ 12 | 13 | % Guillaume Flandin 14 | % $Id: root.m 4460 2011-09-05 14:52:16Z guillaume $ 15 | 16 | % Actually root is necessarily the element whos UID is 1, by 17 | % construction. However, xml_parser should return a tree with a ROOT 18 | % element with as many children as needed but only ONE *element* child 19 | % who would be the real root (and this method should return the UID of 20 | % this element). 21 | 22 | uid = 1; 23 | 24 | % Update: 25 | % xml_parser has been modified (not as explained above) to handle the 26 | % case when several nodes are at the top level of the XML. 27 | % Example: blah blah 28 | % Now root is the first element node of the tree. 29 | 30 | % Look for the first element in the XML Tree 31 | for i=1:length(tree) 32 | if strcmp(get(tree,i,'type'),'element') 33 | uid = i; 34 | break 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /@xmltree/set.m: -------------------------------------------------------------------------------- 1 | function tree = set(tree,uid, parameter, value) 2 | % XMLTREE/SET Method (set object properties) 3 | % FORMAT tree = set(tree,uid,parameter,value) 4 | % 5 | % tree - XMLTree object 6 | % uid - array (or cell) of uid's 7 | % parameter - property name 8 | % value - property value 9 | %__________________________________________________________________________ 10 | % 11 | % Set object properties given its uid and pairs parameter/value 12 | % The tree parameter must be in input AND in output 13 | %__________________________________________________________________________ 14 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 15 | 16 | % Guillaume Flandin 17 | % $Id: set.m 4460 2011-09-05 14:52:16Z guillaume $ 18 | 19 | 20 | %error(nargchk(4,4,nargin)); 21 | 22 | if iscell(uid), uid = [uid{:}]; else uid = uid(:); end 23 | 24 | for i=1:length(uid) 25 | tree.tree{uid(i)} = builtin('subsasgn', tree.tree{uid(i)}, struct('type','.','subs',parameter), value); 26 | %tree.tree{uid(i)} = setfield(tree.tree{uid(i)},parameter,value); 27 | end 28 | -------------------------------------------------------------------------------- /@xmltree/setfilename.m: -------------------------------------------------------------------------------- 1 | function tree = setfilename(tree,filename) 2 | % XMLTREE/SETFILENAME Set filename method 3 | % FORMAT tree = setfilename(tree,filename) 4 | % 5 | % tree - XMLTree object 6 | % filename - XML filename 7 | %__________________________________________________________________________ 8 | % 9 | % Set the filename linked to the XML tree as filename. 10 | %__________________________________________________________________________ 11 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 12 | 13 | % Guillaume Flandin 14 | % $Id: setfilename.m 4460 2011-09-05 14:52:16Z guillaume $ 15 | 16 | tree.filename = filename; 17 | -------------------------------------------------------------------------------- /@xmltree/xmltree.m: -------------------------------------------------------------------------------- 1 | function tree = xmltree(varargin) 2 | % XMLTREE/XMLTREE Constructor of the XMLTree class 3 | % FORMAT tree = xmltree(varargin) 4 | % 5 | % varargin - XML filename or XML string 6 | % tree - XMLTree Object 7 | % 8 | % tree = xmltree; % creates a minimal XML tree: '' 9 | % tree = xmltree('foo.xml'); % creates a tree from XML file 'foo.xml' 10 | % tree = xmltree('content') % creates a tree from string 11 | %__________________________________________________________________________ 12 | % 13 | % This is the constructor of the XMLTree class. 14 | % It creates a tree of an XML 1.0 file (after parsing) that is stored 15 | % using a Document Object Model (DOM) representation. 16 | % See http://www.w3.org/TR/REC-xml for details about XML 1.0. 17 | % See http://www.w3.org/DOM/ for details about DOM platform. 18 | %__________________________________________________________________________ 19 | % Copyright (C) 2002-2011 http://www.artefact.tk/ 20 | 21 | % Guillaume Flandin 22 | % $Id: xmltree.m 4460 2011-09-05 14:52:16Z guillaume $ 23 | 24 | switch(nargin) 25 | case 0 26 | tree.tree{1} = struct('type','element',... 27 | 'name','tag',... 28 | 'attributes',[],... 29 | 'contents',[],... 30 | 'parent',[],... 31 | 'uid',1); 32 | tree.filename = ''; 33 | tree = class(tree,'xmltree'); 34 | case 1 35 | if isa(varargin{1},'xmltree') 36 | tree = varargin{1}; 37 | elseif ischar(varargin{1}) 38 | % Input argument is an XML string 39 | if (~exist(varargin{1},'file') && ... 40 | ~isempty(xml_findstr(varargin{1},'<',1,1))) 41 | tree.tree = xml_parser(varargin{1}); 42 | tree.filename = ''; 43 | % Input argument is an XML filename 44 | else 45 | fid = fopen(varargin{1},'rt'); 46 | if (fid == -1) 47 | error(['[XMLTree] Cannot open ' varargin{1}]); 48 | end 49 | xmlstr = fread(fid,'*char')'; 50 | %xmlstr = fscanf(fid,'%c'); 51 | fclose(fid); 52 | tree.tree = xml_parser(xmlstr); 53 | tree.filename = varargin{1}; 54 | end 55 | tree = class(tree,'xmltree'); 56 | else 57 | error('[XMLTree] Bad input argument'); 58 | end 59 | otherwise 60 | error('[XMLTree] Too many input arguments'); 61 | end 62 | -------------------------------------------------------------------------------- /EASY_RENDER_NIFTI_OVERLAY.m: -------------------------------------------------------------------------------- 1 | 2 | PlotStat = 'Vis100B_Av.nii'; % The nifti overlay file 3 | 4 | afigure; % Opens a large figure window 5 | 6 | D = atemplate('mesh','def5','inflate','overlay',{'curvature' PlotStat},... 7 | 'method','raycast','thresh',4,'hemi','l'); 8 | 9 | axis equal; 10 | 11 | aJointColorbar(D); % Adds a colorbar BUT, CAXIS WONT WORK... :( -------------------------------------------------------------------------------- /Example_AAL90_OverlayQuick.m: -------------------------------------------------------------------------------- 1 | 2 | % Example render AAL90 data on a pre-parcellated mesh 3 | %------------------------------------------------------------------- 4 | 5 | % Vector of values for each of the 90 regions in AAL90 order: 6 | MyVector = randi([-50 50],90,1); 7 | 8 | % render it using defaults: the quickest way 9 | afigure; atemplate('overlay',MyVector,'method',{'aal_super',[]}); -------------------------------------------------------------------------------- /Example_AAL90_ParcelOverlay_Curv.m: -------------------------------------------------------------------------------- 1 | % Example script: generate cortical mesh of AAL90 parcellation with 2 | % curature and inflation 3 | 4 | % Make reduced version of default mesh 5 5 | m = atemplate('mesh','def5');close;drawnow; 6 | m = maker(m.mesh.faces,m.mesh.vertices); 7 | fv = reducepatch(m,.2); 8 | 9 | % AAL90 'Overlay' data: 10 | z = zeros(1,90); 11 | 12 | z([19 20]) = [-5 5]; % motor 13 | z([43 44]) = [-10 10]; % calcarine 14 | 15 | afigure; 16 | D = atemplate(... 17 | 'overlay',{'curvature',z},... 18 | 'method' ,{'aal_light','spheres'} ,... 19 | 'thresh' ,0, ... 20 | 'mesh' ,fv ); 21 | 22 | 23 | % If using default mesh 1, use precomputed parcel values: 24 | % afigure; D = atemplate('inflate','overlay',... 25 | % {'curvature',z},'method',{'aal_super',[]} ,'thresh',0); 26 | -------------------------------------------------------------------------------- /Example_CerebellumCortexNetwork_AAL116.m: -------------------------------------------------------------------------------- 1 | 2 | % Functional Overlay - AAL116 (with cerebellum) 3 | %------------------------------------------------------- 4 | % use atlas-reduced code: aal116 5 | fun_data = zeros(116,1); 6 | fun_data(91:108)=-8:9; % activations in cerebellum only 7 | 8 | % some cortical stuff too 9 | fun_data(11) = -7; 10 | fun_data(20) = 7; 11 | fun_data(59) = -4; 12 | fun_data(84) = 4; 13 | 14 | % generate the figure this way: 15 | figure('position',[1000 249 885 729]); 16 | atemplate('mesh','def3','overlay',fun_data,'method',{'aal116','spheres'}); 17 | 18 | % or this way: supplying the sources and using explicit optimisation 19 | load AAL116 20 | 21 | figure('position',[1000 249 885 729]); 22 | atemplate('mesh','def3','overlay',fun_data,... 23 | 'sourcemodel',{v vi}, 'method',{'user','spheres'},'optimise',0); 24 | 25 | 26 | % Network - AAL116 (with cerebellum) 27 | %------------------------------------------------------- 28 | load AAL116 % load the AAL116 'source' positions 29 | N = zeros(116,116); % make an empty 116x116 network 30 | 31 | % A cerebellar network (see 'labels' - nodes 91:108): 32 | N = zeros(116,116); 33 | N(91:108,91:108) = [ randi([0 1],18,18) .* randi([-6 6],18,18) ]; 34 | 35 | 36 | % just edges: 37 | figure('position',[1000 249 885 729]); 38 | atemplate('mesh','def3','network',N,'sourcemodel',{v vi}) 39 | view([0 17.5791]) 40 | 41 | % with nodes as well as edges: 42 | figure('position',[1000 249 885 729]); 43 | atemplate('mesh','def3','network',N,'sourcemodel',{v vi},'nodes',sum(N)) 44 | view([0 17.5791]) 45 | -------------------------------------------------------------------------------- /Example_FunctionalVolumeRender_Parcellate.m: -------------------------------------------------------------------------------- 1 | 2 | % - Render a functional (cortical) volume (nifti) on a template mesh 3 | % - Compute a parcellation of the cortex (here, AAL-90) 4 | % - Return mesh data, parcel volume & centroid (ROI) data / means. 5 | 6 | % Load the parcel data: contains v (vertices) and vi (vector on integers 7 | % describing which atlas/parcel/region each vertex belongs to 8 | load LightAAL.mat 9 | 10 | % The functional nifti volume to project 11 | FunVol = 'Vis100B_Av.nii'; 12 | 13 | % The default mesh to render 14 | % (def1, 2 & 4 = cortical-only, 3=with cerebellum) 15 | Surf = 'def2'; 16 | 17 | % Not specifying the 'method' defaults to ray-casting 18 | afigure; D = atemplate('mesh',Surf,'overlay',FunVol,'post_parcel',{v vi}); 19 | 20 | 21 | % After rendering, all outputs are in struct 'D'. 22 | % 23 | % We can render the parcellation it returned: 24 | % (I suggest using method 'spheres' for this) 25 | 26 | afigure; atemplate('mesh',Surf,'overlay',D.post_parcel.data, ... 27 | 'sourcemodel', D.post_parcel.pos , 'method', 'spheres' ); 28 | 29 | % We can also render the low-resolution (1-point-per-atlas) 'blocked' into 30 | % parcel space - so the whole parcel has that value: 31 | afigure; atemplate('mesh',Surf,'overlay',D.post_parcel.ParVal, ... 32 | 'sourcemodel', D.post_parcel.pos , 'method', 'spheres' ); 33 | 34 | 35 | % We can also render the single atlas point means - i.e. for AAL90 we give 36 | % it only 90 data points (D.post_parcel.ParcelMean). You can use the 37 | % returned mean points for this: 38 | % 39 | % afigure; atemplate('mesh',Surf,'overlay',D.post_parcel.ParcelMean, ... 40 | % 'sourcemodel', D.post_parcel.ParcelCent , 'method', 'spheres' ); 41 | % 42 | % 43 | % Since we have rendered AAL90 data, which there's already a default parcel 44 | % mapping for, we can render the parcelation from the 90 points, using an 45 | % additional method flag - this means we don't have to supploy the source 46 | % locations / model: 47 | % 48 | afigure; atemplate('mesh',Surf,'overlay',D.post_parcel.data, ... 49 | 'method', {'aal_light', 'spheres'} ); 50 | -------------------------------------------------------------------------------- /Example_HarvardOxfordCerbellum_Rendering.m: -------------------------------------------------------------------------------- 1 | 2 | % Render Harvard-Oxford data with (AAL) Cerebellum 3 | %------------------------------------------------------- 4 | 5 | % Has 74 nodes: 48 HarvOx Atlas, 26 AAL Cerebellar/Vermis 6 | load HOA_Cerebellum.mat 7 | 8 | fun_data = zeros(74,1); 9 | 10 | % see 'labels': 11 | % vals 1:48 = HOA regions 12 | % 49:74 = AAL cerebellar 13 | % 14 | 15 | fun_data(1:48) = randi([0 7],48,1); 16 | fun_data(49:74) = -7; 17 | 18 | % generate overlay figure this way: 19 | figure('position',[1000 249 885 729]); 20 | atemplate('mesh','def3','overlay',fun_data,'method',{'hoac','spheres'}); 21 | 22 | % or this way: supplying the sources and using explicit optimisation 23 | load HOA_Cerebellum.mat 24 | 25 | figure('position',[1000 249 885 729]); 26 | atemplate('mesh','def3','overlay',fun_data,... 27 | 'sourcemodel',{v vi}, 'method',{'user','spheres'}); 28 | 29 | -------------------------------------------------------------------------------- /Example_RenderFunctionalOverCurvature.m: -------------------------------------------------------------------------------- 1 | 2 | % - Render a functional (cortical) volume (nifti) on a template mesh thresholded at top 20% 3 | % - Inflate the mesh 4 | % - Display the curvature of the brain in greyscale under the functional 5 | % - Compute a parcellation of the cortex (here, AAL-90) 6 | % - Return mesh data, parcel volume & centroid (ROI) data / means. 7 | % - Render Right hemisphere only 8 | 9 | % Load the parcel data: contains v (vertices) and vi (vector on integers 10 | % describing which atlas/parcel/region each vertex belongs to 11 | load LightAAL.mat 12 | 13 | % The functional nifti volume to project 14 | FunVol = 'Vis100B_Av.nii'; 15 | 16 | % The default mesh to render 17 | % (def1, 2 & 4 = cortical-only, 3=with cerebellum) 18 | Surf = 'def1'; 19 | 20 | % the threshold 21 | thr = 0.4; 22 | 23 | % overlaying both curvature and function 24 | afigure; D = atemplate('hemi','l','mesh',Surf,'inflate','overlay',... 25 | {'curvature',FunVol},'method','spheres',... 26 | 'thresh',thr,'post_parcel',{v vi}); 27 | 28 | 29 | 30 | % use the output to render a1-value per parcel version 31 | afigure; 32 | atemplate('mesh','def1','inflate','overlay',D.post_parcel.ParVal,... 33 | 'sourcemodel',D.post_parcel.pos,'method','spheres') -------------------------------------------------------------------------------- /Examples/CompareProjectionMethodsScript.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | % Compare the 3 overlay methods 5 | %-------------------------------------------------------------- 6 | 7 | volume = 'mynii.nii'; % the functional volume 8 | 9 | 10 | 11 | 12 | figure('position',[186 290 1927 688]) 13 | 14 | % Ray casting 15 | s(1) = subplot(131); 16 | atemplate('overlay',volume,... 17 | 'method','raycast',... 18 | 'hemi','l',... 19 | 'fighnd', s(1)) 20 | title('Ray casting'); 21 | 22 | % Euclidean search 23 | s(2) = subplot(132); 24 | atemplate('overlay',volume,... 25 | 'method','euclidean',... 26 | 'hemi','l',... 27 | 'fighnd', s(2)) 28 | title('Euclidean search'); 29 | 30 | % Inflated sphere / trap radius 31 | s(3) = subplot(133); 32 | atemplate('overlay',volume,... 33 | 'method','spheres',... 34 | 'hemi','l',... 35 | 'fighnd', s(3)) 36 | title('Inflated spherical trap radius'); 37 | 38 | linksubplots(s); 39 | 40 | -------------------------------------------------------------------------------- /Examples/Ex_OverlayWithNetworkAndLabels.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Examples/Ex_OverlayWithNetworkAndLabels.gif -------------------------------------------------------------------------------- /Examples/ExampleScript_RenderAndOrthogProject2D.m: -------------------------------------------------------------------------------- 1 | % Example Script: 2 | % 3 | % (1) Render an functional data (from volume) on a template brain, and 4 | % (2) Project that 3D rendering onto a 2D plane 5 | 6 | myvol = 'Vis100B_Av.nii'; 7 | 8 | afigure; D = atemplate('mesh','def2','overlay',myvol); % render the 3D mesh 9 | 10 | 11 | % close, then get the mesh vertices, faces and colours for the 2D plot: 12 | v = D.mesh.vertices; 13 | f = D.mesh.faces; 14 | c = D.overlay.data; 15 | cv = D.mesh.curvature; 16 | 17 | afigure; [dv,uv,g] = flatten_mesh(v,f,cv,1); % make the awesome 2D plot -------------------------------------------------------------------------------- /Examples/ExampleScriptingUsage.m: -------------------------------------------------------------------------------- 1 | 2 | % Plot functional overlay on structural image 3 | %========================================================================== 4 | 5 | % from nifti's: 6 | struct = 'GreyMRI.nii'; 7 | funct = 'nTEST_Gamma,60-90,60-90Hz_pairedt.nii'; 8 | 9 | % or from gifti's: 10 | struct = 'TestMesh.gii'; 11 | funct = 'TestMeshOverlay.gii'; 12 | 13 | 14 | % make struct surface 15 | %-------------------------------------------------------------------------- 16 | i.g = struct; 17 | data = aplot.sort_sourcemodel([],i); 18 | [mesh,data] = aplot.get_mesh(i,data); 19 | 20 | % structural options 21 | %-------------------------------------------------------------------------- 22 | i.hemi = 'both'; % if only one hemisphere plot 23 | i.affine = []; % if affine supplied or flip flag 24 | i.flip = 0; 25 | i.inflate = 0; % if inflate, pass flag 26 | i.checkori = 0; % check orientation? 27 | i.fillholes = 0; % fill holes during hemisphere separation? 28 | i.pmesh = 1; % plot the mesh or just return the info 29 | i.write = 0; % write out a gifti file 30 | i.fname = []; % file name for the gifti 31 | i.fighnd = []; % axes handle to plot into 32 | 33 | figure('position',[1091 235 1310 1026]) 34 | 35 | [mesh,data] = aplot.parse_mesh(mesh,i,data); 36 | data.mesh = mesh; 37 | 38 | % functional overlay options 39 | %-------------------------------------------------------------------------- 40 | data.overlay = []; 41 | [y,data] = aplot.parse_overlay(funct,data); % get functional vals & sourcemodel vertices 42 | 43 | data.overlay.method = 'raycast'; % 'raycast', 'euclidean' or 'spheres' 44 | data.overlay.peaks = 0; 45 | 46 | colbar = 0; 47 | data = aplot.overlay(data,y,i.write,i.fname,colbar); 48 | 49 | 50 | -------------------------------------------------------------------------------- /Examples/ExampleScriptingUsageNetwork.m: -------------------------------------------------------------------------------- 1 | 2 | % Plot a network on structural image 3 | %========================================================================== 4 | 5 | % from nifti T1 and network .node/.edge files: 6 | struct = 'GreyMRI.nii'; 7 | net = 'network.edge'; 8 | 9 | % or from a gifti MR surface & matrices representing network (n x n) and 10 | % source locations (n x 3) 11 | struct = 'TestMesh.gii'; 12 | net = randi([0 1],90,90); 13 | funct = (net.*net') .* randi([-7 7],90,90); 14 | locs = randi([-70 70],90,3); 15 | 16 | % parse source model locations 17 | %-------------------------------------------------------------------------- 18 | i.A = net; 19 | data = aplot.sort_sourcemodel([],i); 20 | 21 | % make struct surface 22 | %-------------------------------------------------------------------------- 23 | i.g = struct; 24 | [mesh,data] = aplot.get_mesh(i,data); 25 | 26 | 27 | % plot structural part 28 | %-------------------------------------------------------------------------- 29 | i.hemi = 'both'; % if only one hemisphere plot 30 | i.affine = []; % if affine supplied or flip flag 31 | i.flip = 0; 32 | i.inflate = 0; % if inflate, pass flag 33 | i.checkori = 0; % check orientation? 34 | i.fillholes = 0; % fill holes during hemisphere separation? 35 | i.pmesh = 1; % plot the mesh or just return the info 36 | i.write = 0; % write out a gifti file 37 | i.fname = []; % file name for the gifti 38 | i.fighnd = []; % axes handle to plot into 39 | 40 | figure('position',[1091 235 1310 1026]) 41 | 42 | [mesh,data] = aplot.parse_mesh(mesh,i,data); 43 | data.mesh = mesh; 44 | 45 | % network options 46 | %-------------------------------------------------------------------------- 47 | netcmap = cmocean('balance'); % net color map 48 | colbar = 0; 49 | 50 | [e,n] = aplot.rw_edgenode(net); 51 | data = aplot.connections(data,e,colbar,i.write,i.fname,netcmap); 52 | -------------------------------------------------------------------------------- /Examples/ExampleScriptingUsageNetworkConvertAAL.m: -------------------------------------------------------------------------------- 1 | 2 | % Plot a network on structural image, interpolated to AAL90 3 | %========================================================================== 4 | 5 | % from nifti T1 and network .node/.edge files: 6 | struct = 'GreyMRI.nii'; 7 | net = 'network.edge'; 8 | 9 | % % or from a gifti MR surface & matrices representing network (n x n) and 10 | % % source locations (n x 3) 11 | % struct = 'TestMesh.gii'; 12 | % net = randi([0 1],90,90); 13 | % funct = (net.*net') .* randi([-7 7],90,90); 14 | % locs = randi([-70 70],90,3); 15 | 16 | % parse source model locations 17 | %-------------------------------------------------------------------------- 18 | i.A = net; 19 | data = aplot.sort_sourcemodel([],i); 20 | 21 | % make struct surface 22 | %-------------------------------------------------------------------------- 23 | i.g = struct; 24 | [mesh,data] = aplot.get_mesh(i,data); 25 | 26 | 27 | % plot structural part 28 | %-------------------------------------------------------------------------- 29 | i.hemi = 'both'; % if only one hemisphere plot: 'both' ,'left', 'right' 30 | i.affine = []; % if affine supplied or flip flag 31 | i.flip = 0; 32 | i.inflate = 0; % if inflate, pass flag 33 | i.checkori = 0; % check orientation? 34 | i.fillholes = 0; % fill holes during hemisphere separation? 35 | i.pmesh = 1; % plot the mesh or just return the info 36 | i.write = 0; % write out a gifti file 37 | i.fname = []; % file name for the gifti 38 | i.fighnd = []; % axes handle to plot into 39 | 40 | figure('position',[1091 235 1310 1026]) 41 | 42 | [mesh,data] = aplot.parse_mesh(mesh,i,data); 43 | data.mesh = mesh; 44 | 45 | % convert network to aal90 space 46 | %-------------------------------------------------------------------------- 47 | atlas = aplot.dotemplate('aal90'); 48 | rois = aplot.get_roi_centres(atlas.template_sourcemodel.pos,atlas.all_roi_tissueindex); 49 | 50 | atlas.template_sourcemodel.pos = rois; 51 | atlas = rmfield(atlas,'all_roi_tissueindex'); 52 | 53 | % now register the real source model positions to the atlas ROIs 54 | sm.pos = data.sourcemodel.pos; 55 | reg = aplot.interp_template(sm,rois); 56 | 57 | % now apply the operator - M - to the connection matrix 58 | NM = reg.M; 59 | NM = NM/max(NM(:)); % rescale so not change amplitudes 60 | [A,n] = aplot.rw_edgenode(net); % read the matrix if necessary 61 | S = [min(A(:)) max(A(:))]; % get min/max 62 | NL = NM'*A*NM; % apply M 63 | A = S(1) + ((S(2)-S(1))).*(NL - min(NL(:)))./(max(NL(:)) - min(NL(:))); 64 | A(isnan(A)) = 0; 65 | 66 | data.sourcemodel.pos = reg.pos; 67 | 68 | % network options 69 | %-------------------------------------------------------------------------- 70 | netcmap = cmocean('balance'); % net color map 71 | colbar = 0; 72 | 73 | data = aplot.connections(data,A,colbar,i.write,i.fname,netcmap); -------------------------------------------------------------------------------- /Examples/ExampleScriptingUsage_AAL116_Overlay.m: -------------------------------------------------------------------------------- 1 | 2 | % Plot functional overlay on structural image 3 | %========================================================================== 4 | 5 | % use template cortical + cerebellum mesh 6 | struct = 'def3'; 7 | 8 | % use atlas-reduced code: aal116 9 | funct = zeros(116,1); 10 | funct(91:108)=-8:9; % activations in cerebellum only 11 | 12 | % make struct surface 13 | %-------------------------------------------------------------------------- 14 | i.g = struct; 15 | data = aplot.sort_sourcemodel([],i); 16 | [mesh,data] = aplot.get_mesh(i,data); 17 | 18 | % structural options 19 | %-------------------------------------------------------------------------- 20 | i.hemi = 'both'; % if only one hemisphere plot 21 | i.affine = []; % if affine supplied or flip flag 22 | i.flip = 0; 23 | i.inflate = 0; % if inflate, pass flag 24 | i.checkori = 0; % check orientation? 25 | i.fillholes = 0; % fill holes during hemisphere separation? 26 | i.pmesh = 1; % plot the mesh or just return the info 27 | i.write = 0; % write out a gifti file 28 | i.fname = []; % file name for the gifti 29 | i.fighnd = []; % axes handle to plot into 30 | 31 | figure('position',[1091 235 1310 1026]) 32 | 33 | [mesh,data] = aplot.parse_mesh(mesh,i,data); 34 | data.mesh = mesh; 35 | 36 | % functional overlay options 37 | %-------------------------------------------------------------------------- 38 | data.overlay = []; 39 | [y,data] = aplot.parse_overlay(funct,data); % get functional vals & sourcemodel vertices 40 | 41 | data.overlay.method = {'aal116','spheres'}; % 'raycast', 'euclidean' or 'spheres' 42 | data.overlay.peaks = 0; 43 | 44 | colbar = 0; 45 | data = aplot.overlay(data,y,i.write,i.fname,colbar); 46 | 47 | 48 | -------------------------------------------------------------------------------- /Examples/Example_AAL90_OverlayQuick.m: -------------------------------------------------------------------------------- 1 | 2 | % Example render AAL90 data on a pre-parcellated mesh 3 | %------------------------------------------------------------------- 4 | 5 | % Vector of values for each of the 90 regions in AAL90 order: 6 | MyVector = randi([-50 50],90,1); 7 | 8 | % render it using defaults: the quickest way 9 | afigure; atemplate('overlay',MyVector,'method',{'aal_super',[]}); -------------------------------------------------------------------------------- /Examples/Example_AAL90_ParcelOverlay_Curv.m: -------------------------------------------------------------------------------- 1 | % Example script: generate cortical mesh of AAL90 parcellation with 2 | % curature and inflation 3 | 4 | % Make reduced version of default mesh 5 5 | m = atemplate('mesh','def5');close;drawnow; 6 | m = maker(m.mesh.faces,m.mesh.vertices); 7 | fv = reducepatch(m,.2); 8 | 9 | % AAL90 'Overlay' data: 10 | z = zeros(1,90); 11 | 12 | z([19 20]) = [-5 5]; % motor 13 | z([43 44]) = [-10 10]; % calcarine 14 | 15 | afigure; 16 | D = atemplate(... 17 | 'overlay',{'curvature',z},... 18 | 'method' ,{'aal_light','spheres'} ,... 19 | 'thresh' ,0, ... 20 | 'mesh' ,fv ); 21 | 22 | 23 | % If using default mesh 1, use precomputed parcel values: 24 | % afigure; D = atemplate('inflate','overlay',... 25 | % {'curvature',z},'method',{'aal_super',[]} ,'thresh',0); 26 | -------------------------------------------------------------------------------- /Examples/Example_CerebellumCortexNetwork_AAL116.m: -------------------------------------------------------------------------------- 1 | 2 | % Functional Overlay - AAL116 (with cerebellum) 3 | %------------------------------------------------------- 4 | % use atlas-reduced code: aal116 5 | fun_data = zeros(116,1); 6 | fun_data(91:108)=-8:9; % activations in cerebellum only 7 | 8 | % some cortical stuff too 9 | fun_data(11) = -7; 10 | fun_data(20) = 7; 11 | fun_data(59) = -4; 12 | fun_data(84) = 4; 13 | 14 | % generate the figure this way: 15 | figure('position',[1000 249 885 729]); 16 | atemplate('mesh','def3','overlay',fun_data,'method',{'aal116','spheres'}); 17 | 18 | % or this way: supplying the sources and using explicit optimisation 19 | load AAL116 20 | 21 | figure('position',[1000 249 885 729]); 22 | atemplate('mesh','def3','overlay',fun_data,... 23 | 'sourcemodel',{v vi}, 'method',{'user','spheres'},'optimise',0); 24 | 25 | 26 | % Network - AAL116 (with cerebellum) 27 | %------------------------------------------------------- 28 | load AAL116 % load the AAL116 'source' positions 29 | N = zeros(116,116); % make an empty 116x116 network 30 | 31 | % A cerebellar network (see 'labels' - nodes 91:108): 32 | N = zeros(116,116); 33 | N(91:108,91:108) = [ randi([0 1],18,18) .* randi([-6 6],18,18) ]; 34 | 35 | 36 | % just edges: 37 | figure('position',[1000 249 885 729]); 38 | atemplate('mesh','def3','network',N,'sourcemodel',{v vi}) 39 | view([0 17.5791]) 40 | 41 | % with nodes as well as edges: 42 | figure('position',[1000 249 885 729]); 43 | atemplate('mesh','def3','network',N,'sourcemodel',{v vi},'nodes',sum(N)) 44 | view([0 17.5791]) 45 | -------------------------------------------------------------------------------- /Examples/Example_FunctionalVolumeRender_Parcellate.m: -------------------------------------------------------------------------------- 1 | 2 | % - Render a functional (cortical) volume (nifti) on a template mesh 3 | % - Compute a parcellation of the cortex (here, AAL-90) 4 | % - Return mesh data, parcel volume & centroid (ROI) data / means. 5 | 6 | % Load the parcel data: contains v (vertices) and vi (vector on integers 7 | % describing which atlas/parcel/region each vertex belongs to 8 | load LightAAL.mat 9 | 10 | % The functional nifti volume to project 11 | FunVol = 'Vis100B_Av.nii'; 12 | 13 | % The default mesh to render 14 | % (def1, 2 & 4 = cortical-only, 3=with cerebellum) 15 | Surf = 'def2'; 16 | 17 | % Not specifying the 'method' defaults to ray-casting 18 | afigure; D = atemplate('mesh',Surf,'overlay',FunVol,'post_parcel',{v vi}); 19 | 20 | 21 | % After rendering, all outputs are in struct 'D'. 22 | % 23 | % We can render the parcellation it returned: 24 | % (I suggest using method 'spheres' for this) 25 | 26 | afigure; atemplate('mesh',Surf,'overlay',D.post_parcel.data, ... 27 | 'sourcemodel', D.post_parcel.pos , 'method', 'spheres' ); 28 | 29 | % We can also render the low-resolution (1-point-per-atlas) 'blocked' into 30 | % parcel space - so the whole parcel has that value: 31 | afigure; atemplate('mesh',Surf,'overlay',D.post_parcel.ParVal, ... 32 | 'sourcemodel', D.post_parcel.pos , 'method', 'spheres' ); 33 | 34 | 35 | % We can also render the single atlas point means - i.e. for AAL90 we give 36 | % it only 90 data points (D.post_parcel.ParcelMean). You can use the 37 | % returned mean points for this: 38 | % 39 | % afigure; atemplate('mesh',Surf,'overlay',D.post_parcel.ParcelMean, ... 40 | % 'sourcemodel', D.post_parcel.ParcelCent , 'method', 'spheres' ); 41 | % 42 | % 43 | % Since we have rendered AAL90 data, which there's already a default parcel 44 | % mapping for, we can render the parcelation from the 90 points, using an 45 | % additional method flag - this means we don't have to supploy the source 46 | % locations / model: 47 | % 48 | afigure; atemplate('mesh',Surf,'overlay',D.post_parcel.data, ... 49 | 'method', {'aal_light', 'spheres'} ); 50 | -------------------------------------------------------------------------------- /Examples/Example_HarvardOxfordCerbellum_Rendering.m: -------------------------------------------------------------------------------- 1 | 2 | % Render Harvard-Oxford data with (AAL) Cerebellum 3 | %------------------------------------------------------- 4 | 5 | % Has 74 nodes: 48 HarvOx Atlas, 26 AAL Cerebellar/Vermis 6 | load HOA_Cerebellum.mat 7 | 8 | fun_data = zeros(74,1); 9 | 10 | % see 'labels': 11 | % vals 1:48 = HOA regions 12 | % 49:74 = AAL cerebellar 13 | % 14 | 15 | fun_data(1:48) = randi([0 7],48,1); 16 | fun_data(49:74) = -7; 17 | 18 | % generate overlay figure this way: 19 | figure('position',[1000 249 885 729]); 20 | atemplate('mesh','def3','overlay',fun_data,'method',{'hoac','spheres'}); 21 | 22 | % or this way: supplying the sources and using explicit optimisation 23 | load HOA_Cerebellum.mat 24 | 25 | figure('position',[1000 249 885 729]); 26 | atemplate('mesh','def3','overlay',fun_data,... 27 | 'sourcemodel',{v vi}, 'method',{'user','spheres'}); 28 | 29 | -------------------------------------------------------------------------------- /Examples/Example_RenderFunctionalOverCurvature.m: -------------------------------------------------------------------------------- 1 | 2 | % - Render a functional (cortical) volume (nifti) on a template mesh thresholded at top 20% 3 | % - Inflate the mesh 4 | % - Display the curvature of the brain in greyscale under the functional 5 | % - Compute a parcellation of the cortex (here, AAL-90) 6 | % - Return mesh data, parcel volume & centroid (ROI) data / means. 7 | % - Render Right hemisphere only 8 | 9 | % Load the parcel data: contains v (vertices) and vi (vector on integers 10 | % describing which atlas/parcel/region each vertex belongs to 11 | load LightAAL.mat 12 | 13 | % The functional nifti volume to project 14 | FunVol = 'Vis100B_Av.nii'; 15 | 16 | % The default mesh to render 17 | % (def1, 2 & 4 = cortical-only, 3=with cerebellum) 18 | Surf = 'def1'; 19 | 20 | % the threshold 21 | thr = 0.4; 22 | 23 | % overlaying both curvature and function 24 | afigure; D = atemplate('hemi','l','mesh',Surf,'inflate','overlay',... 25 | {'curvature',FunVol},'method','spheres',... 26 | 'thresh',thr,'post_parcel',{v vi}); 27 | 28 | 29 | 30 | % use the output to render a1-value per parcel version 31 | afigure; 32 | atemplate('mesh','def1','inflate','overlay',D.post_parcel.ParVal,... 33 | 'sourcemodel',D.post_parcel.pos,'method','spheres') -------------------------------------------------------------------------------- /Examples/Example_RerunOverlayFaster.m: -------------------------------------------------------------------------------- 1 | 2 | % Example of how to re-compute an already registered sourcemodel projection 3 | % on the mesh when using EUCLIDEAN option 4 | 5 | % Original run: 6 | %-------------------------------------------------------------------------- 7 | 8 | % sourcemodel with 5061 voxels/vertices 9 | load New_AALROI_6mm.mat; pos = template_sourcemodel.pos; 10 | 11 | % some overlay values for each vertex 12 | o = randi([-4 7],5061,1); 13 | 14 | % make the original plot 15 | figure, 16 | A = atemplate('overlay',o,'sourcemodel',pos) 17 | 18 | 19 | 20 | % using the returned data, plot some different values from the same 21 | % sourcemodel (much quicker): 22 | %-------------------------------------------------------------------------- 23 | 24 | new_overlay_data = o*-1; 25 | 26 | 27 | % get stuff returned from preivous call 28 | M = A.overlay.smooth_weights; 29 | indz = A.overlay.indz; 30 | 31 | % incorporate overlay into precomputed weights matrix 32 | for k = 1:length(new_overlay_data) 33 | M(k,indz(k,:)) = new_overlay_data(k) * M(k,indz(k,:)); 34 | end 35 | 36 | % normalise by number of overlapping points at this vertex 37 | for i = 1:size(M,2) 38 | y(i) = sum( M(:,i) ) / length(find(M(:,i))) ; 39 | end 40 | 41 | % rescale y by L limits 42 | S = [min(new_overlay_data(:)),max(new_overlay_data(:))]; 43 | y = S(1) + ((S(2)-S(1))).*(y - min(y))./(max(y) - min(y)); 44 | y(isnan(y)) = 0; 45 | 46 | % do plot: 47 | figure, A2 = atemplate('overlay',y) 48 | -------------------------------------------------------------------------------- /Examples/Example_SPM_SourceInv_ExtractPlot.m: -------------------------------------------------------------------------------- 1 | 2 | % The spm file that has been souce localised (e.g. has D.inv{1}): 3 | D = spm_eeg_load('bawinica_ef1_30spmeeg_faces_PSP_0008_1_sss') 4 | 5 | % The forward model mesh (D.inv{1}.forward) 6 | mesh = D.inv{1}.forward(1).mesh; 7 | v = mesh.vert; 8 | 9 | % Extract inverse components for reconstruction: 10 | Mods = D.inv{1}.inverse.modality; 11 | U = D.inv{1}.inverse.U; 12 | Ic = D.inv{1}.inverse.Ic; 13 | S = D.inv{1}.inverse.scale; 14 | M = D.inv{1}.inverse.M; 15 | 16 | % Average trials, D0 = (Chans * time) 17 | D0 = mean(D(:,:,:),3); 18 | 19 | for i = 1:length(Mods) 20 | fprintf('Reconstructing modality: %s\n',Mods{i}); 21 | % R = (spatial modes * wights) * Channel Data 22 | R{i} = ( U{i} * S(i) ) * D0(Ic{i},:); 23 | end 24 | 25 | % S = Filters * R(spatially reduced channel data by time) 26 | Source = M*cat(1,R{:}); 27 | time = D.time; 28 | 29 | % Plot the average activity on the forward model mesh: 30 | atemplate('gifti',gifti(mesh),'overlay',mean(Source,2)) 31 | 32 | % Align & plot the average activity on a smooth mesh: 33 | atemplate('sourcemodel',v,'overlay',mean(Source,2)) 34 | 35 | % Plot video of activity on the forward model mesh, ... 36 | % but put in AAL90 space for faster computation: 37 | atemplate('gifti',gifti(mesh),'sourcemodel',v,'template','aal90','video',Source,'myvid',time) 38 | 39 | % Plot video of activity on the smooth mesh, ... 40 | % but put in AAL90 space for faster computation & subsample time: 41 | atemplate('sourcemodel',v,'template','aal90','video',Source(:,1:6:end),'myvid2',time(1:6:end)) 42 | -------------------------------------------------------------------------------- /Examples/Example_Script_OverlayAndNodes.m: -------------------------------------------------------------------------------- 1 | 2 | S = load('T-tests'); 3 | Sub = 2; 4 | t = S.t(Sub,:); 5 | p = S.p(Sub,:); 6 | 7 | % For top n-points: 8 | %---------------------------------------------------------------------- 9 | % [v,i] = maxpoints(abs(t),10); 10 | % N = zeros(90,1); 11 | % N(i) = 1; 12 | % t = double(t); 13 | % atemplate('overlay',t,'nodes',N,'labels'); 14 | % bigimg; 15 | 16 | 17 | % For significant points only: 18 | %---------------------------------------------------------------------- 19 | t = double(mean(S.t)); 20 | 21 | %i = find(mean(S.p)<.05); 22 | i = find(t>2); 23 | N = zeros(90,1); 24 | N(i) = 1; 25 | atemplate('overlay',t,'nodes',N,'labels'); 26 | bigimg; 27 | 28 | % For Average over subjects 29 | %---------------------------------------------------------------------- 30 | muT = mean(double(S.t),1); 31 | N = zeros(90,1); 32 | N([11 12 15 16 17 18 79 80 81 82 85 86]) = 1; 33 | 34 | atemplate('overlay',muT,'nodes',N,'labels'); 35 | bigimg; 36 | 37 | % For MMN-ERP network [A1, STG, IFG] overlay with network and labels 38 | %---------------------------------------------------------------------- 39 | S = load('T-tests'); 40 | t = mean(S.t); 41 | t = double(t); 42 | load labels 43 | 44 | N = zeros(90,1); 45 | Gr = [11 12 81 82 79 80]; 46 | N(Gr) = 1; 47 | 48 | % % L R L R L R 49 | % % i i A A S S 50 | % e = [0 0 0 0 2 0; % i L 51 | % 0 0 0 0 0 2; % i R 52 | % 0 0 0 0 1 0; % A L 53 | % 0 0 0 0 0 1; % A R 54 | % 1 0 2 0 0 0; % S L 55 | % 0 1 0 2 0 0];% S R 56 | % l = labels(Gr); 57 | % [nodes,edges] = write_subset_nodes(l,e); 58 | 59 | atemplate('overlay',t,'nodes',N,'labels'); 60 | -------------------------------------------------------------------------------- /Examples/Example_SubplotsToVideo.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | G = read_nv; 4 | iG = spm_mesh_inflate(G); 5 | iG = gifti(iG); 6 | 7 | N = randi([0 4],90,90); 8 | 9 | ncomp = 90; 10 | while ncomp > 20 11 | N = N .* randi([0 1],90,90); 12 | [~,ncomp] = PEig90(N); 13 | end 14 | 15 | F = figure; 16 | h1 = subplot(121); 17 | atemplate('gifti',iG,'fighnd',h1,'network',N,'nocolbar') 18 | view(0,0); 19 | 20 | h2 = subplot(122); 21 | atemplate('gifti',iG,'fighnd',h2,'overlay',randi([0 4],90,1),'nocolbar'); 22 | view(0,0); 23 | 24 | set(gcf, 'Position', [100, 100, 2400, 1000]) 25 | 26 | im2vid_multi(F,'test3'); -------------------------------------------------------------------------------- /Examples/FieldtripSegmentationUsage.m: -------------------------------------------------------------------------------- 1 | 2 | % Example fieldtrip segmentation usage with atemplate 3 | 4 | load coregseg_0001.mat % saved fieldtrip segmentation 5 | 6 | segvol = segmentedmri.gray; % the gray matter volume 7 | 8 | 9 | % extract surface, check orientation & write gifti file 10 | afigure,atemplate('mesh',segvol,'checkori','write','Alex') 11 | 12 | % Now load up the saved gifti object & plot curvature overlay heatmap on 13 | % leftside (for example) 14 | 15 | afigure,atemplate('mesh','Alex.gii','overlay','curvature','hemi','l'); 16 | -------------------------------------------------------------------------------- /Examples/NEW_RENDER_OVERLAY_FieldTrip_EXAMPLE.m: -------------------------------------------------------------------------------- 1 | % Example Rendering Overlays..... 2 | 3 | load New_AALROI_6mm.mat % sourcemodel 4 | load SaveVolumeTstats.mat % file containing 'Plotstat': vector length(5061) 5 | 6 | projmeth = 'raycast'; 7 | 8 | PlotStat = squeeze(sum(sum(Tstat,1),2)); 9 | 10 | % Just render PlotStat as colours onto the brain (no curvature) 11 | afigure; 12 | D = atemplate('mesh','def5','overlay', PlotStat,... 13 | 'sourcemodel',template_sourcemodel.pos,... 14 | 'method',projmeth); 15 | 16 | axis equal; 17 | caxis([-3 3]); 18 | colormap(cmocean('balance')); 19 | 20 | % Check it against a 3d scatter with overlay of the original positions: 21 | pp = template_sourcemodel.pos; 22 | figure,scatter3(pp(:,1),pp(:,2),pp(:,3),90,PlotStat,'filled'); 23 | view([0 90]); 24 | 25 | 26 | % OR WITH CURVATURE & COLORBAR ALSO, USING EXPLICIT THRESH: 27 | %------------------------------------------------------------ 28 | afigure; 29 | D = atemplate('mesh','def4','inflate','overlay',{'curvature' PlotStat},'sourcemodel',template_sourcemodel.pos,... 30 | 'method',projmeth,'thresh',3);axis equal; 31 | 32 | aJointColorbar(D); % BUT, CAXIS WONT WORK... :( 33 | -------------------------------------------------------------------------------- /Examples/NewExampleScript.m: -------------------------------------------------------------------------------- 1 | % An example script demonstrating how to use atemplate plot function 2 | % 3 | % Generates a random AAL90 network and places in left subplot 4 | % Generates a functional overlay vector and plots in right subplot 5 | % Links the 2 images, so that they rotate together 6 | 7 | 8 | % open a big figure window 9 | %-------------------------------------------------------------------------- 10 | figure('position',[1000 142 1343 836]); 11 | 12 | 13 | % make a spoof AAL90 network and plot on the left 14 | %-------------------------------------------------------------------------- 15 | net = zeros(90,90); 16 | net(randi([1 90],20,1),randi([1 90],20,1)) = randi([-7 7],20,20); 17 | 18 | s(1) = subplot(121); atemplate('network',net,'fighnd',s(1)); 19 | 20 | 21 | % make AAL90 'functional overlay' and plot on the right 22 | %-------------------------------------------------------------------------- 23 | over = randi([-7 9],90,1); 24 | 25 | s(2) = subplot(122); atemplate('overlay',over(:),'fighnd',s(2),'nocolbar'); 26 | 27 | 28 | % use linksubplots function to link rotation, so the two images move 29 | % together in the window 30 | %-------------------------------------------------------------------------- 31 | linksubplot(s) 32 | 33 | 34 | 35 | % Alternatively, plot overlay in left and right subplots, linked: 36 | %-------------------------------------------------------------------------- 37 | figure('position',[1000 142 1343 836]); 38 | 39 | s(1) = subplot(121); atemplate('overlay',over,'hemi','l','fighnd',s(1),'nocolbar') 40 | s(2) = subplot(122); atemplate('overlay',over,'hemi','r','fighnd',s(2),'nocolbar') 41 | 42 | linksubplots(s) -------------------------------------------------------------------------------- /Ext/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Ext/.DS_Store -------------------------------------------------------------------------------- /Ext/InteractiveColorbar/Examples.m: -------------------------------------------------------------------------------- 1 | %Examples to use the InteractiveColorbar 2 | 3 | %basic use 4 | % 5 | %Use the mouse pointer on the colorbar on the top and the bottom. When the 6 | %mouse cursor changes in a hand, the CLim property of the image can be 7 | %changed interactively. Use right mouse button on the InteractiveColorbar 8 | %to set the Colormap. 9 | figure; 10 | imagesc(rand(100,100)) 11 | InteractiveColorbar; 12 | 13 | 14 | %command line manipulation 15 | figure 16 | imagesc(rand(100,100)) 17 | ColorB=InteractiveColorbar; 18 | 19 | %Set the CLim manually. Note setting the CLim property of the axes will not 20 | %affect the colorbar. Set the CLim property on the InteractiveColorBar 21 | %instead. 22 | set(ColorB,'CLim',[0.25 0.75]) 23 | 24 | %Extend or limit the range of the InteractiveColorbar 25 | set(ColorB,'CRange',[-1 2]); %Extend 26 | set(ColorB,'CRange',[0.4 0.6]); %Limit 27 | 28 | %Hide text labels 29 | set(ColorB,'ShowCLimLabels',false) 30 | 31 | 32 | %Advanced use: Connect multiple InteractiveColorbars 33 | clear ColorB;figure; 34 | for i=1:4 35 | h(i)=subplot(2,2,i); 36 | imagesc(rand(100,100)); 37 | axis off; 38 | end 39 | 40 | for i=1:4 41 | ColorB(i)=InteractiveColorbar(h(i)); 42 | end 43 | 44 | %Link InterActiveColorbars: 45 | 46 | %Move one Colorbar, all will follow 47 | set(ColorB,'ConnectedColorBarObjects',ColorB); 48 | 49 | %Disable connection for the first InteractiveColorbar 50 | set(ColorB(1),'UpdateConnectedColorBars',false); 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Ext/InteractiveColorbar/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, hey dude 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /Ext/New_AALROI_6mm.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Ext/New_AALROI_6mm.mat -------------------------------------------------------------------------------- /Ext/brewermap/brewermap_plot.m: -------------------------------------------------------------------------------- 1 | function brewermap_plot() 2 | % Simple plot of all ColorBrewer colorscheme nodes in one figure. 3 | % 4 | % (c) 2014-2022 Stephen Cobeldick 5 | % 6 | %%% Syntax: 7 | % brewermap_plot() 8 | % 9 | % See also BREWERMAP BREWERMAP_VIEW CUBEHELIX MAXDISTCOLOR 10 | % LBMAP PARULA LINES RGBPLOT COLORMAP COLORBAR PLOT PLOT3 AXES SET 11 | 12 | [mcs,nmn,pyt] = brewermap('list'); 13 | % 14 | persistent cbh axh 15 | % 16 | xmx = max(nmn); 17 | ymx = numel(pyt); 18 | % 19 | if ishghandle(cbh) 20 | figure(cbh); 21 | delete(axh); 22 | else 23 | cbh = figure('HandleVisibility','callback', 'IntegerHandle','off',... 24 | 'NumberTitle','off', 'Name',mfilename,'Color','white',... 25 | 'MenuBar','figure', 'Toolbar','none', 'Tag',mfilename); 26 | set(cbh,'Units','pixels') 27 | pos = get(cbh,'Position'); 28 | pos(1:2) = pos(1:2) - 123; 29 | pos(3:4) = max(pos(3:4),[842,532]); 30 | set(cbh,'Position',pos) 31 | end 32 | % 33 | axh = axes('Parent',cbh, 'Color','none',... 34 | 'XTick',0:xmx, 'YTick',0.5:ymx, 'YTickLabel',mcs, 'YDir','reverse'); 35 | title(axh,'ColorBrewer Color Schemes (brewermap.m)', 'Interpreter','none') 36 | xlabel(axh,'Scheme Nodes') 37 | ylabel(axh,'Scheme Name') 38 | axf = get(axh,'FontName'); 39 | % 40 | for y = 1:ymx 41 | N = nmn(y); 42 | M = brewermap(N,mcs{y}); 43 | for x = 1:N 44 | patch([x-1,x-1,x,x],[y-1,y,y,y-1],1, 'FaceColor',M(x,:), 'Parent',axh) 45 | end 46 | text(xmx+0.1,y-0.5,pyt{y}, 'Parent',axh, 'FontName',axf) 47 | end 48 | % 49 | drawnow() 50 | % 51 | end 52 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%brewermap_plot -------------------------------------------------------------------------------- /Ext/brewermap/preset_colormap.m: -------------------------------------------------------------------------------- 1 | function map = preset_colormap(N,varargin) 2 | % Wrapper for any COLORMAP function, to provide preset parameter values. 3 | % 4 | % (c) 2020-2022 Stephen Cobeldick 5 | % 6 | %%% Syntax: 7 | % preset_colormap(@fun,p1,p2,...,pN) % store function and any parameters 8 | % map = preset_colormap(N) % generate colormap 9 | % 10 | %%% Examples %%% 11 | % 12 | % >> preset_colormap(@cubehelix,0.25,-0.67,1.5,1) 13 | % >> colormap(preset_colormap) 14 | % or 15 | % >> preset_colormap(5) 16 | % ans = 17 | % 0 0 0 18 | % 0.1055 0.2788 0.4895 19 | % 0.1660 0.6705 0.4961 20 | % 0.6463 0.8479 0.5076 21 | % 1.0000 1.0000 1.0000 22 | % 23 | % >> preset_colormap(@brewermap,'PuOr') 24 | % >> load topo 25 | % >> load coast 26 | % >> figure 27 | % >> worldmap(topo, topolegend) 28 | % >> contourfm(topo, topolegend); 29 | % >> contourcmap('preset_colormap', 'Colorbar','on', 'Location','horizontal','TitleString','Contour Intervals in Meters'); 30 | % >> plotm(lat, long, 'k') 31 | % 32 | % See Also BREWERMAP CUBEHELIX COLORMAP CONTOURCMAP 33 | 34 | persistent fnh arg 35 | % 36 | if nargin==0 % Default N same as MATLAB colormaps. 37 | N = cmDefaultN(); 38 | elseif nargin==1 && isnumeric(N) 39 | assert(isscalar(N) && isreal(N) && fix(N)==N,... 40 | 'SC:preset_colormap:N:NotRealScalarNumeric',... 41 | 'First input must be a real scalar numeric of the colormap size.') 42 | N = double(N); 43 | else % Store function handle and parameter values. 44 | assert(isa(N,'function_handle'),... 45 | 'SC:preset_colormap:N:NotFunctionHandle',... 46 | 'First input must be a function handle to a colormap function.') 47 | fnh = N; 48 | arg = varargin; 49 | return 50 | end 51 | % 52 | map = fnh(N,arg{:}); 53 | % 54 | end 55 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%preset_colormap 56 | function N = cmDefaultN() 57 | % Get the colormap size from the current figure or default colormap. 58 | try 59 | F = get(groot,'CurrentFigure'); 60 | catch %#ok pre HG2 61 | N = size(get(gcf,'colormap'),1); 62 | return 63 | end 64 | if isempty(F) 65 | N = size(get(groot,'DefaultFigureColormap'),1); 66 | else 67 | N = size(F.Colormap,1); 68 | end 69 | end 70 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%cmDefaultN -------------------------------------------------------------------------------- /Ext/findMeshHoles/circleMeshSample.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Ext/findMeshHoles/circleMeshSample.mat -------------------------------------------------------------------------------- /Ext/findMeshHoles/demo.m: -------------------------------------------------------------------------------- 1 | %% DEMO 2 | function demo() 3 | % load sample mesh - created from circleMesh.m 4 | load circleMeshSample.mat 5 | 6 | xy = p'; 7 | faces = t(1:3,:)'; 8 | 9 | % add 3rd dimension (z) 10 | z = ones(size(xy,1),1); 11 | vertices = [xy,z]; 12 | 13 | figure; trimesh(faces,vertices(:,1),vertices(:,2),vertices(:,3)); axis equal; 14 | title('Original'), xlabel('x'), ylabel('y'), zlabel('z') 15 | 16 | % create hole 17 | holeSize = (max(p(1,:))-min(p(2,1)))/4; 18 | [vertices,faces] = createHole(vertices,faces,holeSize); 19 | figure; trimesh(faces,vertices(:,1),vertices(:,2),vertices(:,3)); axis equal; 20 | title('Add Hole'), xlabel('x'), ylabel('y'), zlabel('z') 21 | 22 | % find hole 23 | holeCellArray = findTriMeshHoles(faces,vertices); 24 | 25 | % view holes 26 | figure; trimesh(faces,vertices(:,1),vertices(:,2),vertices(:,3)); 27 | title('Identify Holes'); xlabel('x');ylabel('y'); hold on; axis equal; 28 | for i = 1:length(holeCellArray) 29 | hole = holeCellArray{i}; 30 | line(vertices(hole,1),vertices(hole,2),vertices(hole,3),'Color','r') 31 | end 32 | end 33 | 34 | function [vertices,faces] = createHole(vertices,faces,holeSize) 35 | % create hole in circle mesh 36 | 37 | dimens = size(vertices,2); 38 | 39 | vertices_norm = vertices - repmat(mean(vertices),size(vertices,1),1); 40 | temp3 = vertices_norm(faces,:); 41 | matrix3 = reshape(temp3,size(faces,1),dimens,3); 42 | faceCenters = sum(matrix3,2)./3; 43 | dist2 = sqrt(sum(faceCenters.^2,3)); 44 | faces = faces(dist2 >= holeSize,:); 45 | 46 | end -------------------------------------------------------------------------------- /Ext/findMeshHoles/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, Audrey Cheong 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /Ext/findthenearest.m: -------------------------------------------------------------------------------- 1 | function [r,c,V] = findthenearest(srchvalue,srcharray,bias) 2 | % Usage: 3 | % Find the nearest numerical value in an array to a search value 4 | % All occurances are returned as array subscripts 5 | % 6 | % Output: 7 | % 8 | % For 2D matrix subscripts (r,c) use: 9 | % 10 | % [r,c] = findnearest(srchvalue,srcharray,gt_or_lt) 11 | % 12 | % 13 | % To also output the found value (V) use: 14 | % 15 | % [r,c,V] = findnearest(srchvalue,srcharray,gt_or_lt) 16 | % 17 | % 18 | % For single subscript (i) use: 19 | % 20 | % i = findnearest(srchvalue,srcharray,gt_or_lt) 21 | % 22 | % 23 | % Inputs: 24 | % 25 | % srchvalue = a numerical search value 26 | % srcharray = the array to be searched 27 | % bias = 0 (default) for no bias 28 | % -1 to bias the output to lower values 29 | % 1 to bias the search to higher values 30 | % (in the latter cases if no values are found 31 | % an empty array is ouput) 32 | % 33 | % 34 | % By Tom Benson (2002) 35 | % University College London 36 | % t.benson@ucl.ac.uk 37 | 38 | if nargin<2 39 | error('Need two inputs: Search value and search array') 40 | elseif nargin<3 41 | bias = 0; 42 | end 43 | 44 | % find the differences 45 | srcharray = srcharray-srchvalue; 46 | 47 | if bias == -1 % only choose values <= to the search value 48 | 49 | srcharray(srcharray>0) =inf; 50 | 51 | elseif bias == 1 % only choose values >= to the search value 52 | 53 | srcharray(srcharray<0) =inf; 54 | 55 | end 56 | 57 | % give the correct output 58 | if nargout==1 | nargout==0 59 | 60 | if all(isinf(srcharray(:))) 61 | r = []; 62 | else 63 | r = find(abs(srcharray)==min(abs(srcharray(:)))); 64 | end 65 | 66 | elseif nargout>1 67 | if all(isinf(srcharray(:))) 68 | r = [];c=[]; 69 | else 70 | [r,c] = find(abs(srcharray)==min(abs(srcharray(:)))); 71 | end 72 | 73 | if nargout==3 74 | V = srcharray(r,c)+srchvalue; 75 | end 76 | end 77 | 78 | end 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /Ext/meshconn.m: -------------------------------------------------------------------------------- 1 | function [conn,connnum,count]=meshconn(elem,nn) 2 | % 3 | % [conn,connnum,count]=meshconn(elem,nn) 4 | % 5 | % create node neighbor list from a mesh 6 | % 7 | % author: Qianqian Fang, 8 | % date: 2007/11/21 9 | % 10 | % input: 11 | % elem: element table of a mesh 12 | % nn : total node number of the mesh 13 | % 14 | % output: 15 | % conn: output, a cell structure of length nn, conn{n} 16 | % contains a list of all neighboring node ID for node n 17 | % connnum: vector of length nn, denotes the neighbor number of each node 18 | % count: total neighbor numbers 19 | % 20 | % -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net) 21 | % 22 | 23 | conn=cell(nn,1); 24 | dim=size(elem); 25 | for i=1:dim(1) 26 | for j=1:dim(2) 27 | conn{elem(i,j)}=[conn{elem(i,j)},elem(i,:)]; 28 | end 29 | end 30 | count=0; 31 | connnum=zeros(1,nn); 32 | for i=1:nn 33 | if(length(conn{i})==0) continue; end 34 | %conn{i}=sort(setdiff(unique(conn{i}),i)); 35 | neig=unique(conn{i}); 36 | neig(neig==i)=[]; 37 | connnum(i)=length(conn{i}); 38 | count=count+connnum(i); 39 | end 40 | -------------------------------------------------------------------------------- /Ext/smoothsurf.m: -------------------------------------------------------------------------------- 1 | function p=smoothsurf(node,mask,conn,iter,useralpha,usermethod,userbeta) 2 | % 3 | % p=smoothsurf(node,mask,conn,iter,useralpha,usermethod,userbeta) 4 | % 5 | % smoothing a surface mesh 6 | % 7 | % author: Qianqian Fang, 8 | % date: 2007/11/21 9 | % 10 | % input: 11 | % node: node coordinates of a surface mesh 12 | % mask: flag whether a node is movable: 0 movable, 1 non-movable 13 | % if mask=[], it assumes all nodes are movable 14 | % conn: input, a cell structure of length size(node), conn{n} 15 | % contains a list of all neighboring node ID for node n, 16 | % this can be computed from meshconn function 17 | % iter: smoothing iteration number 18 | % useralpha: scaler, smoothing parameter, v(k+1)=(1-alpha)*v(k)+alpha*mean(neighbors) 19 | % usermethod: smoothing method, including 'laplacian','laplacianhc' and 'lowpass' 20 | % userbeta: scaler, smoothing parameter, for 'laplacianhc' 21 | % 22 | % output: 23 | % p: output, the smoothed node coordinates 24 | % 25 | % recommendations 26 | % Based on [Bade2006], 'Lowpass' method outperforms 'Laplacian-HC' in volume 27 | % preserving and both are significantly better than the standard Laplacian method 28 | % 29 | % [Bade2006] R. Bade, H. Haase, B. Preim, "Comparison of Fundamental Mesh 30 | % Smoothing Algorithms for Medical Surface Models," 31 | % Simulation and Visualization, pp. 289-304, 2006. 32 | % 33 | % -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net) 34 | % 35 | 36 | p=node; 37 | if(isempty(mask)) 38 | nn=size(node,1); 39 | idx=1:nn; 40 | else 41 | idx=find(mask==0)'; 42 | nn=length(idx); 43 | end 44 | alpha=0.5; 45 | method='laplacian'; 46 | beta=0.5; 47 | if(nargin>4) 48 | alpha=useralpha; 49 | if(nargin>5) 50 | method=usermethod; 51 | if(nargin>6) 52 | beta=userbeta; 53 | end 54 | end 55 | end 56 | ibeta=1-beta; 57 | ialpha=1-alpha; 58 | 59 | for i=1:nn 60 | if(length(conn{idx(i)})==0) 61 | idx(i)=0; 62 | end 63 | end 64 | idx=idx(idx>0); 65 | nn=length(idx); 66 | 67 | if(strcmp(method,'laplacian')) 68 | for j=1:iter 69 | for i=1:nn 70 | p(idx(i),:)=ialpha*p(idx(i),:)+alpha*mean(node(conn{idx(i)},:)); 71 | end 72 | node=p; 73 | end 74 | elseif(strcmp(method,'laplacianhc')) 75 | for j=1:iter 76 | q=p; 77 | for i=1:nn 78 | p(idx(i),:)=mean(q(conn{idx(i)},:)); 79 | end 80 | b=p-(alpha*node+ialpha*q); 81 | for i=1:nn 82 | p(idx(i),:)=p(idx(i),:)-(beta*b(i,:)+ibeta*mean(b(conn{idx(i)},:))); 83 | end 84 | end 85 | elseif(strcmp(method,'lowpass')) 86 | beta=-1.02*alpha; 87 | ibeta=1-beta; 88 | for j=1:iter 89 | for i=1:nn 90 | p(idx(i),:)=ialpha*node(idx(i),:)+alpha*mean(node(conn{idx(i)},:)); 91 | end 92 | node=p; 93 | for i=1:nn 94 | p(idx(i),:)=ibeta *node(idx(i),:)+beta *mean(node(conn{idx(i)},:)); 95 | end 96 | node=p; 97 | end 98 | end 99 | -------------------------------------------------------------------------------- /Ext/sms.m: -------------------------------------------------------------------------------- 1 | function newnode=sms(node,face,iter,alpha,method) 2 | % 3 | % newnode=sms(node,face,iter,useralpha,method) 4 | % 5 | % simplified version of surface mesh smoothing 6 | % 7 | % author: Qianqian Fang, 8 | % date: 2009/10/21 9 | % 10 | % input: 11 | % node: node coordinates of a surface mesh 12 | % face: face element list of the surface mesh 13 | % iter: smoothing iteration number 14 | % alpha: scaler, smoothing parameter, v(k+1)=alpha*v(k)+(1-alpha)*mean(neighbors) 15 | % method: same as in smoothsurf, default is 'laplacianhc' 16 | % 17 | % output: 18 | % newnode: output, the smoothed node coordinates 19 | % 20 | % -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net) 21 | % 22 | 23 | if(nargin<5) 24 | method='laplacianhc'; 25 | end 26 | if(nargin<4) 27 | if(nargin<3) 28 | iter=10; 29 | end 30 | alpha=0.5; 31 | end 32 | 33 | conn=meshconn(face,size(node,1)); 34 | newnode=smoothsurf(node(:,1:3),[],conn,iter,alpha,method,alpha); 35 | -------------------------------------------------------------------------------- /Ext/spm_mesh_inflate.m: -------------------------------------------------------------------------------- 1 | function M = spm_mesh_inflate(M,T,S) 2 | % Surface mesh inflation 3 | % FORMAT M = spm_mesh_inflate(M,T,S) 4 | % 5 | % M - surface mesh structure (see patch) or GIfTI object 6 | % or handle to a patch in a figure 7 | % T - number of time steps [default: Inf (auto)] 8 | % S - update display every S time steps [default: 0 (never)] 9 | %__________________________________________________________________________ 10 | % Copyright (C) 2009-2011 Wellcome Trust Centre for Neuroimaging 11 | 12 | % Guillaume Flandin & Jean Daunizeau 13 | % $Id: spm_mesh_inflate.m 6157 2014-09-05 18:17:54Z guillaume $ 14 | 15 | 16 | if nargin < 3, S = 0; end 17 | 18 | if ishandle(M) 19 | v = double(get(M,'Vertices')); 20 | f = get(M,'Faces'); 21 | p = M; 22 | else 23 | v = double(M.vertices); 24 | f = double(M.faces); 25 | 26 | h = figure('visible','off'); 27 | a = axes('parent',h); 28 | if isa(M,'gifti') 29 | p = patch(export(M,'patch'),'parent',a,'visible','off'); 30 | else 31 | p = patch(M,'parent',a,'visible','off'); 32 | end 33 | S = 0; 34 | end 35 | 36 | % Parameters 37 | %-------------------------------------------------------------------------- 38 | b = 0.5; 39 | w = 0.05; 40 | 41 | if nargin < 2 || isinf(T) 42 | T = floor(size(v,1) * 0.003 - 2); 43 | end 44 | 45 | % Compute (normalised) adjacency matrix 46 | %-------------------------------------------------------------------------- 47 | A = spm_mesh_adjacency(f); 48 | A = sparse(1:size(v,1),1:size(v,1),1./sum(A,2)) * A; 49 | 50 | % Compute bounding box 51 | %-------------------------------------------------------------------------- 52 | minxyz = min(v); 53 | maxxyz = max(v); 54 | 55 | % Iteratively apply forces to vertices 56 | %-------------------------------------------------------------------------- 57 | for i=1:T 58 | 59 | % Compute unit normals 60 | %---------------------------------------------------------------------- 61 | N = spm_mesh_normals(p,1); 62 | 63 | % Compute smoothing force 64 | %---------------------------------------------------------------------- 65 | mv = A*v - v; 66 | 67 | % Update vertices position 68 | %---------------------------------------------------------------------- 69 | v = v + b * (w*repmat(sum(mv.*N,2),1,3).*N + (1-w)*mv); 70 | v = mean((maxxyz - minxyz)./(max(v) - min(v))) * v; 71 | 72 | set(p,'Vertices',v); 73 | 74 | % Update display 75 | %---------------------------------------------------------------------- 76 | if ~mod(i,S) 77 | axis(get(p,'parent'),'image'); 78 | drawnow 79 | end 80 | 81 | end 82 | 83 | % Cleanup 84 | %-------------------------------------------------------------------------- 85 | if ~ishandle(M) 86 | M.vertices = v; 87 | close(h); 88 | end 89 | -------------------------------------------------------------------------------- /Ext/spm_mesh_normals.m: -------------------------------------------------------------------------------- 1 | function N = spm_mesh_normals(M, unit) 2 | % Compute (unit) normals of a surface mesh 3 | % FORMAT N = spm_mesh_normals(M) 4 | % M - a patch structure or a handle to a patch 5 | % unit - boolean to indicate unit normals or not [default: false] 6 | % 7 | % N - a [Nx3] array of (unit) normals on vertices 8 | %__________________________________________________________________________ 9 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 10 | 11 | % Guillaume Flandin 12 | % $Id: spm_mesh_normals.m 5903 2014-03-03 14:56:10Z guillaume $ 13 | 14 | if nargin < 2, unit = false; end 15 | 16 | if ~ishandle(M) 17 | f = figure('visible','off'); 18 | M = patch(M, 'parent',axes('parent',f), 'visible', 'off'); 19 | end 20 | 21 | N = double(get(M,'VertexNormals')); 22 | 23 | if isempty(N) 24 | t = triangulation(double(get(M,'Faces')),double(get(M,'Vertices'))); 25 | N = -double(t.vertexNormal); 26 | end 27 | 28 | try, close(f); end 29 | 30 | if unit 31 | normN = sqrt(sum(N.^2,2)); 32 | normN(normN < eps) = 1; 33 | N = N ./ repmat(normN,1,3); 34 | end -------------------------------------------------------------------------------- /Ext/spm_mesh_smooth.m: -------------------------------------------------------------------------------- 1 | function T = spm_mesh_smooth(M, T, S) 2 | % Perform Gaussian smoothing on data lying on a surface mesh 3 | % FORMAT GL = spm_mesh_smooth(M) 4 | % M - a patch structure or a handle to a patch 5 | % GL - graph Laplacian 6 | % 7 | % FORMAT T = spm_mesh_smooth(M, T, S) 8 | % FORMAT T = spm_mesh_smooth(GL, T, S) 9 | % T - [vx1] data vector 10 | % S - smoothing parameter (number of iterations) 11 | %__________________________________________________________________________ 12 | % Copyright (C) 2010 Wellcome Trust Centre for Neuroimaging 13 | 14 | % Karl Friston, Guillaume Flandin 15 | % $Id: spm_mesh_smooth.m 4079 2010-10-07 11:41:54Z guillaume $ 16 | 17 | if isstruct(M) || numel(M) == 1 18 | A = spm_mesh_distmtx(M,0); 19 | N = size(A,1); 20 | GL = speye(N,N) + (A - spdiags(sum(A,2),0,N,N))/16; 21 | else 22 | GL = M; 23 | end 24 | 25 | if nargin == 1, T = GL; return; end 26 | 27 | for i=1:S 28 | T = GL * T; 29 | end 30 | 31 | return; 32 | -------------------------------------------------------------------------------- /Ext/spm_mesh_utils.mexmaca64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Ext/spm_mesh_utils.mexmaca64 -------------------------------------------------------------------------------- /Funcs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Funcs/.DS_Store -------------------------------------------------------------------------------- /Funcs/CheckCompareOverlay.m: -------------------------------------------------------------------------------- 1 | function t = CheckCompareOverlay(D) 2 | % give the output structure of an atemplate call containing 'overlay' 3 | % structure 4 | 5 | Name = {'Input Overlay' 'Output Overlay' 'Sq Error'}'; 6 | Mean = [mean(D.overlay.orig) mean(D.overlay.data)]'; 7 | Mode = [mode(D.overlay.orig) mode(D.overlay.data)]'; 8 | Median = [median(D.overlay.orig) median(D.overlay.data)]'; 9 | Min = [min(D.overlay.orig) min(D.overlay.data)]'; 10 | Max = [max(D.overlay.orig) max(D.overlay.data)]'; 11 | 12 | Mean(3) = (Mean(1)-Mean(2)).^2; 13 | Mode(3) = (Mode(1)-Mode(2)).^2; 14 | Median(3) = (Median(1)-Median(2)).^2; 15 | Min(3) = (Min(1)-Min(2)).^2; 16 | Max(3) = (Max(1)-Max(2)).^2; 17 | 18 | t = table(Name,Mean,Mode,Median,Min,Max); -------------------------------------------------------------------------------- /Funcs/CheckOrientationMesh.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Funcs/CheckOrientationMesh.fig -------------------------------------------------------------------------------- /Funcs/CompareProjectionMethods.m: -------------------------------------------------------------------------------- 1 | function CompareProjectionMethods(sourcemodel,overlay) 2 | 3 | % Compare the 3 overlay methods 4 | 5 | figure('position',[186 290 1927 688]) 6 | 7 | mesh = 'def1'; 8 | 9 | % Ray casting 10 | s(1) = subplot(131); 11 | atemplate('mesh',mesh,'overlay',overlay,... 12 | 'sourcemodel',sourcemodel,... 13 | 'method','raycast',... 14 | 'fighnd', s(1),'hemi','l') 15 | title('Ray casting'); 16 | 17 | % Euclidean search 18 | s(2) = subplot(132); 19 | atemplate('mesh',mesh,'overlay',overlay,... 20 | 'sourcemodel',sourcemodel,... 21 | 'method','euclidean',... 22 | 'fighnd', s(2),'hemi','l') 23 | title('Euclidean search'); 24 | 25 | % Inflated sphere / trap radius 26 | s(3) = subplot(133); 27 | atemplate('mesh',mesh,'overlay',overlay,... 28 | 'sourcemodel',sourcemodel,... 29 | 'method','spheres',... 30 | 'fighnd', s(3),'hemi','l') 31 | title('Inflated spherical trap radius'); 32 | 33 | 34 | linksubplots(s); 35 | 36 | -------------------------------------------------------------------------------- /Funcs/NewMeanFilt3D.m: -------------------------------------------------------------------------------- 1 | function y = NewMeanFilt3D(M,m1,m2,m3) 2 | % Mean window filtering for 3D matrices 3 | % 4 | % 5 | % 6 | % AS2016 [updt] [updt 17] 7 | 8 | 9 | if ndims(M) > 3; fprintf('Too many dimensions!\n'); return; end 10 | if ndims(M) < 3; fprintf('Too few dimensions!\n'); return; end 11 | 12 | if nargin < 4 13 | [m2, m3] = deal(m1); 14 | end 15 | 16 | y = smoothmat3(M,m1,m2,m3); 17 | 18 | end 19 | 20 | function matrixOut = smoothmat3(matrixIn,Nr,Nc,Nz) 21 | 22 | N(1) = Nr; N(2) = Nc; N(3) = Nz; 23 | 24 | [row,col,dep] = size(matrixIn); 25 | 26 | eL = spdiags(ones(row,2*N(1)+1),(-N(1):N(1)),row,row); 27 | eR = spdiags(ones(col,2*N(2)+1),(-N(2):N(2)),col,col); 28 | eZ = spdiags(ones(dep,2*N(3)+1),(-N(3):N(3)),dep,dep); 29 | 30 | A = isnan(matrixIn); 31 | matrixIn(A) = 0; 32 | 33 | for i = 1:length(eZ); 34 | nrm(:,:,i) = eL*(~A(:,:,i))*eR; 35 | nrm(:,:,i) = nrm(:,:,i)*eZ(i,i); 36 | end 37 | 38 | nrmlize = nrm; 39 | nrmlize(A) = NaN; 40 | 41 | for i = 1:length(eZ); 42 | matrixOut(:,:,i) = eL*matrixIn(:,:,i)*eR; 43 | matrixOut(:,:,i) = matrixOut(:,:,i)*eZ(i,i); 44 | end 45 | matrixOut = matrixOut./nrmlize; 46 | 47 | end 48 | 49 | -------------------------------------------------------------------------------- /Funcs/afigure.m: -------------------------------------------------------------------------------- 1 | function h = afigure() 2 | 3 | h = figure('position',[979 38 1216 947]); -------------------------------------------------------------------------------- /Funcs/avolrender.m: -------------------------------------------------------------------------------- 1 | function D = avolrender(filename) 2 | % a quick-to-execute wrapper on atemplate.m 3 | % 4 | % 5 | % 6 | 7 | % assume we want to register to the cortical AAL parcellation 8 | load DenseAAL.mat 9 | 10 | % The functional nifti volume to project 11 | FunVol = filename; 12 | 13 | % The default mesh to render 14 | % (def1, 2 & 4 = cortical-only, 3=with cerebellum) 15 | Surf = 'def2'; 16 | 17 | % Not specifying the 'method' defaults to ray-casting 18 | afigure; D = atemplate('mesh',Surf,'overlay',FunVol,'post_parcel',{v vi}); 19 | -------------------------------------------------------------------------------- /Funcs/bigimg.m: -------------------------------------------------------------------------------- 1 | 2 | set(gcf, 'Position', [100, 100, 1000, 1000]) 3 | view(0,0) -------------------------------------------------------------------------------- /Funcs/bluewhitered/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009, Nathan Childress 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /Funcs/cdist.m: -------------------------------------------------------------------------------- 1 | function D = cdist(mv,v) %#codegen 2 | % find distance between the 3D coordiates specified in vector v (1x3) and 3 | % the vectors of matrix mv (nx3), or between matrix v (mx3) and matrix mv 4 | % (nx3), where v(m,1:3) = [x y z] 5 | % 6 | % AS17 7 | 8 | % if isvector(v) 9 | % D = sum( ( mv - repmat( v, size(mv,1), 1 )).^2, 2); 10 | % end 11 | 12 | % if ismatrix(v) 13 | % for i = 1:3 14 | % dif(:,:,i) = (v(:,i)'-mv(:,i) ); 15 | % end 16 | % D = squeeze(sum(( dif.^2),3)); 17 | % end 18 | 19 | % 20 | 21 | 22 | % this is a fully vectorised version of the above code, which should be quicker. 23 | %------------------------------------------------------------------------------ 24 | a = v'; 25 | b = mv'; 26 | 27 | aa = sum(a.*a,1); 28 | bb = sum(b.*b,1); 29 | ab = a'*b; 30 | d = sqrt(abs(repmat(aa',[1 size(bb,2)]) + repmat(bb,[size(aa,2) 1]) - 2*ab)); 31 | D = d'; 32 | 33 | -------------------------------------------------------------------------------- /Funcs/conmat2nodes.m: -------------------------------------------------------------------------------- 1 | function [node1,node2,strng] = conmat2nodes(A,savename,varargin) 2 | % Write node & edge files for the AAL90 atlas 3 | % Also returns node-to-node coordinates for the matrix specified. 4 | % 5 | % Input is the 90x90 connectivity matrix 6 | % Input 2 (optional) is savename for the .edge and .node files 7 | % 8 | % AS2017 9 | 10 | try strcmp(varargin{1},'sourcemodel'); 11 | pos = varargin{2}; 12 | catch 13 | load('AAL_SOURCEMOD.mat'); 14 | pos = template_sourcemodel.pos; 15 | end 16 | 17 | 18 | node1 = []; node2 = []; strng = []; 19 | for i = 1:length(A) 20 | [ix,iy,iv] = find(A(i,:)); 21 | 22 | if ~isempty(ix) 23 | conns = max(length(ix),length(iy)); 24 | for nc = 1:conns 25 | node1 = [node1; pos(i(1),:)]; 26 | node2 = [node2; pos(iy(nc),:)]; 27 | strng = [strng; iv(nc)]; 28 | end 29 | end 30 | end 31 | 32 | % UsrVec = 0; 33 | % try v = varargin{1}; 34 | % if isnumeric(v); 35 | % UsrVec = 1; 36 | % end 37 | % end 38 | 39 | if nargin > 1; 40 | C = pos; 41 | C(:,[4 5]) = 1; 42 | 43 | E = A; 44 | E(isnan(E))=0; 45 | i = find(~sum(E)); 46 | C(i,[4 5])=0; 47 | 48 | % if UsrVec 49 | % C(:,[4 5]) = [v,v]; 50 | % end 51 | 52 | dlmwrite([savename '.edge'],A,'delimiter','\t'); 53 | dlmwrite([savename '.node'],C,'delimiter','\t'); 54 | end 55 | 56 | end 57 | 58 | -------------------------------------------------------------------------------- /Funcs/cubric_meg_palettes.m: -------------------------------------------------------------------------------- 1 | function [map2,map3,map4] = cubric_meg_palettes 2 | %UNTITLED Summary of this function goes here 3 | % Detailed explanation goes here 4 | for i=1:255, 5 | map2(i,1)=0; 6 | map2(i,2)=0; 7 | map2(i,3)=0; 8 | map4(i,1)=0; 9 | if i>=128, 10 | map4(i,1)=0.5+0.5*((i-128)/127.0)^0.6; 11 | map2(i,1)=3*(i-128)/128.0; 12 | map2(i,2)=3*0.7*(i-128)/128.0; 13 | end 14 | if i<128, 15 | map4(i,1)=0.5-0.5*((127-i)/126.0)^0.6; 16 | map2(i,2)=3*0.7*(128-i)/128.0; 17 | map2(i,3)=3*(128-i)/127.0; 18 | end 19 | if map4(i,1)>1.0, map4(i,1)=1.0; end 20 | if map4(i,1)<0.0, map4(i,1)=0.0; end 21 | 22 | if map2(i,1)>1.0, map2(i,1)=1.0; end 23 | if map2(i,2)>0.7, map2(i,2)=0.7; end 24 | if map2(i,3)>1.0, map2(i,3)=1.0; end 25 | map4(i,2)=map4(i,1); 26 | map4(i,3)=map4(i,1); 27 | end 28 | M=1; 29 | for i=128:255, 30 | if i>=128&&i<=149, 31 | r=M;g=M-0.0476*M*(i-128);b=M; 32 | end 33 | if(i>=150&&i<=170), 34 | r=M-0.05*M*(i-150);g=0;b=M; 35 | end 36 | if(i>=171&&i<=191), 37 | r=0;g=0;b=M-0.05*M*(i-171); 38 | end 39 | if(i>=192&&i<=212), 40 | r=0.05*M*(i-192);g=0;b=0; 41 | end 42 | if(i>=213&&i<=232), 43 | r=M;g=0.029*M*(i-213);b=0.03*M; 44 | end 45 | if(i>=233&&i<=255), 46 | r=M;g=0.59*M+0.0195*M*(i-233);b=0.03*M; 47 | end 48 | if r<0, 49 | r=0; 50 | end 51 | if g<0, 52 | g=0; 53 | end 54 | if b<0, 55 | b=0; 56 | end 57 | if r>1, 58 | r=1; 59 | end 60 | if g>1, 61 | g=1; 62 | end 63 | if b>1, 64 | b=1; 65 | end 66 | map3(i-127,1)=r; 67 | map3(i-127,2)=g; 68 | map3(i-127,3)=b; 69 | end 70 | end 71 | 72 | -------------------------------------------------------------------------------- /Funcs/exportbrains.m: -------------------------------------------------------------------------------- 1 | function exportbrains(fname) 2 | % exportbrains 3 | 4 | view(0,90); drawnow; print([fname '_top'] ,'-dpng','-r600') ; 5 | view(270,0); drawnow; print([fname '_left'] ,'-dpng','-r600') ; 6 | view(90,0); drawnow; print([fname '_right'] ,'-dpng','-r600') ; 7 | view(0,0); drawnow; print([fname '_back'] ,'-dpng','-r600') ; 8 | view(0,-90); drawnow; print([fname '_bottom'],'-dpng','-r600') ; 9 | view(-180,0);drawnow; print([fname '_front'] ,'-dpng','-r600') ; -------------------------------------------------------------------------------- /Funcs/flatten_mesh.m: -------------------------------------------------------------------------------- 1 | function [dv,uv,g,bnd] = flatten_mesh(v,f,c,doplot) 2 | % squash a 3D cloud [input v(nx3) ] into a 2D orthographic projection, 3 | % using x/y spread relative to original depth. for brains. 4 | % 5 | % % squash/flatten v(nx3) to dv(nx2): 6 | % [dv,uv,g] = flatten_mesh(v) 7 | % 8 | % % approximately translate back to 3D: 9 | % ov = dv./uv; % first 2 dims in orig space 10 | % ov(:,3) = diff(uv')'; % approx (quantised) 3rd dim [scale is wrong] 11 | % 12 | % AS 13 | 14 | if nargin < 4 15 | doplot=0; 16 | end 17 | 18 | % estimate size of required 2d canvas 19 | v = v - repmat(spherefit(v),[size(v,1),1]); 20 | bnd = [min(v); max(v)]; 21 | d3s = diff(bnd(:,3)) / 2; 22 | newcnv = [bnd(1,1:2) - d3s ; bnd(2,1:2) + d3s]; 23 | former = bnd(1:2,1:2); 24 | 25 | % sort highest to lowest points 26 | [~,top2b] = sort(v(:,3),'descend'); 27 | 28 | n_g = 5000; % bigger=smoother 29 | 30 | % chunk top-to-bottom vertex list into n_g groups, 1:n_g = incrs. depth 31 | depths = linspace(1,length(top2b),n_g+1); 32 | dgroup = zeros(1,length(top2b)); 33 | for i = 1:n_g 34 | dgroup(depths(i):depths(i+1)) = i; 35 | end 36 | 37 | % depth group indexing of the original vertex sequence: 38 | g(top2b)=dgroup; 39 | 40 | % scale factor determines how far we spread in x and y directions as a 41 | % function of depth (former z direction) 42 | scale_factor = ( newcnv./former ) / n_g; 43 | scale_factor = mean(scale_factor,1); 44 | new_list = []; 45 | 46 | for i = 1:length(v) 47 | pnt = v(i,:); 48 | grp = g(i); 49 | 50 | new_pnt = pnt(1:2) .* (grp*scale_factor); 51 | new_list = [new_list ; new_pnt]; 52 | 53 | % retain multiplier (e.g. dv = v(1:2).*uv] 54 | uv(i,:) = (grp*scale_factor); 55 | end 56 | 57 | % complete 2nd vertex list - with vertices in same order as input 58 | dv = new_list; 59 | 60 | if doplot 61 | % plot example - brain data: 62 | %[dv,uv] = flatten_mesh(v); 63 | if ~isempty(f) 64 | pv = struct('faces',[f(:,1:2)],'vertices',[dv]); 65 | p = patch(pv); 66 | set(p,'EdgeColor',[.4 .4 .4]);p.EdgeAlpha=.4; hold on; 67 | end 68 | 69 | sc = scatter(dv(:,1),dv(:,2),80,c,'filled');hold on 70 | sc.MarkerFaceAlpha = .4; 71 | k = boundary(double(v(:,1:2))); 72 | k0 = boundary(double(dv)); 73 | l0 = line(v(k,1),v(k,2)); 74 | l1 = line(dv(k0,1),dv(k0,2)); 75 | 76 | l0.Color = [.4 .4 .4]; 77 | l0.LineWidth = 2; 78 | l1.Color = [.4 .4 .4]; 79 | l1.LineWidth = 2; 80 | axis square; 81 | end 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /Funcs/genvol.m: -------------------------------------------------------------------------------- 1 | function V = genvol(vertices,values,dims) 2 | 3 | % initialise volume 4 | V = zeros(dims); 5 | 6 | % make a grid in each direction, with some whitespace at edges 7 | lb = min(vertices)*1.2; 8 | ub = max(vertices)*1.2; 9 | 10 | % using common x,y,z lengths will preserve ratios 11 | edges = [ min(lb) max(ub) ]; 12 | x = linspace( edges(1),edges(2),dims(1) ); 13 | y = linspace( edges(1),edges(2),dims(2) ); 14 | z = linspace( edges(1),edges(2),dims(3) ); 15 | v = [x' y' z']; 16 | 17 | % from our new grid, compute closest points of vertices of interest 18 | % nb. indices of new grid are the volume indices 19 | 20 | %D0 = cdist(vertices,v); 21 | 22 | % now loop to find clsest points 23 | for i = 1:3 24 | for j = 1:length(vertices) 25 | v0(j,i) = findthenearest( vertices(j,i), v(:,i) ); 26 | end 27 | end 28 | 29 | % now embed these positions in the volume 30 | for i = 1:length(vertices) 31 | V( v0(i,1) , v0(i,2) , v0(i,3) ) = values(i); 32 | end -------------------------------------------------------------------------------- /Funcs/im2vid.m: -------------------------------------------------------------------------------- 1 | function im2vid(fn,varargin) 2 | % Capture (current) 3D figure, make video by rotating camera angle 360 3 | % degrees. 4 | % 5 | % Usage: im2vid('myvideo') 6 | % 7 | % Other useage: 8 | % im2vid('myvideo','quick'); 9 | % im2vid('myvideo','background'); 10 | % 11 | % Quick mode is fast, but requires that the figure window be showing and 12 | % on top of all other windows. 13 | % Background is slower but you can carry on doing other stuff - it writes 14 | % each frame to a temporary png. 15 | % 16 | % AS 17 | 18 | if nargin > 1; 19 | method = varargin{1}; 20 | else 21 | method = 'background'; % 'quick' or 'background' 22 | end 23 | 24 | [fp,fn,fe] = fileparts(fn); 25 | if isempty(fp) 26 | try fpath = [pwd, '/', fn]; 27 | catch fpath = [pwd, '/im']; 28 | end 29 | else 30 | fpath = [fp '/' fn]; 31 | end 32 | 33 | pathname = pwd; 34 | D = 'right'; 35 | cam = camlight(D); 36 | vidObj = VideoWriter(fpath,'MPEG-4'); 37 | set(vidObj,'Quality',100); 38 | open(vidObj); 39 | 40 | for num = 1:360 41 | if num > 1; fprintf(repmat('\b',[1 length(str)])); end 42 | str = sprintf('building: %d of %d\n',num,360); 43 | fprintf(str); 44 | camorbit(1,0,'camera'); 45 | camlight(cam); drawnow; 46 | 47 | switch method 48 | case 'quick'; 49 | set(gcf,'Color','none') 50 | currFrame = getframe(gcf); 51 | writeVideo(vidObj,currFrame); 52 | case 'background' 53 | 54 | print(gcf,[pathname,'/temp.png'],'-dpng','-r600'); 55 | %export_fig([pathname,'/temp.png'],'-transparent','-m2','-nocrop'); 56 | tempimg = imread([pathname,'/temp.png']); 57 | 58 | currFrame = im2frame(tempimg); 59 | currFrame.cdata = imresize(currFrame.cdata,[1068,1470]); 60 | writeVideo(vidObj,currFrame); 61 | end 62 | end 63 | 64 | close(vidObj); 65 | switch method 66 | case 'background' 67 | delete([pathname,'temp.png']); 68 | end 69 | fprintf('finished\n'); -------------------------------------------------------------------------------- /Funcs/linksubplots.m: -------------------------------------------------------------------------------- 1 | function linksubplots(ha) 2 | % Link subplot axes for roation purposes. 3 | % ha = figure handle 4 | % 5 | % If fig reopened from .fig do: 6 | % h = figopen('blah.fig') 7 | % ha = allchild(h); 8 | % linksubplots(ha) 9 | % 10 | % AS 11 | 12 | Link = linkprop(ha, ... 13 | {'CameraUpVector', 'CameraPosition', 'CameraTarget'}); 14 | setappdata(gcf, 'StoreTheLink', Link); -------------------------------------------------------------------------------- /Funcs/maker.m: -------------------------------------------------------------------------------- 1 | function mesh = maker(faces,vertices); 2 | 3 | mesh = struct('vertices',vertices,'faces',faces); -------------------------------------------------------------------------------- /Funcs/maxpoints.m: -------------------------------------------------------------------------------- 1 | function [V,I] = maxpoints(x,n,varargin) 2 | % Find max n-points in vector x, and their indices. 3 | % 4 | % optional third input, function string, e.g. 'min' 5 | % hint - also use abs(x) input 6 | % 7 | % 8 | 9 | if nargin < 3 10 | f = @max; 11 | else 12 | f = eval(['@' lower(varargin{1})]); 13 | end 14 | 15 | for i = 1:n 16 | 17 | [V(i),I(i)] = f(x); 18 | x(I(i)) = nan; 19 | 20 | end 21 | end -------------------------------------------------------------------------------- /Funcs/meshnorm.m: -------------------------------------------------------------------------------- 1 | function N = meshnorm(g) 2 | 3 | tr = triangulation(double(g.faces),double(g.vertices(:,1)),... 4 | double(g.vertices(:,2)),... 5 | double(g.vertices(:,3)) ); 6 | g.FaceNorm = tr.faceNormal; 7 | N = -double(tr.vertexNormal); 8 | 9 | normN = sqrt(sum(N.^2,2)); 10 | normN(normN < eps) = 1; 11 | N = N ./ repmat(normN,1,3); 12 | g.VertexNorm = N; 13 | 14 | end -------------------------------------------------------------------------------- /Funcs/pca_on_mesh_overlay.m: -------------------------------------------------------------------------------- 1 | function p = pca_on_mesh_overlay(D) 2 | % compute pca on output of a sourmesh/atemplate model 3 | % input struct returned by atemplate call, e.g. D = atemplate(' ... ') 4 | 5 | A = spm_mesh_adjacency(D.mesh); 6 | Y = D.overlay.data; 7 | M = Y.*A.*Y'; 8 | 9 | [u,s,v] = svds(M); 10 | 11 | d = max(length(s),6); 12 | 13 | for i = 1:d 14 | p(i,:) = u(:,i)'*M; 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /Funcs/pseudoAAL.m: -------------------------------------------------------------------------------- 1 | function [pos,overlay] = psudoAAL(type) 2 | % Make psudo overlay from AAL90 sourcemodel 3 | % 4 | % 1) call [pos,overlay] = psudoAAL('r') to select nodes to be non-zero from a 5 | % popup list. 'r' indicates the values for these nodes will be randomly 6 | % generated between -7 - 7. 7 | % 8 | % 2) call [pos,overlay] = psudoAAL() with no input to select nodes to be 9 | % non-zero from a popup list. No input indicates values assigned to 10 | % selected nodes will increase from 1:num selected. 11 | % 12 | % AS 13 | 14 | 15 | load AAL_labels.mat 16 | load New_AALROI_6mm.mat 17 | 18 | if nargin < 1 19 | type = ' '; 20 | end 21 | 22 | 23 | [SELECTION,OK] = listdlg('ListString',AAL_Labels); 24 | 25 | switch type 26 | case 'r'; 27 | Vals = randi([-7 7],length(SELECTION),1); 28 | otherwise 29 | Vals = 1:length(unique(SELECTION)); 30 | end 31 | 32 | overlay = zeros(5061,1); 33 | pos = template_sourcemodel.pos; 34 | 35 | if OK 36 | for i = 1:length(SELECTION) 37 | this = find(all_roi_tissueindex==SELECTION(i)); 38 | overlay(this) = Vals(i); 39 | end 40 | end -------------------------------------------------------------------------------- /Funcs/read_nifti.m: -------------------------------------------------------------------------------- 1 | function D = read_nifti(filein) 2 | 3 | N = spm_vol(filein); 4 | D = spm_read_vols(N); -------------------------------------------------------------------------------- /Funcs/read_nv.m: -------------------------------------------------------------------------------- 1 | function mesh = read_nv(X) 2 | 3 | if nargin < 1 4 | %fprintf('Using template\n'); 5 | X = dlmread('BrainMesh_ICBM152_smoothed.nv'); 6 | else 7 | if ~strcmp(X(end-1:end),'nv') 8 | X = [X '.nv']; 9 | end 10 | X = dlmread(X); 11 | end 12 | 13 | NVert = X(1); 14 | %fprintf('There are %d vertices ',NVert); 15 | v = X(2:NVert+1,:); 16 | NFace = X(NVert+2); 17 | %fprintf('and %d faces\n',NFace); 18 | f = X(NVert+3:NVert+3+(NFace-1),:); 19 | 20 | mesh.vertices = v; 21 | mesh.faces = f; -------------------------------------------------------------------------------- /Funcs/rw_edgenode.m: -------------------------------------------------------------------------------- 1 | function [edge,node] = rw_edgenode(name,rw,varargin) 2 | % Read / write (AAL) edge and node files from a matrix 3 | % 4 | % usage: 5 | % read: [edge,node] = rw_edgenode('name'); 6 | % write: rw_edgenode('savename','w',A) 7 | % 8 | % where A is connectivity matrix. 9 | % 10 | % To only write a subset of nodes / edges, see write_plot_node.m 11 | % AS 12 | 13 | if nargin < 2; rw = 'r' ; end 14 | 15 | switch rw 16 | case 'r'; 17 | [fp,f,e] = fileparts(name); 18 | if isempty(fp) 19 | node = dlmread([f '.node']); 20 | edge = dlmread([f '.edge']); 21 | else 22 | node = dlmread([fp '/' f '.node']); 23 | edge = dlmread([fp '/' f '.edge']); 24 | end 25 | 26 | case 'w'; 27 | A = varargin{1}; 28 | A(isnan(A)) = 0; 29 | conmat2nodes(A,name); 30 | end -------------------------------------------------------------------------------- /Funcs/slice2.m: -------------------------------------------------------------------------------- 1 | function slice2() 2 | % Take a figure with 1 axis and put it into a 2 subplots in a new figure. 3 | % 4 | % For brains (see atemplate). Rotates so three axes are L, R. 5 | % 6 | % AS17 7 | 8 | coloff; 9 | f_c = gcf; 10 | f = figure; 11 | a(1) = subplot(1,2,1); 12 | a(2) = subplot(1,2,2); 13 | 14 | axes_to_be_copied = findobj(f_c,'type','axes'); 15 | children = get(axes_to_be_copied,'children'); 16 | overlay = get(children{1}(end),'FaceVertexCData'); 17 | 18 | % set views: 19 | v{1} = [270 0]; % L 20 | v{2} = [90 0]; % R 21 | 22 | asp{1} = [3 5 3]; 23 | asp{2} = [3 5 3]; 24 | 25 | for k = 1:2 26 | this = a(k); 27 | for i = 1; 28 | stuff = handle2struct(children{i}); 29 | struct2handle(stuff,this); 30 | set(f,'currentaxes',this); 31 | camlight('headlight') 32 | set(gca,'visible','off'); 33 | end 34 | view(this,v{k}); 35 | pbaspect(asp{k}); 36 | end 37 | 38 | set(f, 'Position', [100, 100, 1800, 600]); 39 | 40 | for i = 1:2 41 | p = get(a(i), 'pos'); 42 | p(3) = p(3) + 0.1; 43 | set(a(i), 'pos', p); 44 | end 45 | 46 | 47 | -------------------------------------------------------------------------------- /Funcs/slice3.m: -------------------------------------------------------------------------------- 1 | function slice3() 2 | % Take a figure with 1 axis and put it into a 3 subplots in a new figure. 3 | % 4 | % For brains (see atemplate). Rotates so three axes are L, topo & R. 5 | % 6 | % AS17 7 | 8 | %coloff; 9 | f_c = gcf; 10 | f = figure; 11 | a(1) = subplot(1,3,1); 12 | a(2) = subplot(1,3,2); 13 | a(3) = subplot(1,3,3); 14 | 15 | axes_to_be_copied = findobj(f_c,'type','axes'); 16 | children = get(axes_to_be_copied,'children'); 17 | try 18 | overlay = get(children{1}(end),'FaceVertexCData'); 19 | catch 20 | overlay = get(children(end),'FaceVertexCData'); 21 | end 22 | 23 | % set views: 24 | v{1} = [270 0]; % L 25 | v{2} = [0 90]; % Topo 26 | v{3} = [90 0]; % R 27 | 28 | asp{1} = [2 3 2]; 29 | asp{2} = [1 1 1]; 30 | asp{3} = [2 3 2]; 31 | 32 | for k = 1:3 33 | this = a(k); 34 | if iscell(children) 35 | for i = 1; 36 | stuff = handle2struct(children{i}); 37 | struct2handle(stuff,this); 38 | set(f,'currentaxes',this); 39 | set(gca,'visible','off'); 40 | axis(gca,'image'); 41 | end 42 | else 43 | stuff = handle2struct(children); 44 | struct2handle(stuff,this); 45 | set(f,'currentaxes',this); 46 | set(gca,'visible','off'); 47 | axis(gca,'image'); 48 | end 49 | view(this,v{k}); 50 | pbaspect(asp{k}); 51 | end 52 | 53 | set(f, 'Position', [100, 100, 2300, 600]); 54 | 55 | for i = 1:3 56 | p = get(a(i), 'pos'); 57 | p(3) = p(3) + 0.1; 58 | set(a(i), 'pos', p); 59 | end 60 | 61 | 62 | -------------------------------------------------------------------------------- /Funcs/slice6.m: -------------------------------------------------------------------------------- 1 | function slice6() 2 | % Take a figure with 1 axis and put it into a 6 subplots in a new figure. 3 | % 4 | % For brains (see atemplate). 5 | % 6 | % Rotates so three axes are L, topo, R, back, bottom & front 7 | % 8 | % AS17 9 | 10 | %coloff; 11 | f_c = gcf; 12 | f = figure('Position', [622 195 1728 1139]); 13 | % a(1) = subplot(2,3,1,'align'); 14 | % a(2) = subplot(2,3,2,'align'); 15 | % a(3) = subplot(2,3,3,'align'); 16 | % a(4) = subplot(2,3,4,'align'); 17 | % a(5) = subplot(2,3,5,'align'); 18 | % a(6) = subplot(2,3,6,'align'); 19 | 20 | a(1) = subplot('position',[0 2 1 1]/4); ... [left bottom width height] 21 | a(2) = subplot('position',[1 2 1 1]/4); 22 | a(3) = subplot('position',[2 2 1 1]/4); 23 | a(4) = subplot('position',[0 1 1 1]/4); 24 | a(5) = subplot('position',[1 1 1 1]/4); 25 | a(6) = subplot('position',[2 1 1 1]/4); 26 | 27 | 28 | 29 | axes_to_be_copied = findobj(f_c,'type','axes'); 30 | children = get(axes_to_be_copied,'children'); 31 | try 32 | overlay = get(children{1}(end),'FaceVertexCData'); 33 | catch 34 | overlay = get(children(end),'FaceVertexCData'); 35 | end 36 | 37 | % set views: 38 | v{1} = [270 0]; % L 39 | v{2} = [0 90]; % Topo 40 | v{3} = [90 0]; % R 41 | v{4} = [0 0]; % back 42 | v{5} = [0 -90]; % bottom 43 | v{6} = [-180 0]; % front 44 | 45 | % set aspects: 46 | asp{1} = [2 3 2]; 47 | asp{2} = [2 3 2]; 48 | asp{3} = [2 3 2]; 49 | asp{4} = [2 3 2]; 50 | asp{5} = [2 3 2]; 51 | asp{6} = [2 3 2]; 52 | 53 | for k = 1:length(a) 54 | this = a(k); 55 | if iscell(children) 56 | for i = 1; 57 | stuff = handle2struct(children{i}); 58 | struct2handle(stuff,this); 59 | set(f,'currentaxes',this); 60 | set(gca,'visible','off'); 61 | axis(gca,'image'); 62 | end 63 | else 64 | stuff = handle2struct(children); 65 | struct2handle(stuff,this); 66 | set(f,'currentaxes',this); 67 | set(gca,'visible','off'); 68 | axis(gca,'image'); 69 | end 70 | view(this,v{k}); 71 | pbaspect(asp{k}); 72 | axis(gca,'image'); 73 | end 74 | 75 | for i = 1:length(a) 76 | p = get(a(i), 'pos'); 77 | p(3) = p(3) + 0.1; 78 | set(a(i), 'pos', p); 79 | end 80 | -------------------------------------------------------------------------------- /Funcs/spherefit.m: -------------------------------------------------------------------------------- 1 | function [Centre,AA,B] = spherefit(X) 2 | 3 | AA = [mean(X(:,1).*(X(:,1)-mean(X(:,1)))), ... 4 | 2*mean(X(:,1).*(X(:,2)-mean(X(:,2)))), ... 5 | 2*mean(X(:,1).*(X(:,3)-mean(X(:,3)))); ... 6 | 0, ... 7 | mean(X(:,2).*(X(:,2)-mean(X(:,2)))), ... 8 | 2*mean(X(:,2).*(X(:,3)-mean(X(:,3)))); ... 9 | 0, ... 10 | 0, ... 11 | mean(X(:,3).*(X(:,3)-mean(X(:,3))))]; 12 | A = AA+AA.'; 13 | B = [mean((X(:,1).^2+X(:,2).^2+X(:,3).^2).*(X(:,1)-mean(X(:,1))));... 14 | mean((X(:,1).^2+X(:,2).^2+X(:,3).^2).*(X(:,2)-mean(X(:,2))));... 15 | mean((X(:,1).^2+X(:,2).^2+X(:,3).^2).*(X(:,3)-mean(X(:,3))))]; 16 | Centre=(A\B).'; 17 | end -------------------------------------------------------------------------------- /Funcs/spherefit.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Funcs/spherefit.mexa64 -------------------------------------------------------------------------------- /Funcs/spm/spm_mesh_adjacency.m: -------------------------------------------------------------------------------- 1 | function A = spm_mesh_adjacency(F) 2 | % Compute the adjacency matrix of a triangle mesh 3 | % FORMAT A = spm_mesh_adjacency(F) 4 | % F - a [fx3] faces array or a patch structure 5 | % 6 | % A - adjacency matrix as a sparse [vxv] array 7 | %__________________________________________________________________________ 8 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 9 | 10 | % Guillaume Flandin 11 | % $Id: spm_mesh_adjacency.m 4035 2010-08-05 18:54:32Z guillaume $ 12 | 13 | if ~isnumeric(F) && isfield(F,'vertices') 14 | N = size(F.vertices,1); 15 | F = double(F.faces); 16 | A = sparse([F(:,1); F(:,1); F(:,2); F(:,2); F(:,3); F(:,3)], ... 17 | [F(:,2); F(:,3); F(:,1); F(:,3); F(:,1); F(:,2)], 1, N, N); 18 | else 19 | if isstruct(F), F = F.faces; end 20 | F = double(F); 21 | A = sparse([F(:,1); F(:,1); F(:,2); F(:,2); F(:,3); F(:,3)], ... 22 | [F(:,2); F(:,3); F(:,1); F(:,3); F(:,1); F(:,2)], 1); 23 | end 24 | 25 | A = double(A > 0); 26 | -------------------------------------------------------------------------------- /Funcs/spm/spm_mesh_distmtx.m: -------------------------------------------------------------------------------- 1 | function D = spm_mesh_distmtx(M,order) 2 | % Compute the distance matrix of a triangle mesh 3 | % FORMAT D = spm_mesh_distmtx(M,order) 4 | % M - patch structure 5 | % order - 0: adjacency matrix 6 | % 1: first order distance matrix [default] 7 | % 2: second order distance matrix 8 | % 9 | % D - distance matrix 10 | %__________________________________________________________________________ 11 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 12 | 13 | % Guillaume Flandin 14 | % $Id: spm_mesh_distmtx.m 4035 2010-08-05 18:54:32Z guillaume $ 15 | 16 | if nargin < 2, order = 1; end 17 | 18 | if order > 2, error('High order distance matrix not handled.'); end 19 | 20 | %-Adjacency matrix 21 | %-------------------------------------------------------------------------- 22 | if order == 0 23 | D = spm_mesh_adjacency(M); 24 | return; 25 | end 26 | 27 | %-First order distance matrix 28 | %-------------------------------------------------------------------------- 29 | if isstruct(M) && ~isa(M.faces,'double') 30 | M.faces = double(M.faces); 31 | elseif isa(M,'gifti') 32 | M = export(M,'patch'); 33 | M.faces = double(M.faces); 34 | end 35 | d = M.vertices(M.faces(:,[1 2 3]),:) - M.vertices(M.faces(:,[2 3 1]),:); 36 | 37 | D = sparse([M.faces(:,1); M.faces(:,2); M.faces(:,3)], ... 38 | [M.faces(:,2); M.faces(:,3); M.faces(:,1)], sqrt(sum(d.^2, 2))); 39 | 40 | D = (D + D')/2; 41 | 42 | if order == 1, return; end 43 | 44 | %-Second order distance matrix 45 | %-------------------------------------------------------------------------- 46 | D2 = D; 47 | for i=1:size(M.vertices,1) 48 | a = find(D2(i,:)); 49 | [b,c] = find(D2(a,:)); 50 | D(i,c) = D(i,a(b)) + diag(D(a(b),c))'; 51 | D(c,i) = D(i,c)'; 52 | end 53 | -------------------------------------------------------------------------------- /Funcs/spm/spm_unvec.m: -------------------------------------------------------------------------------- 1 | function [varargout] = spm_unvec(vX,varargin) 2 | % Unvectorise a vectorised array - a compiled routine 3 | % FORMAT [varargout] = spm_unvec(vX,varargin) 4 | % varargin - numeric, cell or structure array 5 | % vX - spm_vec(X) 6 | % 7 | % i.e. X = spm_unvec(spm_vec(X),X) 8 | % [X1,X2,...] = spm_unvec(spm_vec(X1,X2,...),X1,X2,...) 9 | % 10 | % See spm_vec 11 | %__________________________________________________________________________ 12 | % Copyright (C) 2005-2014 Wellcome Trust Centre for Neuroimaging 13 | 14 | % Karl Friston 15 | % $Id: spm_unvec.m 6238 2014-10-13 09:38:23Z karl $ 16 | 17 | 18 | %error('spm_unvec.c not compiled - see Makefile') 19 | 20 | % deal to multiple outputs if necessary 21 | %-------------------------------------------------------------------------- 22 | if nargout > 1 23 | varargout = spm_unvec(vX,varargin); 24 | return 25 | end 26 | if numel(varargin) == 1 27 | X = varargin{1}; 28 | else 29 | X = varargin; 30 | end 31 | 32 | % check vX is numeric 33 | %-------------------------------------------------------------------------- 34 | if ~(isnumeric(vX) || islogical(vX)) 35 | vX = spm_vec(vX); 36 | end 37 | 38 | 39 | % reshape numerical arrays 40 | %-------------------------------------------------------------------------- 41 | if isnumeric(X) || islogical(X) 42 | if ndims(X) > 2 43 | X(:) = full(vX); 44 | else 45 | X(:) = vX; 46 | end 47 | varargout = {X}; 48 | return 49 | end 50 | 51 | % fill in structure arrays 52 | %-------------------------------------------------------------------------- 53 | if isstruct(X) 54 | f = fieldnames(X); 55 | for i = 1:numel(f) 56 | c = {X.(f{i})}; 57 | if isnumeric(c) 58 | n = numel(c); 59 | else 60 | n = spm_length(c); 61 | end 62 | c = spm_unvec(vX(1:n),c); 63 | [X.(f{i})] = deal(c{:}); 64 | vX = vX(n + 1:end); 65 | end 66 | varargout = {X}; 67 | return 68 | end 69 | 70 | % fill in cell arrays 71 | %-------------------------------------------------------------------------- 72 | if iscell(X) 73 | for i = 1:numel(X) 74 | if isnumeric(X{i}) 75 | n = numel(X{i}); 76 | else 77 | n = spm_length(X{i}); 78 | end 79 | X{i} = spm_unvec(vX(1:n),X{i}); 80 | vX = vX(n + 1:end); 81 | end 82 | varargout = {X}; 83 | return 84 | end 85 | 86 | % else 87 | %-------------------------------------------------------------------------- 88 | X = []; 89 | varargout = {X}; 90 | -------------------------------------------------------------------------------- /Funcs/spm/spm_vec.m: -------------------------------------------------------------------------------- 1 | function [vX] = spm_vec(X,varargin) 2 | % Vectorise a numeric, cell or structure array - a compiled routine 3 | % FORMAT [vX] = spm_vec(X) 4 | % X - numeric, cell or stucture array[s] 5 | % vX - vec(X) 6 | % 7 | % See spm_unvec 8 | %__________________________________________________________________________ 9 | % 10 | % e.g.: 11 | % spm_vec({eye(2) 3}) = [1 0 0 1 3]' 12 | %__________________________________________________________________________ 13 | % Copyright (C) 2005-2013 Wellcome Trust Centre for Neuroimaging 14 | 15 | % Karl Friston 16 | % $Id: spm_vec.m 6110 2014-07-21 09:36:13Z karl $ 17 | 18 | 19 | %error('spm_vec.c not compiled - see Makefile') 20 | 21 | % initialise X and vX 22 | %-------------------------------------------------------------------------- 23 | if nargin > 1 24 | X = [{X},varargin]; 25 | end 26 | 27 | 28 | % vectorise numerical arrays 29 | %-------------------------------------------------------------------------- 30 | if isnumeric(X) 31 | vX = X(:); 32 | 33 | % vectorise logical arrays 34 | %-------------------------------------------------------------------------- 35 | elseif islogical(X) 36 | vX = X(:); 37 | 38 | % vectorise structure into cell arrays 39 | %-------------------------------------------------------------------------- 40 | elseif isstruct(X) 41 | vX = []; 42 | f = fieldnames(X); 43 | X = X(:); 44 | for i = 1:numel(f) 45 | vX = cat(1,vX,spm_vec({X.(f{i})})); 46 | end 47 | 48 | % vectorise cells into numerical arrays 49 | %-------------------------------------------------------------------------- 50 | elseif iscell(X) 51 | vX = []; 52 | for i = 1:numel(X) 53 | vX = cat(1,vX,spm_vec(X{i})); 54 | end 55 | else 56 | vX = []; 57 | end 58 | -------------------------------------------------------------------------------- /Funcs/spm_mesh_adjacency.m: -------------------------------------------------------------------------------- 1 | function A = spm_mesh_adjacency(F) 2 | % Compute the adjacency matrix of a triangle mesh 3 | % FORMAT A = spm_mesh_adjacency(F) 4 | % F - a [fx3] faces array or a patch structure 5 | % 6 | % A - adjacency matrix as a sparse [vxv] array 7 | %__________________________________________________________________________ 8 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 9 | 10 | % Guillaume Flandin 11 | % $Id: spm_mesh_adjacency.m 4035 2010-08-05 18:54:32Z guillaume $ 12 | 13 | if ~isnumeric(F) && isfield(F,'vertices') 14 | N = size(F.vertices,1); 15 | F = double(F.faces); 16 | A = sparse([F(:,1); F(:,1); F(:,2); F(:,2); F(:,3); F(:,3)], ... 17 | [F(:,2); F(:,3); F(:,1); F(:,3); F(:,1); F(:,2)], 1, N, N); 18 | else 19 | if isstruct(F), F = F.faces; end 20 | F = double(F); 21 | A = sparse([F(:,1); F(:,1); F(:,2); F(:,2); F(:,3); F(:,3)], ... 22 | [F(:,2); F(:,3); F(:,1); F(:,3); F(:,1); F(:,2)], 1); 23 | end 24 | 25 | A = double(A > 0); 26 | -------------------------------------------------------------------------------- /Funcs/spm_mesh_clusters.m: -------------------------------------------------------------------------------- 1 | function [C, N] = spm_mesh_clusters(M,T) 2 | % Label connected components of surface mesh data 3 | % FORMAT [C, N] = spm_mesh_clusters(M,T) 4 | % M - a [mx3] faces array or a patch structure 5 | % T - a [nx1] data vector (using NaNs or logicals), n = #vertices 6 | % 7 | % C - a [nx1] vector of cluster indices 8 | % N - a [px1] size of connected components {in vertices} 9 | %__________________________________________________________________________ 10 | % Copyright (C) 2010-2012 Wellcome Trust Centre for Neuroimaging 11 | 12 | % Guillaume Flandin 13 | % $Id: spm_mesh_clusters.m 5065 2012-11-16 20:00:21Z guillaume $ 14 | 15 | 16 | %-Input parameters 17 | %-------------------------------------------------------------------------- 18 | if ~islogical(T) 19 | T = ~isnan(T); 20 | end 21 | 22 | %-Compute the (reduced) adjacency matrix 23 | %-------------------------------------------------------------------------- 24 | A = spm_mesh_adjacency(M); 25 | A = A + speye(size(A)); 26 | A(~T,:) = []; 27 | A(:,~T) = []; 28 | 29 | %-And perform Dulmage-Mendelsohn decomposition to find connected components 30 | %-------------------------------------------------------------------------- 31 | [p,q,r] = dmperm(A); 32 | N = diff(r); 33 | CC = zeros(size(A,1),1); 34 | for i=1:length(r)-1 35 | CC(p(r(i):r(i+1)-1)) = i; 36 | end 37 | C = NaN(numel(T),1); 38 | C(T) = CC; 39 | 40 | %-Sort connected component labels according to their size 41 | %-------------------------------------------------------------------------- 42 | [N,ni] = sort(N(:), 1, 'descend'); 43 | [ni,ni] = sort(ni); 44 | C(T) = ni(C(T)); 45 | -------------------------------------------------------------------------------- /Funcs/spm_mesh_distmtx.m: -------------------------------------------------------------------------------- 1 | function D = spm_mesh_distmtx(M,order) 2 | % Compute the distance matrix of a triangle mesh 3 | % FORMAT D = spm_mesh_distmtx(M,order) 4 | % M - patch structure 5 | % order - 0: adjacency matrix 6 | % 1: first order distance matrix [default] 7 | % 2: second order distance matrix 8 | % 9 | % D - distance matrix 10 | %__________________________________________________________________________ 11 | % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging 12 | 13 | % Guillaume Flandin 14 | % $Id: spm_mesh_distmtx.m 4035 2010-08-05 18:54:32Z guillaume $ 15 | 16 | if nargin < 2, order = 1; end 17 | 18 | if order > 2, error('High order distance matrix not handled.'); end 19 | 20 | %-Adjacency matrix 21 | %-------------------------------------------------------------------------- 22 | if order == 0 23 | D = spm_mesh_adjacency(M); 24 | return; 25 | end 26 | 27 | %-First order distance matrix 28 | %-------------------------------------------------------------------------- 29 | if isstruct(M) && ~isa(M.faces,'double') 30 | M.faces = double(M.faces); 31 | elseif isa(M,'gifti') 32 | M = export(M,'patch'); 33 | M.faces = double(M.faces); 34 | end 35 | d = M.vertices(M.faces(:,[1 2 3]),:) - M.vertices(M.faces(:,[2 3 1]),:); 36 | 37 | D = sparse([M.faces(:,1); M.faces(:,2); M.faces(:,3)], ... 38 | [M.faces(:,2); M.faces(:,3); M.faces(:,1)], sqrt(sum(d.^2, 2))); 39 | 40 | D = (D + D')/2; 41 | 42 | if order == 1, return; end 43 | 44 | %-Second order distance matrix 45 | %-------------------------------------------------------------------------- 46 | D2 = D; 47 | for i=1:size(M.vertices,1) 48 | a = find(D2(i,:)); 49 | [b,c] = find(D2(a,:)); 50 | D(i,c) = D(i,a(b)) + diag(D(a(b),c))'; 51 | D(c,i) = D(i,c)'; 52 | end 53 | -------------------------------------------------------------------------------- /Funcs/spm_mesh_utils.m: -------------------------------------------------------------------------------- 1 | function varargout = spm_mesh_utils(action,varargin) 2 | % A gateway function for surface mesh-related compiled algorithms 3 | % 4 | % FORMAT [N, D] = spm_mesh_utils('neighbours',A) 5 | % Return an array of first-order neighbours given an adjacency matrix 6 | % 7 | % FORMAT D = spm_mesh_utils('dijkstra',N,D,i,dmax) 8 | % Compute geodesic distance on a triangular mesh using Dijkstra algorith 9 | % 10 | % FORMAT V = spm_mesh_utils('volume',M) 11 | % Compute the volume of a closed surface mesh 12 | %__________________________________________________________________________ 13 | % Copyright (C) 2010 Wellcome Trust Centre for Neuroimaging 14 | 15 | % Guillaume Flandin 16 | % $Id: spm_mesh_utils.m 4081 2010-10-07 14:04:44Z guillaume $ 17 | 18 | %-This is merely the help file for the compiled routine 19 | error('spm_mesh_utils.c not compiled - see Makefile') -------------------------------------------------------------------------------- /Funcs/spm_mesh_utils.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Funcs/spm_mesh_utils.mexa64 -------------------------------------------------------------------------------- /Funcs/spm_mesh_utils.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Funcs/spm_mesh_utils.mexmaci64 -------------------------------------------------------------------------------- /Funcs/spm_mesh_utils.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Funcs/spm_mesh_utils.mexw32 -------------------------------------------------------------------------------- /Funcs/spm_mesh_utils.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/Funcs/spm_mesh_utils.mexw64 -------------------------------------------------------------------------------- /Funcs/ug.m: -------------------------------------------------------------------------------- 1 | function out = ug(mesh) 2 | % un-gifti object: convert gifti to struct 3 | 4 | out = struct; 5 | out.vertices = mesh.vertices; 6 | out.faces = mesh.faces; -------------------------------------------------------------------------------- /Funcs/volumise_points.m: -------------------------------------------------------------------------------- 1 | function vol = volumise_points(v,L) 2 | % 3 | % vol = volumise_points(v,[L]) 4 | % 5 | % convert nx3 matrix, v, of 3D points to a 3D volume. 6 | % optionally include functional value, L, for each point - must be length n 7 | % 8 | % 9 | % AS 10 | 11 | dv = v; 12 | 13 | if nargin < 2 || isempty(L) 14 | L = ones(length(v),1); 15 | end 16 | 17 | vol = zeros( (max(dv) - min(dv))+1 ); 18 | ndv = (min(dv))-1; 19 | 20 | for i = 1:length(dv) 21 | if L(i) ~= 0 22 | a(1) = L(i); 23 | a(2) = vol(dv(i,1)-ndv(1),dv(i,2)-ndv(2),dv(i,3)-ndv(3)); 24 | [~,I] = max(abs(a)); 25 | vol(dv(i,1)-ndv(1),dv(i,2)-ndv(2),dv(i,3)-ndv(3)) = ... 26 | vol(dv(i,1)-ndv(1),dv(i,2)-ndv(2),dv(i,3)-ndv(3)) + a(I); 27 | end 28 | end -------------------------------------------------------------------------------- /NEW_RENDER_OVERLAY_FieldTrip_EXAMPLE.m: -------------------------------------------------------------------------------- 1 | % Example Rendering Overlays..... 2 | 3 | load New_AALROI_6mm.mat % sourcemodel 4 | load SaveVolumeTstats.mat % file containing 'Plotstat': vector length(5061) 5 | 6 | projmeth = 'raycast'; 7 | 8 | % Just render PlotStat as colours onto the brain (no curvature) 9 | afigure; 10 | D = atemplate('mesh','def1','overlay', PlotStat,... 11 | 'sourcemodel',template_sourcemodel.pos,... 12 | 'method',projmeth); 13 | 14 | axis equal; 15 | caxis([-3 3]); 16 | colormap(cmocean('balance')); 17 | 18 | % Check it against a 3d scatter with overlay of the original positions: 19 | pp = template_sourcemodel.pos; 20 | figure,scatter3(pp(:,1),pp(:,2),pp(:,3),90,PlotStat,'filled'); 21 | view([0 90]); 22 | 23 | 24 | % OR WITH CURVATURE & COLORBAR ALSO, USING EXPLICIT THRESH: 25 | %------------------------------------------------------------ 26 | afigure; 27 | D = atemplate('mesh','def4','inflate','overlay',{'curvature' PlotStat},'sourcemodel',template_sourcemodel.pos,... 28 | 'method',projmeth,'thresh',3);axis equal; 29 | 30 | aJointColorbar(D); % BUT, CAXIS WONT WORK... :( 31 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-dinky 2 | title: MeshAAL 3 | -------------------------------------------------------------------------------- /aJointColorbar.m: -------------------------------------------------------------------------------- 1 | function aJointColorbar(D) 2 | % Generate a colorbar when... 3 | % ... you've used atemplate to generate a mesh overlay that has both 4 | % grayscale curvature and coloured function overlay values. It does this by 5 | % generating a long colormap that is grayscale for the first 256 parts, 6 | % then colour for the latter 256. 7 | % 8 | % The problem is that it means the default colourbar values are gibberish, 9 | % so this function corrects them. 10 | % 11 | % Input is the structure outputted by atemplate. 12 | % 13 | % AS 14 | 15 | % Find the axes 16 | axes(D.mesh.h.Parent); 17 | colorbar; 18 | 19 | % the actual colorbar values 20 | cbv = D.overlay.colbar_values; 21 | 22 | % get the colorbar of the parent axes of the mesh plot 23 | cb = get(D.mesh.h.Parent,'colorbar'); 24 | 25 | % flip the colour part of the bar 26 | set(cb, 'YDir', 'reverse' ); 27 | set(cb, 'ylim', [1 256]); 28 | 29 | % now generate some tickmarks ONLY for the color portion of the bar 30 | points = round(linspace(1,256,11)); 31 | cb.Ticks = points; 32 | vals = flipud( cbv(256+points) ); 33 | vals = vals - vals(6); 34 | vals(1:5)= -flipud(vals(7:end)); % correct rounding error 35 | 36 | cb.TickLabels = vals; -------------------------------------------------------------------------------- /another_example_overlay.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | figure, 4 | 5 | load('example_aal90_data','M') 6 | load DenseAAL.mat 7 | load pastelmap 8 | 9 | D = atemplate('mesh','def6','sourcemodel',{v vi},'overlay',M,'nocolbar'); 10 | 11 | colormap(map) 12 | 13 | D.mesh.h.LineStyle = 'none'; 14 | D.mesh.h.FaceAlpha=.4; 15 | D.mesh.h.AmbientStrength=.8; 16 | 17 | D.overlay.cb.CLim = [-2.5 3.5]; -------------------------------------------------------------------------------- /figs/DualRotate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/DualRotate.gif -------------------------------------------------------------------------------- /figs/ExampleMeshRotate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/ExampleMeshRotate.gif -------------------------------------------------------------------------------- /figs/Example_HemiNetOverlayNodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/Example_HemiNetOverlayNodes.png -------------------------------------------------------------------------------- /figs/FillHolesExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/FillHolesExample.png -------------------------------------------------------------------------------- /figs/NewCurvOverlay1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/NewCurvOverlay1.gif -------------------------------------------------------------------------------- /figs/NewSourceMeshExampleFig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/NewSourceMeshExampleFig.png -------------------------------------------------------------------------------- /figs/NodePowOnSurface.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/NodePowOnSurface.gif -------------------------------------------------------------------------------- /figs/V1_RenderRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/V1_RenderRight.png -------------------------------------------------------------------------------- /figs/VideoExample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/VideoExample.gif -------------------------------------------------------------------------------- /figs/VisGammaExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/VisGammaExample.png -------------------------------------------------------------------------------- /figs/peaks_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/figs/peaks_1.png -------------------------------------------------------------------------------- /gui/SourceMeshGUI.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/gui/SourceMeshGUI.fig -------------------------------------------------------------------------------- /lovelybrain_pasteljet_R.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/lovelybrain_pasteljet_R.png -------------------------------------------------------------------------------- /sourcemesh_fig1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/sourcemesh_fig1.png -------------------------------------------------------------------------------- /template/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/.DS_Store -------------------------------------------------------------------------------- /template/AAL116.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/AAL116.mat -------------------------------------------------------------------------------- /template/AAL90DefaultWeights.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/AAL90DefaultWeights.mat -------------------------------------------------------------------------------- /template/AAL_90_SOURCEMOD.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/AAL_90_SOURCEMOD.mat -------------------------------------------------------------------------------- /template/AAL_SOURCEMOD.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/AAL_SOURCEMOD.mat -------------------------------------------------------------------------------- /template/AAL_labels.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/AAL_labels.mat -------------------------------------------------------------------------------- /template/DefaultMeshCentroidsNormals.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/DefaultMeshCentroidsNormals.mat -------------------------------------------------------------------------------- /template/DenseAAL.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/DenseAAL.mat -------------------------------------------------------------------------------- /template/GenSourceBrainMapping.m: -------------------------------------------------------------------------------- 1 | function MeshVertexParcelID = GenSourceBrainMapping(m,v,vi) 2 | % Generate a pre-reigstered mapping from atlas vertices to brain surface 3 | % 4 | % m = mesh structure of brain surface (vertices and afces) 5 | % v = source/atlas positions (nx3) 6 | % vi = vector indexing which parcel/region each element of v belongs to 7 | % 8 | 9 | for i = 1:length(m.vertices) 10 | this = cdist(m.vertices(i,:),v); 11 | [~,I] = min(this); 12 | MeshVertexParcelID(i) = vi(I); 13 | end -------------------------------------------------------------------------------- /template/HCP250.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/HCP250.mat -------------------------------------------------------------------------------- /template/HCP360.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/HCP360.mat -------------------------------------------------------------------------------- /template/HOA_Cerebellum.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/HOA_Cerebellum.mat -------------------------------------------------------------------------------- /template/HarvOx.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/HarvOx.mat -------------------------------------------------------------------------------- /template/LightAAL.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/LightAAL.mat -------------------------------------------------------------------------------- /template/MakeSourceModelFromNifti.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | %mri = ft_read_mri('/Users/Alex/Dropbox/AAL_Template/AAL_Labels.nii'); 4 | %mri = ft_read_mri('HarvardOxford-cort-maxprob-thr50-1mm.nii'); 5 | mri = ft_read_mri('/Users/Alex/fieldtrip-master/template/atlas/brainnetome/BNA_MPM_thr25_1.25mm.nii'); 6 | ana = mri.anatomy; 7 | 8 | S = size(ana); 9 | x = 1:S(1); 10 | y = 1:S(2); 11 | z = 1:S(3); 12 | 13 | % Map volume to a Cartesian grid with indicies for vertex membership 14 | v = []; 15 | vi = []; 16 | VALS = unique(ana(:)); 17 | VALS(VALS==0)=[]; 18 | for i = 1:length(VALS) %48 %90 19 | If = find(ana==i); 20 | [xi,yi,zi] = ind2sub(S,If); 21 | 22 | newv = [x(xi); y(yi); z(zi)]'; 23 | 24 | if any(If(:)) 25 | 26 | % assess proximity of verts in this group 27 | t = delaunay(newv); t = t(:,1:3); 28 | [nf,nv] = reducepatch(maker(t,newv),0.2); 29 | %nf=t;nv=newv; 30 | newv = nv; 31 | newi = ones(length(newv),1)*i; 32 | 33 | v = [v; newv]; 34 | vi = [vi ; newi]; 35 | end 36 | end 37 | 38 | c = spherefit(v); 39 | v = v - repmat(c,[size(v,1),1]); 40 | 41 | % optionally compute face and recude using points_to_alphaShape 42 | [f,v,Ci] = points_to_alphashape(v); 43 | vi = vi(Ci); 44 | c = spherefit(v); 45 | v = v - repmat(c,[size(v,1),1]); 46 | 47 | % separate hemispheres if labelled the same in each hemisphere - e.g. the 48 | % HCP360/250 atlasses 49 | 50 | ui = unique(vi); 51 | for i = 1:length(ui) 52 | 53 | x = find(vi==ui(i)); 54 | 55 | L = find(v(x,1)<0); 56 | R = find(v(x,1)>0); 57 | 58 | % rename 59 | vi(x(L)) = i; 60 | vi(x(R)) = i + 180; 61 | end 62 | 63 | 64 | %save('~/code/MeshAAL/template/DenseAAL','v','vi') 65 | save('~/Dropbox/code/MeshAAL/template/HCP360','v','vi','f') 66 | 67 | % trisurf(f,v(:,1),v(:,2),v(:,3),'facevertexcdata',vi); 68 | % colormap(alexcmap); axis equal 69 | 70 | % lighter or sparser-version 71 | %------------------------------------------- 72 | mri = ft_read_mri('/Users/Alex/Dropbox/AAL_Template/AAL_Labels.nii'); 73 | ana = mri.anatomy; 74 | 75 | S = size(ana); 76 | x = 1:S(1); 77 | y = 1:S(2); 78 | z = 1:S(3); 79 | 80 | % Map volume to a Cartesian grid with indicies for vertex membership 81 | v = []; 82 | vi = []; 83 | for i = 1:90 84 | If = find(ana==i); 85 | [xi,yi,zi] = ind2sub(S,If); 86 | 87 | newv = [x(xi); y(yi); z(zi)]'; 88 | 89 | % assess proximity of verts in this group 90 | t = delaunay(newv); t = t(:,1:3); 91 | [nf,nv] = reducepatch(maker(t,newv),0.05); 92 | newv = nv; 93 | 94 | newi = ones(length(newv),1)*i; 95 | 96 | v = [v; newv]; 97 | vi = [vi ; newi]; 98 | end 99 | 100 | c = spherefit(v); 101 | v = v - repmat(c,[size(v,1),1]); 102 | 103 | save('~/code/MeshAAL/template/LightAAL','v','vi') -------------------------------------------------------------------------------- /template/MakeSourceModelFromNifti_AAL120.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | %mri = ft_read_mri('/Users/Alex/Dropbox/AAL_Template/AAL_Labels.nii'); 4 | mri = ft_read_atlas('~/fieldtrip-master/template/atlas/aal/ROI_MNI_V4.nii'); 5 | ana = mri.tissue; 6 | 7 | S = size(ana); 8 | x = 1:S(1); 9 | y = 1:S(2); 10 | z = 1:S(3); 11 | 12 | % Map volume to a Cartesian grid with indicies for vertex membership 13 | v = []; 14 | vi = []; 15 | 16 | ID = unique(ana(:)); 17 | 18 | for i = 1:length(ID) %90 19 | if ID(i) > 0 20 | If = find(ana==ID(i)); 21 | [xi,yi,zi] = ind2sub(S,If); 22 | 23 | newv = [x(xi); y(yi); z(zi)]'; 24 | 25 | if any(If(:)) 26 | 27 | % assess proximity of verts in this group 28 | t = delaunay(newv); t = t(:,1:3); 29 | [nf,nv] = reducepatch(maker(t,newv),0.1); 30 | newv = nv; 31 | newi = ones(length(newv),1)*i; 32 | 33 | v = [v; newv]; 34 | vi = [vi ; newi]; 35 | end 36 | end 37 | end 38 | 39 | c = spherefit(v); 40 | v = v - repmat(c,[size(v,1),1]); 41 | 42 | %save('~/code/MeshAAL/template/DenseAAL','v','vi') 43 | %save('~/code/MeshAAL/template/HarvOx','v','vi') 44 | labels = mri.tissuelabel'; 45 | save('~/code/MeshAAL/template/AAL120','v','vi','labels') 46 | 47 | -------------------------------------------------------------------------------- /template/MakeSourceModel_HarvOx_wCerebellum.m: -------------------------------------------------------------------------------- 1 | % Make a parcellation that uses Harvard-Oxford Cortical & AAL Cerebellar regions 2 | %------------------------------------------------------------------------------- 3 | 4 | AAL = load('AAL116.mat'); 5 | HOA = load('HarvOx.mat'); 6 | 7 | % coregister both points to MNI models so they're approx aligned: 8 | % register HarvOx to Cortex2 9 | % register AAL (with Cereb) to Cortex3 (with Cereb), both MNI 10 | figure;D = atemplate('mesh','def2','sourcemodel',HOA.v); 11 | HOA.v = D.sourcemodel.pos; close; 12 | 13 | figure;D = atemplate('mesh','def3','sourcemodel',AAL.v); 14 | AAL.v = D.sourcemodel.pos; close; 15 | 16 | 17 | 18 | Cereb = 91:116; 19 | CLab = AAL.labels(Cereb); 20 | C = []; 21 | VI = []; 22 | 23 | for j = 1:length(Cereb) 24 | i = find( AAL.vi == Cereb(j) ); 25 | C = [C ; AAL.v(i,:) ]; 26 | VI = [VI ; (i*0)+j ]; 27 | end 28 | 29 | 30 | % plot conbination of models on mesh: 31 | afigure;D = atemplate('mesh','def3'); 32 | 33 | % Harvard-Oxford cortex 34 | scatter3(HOA.v(:,1),HOA.v(:,2),HOA.v(:,3),'b','filled'); hold on; 35 | 36 | % AAL Cerebellum & Vermis 37 | scatter3(C(:,1),C(:,2),C(:,3),'r','filled'); 38 | 39 | % Combine model vertices and optimise alignment with MNI 40 | mixmodel = [HOA.v ; C ]; 41 | mixmodel_iv = [HOA.vi ; VI + max(HOA.vi)]; 42 | mixmodel_al = align_clouds_3d(D.mesh.vertices,mixmodel); 43 | 44 | % Now move each point to the closest mesh point 45 | D0 = cdist(mixmodel_al,D.mesh.vertices); 46 | 47 | for i = 1:size(D0,1) 48 | [~,p] = min(D0(i,:)); 49 | mixmodel_al_re(i,:) = D.mesh.vertices(p,:); 50 | end 51 | 52 | 53 | close all; 54 | 55 | v = mixmodel_al_re; 56 | vi = mixmodel_iv; 57 | 58 | % also keep a record of which vertices came from which model: 59 | v_source( 1:length(HOA.vi)) = 0; 60 | v_source( length(HOA.vi) + (1:length(VI)) ) = 1; 61 | 62 | Cort = v(v_source==0,:); 63 | Cere = v(v_source==1,:); 64 | 65 | % re-render aligned models: 66 | afigure;D = atemplate('mesh','def3'); hold on; 67 | 68 | scatter3(Cort(:,1),Cort(:,2),Cort(:,3),50,'b','filled'); 69 | scatter3(Cere(:,1),Cere(:,2),Cere(:,3),50,'r','filled'); 70 | 71 | % save it 72 | labels = [HOA.labels(:,2) ; CLab ]; 73 | save('/Users/Alex/code/MeshAAL/template/HOA_Cerebellum','v','vi','Cort','Cere','labels','v_source'); 74 | 75 | -------------------------------------------------------------------------------- /template/New_58cortical_AALROI_6mm.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/New_58cortical_AALROI_6mm.mat -------------------------------------------------------------------------------- /template/New_AALROI_6mm.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/New_AALROI_6mm.mat -------------------------------------------------------------------------------- /template/New_AALROI_Cortical78_6mm.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/New_AALROI_Cortical78_6mm.mat -------------------------------------------------------------------------------- /template/ROI_MNI_V4.nii: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/ROI_MNI_V4.nii -------------------------------------------------------------------------------- /template/SaveVolumeTstats.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/SaveVolumeTstats.mat -------------------------------------------------------------------------------- /template/SuperAAL.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/SuperAAL.mat -------------------------------------------------------------------------------- /template/aal38_labels.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/aal38_labels.mat -------------------------------------------------------------------------------- /template/alexcmap.m: -------------------------------------------------------------------------------- 1 | function map = alexcmap(m) 2 | 3 | [map2,map3,map4]=cubric_meg_palettes; 4 | 5 | map(:,1) = spm_vec([map3(:,1) map3(:,1)]'); 6 | map(:,2) = spm_vec([map3(:,2) map3(:,2)]'); 7 | map(:,3) = spm_vec([map3(:,3) map3(:,3)]'); 8 | 9 | if nargin > 0 10 | 11 | for i = 1:3 12 | %im(:,i) = interp1((1:256)-(256/2),map(:,i),(1:m)-(m/2),'cubic'); 13 | im(:,i) = resample(map(:,i),m,256); 14 | end 15 | map = im; 16 | map = max(min(round(map*100)/100,1),0); 17 | 18 | end 19 | -------------------------------------------------------------------------------- /template/alignclouds.m: -------------------------------------------------------------------------------- 1 | function v0 = alignclouds(v0,v) 2 | % 3 | % v0 = alignclouds(v0,v) 4 | % 5 | % 6 | 7 | v0 = centralise(v0) ; 8 | v0 = boxbound(v,v0); 9 | 10 | M = ones(10,1); 11 | 12 | f = @(M) p2pmap(v,v0*reshape(M(1:9),[3 3])*M(10)); 13 | 14 | %[X, fX, i] = PR_minimize(M, f, 1) 15 | 16 | end 17 | 18 | function e = p2pmap(v,v0) 19 | 20 | [IDX, D] = knnsearch(v,v0); 21 | e = norm(D); 22 | 23 | end 24 | 25 | function g = grid3(b,n) 26 | for i = 1:3 27 | g(:,i) = linspace(b(1,i),b(2,i),n); 28 | end 29 | end 30 | 31 | function v = centralise(v) 32 | 33 | v = v - repmat(spherefit(v),[size(v,1),1]); 34 | 35 | end 36 | 37 | function [v0,b] = boxbound(v,v0) 38 | 39 | b = [min(v);max(v)]; 40 | 41 | for i = 1:3 42 | v0(:,i) = rescale(v0(:,i),b(1,i),b(2,i)); 43 | end 44 | 45 | end 46 | 47 | function [vin,Ed] = dosphere(v) 48 | 49 | Bnd = [min(min(v)); max(max(v))]*1.1; 50 | Ed = cdist(v,spherefit(v)); 51 | v = v ./ [Ed/3 Ed/3 Ed/3]; 52 | for i = 1:3 53 | vin(:,i) = rescale(v(:,i),Bnd(1),Bnd(2)); 54 | end 55 | 56 | end 57 | 58 | function [Centre,A,B] = spherefit(X) 59 | % Fit sphere to centre of vertices, return centre points 60 | % 61 | % 62 | 63 | A = [mean(X(:,1).*(X(:,1)-mean(X(:,1)))), ... 64 | 2*mean(X(:,1).*(X(:,2)-mean(X(:,2)))), ... 65 | 2*mean(X(:,1).*(X(:,3)-mean(X(:,3)))); ... 66 | 0, ... 67 | mean(X(:,2).*(X(:,2)-mean(X(:,2)))), ... 68 | 2*mean(X(:,2).*(X(:,3)-mean(X(:,3)))); ... 69 | 0, ... 70 | 0, ... 71 | mean(X(:,3).*(X(:,3)-mean(X(:,3))))]; 72 | A = A+A.'; 73 | B = [mean((X(:,1).^2+X(:,2).^2+X(:,3).^2).*(X(:,1)-mean(X(:,1))));... 74 | mean((X(:,1).^2+X(:,2).^2+X(:,3).^2).*(X(:,2)-mean(X(:,2))));... 75 | mean((X(:,1).^2+X(:,2).^2+X(:,3).^2).*(X(:,3)-mean(X(:,3))))]; 76 | Centre=(A\B).'; 77 | end 78 | 79 | function [e0,g] = dfdx(f,x) 80 | % simple 1-step finite difference routine for compute partial gradients 81 | 82 | e0 = f(x); 83 | k = exp(-8); 84 | 85 | for i = 1:length(x) 86 | dx = x; 87 | dx(i) = dx(i) + k; 88 | g(i) = (f(dx) - e0) ./ k; 89 | end 90 | g=g'; 91 | 92 | end -------------------------------------------------------------------------------- /template/atlasdata_patchplot.m: -------------------------------------------------------------------------------- 1 | % script to make plots using patch when using a triangulated source model 2 | % and functional overlay values 3 | 4 | p = patch('faces',HCP360.f,'vertices',HCP360.v); 5 | p.FaceVertexCData = o; 6 | shading interp; 7 | camlight left; camlight right; 8 | lighting gouraud; 9 | material dull 10 | view(3) -------------------------------------------------------------------------------- /template/avg152PD.nii: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/avg152PD.nii -------------------------------------------------------------------------------- /template/compute_reduced_indices.m: -------------------------------------------------------------------------------- 1 | 2 | function indices = compute_reduced_indices(before, after) 3 | % Compute the retained functional (colour) values after patch reduction 4 | % 5 | 6 | indices = zeros(length(after), 1); 7 | for i = 1:length(after) 8 | dotprods = (before * after(i, :)') ./ sqrt(sum(before.^2, 2)); 9 | [~, indices(i)] = max(dotprods); 10 | end 11 | end -------------------------------------------------------------------------------- /template/example_aal90_data.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/example_aal90_data.mat -------------------------------------------------------------------------------- /template/ft_mesh_mni.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/ft_mesh_mni.mat -------------------------------------------------------------------------------- /template/map_pos_to_aal.m: -------------------------------------------------------------------------------- 1 | function [pos,labs] = map_pos_to_aal(pos,vi) 2 | 3 | 4 | aal = load('SuperAAL.mat'); 5 | labels = load('AAL_labels.mat'); 6 | 7 | % alginmane and scaling 8 | pos = alignclouds(pos,aal.v); 9 | 10 | % now find centre of each parcel in input data 11 | roi = unique(vi); 12 | 13 | for i = 1:length(roi) 14 | I = find(vi == roi(i)); 15 | 16 | verts = pos(I,:); 17 | 18 | C = spherefit(verts); 19 | 20 | if any(isnan(C)) || any(isinf(C)) 21 | C = mean(verts,1); 22 | end 23 | 24 | npos(i,:) = C; 25 | end 26 | 27 | %npos = npos - (pinv(cdist(npos,npos))*npos); 28 | 29 | for i = 1:size(npos,1) 30 | 31 | % closest in euclidean space 32 | [~,ind] = min(cdist(npos(i,:),aal.v)); 33 | 34 | labs{i} = labels.labels{aal.vi(ind)}; 35 | 36 | 37 | end 38 | 39 | % output 40 | L = {... 41 | 'Cuneus_L' 42 | 'Cuneus_R' 43 | 'Occipital_Inf_L' 44 | 'Occipital_Inf_R' 45 | 'Postcentral_L' 46 | 'Postcentral_R' 47 | 'Rolandic_Oper_L' 48 | 'Rolandic_Oper_R' 49 | 'Precentral_L' 50 | 'Precentral_R' 51 | 'Parietal_Sup_L' 52 | 'Parietal_Sup_R' 53 | 'Temporal_Sup_L' %13 54 | 'Temporal_Sup_R' %14 55 | 'Angular_L' 56 | 'Angular_R' 57 | 'Temporal_Pole_Sup_L' 58 | 'Temporal_Pole_Sup_R' 59 | 'Paracentral_Lobule_L' 60 | 'Paracentral_Lobule_R' 61 | 'Parietal_Inf_L' 62 | 'Parietal_Inf_R' 63 | 'Frontal_Inf_Tri_L' 64 | 'Frontal_Inf_Tri_R' 65 | 'Occipital_Mid_L' 66 | 'Occipital_Mid_R' 67 | 'Frontal_Mid_L' 68 | 'Frontal_Mid_R' 69 | 'Frontal_Sup_L' % 29 yes sup 70 | 'Frontal_Sup_R' % 30 71 | 'Frontal_Mid_Orb_L' 72 | 'Frontal_Mid_Orb_R' 73 | 'Temporal_Mid_L' % 33 74 | 'Temporal_Mid_R' % 34 75 | 'Frontal_Sup_Orb_L' % 35 76 | 'Frontal_Sup_Orb_R' % 36 77 | 'Cingulum_Post_L' 78 | 'Cingulum_Ant_L'}; -------------------------------------------------------------------------------- /template/mni152_2009.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/mni152_2009.mat -------------------------------------------------------------------------------- /template/pastelmap.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/pastelmap.mat -------------------------------------------------------------------------------- /template/points_to_alphashape.m: -------------------------------------------------------------------------------- 1 | function [f,nv,Ci] = points_to_alphashape(v) 2 | % given a nx3 vertex list, this function 3 | % 4 | % 1) triangulates faces using alphaShape which outperforms delaunay 5 | % 2) also does minor patch reduction on the fly 6 | % 3) computed indices of vertices retained from original list (Ci) 7 | % 8 | % [f,nv,Ci] = points_to_alphashape(v) 9 | % 10 | % AS 11 | 12 | tr = alphaShape(v); 13 | [f, nv] = boundaryFacets(tr); 14 | Ci = compute_reduced_indices(v,nv); -------------------------------------------------------------------------------- /template/quickscatter3.m: -------------------------------------------------------------------------------- 1 | function quickscatter3(v,varargin) 2 | 3 | if nargin == 1 4 | 5 | scatter3(v(:,1),v(:,2),v(:,3),100); 6 | 7 | else 8 | scatter3(v(:,1),v(:,2),v(:,3),100);hold on; 9 | for i = 1:length(varargin) 10 | vx = varargin{i}; 11 | scatter3(vx(:,1),vx(:,2),vx(:,3),100);hold on; 12 | end 13 | 14 | end -------------------------------------------------------------------------------- /template/standard_bem.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandershaw4/SourceMesh/410f5c82c9a34454f9146ca6e45c28b5e7e48c90/template/standard_bem.mat -------------------------------------------------------------------------------- /template/vec2meshvals.m: -------------------------------------------------------------------------------- 1 | function y=vec2meshvals(vi,vals) 2 | % 3 | % 4 | % 5 | 6 | y = vi*0; 7 | for i = 1:length(vals) 8 | f = find(vi==i); 9 | y(f) = vals(i); 10 | end --------------------------------------------------------------------------------