├── logo.png ├── CorrICC.fig ├── Overlap.fig ├── Summary.fig ├── design.fig ├── fmreli.fig ├── Corr2ROI.fig ├── SplitHalf.fig ├── Contrast_Def.fig ├── Similarity.fig ├── atlas ├── atlas.nii ├── labels.mat ├── labels_yeo.mat ├── batch_reslice_atlas.mat └── atlas.txt ├── design_ana.fig ├── scripts_templates ├── id.mat ├── temp_img.nii ├── template_3D-4D.mat ├── expand_nii_scan.m ├── rri_zoom_menu.m ├── abk_4Dto3D.m ├── similarity_subjectwise.m ├── save_nii_ext.m ├── unxform_nii.m ├── license.txt ├── ICC_computation.m ├── fmri_clust_filt.m ├── similarity_figure.m ├── verify_nii_ext.m ├── rri_orient.m ├── bipolar.m ├── rri_xhair.m ├── mat_into_hdr.m ├── get_nii_frame.m ├── flip_lr.m ├── load_nii_ext.m ├── load_untouch_nii.m ├── rri_file_menu.m ├── bresenham_line3d.m ├── load_nii.m ├── load_untouch_header_only.m ├── make_ana.m ├── save_untouch_nii.m ├── collapse_nii_scan.m ├── rri_orient_ui.m ├── make_nii.m ├── load_untouch0_nii_hdr.m ├── extra_nii_hdr.m ├── reslice_nii.m ├── save_untouch_nii_hdr.m ├── load_untouch_nii_hdr.m ├── save_nii.m ├── save_untouch0_nii_hdr.m ├── save_nii_hdr.m └── load_nii_hdr.m ├── colormaps ├── license.txt └── fake_parula.m ├── fmreli.m ├── README.md └── Summary.m /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/logo.png -------------------------------------------------------------------------------- /CorrICC.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/CorrICC.fig -------------------------------------------------------------------------------- /Overlap.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/Overlap.fig -------------------------------------------------------------------------------- /Summary.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/Summary.fig -------------------------------------------------------------------------------- /design.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/design.fig -------------------------------------------------------------------------------- /fmreli.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/fmreli.fig -------------------------------------------------------------------------------- /Corr2ROI.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/Corr2ROI.fig -------------------------------------------------------------------------------- /SplitHalf.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/SplitHalf.fig -------------------------------------------------------------------------------- /Contrast_Def.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/Contrast_Def.fig -------------------------------------------------------------------------------- /Similarity.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/Similarity.fig -------------------------------------------------------------------------------- /atlas/atlas.nii: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/atlas/atlas.nii -------------------------------------------------------------------------------- /atlas/labels.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/atlas/labels.mat -------------------------------------------------------------------------------- /design_ana.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/design_ana.fig -------------------------------------------------------------------------------- /atlas/labels_yeo.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/atlas/labels_yeo.mat -------------------------------------------------------------------------------- /scripts_templates/id.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/scripts_templates/id.mat -------------------------------------------------------------------------------- /atlas/batch_reslice_atlas.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/atlas/batch_reslice_atlas.mat -------------------------------------------------------------------------------- /scripts_templates/temp_img.nii: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/scripts_templates/temp_img.nii -------------------------------------------------------------------------------- /scripts_templates/template_3D-4D.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkroemer/reliability/HEAD/scripts_templates/template_3D-4D.mat -------------------------------------------------------------------------------- /scripts_templates/expand_nii_scan.m: -------------------------------------------------------------------------------- 1 | % Expand a multiple-scan NIFTI file into multiple single-scan NIFTI files 2 | % 3 | % Usage: expand_nii_scan(multi_scan_filename, [img_idx], [path_to_save]) 4 | % 5 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 6 | % 7 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 8 | % 9 | function expand_nii_scan(filename, img_idx, newpath) 10 | 11 | if ~exist('newpath','var'), newpath = pwd; end 12 | if ~exist('img_idx','var'), img_idx = 1:get_nii_frame(filename); end 13 | 14 | for i=img_idx 15 | nii_i = load_untouch_nii(filename, i); 16 | 17 | fn = [nii_i.fileprefix '_' sprintf('%04d',i)]; 18 | pnfn = fullfile(newpath, fn); 19 | 20 | save_untouch_nii(nii_i, pnfn); 21 | end 22 | 23 | return; % expand_nii_scan 24 | 25 | -------------------------------------------------------------------------------- /scripts_templates/rri_zoom_menu.m: -------------------------------------------------------------------------------- 1 | % Imbed a zoom menu to any figure. 2 | % 3 | % Usage: rri_zoom_menu(fig); 4 | % 5 | 6 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 7 | % 8 | %-------------------------------------------------------------------- 9 | function menu_hdl = rri_zoom_menu(fig) 10 | 11 | if isnumeric(fig) 12 | menu_hdl = uimenu('Parent',fig, ... 13 | 'Label','Zoom on', ... 14 | 'Userdata', 1, ... 15 | 'Callback','rri_zoom_menu(''zoom'');'); 16 | 17 | return; 18 | end 19 | 20 | zoom_on_state = get(gcbo,'Userdata'); 21 | 22 | if (zoom_on_state == 1) 23 | zoom on; 24 | set(gcbo,'Userdata',0,'Label','Zoom off'); 25 | set(gcbf,'pointer','crosshair'); 26 | else 27 | zoom off; 28 | set(gcbo,'Userdata',1,'Label','Zoom on'); 29 | set(gcbf,'pointer','arrow'); 30 | end 31 | 32 | return % rri_zoom_menu 33 | 34 | -------------------------------------------------------------------------------- /scripts_templates/abk_4Dto3D.m: -------------------------------------------------------------------------------- 1 | function abk_4Dto3D(fname,idx) 2 | % function abk_4Dto3D(fname) 3 | % 4 | % Splits a 4D nifti file into a series of 3D nifti files. 5 | % Needs SPM functions to work. If input file is fdata.nii, 6 | % the output files will have filenames like fdata_001.nii, 7 | % fdata_002.nii, etc. 8 | 9 | if (nargin < 1) 10 | [fname,sts] = spm_select; 11 | if (sts == 0) 12 | fprintf('abk_4Dto3D: Operation cancelled.\n'); 13 | return; 14 | end 15 | end 16 | 17 | vol = spm_vol(fname); 18 | img = spm_read_vols(vol); 19 | sz = size(img); 20 | 21 | tvol = vol(1); 22 | tvol = rmfield(tvol,'private'); 23 | tvol.descrip = 'generated by abk_4Dto3D.m'; 24 | 25 | [dn,fn,ext] = fileparts(fname); 26 | 27 | for ctr=1:length(idx) 28 | tvol.fname = sprintf('%s%stemplate_3D%s',dn,filesep,ext); 29 | fprintf('Writing %s\n',tvol.fname); 30 | spm_write_vol(tvol,img(:,:,:,idx(ctr))); 31 | end 32 | fprintf('done.\n'); 33 | end -------------------------------------------------------------------------------- /scripts_templates/similarity_subjectwise.m: -------------------------------------------------------------------------------- 1 | function out = similarity_subjectwise(nr_subj,TempFourD1,TempFourD2,use_roi,sim2mean,r_roi_ind) 2 | 3 | if sim2mean == 1 4 | mean_temp = []; 5 | mean_temp = mean(TempFourD2,4); 6 | mean_temp = mean_temp(~isnan(mean_temp)); 7 | end; 8 | 9 | for i = 1:nr_subj 10 | for j = 1:nr_subj 11 | temp_nii_1 = []; 12 | temp_nii_2 = []; 13 | temp_nii_1 = TempFourD1(:,:,:,i); 14 | temp_nii_2 = TempFourD2(:,:,:,j); 15 | if use_roi == 1 16 | temp_nii_1(~r_roi_ind) = 0; 17 | temp_nii_2(~r_roi_ind) = 0; 18 | end; 19 | temp_1 = temp_nii_1(~isnan(temp_nii_1)); 20 | temp_2 = temp_nii_2(~isnan(temp_nii_2)); 21 | 22 | [out.r, out.p] = corrcoef([temp_1,temp_2]); 23 | out.r_mat(i,j) = out.r(1,2); 24 | out.p_mat(i,j) = out.p(1,2); 25 | end; 26 | if sim2mean == 1 27 | [out.r, out.p] = corrcoef([temp_1,mean_temp]); 28 | out.r_mat(i,j+1) = out.r(1,2); 29 | out.p_mat(i,j+1) = out.p(1,2); 30 | end; 31 | end; -------------------------------------------------------------------------------- /scripts_templates/save_nii_ext.m: -------------------------------------------------------------------------------- 1 | % Save NIFTI header extension. 2 | % 3 | % Usage: save_nii_ext(ext, fid) 4 | % 5 | % ext - struct with NIFTI header extension fields. 6 | % 7 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 8 | % 9 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 10 | % 11 | function save_nii_ext(ext, fid) 12 | 13 | if ~exist('ext','var') | ~exist('fid','var') 14 | error('Usage: save_nii_ext(ext, fid)'); 15 | end 16 | 17 | if ~isfield(ext,'extension') | ~isfield(ext,'section') | ~isfield(ext,'num_ext') 18 | error('Wrong header extension'); 19 | end 20 | 21 | write_ext(ext, fid); 22 | 23 | return; % save_nii_ext 24 | 25 | 26 | %--------------------------------------------------------------------- 27 | function write_ext(ext, fid) 28 | 29 | fwrite(fid, ext.extension, 'uchar'); 30 | 31 | for i=1:ext.num_ext 32 | fwrite(fid, ext.section(i).esize, 'int32'); 33 | fwrite(fid, ext.section(i).ecode, 'int32'); 34 | fwrite(fid, ext.section(i).edata, 'uchar'); 35 | end 36 | 37 | return; % write_ext 38 | 39 | -------------------------------------------------------------------------------- /scripts_templates/unxform_nii.m: -------------------------------------------------------------------------------- 1 | % Undo the flipping and rotations performed by xform_nii; spit back only 2 | % the raw img data block. Initial cut will only deal with 3D volumes 3 | % strongly assume we have called xform_nii to write down the steps used 4 | % in xform_nii. 5 | % 6 | % Usage: a = load_nii('original_name'); 7 | % manipulate a.img to make array b; 8 | % 9 | % if you use unxform_nii to un-tranform the image (img) data 10 | % block, then nii.original.hdr is the corresponding header. 11 | % 12 | % nii.original.img = unxform_nii(a, b); 13 | % save_nii(nii.original,'newname'); 14 | % 15 | % Where, 'newname' is created with data in the same space as the 16 | % original_name data 17 | % 18 | % - Jeff Gunter, 26-JUN-06 19 | % 20 | function outblock = unxform_nii(nii, inblock) 21 | 22 | if isempty(nii.hdr.hist.rot_orient) 23 | outblock=inblock; 24 | else 25 | [dummy unrotate_orient] = sort(nii.hdr.hist.rot_orient); 26 | outblock = permute(inblock, unrotate_orient); 27 | end 28 | 29 | if ~isempty(nii.hdr.hist.flip_orient) 30 | flip_orient = nii.hdr.hist.flip_orient(unrotate_orient); 31 | 32 | for i = 1:3 33 | if flip_orient(i) 34 | outblock = flipdim(outblock, i); 35 | end 36 | end 37 | end; 38 | 39 | return; 40 | 41 | -------------------------------------------------------------------------------- /colormaps/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Ander Biguri 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 | -------------------------------------------------------------------------------- /scripts_templates/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009, Jimmy Shen 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 | -------------------------------------------------------------------------------- /scripts_templates/ICC_computation.m: -------------------------------------------------------------------------------- 1 | function [BMS,WMS,JMS,EMS] = ICC_computation(nr_subj,runs,data) 2 | 3 | nsamples=nr_subj*runs; 4 | grandmean=0; 5 | for sub=1:nr_subj, 6 | for sess=1:runs, 7 | grandmean= grandmean + data(sess,sub); 8 | end; 9 | end; 10 | grandmean=grandmean./nsamples; 11 | 12 | sessionmean=zeros(runs,1); 13 | for sess=1:runs 14 | for sub=1:nr_subj, 15 | sessionmean(sess) = sessionmean(sess) + data(sess,sub); 16 | end; 17 | sessionmean(sess)=sessionmean(sess)./nr_subj; 18 | end; 19 | 20 | subjmean=zeros(nr_subj,1); 21 | for sub=1:nr_subj 22 | for sess=1:runs 23 | subjmean(sub)=subjmean(sub) + data(sess,sub); 24 | end 25 | subjmean(sub)=subjmean(sub)./runs; 26 | end 27 | 28 | % mean squares 29 | BMS=0; % between subject 30 | WMS=0; % within subject 31 | EMS=0; % error 32 | JMS=0; % session 33 | 34 | for sub=1:nr_subj, 35 | BMS = BMS + (subjmean(sub)-grandmean).^2; 36 | for sess=1:runs 37 | WMS = WMS + (data(sess,sub)-subjmean(sub)).^2; 38 | EMS = EMS + (data(sess,sub)-subjmean(sub)-sessionmean(sess)+grandmean).^2; 39 | end 40 | end; 41 | 42 | for sess=1:runs 43 | JMS= JMS + (sessionmean(sess)-grandmean).^2; 44 | end; 45 | 46 | %define the true value of the mean square. 47 | BMS= runs.*BMS./(nr_subj-1); 48 | WMS= WMS./(runs-1)./nr_subj; 49 | JMS= nr_subj.*JMS./(runs-1); 50 | EMS= EMS./(runs-1)./(nr_subj-1); 51 | -------------------------------------------------------------------------------- /scripts_templates/fmri_clust_filt.m: -------------------------------------------------------------------------------- 1 | function [Y,XYZ,C] = fmri_clust_filt(Y,k) 2 | % identification of voxel cluster size k in Y 3 | 4 | XYZ = {}; 5 | 6 | % Find all non-NaN or non-zero voxels in the volume 7 | if any(isnan(Y)) 8 | good_vox_idxs = find(~isnan(Y)); 9 | multiplier = NaN; 10 | else 11 | good_vox_idxs = find(Y); 12 | multiplier = 0; 13 | end 14 | 15 | fprintf('Finding clusters of size >=%d in %d good voxels\n', k, length(good_vox_idxs)); 16 | 17 | % Create an XYZ list 18 | [XYZ{1:3}] = ind2sub(size(Y),good_vox_idxs); 19 | XYZ = cat(2,XYZ{:})'; 20 | 21 | % Get a list of cluster memberships 22 | A = spm_clusters(XYZ); 23 | 24 | % Create a list of indices that exceed cluster threshold 25 | Q = []; 26 | C = []; 27 | nc = 0; 28 | for i = 1:max(A) 29 | j = find(A == i); 30 | if length(j) >= k 31 | Q = [Q j]; 32 | nc = nc+1; 33 | C(nc).size = length(j); 34 | C(nc).XYZ = XYZ(:,j); 35 | curr_good_idxs = good_vox_idxs(j); 36 | [C(nc).maxvoxval maxidxs] = max(Y(curr_good_idxs)); 37 | C(nc).maxvoxidx_in_vol = curr_good_idxs(maxidxs); 38 | C(nc).maxvoxidx_in_clust = find(Y(curr_good_idxs)==C(nc).maxvoxval); 39 | C(nc).voxidx_in_vol = good_vox_idxs(j); 40 | end 41 | end 42 | 43 | % Weed out voxels that didn't pass the threshold 44 | fprintf('Found %d voxels belonging to %d clusters\n', length(Q), nc); 45 | XYZ = XYZ(:,Q); 46 | good_vox_idxs = good_vox_idxs(Q); 47 | 48 | % Filter the data volume 49 | Y1 = zeros(size(Y))*multiplier; 50 | Y1(good_vox_idxs) = 1; 51 | 52 | Y = Y.*Y1; 53 | 54 | return -------------------------------------------------------------------------------- /scripts_templates/similarity_figure.m: -------------------------------------------------------------------------------- 1 | function [fig] = similarity_figure(r_mat,sim2mean,run1,run2,str) 2 | 3 | fig = figure; 4 | set(fig,'units','normalized','position',[0.25 0 0.50 1]); 5 | %color matrix 6 | subplot(2,2,1:2); 7 | imagesc(r_mat,[0,1]); 8 | colormap('inferno'); 9 | caxis([0,1]); 10 | colorbar; 11 | if sim2mean == 1 12 | xlabel(sprintf('subjects session %d (last column similarity to mean image)',run2)); 13 | else 14 | xlabel(sprintf('subjects session %d ',run2)); 15 | end; 16 | ylabel(sprintf('subjects session %d',run1)); 17 | name1 = sprintf('similarity-%s-%d-%d',str,run1,run2); 18 | title(name1); 19 | 20 | % histograms 21 | subplot(2,2,3); 22 | triu_r_mat = triu(r_mat,1); 23 | vec_off_diag_r_mat = triu_r_mat(triu_r_mat~=0); 24 | h1 = histogram(diag(r_mat)); 25 | hold on; 26 | h2 = histogram(vec_off_diag_r_mat); 27 | h1.Normalization = 'probability'; 28 | h1.BinWidth = 0.1; 29 | h2.Normalization = 'probability'; 30 | h2.BinWidth = 0.1; 31 | xlabel('similarity'); 32 | ylabel('frequency in percentage'); 33 | title(sprintf('histogram-%s-%d-%d',str,run1,run2)); 34 | 35 | 36 | % ecdf - densitiy plots 37 | subplot(2,2,4); 38 | [f,x,flo,fup]=ecdf(diag(r_mat),'bounds','on'); 39 | plot(x,f,'LineWidth',2,'Color','blue') 40 | hold on 41 | plot(x,flo,'LineWidth',1,'Color','blue','LineStyle','--') 42 | hold on 43 | plot(x,fup,'LineWidth',1,'Color','blue','LineStyle','--') 44 | hold on; 45 | clear x f flo fup 46 | [f,x,flo,fup]=ecdf(vec_off_diag_r_mat,'bounds','on'); 47 | plot(x,f,'LineWidth',2,'Color','red') 48 | hold on 49 | plot(x,flo,'LineWidth',1,'Color','red','LineStyle','--') 50 | hold on 51 | plot(x,fup,'LineWidth',1,'Color','red','LineStyle','--') 52 | title(sprintf('cumulative-density-%s-%d-%d',str,run1,run2)); 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /scripts_templates/verify_nii_ext.m: -------------------------------------------------------------------------------- 1 | % Verify NIFTI header extension to make sure that each extension section 2 | % must be an integer multiple of 16 byte long that includes the first 8 3 | % bytes of esize and ecode. If the length of extension section is not the 4 | % above mentioned case, edata should be padded with all 0. 5 | % 6 | % Usage: [ext, esize_total] = verify_nii_ext(ext) 7 | % 8 | % ext - Structure of NIFTI header extension, which includes num_ext, 9 | % and all the extended header sections in the header extension. 10 | % Each extended header section will have its esize, ecode, and 11 | % edata, where edata can be plain text, xml, or any raw data 12 | % that was saved in the extended header section. 13 | % 14 | % esize_total - Sum of all esize variable in all header sections. 15 | % 16 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 17 | % 18 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 19 | % 20 | function [ext, esize_total] = verify_nii_ext(ext) 21 | 22 | if ~isfield(ext, 'section') 23 | error('Incorrect NIFTI header extension structure.'); 24 | elseif ~isfield(ext, 'num_ext') 25 | ext.num_ext = length(ext.section); 26 | elseif ~isfield(ext, 'extension') 27 | ext.extension = [1 0 0 0]; 28 | end 29 | 30 | esize_total = 0; 31 | 32 | for i=1:ext.num_ext 33 | if ~isfield(ext.section(i), 'ecode') | ~isfield(ext.section(i), 'edata') 34 | error('Incorrect NIFTI header extension structure.'); 35 | end 36 | 37 | ext.section(i).esize = ceil((length(ext.section(i).edata)+8)/16)*16; 38 | ext.section(i).edata = ... 39 | [ext.section(i).edata ... 40 | zeros(1,ext.section(i).esize-length(ext.section(i).edata)-8)]; 41 | esize_total = esize_total + ext.section(i).esize; 42 | end 43 | 44 | return % verify_nii_ext 45 | 46 | -------------------------------------------------------------------------------- /scripts_templates/rri_orient.m: -------------------------------------------------------------------------------- 1 | % Convert image of different orientations to standard Analyze orientation 2 | % 3 | % Usage: nii = rri_orient(nii); 4 | 5 | % Jimmy Shen (jimmy@rotman-baycrest.on.ca), 26-APR-04 6 | %___________________________________________________________________ 7 | 8 | function [nii, orient, pattern] = rri_orient(nii, varargin) 9 | 10 | if nargin > 1 11 | pattern = varargin{1}; 12 | else 13 | pattern = []; 14 | end 15 | 16 | orient = [1 2 3]; 17 | dim = double(nii.hdr.dime.dim([2:4])); 18 | 19 | if ~isempty(pattern) & ~isequal(length(pattern), prod(dim)) 20 | return; 21 | end 22 | 23 | % get orient of the current image 24 | % 25 | orient = rri_orient_ui; 26 | pause(.1); 27 | 28 | % no need for conversion 29 | % 30 | if isequal(orient, [1 2 3]) 31 | return; 32 | end 33 | 34 | if isempty(pattern) 35 | pattern = 1:prod(dim); 36 | end 37 | 38 | pattern = reshape(pattern, dim); 39 | img = nii.img; 40 | 41 | % calculate after flip orient 42 | % 43 | rot_orient = mod(orient + 2, 3) + 1; 44 | 45 | % do flip: 46 | % 47 | flip_orient = orient - rot_orient; 48 | 49 | for i = 1:3 50 | if flip_orient(i) 51 | pattern = flipdim(pattern, i); 52 | img = flipdim(img, i); 53 | end 54 | end 55 | 56 | % get index of orient (do inverse) 57 | % 58 | [tmp rot_orient] = sort(rot_orient); 59 | 60 | % do rotation: 61 | % 62 | pattern = permute(pattern, rot_orient); 63 | img = permute(img, [rot_orient 4 5 6]); 64 | 65 | % rotate resolution, or 'dim' 66 | % 67 | new_dim = nii.hdr.dime.dim([2:4]); 68 | new_dim = new_dim(rot_orient); 69 | nii.hdr.dime.dim([2:4]) = new_dim; 70 | 71 | % rotate voxel_size, or 'pixdim' 72 | % 73 | tmp = nii.hdr.dime.pixdim([2:4]); 74 | tmp = tmp(rot_orient); 75 | nii.hdr.dime.pixdim([2:4]) = tmp; 76 | 77 | % re-calculate originator 78 | % 79 | tmp = nii.hdr.hist.originator([1:3]); 80 | tmp = tmp(rot_orient); 81 | flip_orient = flip_orient(rot_orient); 82 | 83 | for i = 1:3 84 | if flip_orient(i) & ~isequal(double(tmp(i)), 0) 85 | tmp(i) = int16(double(new_dim(i)) - double(tmp(i)) + 1); 86 | end 87 | end 88 | 89 | nii.hdr.hist.originator([1:3]) = tmp; 90 | 91 | nii.img = img; 92 | pattern = pattern(:); 93 | 94 | return; % rri_orient 95 | 96 | -------------------------------------------------------------------------------- /scripts_templates/bipolar.m: -------------------------------------------------------------------------------- 1 | %BIPOLAR returns an M-by-3 matrix containing a blue-red colormap, in 2 | % in which red stands for positive, blue stands for negative, 3 | % and white stands for 0. 4 | % 5 | % Usage: cmap = bipolar(M, lo, hi, contrast); or cmap = bipolar; 6 | % 7 | % cmap: output M-by-3 matrix for BIPOLAR colormap. 8 | % M: number of shades in the colormap. By default, it is the 9 | % same length as the current colormap. 10 | % lo: the lowest value to represent. 11 | % hi: the highest value to represent. 12 | % 13 | % Inspired from the LORETA PASCAL program: 14 | % http://www.unizh.ch/keyinst/NewLORETA 15 | % 16 | % jimmy@rotman-baycrest.on.ca 17 | % 18 | %---------------------------------------------------------------- 19 | function cmap = bipolar(M, lo, hi, contrast) 20 | 21 | if ~exist('contrast','var') 22 | contrast = 128; 23 | end 24 | 25 | if ~exist('lo','var') 26 | lo = -1; 27 | end 28 | 29 | if ~exist('hi','var') 30 | hi = 1; 31 | end 32 | 33 | if ~exist('M','var') 34 | cmap = colormap; 35 | M = size(cmap,1); 36 | end 37 | 38 | steepness = 10 ^ (1 - (contrast-1)/127); 39 | pos_infs = 1e-99; 40 | neg_infs = -1e-99; 41 | 42 | doubleredc = []; 43 | doublebluec = []; 44 | 45 | if lo >= 0 % all positive 46 | 47 | if lo == 0 48 | lo = pos_infs; 49 | end 50 | 51 | for i=linspace(hi/M, hi, M) 52 | t = exp(log(i/hi)*steepness); 53 | doubleredc = [doubleredc; [(1-t)+t,(1-t)+0,(1-t)+0]]; 54 | end 55 | 56 | cmap = doubleredc; 57 | 58 | elseif hi <= 0 % all negative 59 | 60 | if hi == 0 61 | hi = neg_infs; 62 | end 63 | 64 | for i=linspace(abs(lo)/M, abs(lo), M) 65 | t = exp(log(i/abs(lo))*steepness); 66 | doublebluec = [doublebluec; [(1-t)+0,(1-t)+0,(1-t)+t]]; 67 | end 68 | 69 | cmap = flipud(doublebluec); 70 | 71 | else 72 | 73 | if hi > abs(lo) 74 | maxc = hi; 75 | else 76 | maxc = abs(lo); 77 | end 78 | 79 | for i=linspace(maxc/M, hi, round(M*hi/(hi-lo))) 80 | t = exp(log(i/maxc)*steepness); 81 | doubleredc = [doubleredc; [(1-t)+t,(1-t)+0,(1-t)+0]]; 82 | end 83 | 84 | for i=linspace(maxc/M, abs(lo), round(M*abs(lo)/(hi-lo))) 85 | t = exp(log(i/maxc)*steepness); 86 | doublebluec = [doublebluec; [(1-t)+0,(1-t)+0,(1-t)+t]]; 87 | end 88 | 89 | cmap = [flipud(doublebluec); doubleredc]; 90 | 91 | end 92 | 93 | return; % bipolar 94 | 95 | -------------------------------------------------------------------------------- /scripts_templates/rri_xhair.m: -------------------------------------------------------------------------------- 1 | % rri_xhair: create a pair of full_cross_hair at point [x y] in 2 | % axes h_ax, and return xhair struct 3 | % 4 | % Usage: xhair = rri_xhair([x y], xhair, h_ax); 5 | % 6 | % If omit xhair, rri_xhair will create a pair of xhair; otherwise, 7 | % rri_xhair will update the xhair. If omit h_ax, current axes will 8 | % be used. 9 | % 10 | 11 | % 24-nov-2003 jimmy (jimmy@rotman-baycrest.on.ca) 12 | % 13 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | 15 | function xhair = rri_xhair(varargin) 16 | 17 | if nargin == 0 18 | error('Please enter a point position as first argument'); 19 | return; 20 | end 21 | 22 | if nargin > 0 23 | p = varargin{1}; 24 | 25 | if ~isnumeric(p) | length(p) ~= 2 26 | error('Invalid point position'); 27 | return; 28 | else 29 | xhair = []; 30 | end 31 | end 32 | 33 | if nargin > 1 34 | xhair = varargin{2}; 35 | 36 | if ~isempty(xhair) 37 | if ~isstruct(xhair) 38 | error('Invalid xhair struct'); 39 | return; 40 | elseif ~isfield(xhair,'lx') | ~isfield(xhair,'ly') 41 | error('Invalid xhair struct'); 42 | return; 43 | elseif ~ishandle(xhair.lx) | ~ishandle(xhair.ly) 44 | error('Invalid xhair struct'); 45 | return; 46 | end 47 | 48 | lx = xhair.lx; 49 | ly = xhair.ly; 50 | else 51 | lx = []; 52 | ly = []; 53 | end 54 | end 55 | 56 | if nargin > 2 57 | h_ax = varargin{3}; 58 | 59 | if ~ishandle(h_ax) 60 | error('Invalid axes handle'); 61 | return; 62 | elseif ~strcmp(lower(get(h_ax,'type')), 'axes') 63 | error('Invalid axes handle'); 64 | return; 65 | end 66 | else 67 | h_ax = gca; 68 | end 69 | 70 | x_range = get(h_ax,'xlim'); 71 | y_range = get(h_ax,'ylim'); 72 | 73 | if ~isempty(xhair) 74 | set(lx, 'ydata', [p(2) p(2)]); 75 | set(ly, 'xdata', [p(1) p(1)]); 76 | set(h_ax, 'selected', 'on'); 77 | set(h_ax, 'selected', 'off'); 78 | else 79 | figure(get(h_ax,'parent')); 80 | axes(h_ax); 81 | 82 | xhair.lx = line('xdata', x_range, 'ydata', [p(2) p(2)], ... 83 | 'zdata', [11 11], 'color', [1 0 0], 'hittest', 'off'); 84 | xhair.ly = line('xdata', [p(1) p(1)], 'ydata', y_range, ... 85 | 'zdata', [11 11], 'color', [1 0 0], 'hittest', 'off'); 86 | end 87 | 88 | set(h_ax,'xlim',x_range); 89 | set(h_ax,'ylim',y_range); 90 | 91 | return; 92 | 93 | -------------------------------------------------------------------------------- /scripts_templates/mat_into_hdr.m: -------------------------------------------------------------------------------- 1 | %MAT_INTO_HDR The old versions of SPM (any version before SPM5) store 2 | % an affine matrix of the SPM Reoriented image into a matlab file 3 | % (.mat extension). The file name of this SPM matlab file is the 4 | % same as the SPM Reoriented image file (.img/.hdr extension). 5 | % 6 | % This program will convert the ANALYZE 7.5 SPM Reoriented image 7 | % file into NIfTI format, and integrate the affine matrix in the 8 | % SPM matlab file into its header file (.hdr extension). 9 | % 10 | % WARNING: Before you run this program, please save the header 11 | % file (.hdr extension) into another file name or into another 12 | % folder location, because all header files (.hdr extension) 13 | % will be overwritten after they are converted into NIfTI 14 | % format. 15 | % 16 | % Usage: mat_into_hdr(filename); 17 | % 18 | % filename: file name(s) with .hdr or .mat file extension, like: 19 | % '*.hdr', or '*.mat', or a single .hdr or .mat file. 20 | % e.g. mat_into_hdr('T1.hdr') 21 | % mat_into_hdr('*.mat') 22 | % 23 | 24 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 25 | % 26 | %------------------------------------------------------------------------- 27 | function mat_into_hdr(files) 28 | 29 | pn = fileparts(files); 30 | file_lst = dir(files); 31 | file_lst = {file_lst.name}; 32 | file1 = file_lst{1}; 33 | [p n e]= fileparts(file1); 34 | 35 | for i=1:length(file_lst) 36 | [p n e]= fileparts(file_lst{i}); 37 | disp(['working on file ', num2str(i) ,' of ', num2str(length(file_lst)), ': ', n,e]); 38 | process=1; 39 | 40 | if isequal(e,'.hdr') 41 | mat=fullfile(pn, [n,'.mat']); 42 | hdr=fullfile(pn, file_lst{i}); 43 | 44 | if ~exist(mat,'file') 45 | warning(['Cannot find file "',mat , '". File "', n, e, '" will not be processed.']); 46 | process=0; 47 | end 48 | elseif isequal(e,'.mat') 49 | hdr=fullfile(pn, [n,'.hdr']); 50 | mat=fullfile(pn, file_lst{i}); 51 | 52 | if ~exist(hdr,'file') 53 | warning(['Can not find file "',hdr , '". File "', n, e, '" will not be processed.']); 54 | process=0; 55 | end 56 | else 57 | warning(['Input file must have .mat or .hdr extension. File "', n, e, '" will not be processed.']); 58 | process=0; 59 | end 60 | 61 | if process 62 | load(mat); 63 | R=M(1:3,1:3); 64 | T=M(1:3,4); 65 | T=R*ones(3,1)+T; 66 | M(1:3,4)=T; 67 | 68 | [h filetype fileprefix machine]=load_nii_hdr(hdr); 69 | h.hist.qform_code=0; 70 | h.hist.sform_code=1; 71 | h.hist.srow_x=M(1,:); 72 | h.hist.srow_y=M(2,:); 73 | h.hist.srow_z=M(3,:); 74 | h.hist.magic='ni1'; 75 | 76 | fid = fopen(hdr,'w',machine); 77 | save_nii_hdr(h,fid); 78 | fclose(fid); 79 | end 80 | end 81 | 82 | return; % mat_into_hdr 83 | 84 | -------------------------------------------------------------------------------- /scripts_templates/get_nii_frame.m: -------------------------------------------------------------------------------- 1 | % Return time frame of a NIFTI dataset. Support both *.nii and 2 | % *.hdr/*.img file extension. If file extension is not provided, 3 | % *.hdr/*.img will be used as default. 4 | % 5 | % It is a lightweighted "load_nii_hdr", and is equivalent to 6 | % hdr.dime.dim(5) 7 | % 8 | % Usage: [ total_scan ] = get_nii_frame(filename) 9 | % 10 | % filename - NIFTI file name. 11 | % 12 | % Returned values: 13 | % 14 | % total_scan - total number of image scans for the time frame 15 | % 16 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 17 | % 18 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 19 | % 20 | function [ total_scan ] = get_nii_frame(fileprefix) 21 | 22 | if ~exist('fileprefix','var'), 23 | error('Usage: [ hdr, fileprefix, machine ] = get_nii_frame(filename)'); 24 | end 25 | 26 | if ~exist('machine','var'), machine = 'ieee-le'; end 27 | 28 | new_ext = 0; 29 | 30 | if findstr('.nii',fileprefix) 31 | new_ext = 1; 32 | fileprefix = strrep(fileprefix,'.nii',''); 33 | end 34 | 35 | if findstr('.hdr',fileprefix) 36 | fileprefix = strrep(fileprefix,'.hdr',''); 37 | end 38 | 39 | if findstr('.img',fileprefix) 40 | fileprefix = strrep(fileprefix,'.img',''); 41 | end 42 | 43 | if new_ext 44 | fn = sprintf('%s.nii',fileprefix); 45 | 46 | if ~exist(fn) 47 | msg = sprintf('Cannot find file "%s.nii".', fileprefix); 48 | error(msg); 49 | end 50 | else 51 | fn = sprintf('%s.hdr',fileprefix); 52 | 53 | if ~exist(fn) 54 | msg = sprintf('Cannot find file "%s.hdr".', fileprefix); 55 | error(msg); 56 | end 57 | end 58 | 59 | fid = fopen(fn,'r',machine); 60 | 61 | if fid < 0, 62 | msg = sprintf('Cannot open file %s.',fn); 63 | error(msg); 64 | else 65 | hdr = read_header(fid); 66 | fclose(fid); 67 | end 68 | 69 | if hdr.sizeof_hdr ~= 348 70 | % first try reading the opposite endian to 'machine' 71 | switch machine, 72 | case 'ieee-le', machine = 'ieee-be'; 73 | case 'ieee-be', machine = 'ieee-le'; 74 | end 75 | 76 | fid = fopen(fn,'r',machine); 77 | 78 | if fid < 0, 79 | msg = sprintf('Cannot open file %s.',fn); 80 | error(msg); 81 | else 82 | hdr = read_header(fid); 83 | fclose(fid); 84 | end 85 | end 86 | 87 | if hdr.sizeof_hdr ~= 348 88 | % Now throw an error 89 | msg = sprintf('File "%s" is corrupted.',fn); 90 | error(msg); 91 | end 92 | 93 | total_scan = hdr.dim(5); 94 | 95 | return; % get_nii_frame 96 | 97 | 98 | %--------------------------------------------------------------------- 99 | function [ dsr ] = read_header(fid) 100 | 101 | fseek(fid,0,'bof'); 102 | dsr.sizeof_hdr = fread(fid,1,'int32')'; % should be 348! 103 | 104 | fseek(fid,40,'bof'); 105 | dsr.dim = fread(fid,8,'int16')'; 106 | 107 | return; % read_header 108 | 109 | -------------------------------------------------------------------------------- /colormaps/fake_parula.m: -------------------------------------------------------------------------------- 1 | function cm_data=fake_parula(m) 2 | 3 | cm = [[0.2081, 0.1663, 0.5292], 4 | [0.2116238095, 0.1897809524, 0.5776761905], 5 | [0.212252381, 0.2137714286, 0.6269714286], 6 | [0.2081, 0.2386, 0.6770857143], 7 | [0.1959047619, 0.2644571429, 0.7279], 8 | [0.1707285714, 0.2919380952, 0.779247619], 9 | [0.1252714286, 0.3242428571, 0.8302714286], 10 | [0.0591333333, 0.3598333333, 0.8683333333], 11 | [0.0116952381, 0.3875095238, 0.8819571429], 12 | [0.0059571429, 0.4086142857, 0.8828428571], 13 | [0.0165142857, 0.4266, 0.8786333333], 14 | [0.032852381, 0.4430428571, 0.8719571429], 15 | [0.0498142857, 0.4585714286, 0.8640571429], 16 | [0.0629333333, 0.4736904762, 0.8554380952], 17 | [0.0722666667, 0.4886666667, 0.8467], 18 | [0.0779428571, 0.5039857143, 0.8383714286], 19 | [0.079347619, 0.5200238095, 0.8311809524], 20 | [0.0749428571, 0.5375428571, 0.8262714286], 21 | [0.0640571429, 0.5569857143, 0.8239571429], 22 | [0.0487714286, 0.5772238095, 0.8228285714], 23 | [0.0343428571, 0.5965809524, 0.819852381], 24 | [0.0265, 0.6137, 0.8135], 25 | [0.0238904762, 0.6286619048, 0.8037619048], 26 | [0.0230904762, 0.6417857143, 0.7912666667], 27 | [0.0227714286, 0.6534857143, 0.7767571429], 28 | [0.0266619048, 0.6641952381, 0.7607190476], 29 | [0.0383714286, 0.6742714286, 0.743552381], 30 | [0.0589714286, 0.6837571429, 0.7253857143], 31 | [0.0843, 0.6928333333, 0.7061666667], 32 | [0.1132952381, 0.7015, 0.6858571429], 33 | [0.1452714286, 0.7097571429, 0.6646285714], 34 | [0.1801333333, 0.7176571429, 0.6424333333], 35 | [0.2178285714, 0.7250428571, 0.6192619048], 36 | [0.2586428571, 0.7317142857, 0.5954285714], 37 | [0.3021714286, 0.7376047619, 0.5711857143], 38 | [0.3481666667, 0.7424333333, 0.5472666667], 39 | [0.3952571429, 0.7459, 0.5244428571], 40 | [0.4420095238, 0.7480809524, 0.5033142857], 41 | [0.4871238095, 0.7490619048, 0.4839761905], 42 | [0.5300285714, 0.7491142857, 0.4661142857], 43 | [0.5708571429, 0.7485190476, 0.4493904762], 44 | [0.609852381, 0.7473142857, 0.4336857143], 45 | [0.6473, 0.7456, 0.4188], 46 | [0.6834190476, 0.7434761905, 0.4044333333], 47 | [0.7184095238, 0.7411333333, 0.3904761905], 48 | [0.7524857143, 0.7384, 0.3768142857], 49 | [0.7858428571, 0.7355666667, 0.3632714286], 50 | [0.8185047619, 0.7327333333, 0.3497904762], 51 | [0.8506571429, 0.7299, 0.3360285714], 52 | [0.8824333333, 0.7274333333, 0.3217], 53 | [0.9139333333, 0.7257857143, 0.3062761905], 54 | [0.9449571429, 0.7261142857, 0.2886428571], 55 | [0.9738952381, 0.7313952381, 0.266647619], 56 | [0.9937714286, 0.7454571429, 0.240347619], 57 | [0.9990428571, 0.7653142857, 0.2164142857], 58 | [0.9955333333, 0.7860571429, 0.196652381], 59 | [0.988, 0.8066, 0.1793666667], 60 | [0.9788571429, 0.8271428571, 0.1633142857], 61 | [0.9697, 0.8481380952, 0.147452381], 62 | [0.9625857143, 0.8705142857, 0.1309], 63 | [0.9588714286, 0.8949, 0.1132428571], 64 | [0.9598238095, 0.9218333333, 0.0948380952], 65 | [0.9661, 0.9514428571, 0.0755333333], 66 | [0.9763, 0.9831, 0.0538]]; 67 | 68 | if nargin < 1 69 | cm_data = cm; 70 | else 71 | hsv=rgb2hsv(cm); 72 | cm_data=interp1(linspace(0,1,size(cm,1)),hsv,linspace(0,1,m)); 73 | cm_data=hsv2rgb(cm_data); 74 | 75 | end 76 | end -------------------------------------------------------------------------------- /scripts_templates/flip_lr.m: -------------------------------------------------------------------------------- 1 | % When you load any ANALYZE or NIfTI file with 'load_nii.m', and view 2 | % it with 'view_nii.m', you may find that the image is L-R flipped. 3 | % This is because of the confusion of radiological and neurological 4 | % convention in the medical image before NIfTI format is adopted. You 5 | % can find more details from: 6 | % 7 | % http://www.rotman-baycrest.on.ca/~jimmy/UseANALYZE.htm 8 | % 9 | % Sometime, people even want to convert RAS (standard orientation) back 10 | % to LAS orientation to satisfy the legend programs or processes. This 11 | % program is only written for those purpose. So PLEASE BE VERY CAUTIOUS 12 | % WHEN USING THIS 'FLIP_LR.M' PROGRAM. 13 | % 14 | % With 'flip_lr.m', you can convert any ANALYZE or NIfTI (no matter 15 | % 3D or 4D) file to a flipped NIfTI file. This is implemented simply 16 | % by flipping the affine matrix in the NIfTI header. Since the L-R 17 | % orientation is determined there, so the image will be flipped. 18 | % 19 | % Usage: flip_lr(original_fn, flipped_fn, [old_RGB],[tolerance],[preferredForm]) 20 | % 21 | % original_fn - filename of the original ANALYZE or NIfTI (3D or 4D) file 22 | % 23 | % flipped_fn - filename of the L-R flipped NIfTI file 24 | % 25 | % old_RGB (optional) - a scale number to tell difference of new RGB24 26 | % from old RGB24. New RGB24 uses RGB triple sequentially for each 27 | % voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect 28 | % uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for 29 | % each slices. If the image that you view is garbled, try to set 30 | % old_RGB variable to 1 and try again, because it could be in 31 | % old RGB24. It will be set to 0, if it is default or empty. 32 | % 33 | % tolerance (optional) - distortion allowed for non-orthogonal rotation 34 | % or shearing in NIfTI affine matrix. It will be set to 0.1 (10%), 35 | % if it is default or empty. 36 | % 37 | % preferredForm (optional) - selects which transformation from voxels 38 | % to RAS coordinates; values are s,q,S,Q. Lower case s,q indicate 39 | % "prefer sform or qform, but use others if preferred not present". 40 | % Upper case indicate the program is forced to use the specificied 41 | % tranform or fail loading. 'preferredForm' will be 's', if it is 42 | % default or empty. - Jeff Gunter 43 | % 44 | % Example: flip_lr('avg152T1_LR_nifti.nii', 'flipped_lr.nii'); 45 | % flip_lr('avg152T1_RL_nifti.nii', 'flipped_rl.nii'); 46 | % 47 | % You will find that 'avg152T1_LR_nifti.nii' and 'avg152T1_RL_nifti.nii' 48 | % are the same, and 'flipped_lr.nii' and 'flipped_rl.nii' are also the 49 | % the same, but they are L-R flipped from 'avg152T1_*'. 50 | % 51 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 52 | % 53 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 54 | % 55 | function flip_lr(original_fn, flipped_fn, old_RGB, tolerance, preferredForm) 56 | 57 | if ~exist('original_fn','var') | ~exist('flipped_fn','var') 58 | error('Usage: flip_lr(original_fn, flipped_fn, [old_RGB],[tolerance])'); 59 | end 60 | 61 | if ~exist('old_RGB','var') | isempty(old_RGB) 62 | old_RGB = 0; 63 | end 64 | 65 | if ~exist('tolerance','var') | isempty(tolerance) 66 | tolerance = 0.1; 67 | end 68 | 69 | if ~exist('preferredForm','var') | isempty(preferredForm) 70 | preferredForm= 's'; % Jeff 71 | end 72 | 73 | nii = load_nii(original_fn, [], [], [], [], old_RGB, tolerance, preferredForm); 74 | M = diag(nii.hdr.dime.pixdim(2:5)); 75 | M(1:3,4) = -M(1:3,1:3)*(nii.hdr.hist.originator(1:3)-1)'; 76 | M(1,:) = -1*M(1,:); 77 | nii.hdr.hist.sform_code = 1; 78 | nii.hdr.hist.srow_x = M(1,:); 79 | nii.hdr.hist.srow_y = M(2,:); 80 | nii.hdr.hist.srow_z = M(3,:); 81 | save_nii(nii, flipped_fn); 82 | 83 | return; % flip_lr 84 | 85 | -------------------------------------------------------------------------------- /scripts_templates/load_nii_ext.m: -------------------------------------------------------------------------------- 1 | % Load NIFTI header extension after its header is loaded using load_nii_hdr. 2 | % 3 | % Usage: ext = load_nii_ext(filename) 4 | % 5 | % filename - NIFTI file name. 6 | % 7 | % Returned values: 8 | % 9 | % ext - Structure of NIFTI header extension, which includes num_ext, 10 | % and all the extended header sections in the header extension. 11 | % Each extended header section will have its esize, ecode, and 12 | % edata, where edata can be plain text, xml, or any raw data 13 | % that was saved in the extended header section. 14 | % 15 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 16 | % 17 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 18 | % 19 | function ext = load_nii_ext(fileprefix) 20 | 21 | if ~exist('fileprefix','var'), 22 | error('Usage: ext = load_nii_ext(filename)'); 23 | end 24 | 25 | machine = 'ieee-le'; 26 | new_ext = 0; 27 | 28 | if findstr('.nii',fileprefix) 29 | new_ext = 1; 30 | fileprefix = strrep(fileprefix,'.nii',''); 31 | end 32 | 33 | if findstr('.hdr',fileprefix) 34 | fileprefix = strrep(fileprefix,'.hdr',''); 35 | end 36 | 37 | if findstr('.img',fileprefix) 38 | fileprefix = strrep(fileprefix,'.img',''); 39 | end 40 | 41 | if new_ext 42 | fn = sprintf('%s.nii',fileprefix); 43 | 44 | if ~exist(fn) 45 | msg = sprintf('Cannot find file "%s.nii".', fileprefix); 46 | error(msg); 47 | end 48 | else 49 | fn = sprintf('%s.hdr',fileprefix); 50 | 51 | if ~exist(fn) 52 | msg = sprintf('Cannot find file "%s.hdr".', fileprefix); 53 | error(msg); 54 | end 55 | end 56 | 57 | fid = fopen(fn,'r',machine); 58 | vox_offset = 0; 59 | 60 | if fid < 0, 61 | msg = sprintf('Cannot open file %s.',fn); 62 | error(msg); 63 | else 64 | fseek(fid,0,'bof'); 65 | 66 | if fread(fid,1,'int32') == 348 67 | if new_ext 68 | fseek(fid,108,'bof'); 69 | vox_offset = fread(fid,1,'float32'); 70 | end 71 | 72 | ext = read_extension(fid, vox_offset); 73 | fclose(fid); 74 | else 75 | fclose(fid); 76 | 77 | % first try reading the opposite endian to 'machine' 78 | % 79 | switch machine, 80 | case 'ieee-le', machine = 'ieee-be'; 81 | case 'ieee-be', machine = 'ieee-le'; 82 | end 83 | 84 | fid = fopen(fn,'r',machine); 85 | 86 | if fid < 0, 87 | msg = sprintf('Cannot open file %s.',fn); 88 | error(msg); 89 | else 90 | fseek(fid,0,'bof'); 91 | 92 | if fread(fid,1,'int32') ~= 348 93 | 94 | % Now throw an error 95 | % 96 | msg = sprintf('File "%s" is corrupted.',fn); 97 | error(msg); 98 | end 99 | 100 | if new_ext 101 | fseek(fid,108,'bof'); 102 | vox_offset = fread(fid,1,'float32'); 103 | end 104 | 105 | ext = read_extension(fid, vox_offset); 106 | fclose(fid); 107 | end 108 | end 109 | end 110 | 111 | return % load_nii_ext 112 | 113 | 114 | %--------------------------------------------------------------------- 115 | function ext = read_extension(fid, vox_offset) 116 | 117 | ext = []; 118 | 119 | if vox_offset 120 | end_of_ext = vox_offset; 121 | else 122 | fseek(fid, 0, 'eof'); 123 | end_of_ext = ftell(fid); 124 | end 125 | 126 | if end_of_ext > 352 127 | fseek(fid, 348, 'bof'); 128 | ext.extension = fread(fid,4)'; 129 | end 130 | 131 | if isempty(ext) | ext.extension(1) == 0 132 | ext = []; 133 | return; 134 | end 135 | 136 | i = 1; 137 | 138 | while(ftell(fid) < end_of_ext) 139 | ext.section(i).esize = fread(fid,1,'int32'); 140 | ext.section(i).ecode = fread(fid,1,'int32'); 141 | ext.section(i).edata = char(fread(fid,ext.section(i).esize-8)'); 142 | i = i + 1; 143 | end 144 | 145 | ext.num_ext = length(ext.section); 146 | 147 | return % read_extension 148 | 149 | -------------------------------------------------------------------------------- /scripts_templates/load_untouch_nii.m: -------------------------------------------------------------------------------- 1 | % Load NIFTI or ANALYZE dataset, but not applying any appropriate affine 2 | % geometric transform or voxel intensity scaling. 3 | % 4 | % Although according to NIFTI website, all those header information are 5 | % supposed to be applied to the loaded NIFTI image, there are some 6 | % situations that people do want to leave the original NIFTI header and 7 | % data untouched. They will probably just use MATLAB to do certain image 8 | % processing regardless of image orientation, and to save data back with 9 | % the same NIfTI header. 10 | % 11 | % Since this program is only served for those situations, please use it 12 | % together with "save_untouch_nii.m", and do not use "save_nii.m" or 13 | % "view_nii.m" for the data that is loaded by "load_untouch_nii.m". For 14 | % normal situation, you should use "load_nii.m" instead. 15 | % 16 | % Usage: nii = load_untouch_nii(filename, [img_idx], [dim5_idx], [dim6_idx], ... 17 | % [dim7_idx], [old_RGB], [slice_idx]) 18 | % 19 | % filename - NIFTI or ANALYZE file name. 20 | % 21 | % img_idx (optional) - a numerical array of image volume indices. 22 | % Only the specified volumes will be loaded. All available image 23 | % volumes will be loaded, if it is default or empty. 24 | % 25 | % The number of images scans can be obtained from get_nii_frame.m, 26 | % or simply: hdr.dime.dim(5). 27 | % 28 | % dim5_idx (optional) - a numerical array of 5th dimension indices. 29 | % Only the specified range will be loaded. All available range 30 | % will be loaded, if it is default or empty. 31 | % 32 | % dim6_idx (optional) - a numerical array of 6th dimension indices. 33 | % Only the specified range will be loaded. All available range 34 | % will be loaded, if it is default or empty. 35 | % 36 | % dim7_idx (optional) - a numerical array of 7th dimension indices. 37 | % Only the specified range will be loaded. All available range 38 | % will be loaded, if it is default or empty. 39 | % 40 | % old_RGB (optional) - a scale number to tell difference of new RGB24 41 | % from old RGB24. New RGB24 uses RGB triple sequentially for each 42 | % voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect 43 | % uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for 44 | % each slices. If the image that you view is garbled, try to set 45 | % old_RGB variable to 1 and try again, because it could be in 46 | % old RGB24. It will be set to 0, if it is default or empty. 47 | % 48 | % slice_idx (optional) - a numerical array of image slice indices. 49 | % Only the specified volumes will be loaded. All available image 50 | % slices will be loaded, if it is default or empty. 51 | % 52 | % Returned values: 53 | % 54 | % nii structure: 55 | % 56 | % hdr - struct with NIFTI header fields. 57 | % 58 | % filetype - Analyze format .hdr/.img (0); 59 | % NIFTI .hdr/.img (1); 60 | % NIFTI .nii (2) 61 | % 62 | % fileprefix - NIFTI filename without extension. 63 | % 64 | % machine - machine string variable. 65 | % 66 | % img - 3D (or 4D) matrix of NIFTI data. 67 | % 68 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 69 | % 70 | function nii = load_untouch_nii(filename, img_idx, dim5_idx, dim6_idx, dim7_idx, ... 71 | old_RGB, slice_idx) 72 | 73 | if ~exist('filename','var') 74 | error('Usage: nii = load_untouch_nii(filename, [img_idx], [dim5_idx], [dim6_idx], [dim7_idx], [old_RGB], [slice_idx])'); 75 | end 76 | 77 | if ~exist('img_idx','var') | isempty(img_idx) 78 | img_idx = []; 79 | end 80 | 81 | if ~exist('dim5_idx','var') | isempty(dim5_idx) 82 | dim5_idx = []; 83 | end 84 | 85 | if ~exist('dim6_idx','var') | isempty(dim6_idx) 86 | dim6_idx = []; 87 | end 88 | 89 | if ~exist('dim7_idx','var') | isempty(dim7_idx) 90 | dim7_idx = []; 91 | end 92 | 93 | if ~exist('old_RGB','var') | isempty(old_RGB) 94 | old_RGB = 0; 95 | end 96 | 97 | if ~exist('slice_idx','var') | isempty(slice_idx) 98 | slice_idx = []; 99 | end 100 | 101 | % Read the dataset header 102 | % 103 | [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); 104 | 105 | if nii.filetype == 0 106 | nii.hdr = load_untouch0_nii_hdr(nii.fileprefix,nii.machine); 107 | nii.ext = []; 108 | else 109 | nii.hdr = load_untouch_nii_hdr(nii.fileprefix,nii.machine,nii.filetype); 110 | 111 | % Read the header extension 112 | % 113 | nii.ext = load_nii_ext(filename); 114 | end 115 | 116 | % Read the dataset body 117 | % 118 | [nii.img,nii.hdr] = load_untouch_nii_img(nii.hdr,nii.filetype,nii.fileprefix, ... 119 | nii.machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB,slice_idx); 120 | 121 | % Perform some of sform/qform transform 122 | % 123 | % nii = xform_nii(nii, tolerance, preferredForm); 124 | 125 | nii.untouch = 1; 126 | 127 | return % load_untouch_nii 128 | 129 | -------------------------------------------------------------------------------- /scripts_templates/rri_file_menu.m: -------------------------------------------------------------------------------- 1 | % Imbed a file menu to any figure. If file menu exist, it will append 2 | % to the existing file menu. This file menu includes: Copy to clipboard, 3 | % print, save, close etc. 4 | % 5 | % Usage: rri_file_menu(fig); 6 | % 7 | % rri_file_menu(fig,0) means no 'Close' menu. 8 | % 9 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 10 | % 11 | %-------------------------------------------------------------------- 12 | 13 | function rri_file_menu(action, varargin) 14 | 15 | if isnumeric(action) 16 | fig = action; 17 | action = 'init'; 18 | end 19 | 20 | % clear the message line, 21 | % 22 | h = findobj(gcf,'Tag','MessageLine'); 23 | set(h,'String',''); 24 | 25 | if ~strcmp(action, 'init') 26 | set(gcbf, 'InvertHardcopy','off'); 27 | % set(gcbf, 'PaperPositionMode','auto'); 28 | end 29 | 30 | switch action 31 | case {'init'} 32 | if nargin > 1 33 | init(fig, 1); % no 'close' menu 34 | else 35 | init(fig, 0); 36 | end 37 | case {'print_fig'} 38 | printdlg(gcbf); 39 | case {'copy_fig'} 40 | copy_fig; 41 | case {'export_fig'} 42 | export_fig; 43 | end 44 | 45 | return % rri_file_menu 46 | 47 | 48 | %------------------------------------------------ 49 | % 50 | % Create (or append) File menu 51 | % 52 | function init(fig, no_close) 53 | 54 | % search for file menu 55 | % 56 | h_file = []; 57 | menuitems = findobj(fig, 'type', 'uimenu'); 58 | 59 | for i=1:length(menuitems) 60 | filelabel = get(menuitems(i),'label'); 61 | 62 | if strcmpi(strrep(filelabel, '&', ''), 'file') 63 | h_file = menuitems(i); 64 | break; 65 | end 66 | end 67 | 68 | set(fig, 'menubar', 'none'); 69 | 70 | if isempty(h_file) 71 | if isempty(menuitems) 72 | h_file = uimenu('parent', fig, 'label', 'File'); 73 | else 74 | h_file = uimenu('parent', fig, 'label', 'Copy Figure'); 75 | end 76 | 77 | h1 = uimenu('parent', h_file, ... 78 | 'callback','rri_file_menu(''copy_fig'');', ... 79 | 'label','Copy to Clipboard'); 80 | else 81 | h1 = uimenu('parent', h_file, ... 82 | 'callback','rri_file_menu(''copy_fig'');', ... 83 | 'separator','on', ... 84 | 'label','Copy to Clipboard'); 85 | end 86 | 87 | h2 = uimenu(h_file, ... 88 | 'callback','pagesetupdlg(gcbf);', ... 89 | 'label','Page Setup...'); 90 | 91 | h2 = uimenu(h_file, ... 92 | 'callback','printpreview(gcbf);', ... 93 | 'label','Print Preview...'); 94 | 95 | h2 = uimenu('parent', h_file, ... 96 | 'callback','printdlg(gcbf);', ... 97 | 'label','Print Figure ...'); 98 | 99 | h2 = uimenu('parent', h_file, ... 100 | 'callback','rri_file_menu(''export_fig'');', ... 101 | 'label','Save Figure ...'); 102 | 103 | arch = computer; 104 | if ~strcmpi(arch(1:2),'PC') 105 | set(h1, 'enable', 'off'); 106 | end 107 | 108 | if ~no_close 109 | h1 = uimenu('parent', h_file, ... 110 | 'callback','close(gcbf);', ... 111 | 'separator','on', ... 112 | 'label','Close'); 113 | end 114 | 115 | return; % init 116 | 117 | 118 | %------------------------------------------------ 119 | % 120 | % Copy to clipboard 121 | % 122 | function copy_fig 123 | 124 | arch = computer; 125 | if(~strcmpi(arch(1:2),'PC')) 126 | error('copy to clipboard can only be used under MS Windows'); 127 | return; 128 | end 129 | 130 | print -noui -dbitmap; 131 | 132 | return % copy_fig 133 | 134 | 135 | %------------------------------------------------ 136 | % 137 | % Save as an image file 138 | % 139 | function export_fig 140 | 141 | curr = pwd; 142 | if isempty(curr) 143 | curr = filesep; 144 | end 145 | 146 | [selected_file, selected_path] = rri_select_file(curr,'Save As'); 147 | 148 | if isempty(selected_file) | isempty(selected_path) 149 | return; 150 | end 151 | 152 | filename = [selected_path selected_file]; 153 | 154 | if(exist(filename,'file')==2) % file exist 155 | 156 | dlg_title = 'Confirm File Overwrite'; 157 | msg = ['File ',filename,' exist. Are you sure you want to overwrite it?']; 158 | response = questdlg(msg,dlg_title,'Yes','No','Yes'); 159 | 160 | if(strcmp(response,'No')) 161 | return; 162 | end 163 | 164 | end 165 | 166 | old_pointer = get(gcbf,'pointer'); 167 | set(gcbf,'pointer','watch'); 168 | 169 | try 170 | saveas(gcbf,filename); 171 | catch 172 | msg = 'ERROR: Cannot save file'; 173 | set(findobj(gcf,'Tag','MessageLine'),'String',msg); 174 | end 175 | 176 | set(gcbf,'pointer',old_pointer); 177 | 178 | return; % export_fig 179 | 180 | -------------------------------------------------------------------------------- /atlas/atlas.txt: -------------------------------------------------------------------------------- 1 | FP r (Frontal Pole Right) 2 | FP l (Frontal Pole Left) 3 | IC r (Insular Cortex Right) 4 | IC l (Insular Cortex Left) 5 | SFG r (Superior Frontal Gyrus Right) 6 | SFG l (Superior Frontal Gyrus Left) 7 | MidFG r (Middle Frontal Gyrus Right) 8 | MidFG l (Middle Frontal Gyrus Left) 9 | IFG tri r (Inferior Frontal Gyrus, pars triangularis Right) 10 | IFG tri l (Inferior Frontal Gyrus, pars triangularis Left) 11 | IFG oper r (Inferior Frontal Gyrus, pars opercularis Right) 12 | IFG oper l (Inferior Frontal Gyrus, pars opercularis Left) 13 | PreCG r (Precentral Gyrus Right) 14 | PreCG l (Precentral Gyrus Left) 15 | TP r (Temporal Pole Right) 16 | TP l (Temporal Pole Left) 17 | aSTG r (Superior Temporal Gyrus, anterior division Right) 18 | aSTG l (Superior Temporal Gyrus, anterior division Left) 19 | pSTG r (Superior Temporal Gyrus, posterior division Right) 20 | pSTG l (Superior Temporal Gyrus, posterior division Left) 21 | aMTG r (Middle Temporal Gyrus, anterior division Right) 22 | aMTG l (Middle Temporal Gyrus, anterior division Left) 23 | pMTG r (Middle Temporal Gyrus, posterior division Right) 24 | pMTG l (Middle Temporal Gyrus, posterior division Left) 25 | toMTG r (Middle Temporal Gyrus, temporooccipital part Right) 26 | toMTG l (Middle Temporal Gyrus, temporooccipital part Left) 27 | aITG r (Inferior Temporal Gyrus, anterior division Right) 28 | aITG l (Inferior Temporal Gyrus, anterior division Left) 29 | pITG r (Inferior Temporal Gyrus, posterior division Right) 30 | pITG l (Inferior Temporal Gyrus, posterior division Left) 31 | toITG r (Inferior Temporal Gyrus, temporooccipital part Right) 32 | toITG l (Inferior Temporal Gyrus, temporooccipital part Left) 33 | PostCG r (Postcentral Gyrus Right) 34 | PostCG l (Postcentral Gyrus Left) 35 | SPL r (Superior Parietal Lobule Right) 36 | SPL l (Superior Parietal Lobule Left) 37 | aSMG r (Supramarginal Gyrus, anterior division Right) 38 | aSMG l (Supramarginal Gyrus, anterior division Left) 39 | pSMG r (Supramarginal Gyrus, posterior division Right) 40 | pSMG l (Supramarginal Gyrus, posterior division Left) 41 | AG r (Angular Gyrus Right) 42 | AG l (Angular Gyrus Left) 43 | sLOC r (Lateral Occipital Cortex, superior division Right) 44 | sLOC l (Lateral Occipital Cortex, superior division Left) 45 | iLOC r (Lateral Occipital Cortex, inferior division Right) 46 | iLOC l (Lateral Occipital Cortex, inferior division Left) 47 | ICC r (Intracalcarine Cortex Right) 48 | ICC l (Intracalcarine Cortex Left) 49 | MedFC (Frontal Medial Cortex) 50 | SMA r (Juxtapositional Lobule Cortex -formerly Supplementary Motor Cortex- Right) 51 | SMA L(Juxtapositional Lobule Cortex -formerly Supplementary Motor Cortex- Left) 52 | SubCalC (Subcallosal Cortex) 53 | PaCiG r (Paracingulate Gyrus Right) 54 | PaCiG l (Paracingulate Gyrus Left) 55 | AC (Cingulate Gyrus, anterior division) 56 | PC (Cingulate Gyrus, posterior division) 57 | Precuneous (Precuneous Cortex) 58 | Cuneal r (Cuneal Cortex Right) 59 | Cuneal l (Cuneal Cortex Left) 60 | FOrb r (Frontal Orbital Cortex Right) 61 | FOrb l (Frontal Orbital Cortex Left) 62 | aPaHC r (Parahippocampal Gyrus, anterior division Right) 63 | aPaHC l (Parahippocampal Gyrus, anterior division Left) 64 | pPaHC r (Parahippocampal Gyrus, posterior division Right) 65 | pPaHC l (Parahippocampal Gyrus, posterior division Left) 66 | LG r (Lingual Gyrus Right) 67 | LG l (Lingual Gyrus Left) 68 | aTFusC r (Temporal Fusiform Cortex, anterior division Right) 69 | aTFusC l (Temporal Fusiform Cortex, anterior division Left) 70 | pTFusC r (Temporal Fusiform Cortex, posterior division Right) 71 | pTFusC l (Temporal Fusiform Cortex, posterior division Left) 72 | TOFusC r (Temporal Occipital Fusiform Cortex Right) 73 | TOFusC l (Temporal Occipital Fusiform Cortex Left) 74 | OFusG r (Occipital Fusiform Gyrus Right) 75 | OFusG l (Occipital Fusiform Gyrus Left) 76 | FO r (Frontal Operculum Cortex Right) 77 | FO l (Frontal Operculum Cortex Left) 78 | CO r (Central Opercular Cortex Right) 79 | CO l (Central Opercular Cortex Left) 80 | PO r (Parietal Operculum Cortex Right) 81 | PO l (Parietal Operculum Cortex Left) 82 | PP r (Planum Polare Right) 83 | PP l (Planum Polare Left) 84 | HG r (Heschl's Gyrus Right) 85 | HG l (Heschl's Gyrus Left) 86 | PT r (Planum Temporale Right) 87 | PT l (Planum Temporale Left) 88 | SCC r (Supracalcarine Cortex Right) 89 | SCC l (Supracalcarine Cortex Left) 90 | OP r (Occipital Pole Right) 91 | OP l (Occipital Pole Left) 92 | Thalamus r 93 | Thalamus l 94 | Caudate r 95 | Caudate l 96 | Putamen r 97 | Putamen l 98 | Pallidum r 99 | Pallidum l 100 | Hippocampus r 101 | Hippocampus l 102 | Amygdala r 103 | Amygdala l 104 | Accumbens r 105 | Accumbens l 106 | Brain-Stem 107 | Cereb1 l (Cerebelum Crus1 Left) 108 | Cereb1 r (Cerebelum Crus1 Right) 109 | Cereb2 l (Cerebelum Crus2 Left) 110 | Cereb2 r (Cerebelum Crus2 Right) 111 | Cereb3 l (Cerebelum 3 Left) 112 | Cereb3 r (Cerebelum 3 Right) 113 | Cereb45 l (Cerebelum 4 5 Left) 114 | Cereb45 r (Cerebelum 4 5 Right) 115 | Cereb6 l (Cerebelum 6 Left) 116 | Cereb6 r (Cerebelum 6 Right) 117 | Cereb7 l (Cerebelum 7b Left) 118 | Cereb7 r (Cerebelum 7b Right) 119 | Cereb8 l (Cerebelum 8 Left) 120 | Cereb8 r (Cerebelum 8 Right) 121 | Cereb9 l (Cerebelum 9 Left) 122 | Cereb9 r (Cerebelum 9 Right) 123 | Cereb10 l (Cerebelum 10 Left) 124 | Cereb10 r (Cerebelum 10 Right) 125 | Ver12 (Vermis 1 2) 126 | Ver3 (Vermis 3) 127 | Ver45 (Vermis 4 5) 128 | Ver6 (Vermis 6) 129 | Ver7 (Vermis 7) 130 | Ver8 (Vermis 8) 131 | Ver9 (Vermis 9) 132 | Ver10 (Vermis 10) -------------------------------------------------------------------------------- /scripts_templates/bresenham_line3d.m: -------------------------------------------------------------------------------- 1 | % Generate X Y Z coordinates of a 3D Bresenham's line between 2 | % two given points. 3 | % 4 | % A very useful application of this algorithm can be found in the 5 | % implementation of Fischer's Bresenham interpolation method in my 6 | % another program that can rotate three dimensional image volume 7 | % with an affine matrix: 8 | % http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21080 9 | % 10 | % Usage: [X Y Z] = bresenham_line3d(P1, P2, [precision]); 11 | % 12 | % P1 - vector for Point1, where P1 = [x1 y1 z1] 13 | % 14 | % P2 - vector for Point2, where P2 = [x2 y2 z2] 15 | % 16 | % precision (optional) - Although according to Bresenham's line 17 | % algorithm, point coordinates x1 y1 z1 and x2 y2 z2 should 18 | % be integer numbers, this program extends its limit to all 19 | % real numbers. If any of them are floating numbers, you 20 | % should specify how many digits of decimal that you would 21 | % like to preserve. Be aware that the length of output X Y 22 | % Z coordinates will increase in 10 times for each decimal 23 | % digit that you want to preserve. By default, the precision 24 | % is 0, which means that they will be rounded to the nearest 25 | % integer. 26 | % 27 | % X - a set of x coordinates on Bresenham's line 28 | % 29 | % Y - a set of y coordinates on Bresenham's line 30 | % 31 | % Z - a set of z coordinates on Bresenham's line 32 | % 33 | % Therefore, all points in XYZ set (i.e. P(i) = [X(i) Y(i) Z(i)]) 34 | % will constitute the Bresenham's line between P1 and P1. 35 | % 36 | % Example: 37 | % P1 = [12 37 6]; P2 = [46 3 35]; 38 | % [X Y Z] = bresenham_line3d(P1, P2); 39 | % figure; plot3(X,Y,Z,'s','markerface','b'); 40 | % 41 | % This program is ported to MATLAB from: 42 | % 43 | % B.Pendleton. line3d - 3D Bresenham's (a 3D line drawing algorithm) 44 | % ftp://ftp.isc.org/pub/usenet/comp.sources.unix/volume26/line3d, 1992 45 | % 46 | % Which is also referenced by: 47 | % 48 | % Fischer, J., A. del Rio (2004). A Fast Method for Applying Rigid 49 | % Transformations to Volume Data, WSCG2004 Conference. 50 | % http://wscg.zcu.cz/wscg2004/Papers_2004_Short/M19.pdf 51 | % 52 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 53 | % 54 | function [X,Y,Z] = bresenham_line3d(P1, P2, precision) 55 | 56 | if ~exist('precision','var') | isempty(precision) | round(precision) == 0 57 | precision = 0; 58 | P1 = round(P1); 59 | P2 = round(P2); 60 | else 61 | precision = round(precision); 62 | P1 = round(P1*(10^precision)); 63 | P2 = round(P2*(10^precision)); 64 | end 65 | 66 | d = max(abs(P2-P1)+1); 67 | X = zeros(1, d); 68 | Y = zeros(1, d); 69 | Z = zeros(1, d); 70 | 71 | x1 = P1(1); 72 | y1 = P1(2); 73 | z1 = P1(3); 74 | 75 | x2 = P2(1); 76 | y2 = P2(2); 77 | z2 = P2(3); 78 | 79 | dx = x2 - x1; 80 | dy = y2 - y1; 81 | dz = z2 - z1; 82 | 83 | ax = abs(dx)*2; 84 | ay = abs(dy)*2; 85 | az = abs(dz)*2; 86 | 87 | sx = sign(dx); 88 | sy = sign(dy); 89 | sz = sign(dz); 90 | 91 | x = x1; 92 | y = y1; 93 | z = z1; 94 | idx = 1; 95 | 96 | if(ax>=max(ay,az)) % x dominant 97 | yd = ay - ax/2; 98 | zd = az - ax/2; 99 | 100 | while(1) 101 | X(idx) = x; 102 | Y(idx) = y; 103 | Z(idx) = z; 104 | idx = idx + 1; 105 | 106 | if(x == x2) % end 107 | break; 108 | end 109 | 110 | if(yd >= 0) % move along y 111 | y = y + sy; 112 | yd = yd - ax; 113 | end 114 | 115 | if(zd >= 0) % move along z 116 | z = z + sz; 117 | zd = zd - ax; 118 | end 119 | 120 | x = x + sx; % move along x 121 | yd = yd + ay; 122 | zd = zd + az; 123 | end 124 | elseif(ay>=max(ax,az)) % y dominant 125 | xd = ax - ay/2; 126 | zd = az - ay/2; 127 | 128 | while(1) 129 | X(idx) = x; 130 | Y(idx) = y; 131 | Z(idx) = z; 132 | idx = idx + 1; 133 | 134 | if(y == y2) % end 135 | break; 136 | end 137 | 138 | if(xd >= 0) % move along x 139 | x = x + sx; 140 | xd = xd - ay; 141 | end 142 | 143 | if(zd >= 0) % move along z 144 | z = z + sz; 145 | zd = zd - ay; 146 | end 147 | 148 | y = y + sy; % move along y 149 | xd = xd + ax; 150 | zd = zd + az; 151 | end 152 | elseif(az>=max(ax,ay)) % z dominant 153 | xd = ax - az/2; 154 | yd = ay - az/2; 155 | 156 | while(1) 157 | X(idx) = x; 158 | Y(idx) = y; 159 | Z(idx) = z; 160 | idx = idx + 1; 161 | 162 | if(z == z2) % end 163 | break; 164 | end 165 | 166 | if(xd >= 0) % move along x 167 | x = x + sx; 168 | xd = xd - az; 169 | end 170 | 171 | if(yd >= 0) % move along y 172 | y = y + sy; 173 | yd = yd - az; 174 | end 175 | 176 | z = z + sz; % move along z 177 | xd = xd + ax; 178 | yd = yd + ay; 179 | end 180 | end 181 | 182 | if precision ~= 0 183 | X = X/(10^precision); 184 | Y = Y/(10^precision); 185 | Z = Z/(10^precision); 186 | end 187 | 188 | return; % bresenham_line3d 189 | 190 | -------------------------------------------------------------------------------- /scripts_templates/load_nii.m: -------------------------------------------------------------------------------- 1 | % Load NIFTI or ANALYZE dataset. Support both *.nii and *.hdr/*.img 2 | % file extension. If file extension is not provided, *.hdr/*.img will 3 | % be used as default. 4 | % 5 | % A subset of NIFTI transform is included. For non-orthogonal rotation, 6 | % shearing etc., please use 'reslice_nii.m' to reslice the NIFTI file. 7 | % It will not cause negative effect, as long as you remember not to do 8 | % slice time correction after reslicing the NIFTI file. Output variable 9 | % nii will be in RAS orientation, i.e. X axis from Left to Right, 10 | % Y axis from Posterior to Anterior, and Z axis from Inferior to 11 | % Superior. 12 | % 13 | % Usage: nii = load_nii(filename, [img_idx], [dim5_idx], [dim6_idx], ... 14 | % [dim7_idx], [old_RGB], [tolerance], [preferredForm]) 15 | % 16 | % filename - NIFTI or ANALYZE file name. 17 | % 18 | % img_idx (optional) - a numerical array of 4th dimension indices, 19 | % which is the indices of image scan volume. The number of images 20 | % scan volumes can be obtained from get_nii_frame.m, or simply 21 | % hdr.dime.dim(5). Only the specified volumes will be loaded. 22 | % All available image volumes will be loaded, if it is default or 23 | % empty. 24 | % 25 | % dim5_idx (optional) - a numerical array of 5th dimension indices. 26 | % Only the specified range will be loaded. All available range 27 | % will be loaded, if it is default or empty. 28 | % 29 | % dim6_idx (optional) - a numerical array of 6th dimension indices. 30 | % Only the specified range will be loaded. All available range 31 | % will be loaded, if it is default or empty. 32 | % 33 | % dim7_idx (optional) - a numerical array of 7th dimension indices. 34 | % Only the specified range will be loaded. All available range 35 | % will be loaded, if it is default or empty. 36 | % 37 | % old_RGB (optional) - a scale number to tell difference of new RGB24 38 | % from old RGB24. New RGB24 uses RGB triple sequentially for each 39 | % voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect 40 | % uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for 41 | % each slices. If the image that you view is garbled, try to set 42 | % old_RGB variable to 1 and try again, because it could be in 43 | % old RGB24. It will be set to 0, if it is default or empty. 44 | % 45 | % tolerance (optional) - distortion allowed in the loaded image for any 46 | % non-orthogonal rotation or shearing of NIfTI affine matrix. If 47 | % you set 'tolerance' to 0, it means that you do not allow any 48 | % distortion. If you set 'tolerance' to 1, it means that you do 49 | % not care any distortion. The image will fail to be loaded if it 50 | % can not be tolerated. The tolerance will be set to 0.1 (10%), if 51 | % it is default or empty. 52 | % 53 | % preferredForm (optional) - selects which transformation from voxels 54 | % to RAS coordinates; values are s,q,S,Q. Lower case s,q indicate 55 | % "prefer sform or qform, but use others if preferred not present". 56 | % Upper case indicate the program is forced to use the specificied 57 | % tranform or fail loading. 'preferredForm' will be 's', if it is 58 | % default or empty. - Jeff Gunter 59 | % 60 | % Returned values: 61 | % 62 | % nii structure: 63 | % 64 | % hdr - struct with NIFTI header fields. 65 | % 66 | % filetype - Analyze format .hdr/.img (0); 67 | % NIFTI .hdr/.img (1); 68 | % NIFTI .nii (2) 69 | % 70 | % fileprefix - NIFTI filename without extension. 71 | % 72 | % machine - machine string variable. 73 | % 74 | % img - 3D (or 4D) matrix of NIFTI data. 75 | % 76 | % original - the original header before any affine transform. 77 | % 78 | % Part of this file is copied and modified from: 79 | % http://www.mathworks.com/matlabcentral/fileexchange/1878-mri-analyze-tools 80 | % 81 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 82 | % 83 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 84 | % 85 | function nii = load_nii(filename, img_idx, dim5_idx, dim6_idx, dim7_idx, ... 86 | old_RGB, tolerance, preferredForm) 87 | 88 | if ~exist('filename','var') 89 | error('Usage: nii = load_nii(filename, [img_idx], [dim5_idx], [dim6_idx], [dim7_idx], [old_RGB], [tolerance], [preferredForm])'); 90 | end 91 | 92 | if ~exist('img_idx','var') | isempty(img_idx) 93 | img_idx = []; 94 | end 95 | 96 | if ~exist('dim5_idx','var') | isempty(dim5_idx) 97 | dim5_idx = []; 98 | end 99 | 100 | if ~exist('dim6_idx','var') | isempty(dim6_idx) 101 | dim6_idx = []; 102 | end 103 | 104 | if ~exist('dim7_idx','var') | isempty(dim7_idx) 105 | dim7_idx = []; 106 | end 107 | 108 | if ~exist('old_RGB','var') | isempty(old_RGB) 109 | old_RGB = 0; 110 | end 111 | 112 | if ~exist('tolerance','var') | isempty(tolerance) 113 | tolerance = 0.1; % 10 percent 114 | end 115 | 116 | if ~exist('preferredForm','var') | isempty(preferredForm) 117 | preferredForm= 's'; % Jeff 118 | end 119 | 120 | % Read the dataset header 121 | % 122 | [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); 123 | 124 | % Read the header extension 125 | % 126 | % nii.ext = load_nii_ext(filename); 127 | 128 | % Read the dataset body 129 | % 130 | [nii.img,nii.hdr] = load_nii_img(nii.hdr,nii.filetype,nii.fileprefix, ... 131 | nii.machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB); 132 | 133 | % Perform some of sform/qform transform 134 | % 135 | nii = xform_nii(nii, tolerance, preferredForm); 136 | 137 | return % load_nii 138 | 139 | -------------------------------------------------------------------------------- /scripts_templates/load_untouch_header_only.m: -------------------------------------------------------------------------------- 1 | % Load NIfTI / Analyze header without applying any appropriate affine 2 | % geometric transform or voxel intensity scaling. It is equivalent to 3 | % hdr field when using load_untouch_nii to load dataset. Support both 4 | % *.nii and *.hdr file extension. If file extension is not provided, 5 | % *.hdr will be used as default. 6 | % 7 | % Usage: [header, ext, filetype, machine] = load_untouch_header_only(filename) 8 | % 9 | % filename - NIfTI / Analyze file name. 10 | % 11 | % Returned values: 12 | % 13 | % header - struct with NIfTI / Analyze header fields. 14 | % 15 | % ext - NIfTI extension if it is not empty. 16 | % 17 | % filetype - 0 for Analyze format (*.hdr/*.img); 18 | % 1 for NIFTI format in 2 files (*.hdr/*.img); 19 | % 2 for NIFTI format in 1 file (*.nii). 20 | % 21 | % machine - a string, see below for details. The default here is 'ieee-le'. 22 | % 23 | % 'native' or 'n' - local machine format - the default 24 | % 'ieee-le' or 'l' - IEEE floating point with little-endian 25 | % byte ordering 26 | % 'ieee-be' or 'b' - IEEE floating point with big-endian 27 | % byte ordering 28 | % 'vaxd' or 'd' - VAX D floating point and VAX ordering 29 | % 'vaxg' or 'g' - VAX G floating point and VAX ordering 30 | % 'cray' or 'c' - Cray floating point with big-endian 31 | % byte ordering 32 | % 'ieee-le.l64' or 'a' - IEEE floating point with little-endian 33 | % byte ordering and 64 bit long data type 34 | % 'ieee-be.l64' or 's' - IEEE floating point with big-endian byte 35 | % ordering and 64 bit long data type. 36 | % 37 | % Part of this file is copied and modified from: 38 | % http://www.mathworks.com/matlabcentral/fileexchange/1878-mri-analyze-tools 39 | % 40 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 41 | % 42 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 43 | % 44 | function [hdr, ext, filetype, machine] = load_untouch_header_only(filename) 45 | 46 | if ~exist('filename','var') 47 | error('Usage: [header, ext, filetype, machine] = load_untouch_header_only(filename)'); 48 | end 49 | 50 | % Read the dataset header 51 | % 52 | [hdr, filetype, fileprefix, machine] = load_nii_hdr(filename); 53 | 54 | if filetype == 0 55 | hdr = load_untouch0_nii_hdr(fileprefix, machine); 56 | ext = []; 57 | else 58 | hdr = load_untouch_nii_hdr(fileprefix, machine, filetype); 59 | 60 | % Read the header extension 61 | % 62 | ext = load_nii_ext(filename); 63 | end 64 | 65 | % Set bitpix according to datatype 66 | % 67 | % /*Acceptable values for datatype are*/ 68 | % 69 | % 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN 70 | % 1 Binary (ubit1, bitpix=1) % DT_BINARY 71 | % 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 72 | % 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 73 | % 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 74 | % 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 75 | % 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 76 | % 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 77 | % 128 uint8 RGB (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 78 | % 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 79 | % 511 Single RGB (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96 80 | % 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 81 | % 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 82 | % 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 83 | % 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 84 | % 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 85 | % 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 86 | % 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 87 | % 88 | switch hdr.dime.datatype 89 | case 1, 90 | hdr.dime.bitpix = 1; precision = 'ubit1'; 91 | case 2, 92 | hdr.dime.bitpix = 8; precision = 'uint8'; 93 | case 4, 94 | hdr.dime.bitpix = 16; precision = 'int16'; 95 | case 8, 96 | hdr.dime.bitpix = 32; precision = 'int32'; 97 | case 16, 98 | hdr.dime.bitpix = 32; precision = 'float32'; 99 | case 32, 100 | hdr.dime.bitpix = 64; precision = 'float32'; 101 | case 64, 102 | hdr.dime.bitpix = 64; precision = 'float64'; 103 | case 128, 104 | hdr.dime.bitpix = 24; precision = 'uint8'; 105 | case 256 106 | hdr.dime.bitpix = 8; precision = 'int8'; 107 | case 511 108 | hdr.dime.bitpix = 96; precision = 'float32'; 109 | case 512 110 | hdr.dime.bitpix = 16; precision = 'uint16'; 111 | case 768 112 | hdr.dime.bitpix = 32; precision = 'uint32'; 113 | case 1024 114 | hdr.dime.bitpix = 64; precision = 'int64'; 115 | case 1280 116 | hdr.dime.bitpix = 64; precision = 'uint64'; 117 | case 1792, 118 | hdr.dime.bitpix = 128; precision = 'float64'; 119 | otherwise 120 | error('This datatype is not supported'); 121 | end 122 | 123 | tmp = hdr.dime.dim(2:end); 124 | tmp(find(tmp < 1)) = 1; 125 | hdr.dime.dim(2:end) = tmp; 126 | 127 | 128 | return % load_untouch_header_only 129 | 130 | -------------------------------------------------------------------------------- /scripts_templates/make_ana.m: -------------------------------------------------------------------------------- 1 | % Make ANALYZE 7.5 data structure specified by a 3D or 4D matrix. 2 | % Optional parameters can also be included, such as: voxel_size, 3 | % origin, datatype, and description. 4 | % 5 | % Once the ANALYZE structure is made, it can be saved into ANALYZE 7.5 6 | % format data file using "save_untouch_nii" command (for more detail, 7 | % type: help save_untouch_nii). 8 | % 9 | % Usage: ana = make_ana(img, [voxel_size], [origin], [datatype], [description]) 10 | % 11 | % Where: 12 | % 13 | % img: a 3D matrix [x y z], or a 4D matrix with time 14 | % series [x y z t]. When image is in RGB format, 15 | % make sure that the size of 4th dimension is 16 | % always 3 (i.e. [R G B]). In that case, make 17 | % sure that you must specify RGB datatype to 128. 18 | % 19 | % voxel_size (optional): Voxel size in millimeter for each 20 | % dimension. Default is [1 1 1]. 21 | % 22 | % origin (optional): The AC origin. Default is [0 0 0]. 23 | % 24 | % datatype (optional): Storage data type: 25 | % 2 - uint8, 4 - int16, 8 - int32, 16 - float32, 26 | % 64 - float64, 128 - RGB24 27 | % Default will use the data type of 'img' matrix 28 | % For RGB image, you must specify it to 128. 29 | % 30 | % description (optional): Description of data. Default is ''. 31 | % 32 | % e.g.: 33 | % origin = [33 44 13]; datatype = 64; 34 | % ana = make_ana(img, [], origin, datatype); % default voxel_size 35 | % 36 | % ANALYZE 7.5 format: http://www.rotman-baycrest.on.ca/~jimmy/ANALYZE75.pdf 37 | % 38 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 39 | % 40 | function ana = make_ana(varargin) 41 | 42 | ana.img = varargin{1}; 43 | dims = size(ana.img); 44 | dims = [4 dims ones(1,8)]; 45 | dims = dims(1:8); 46 | 47 | voxel_size = [0 ones(1,3) zeros(1,4)]; 48 | origin = zeros(1,5); 49 | descrip = ''; 50 | 51 | switch class(ana.img) 52 | case 'uint8' 53 | datatype = 2; 54 | case 'int16' 55 | datatype = 4; 56 | case 'int32' 57 | datatype = 8; 58 | case 'single' 59 | datatype = 16; 60 | case 'double' 61 | datatype = 64; 62 | otherwise 63 | error('Datatype is not supported by make_ana.'); 64 | end 65 | 66 | if nargin > 1 & ~isempty(varargin{2}) 67 | voxel_size(2:4) = double(varargin{2}); 68 | end 69 | 70 | if nargin > 2 & ~isempty(varargin{3}) 71 | origin(1:3) = double(varargin{3}); 72 | end 73 | 74 | if nargin > 3 & ~isempty(varargin{4}) 75 | datatype = double(varargin{4}); 76 | 77 | if datatype == 128 | datatype == 511 78 | dims(5) = []; 79 | dims = [dims 1]; 80 | end 81 | end 82 | 83 | if nargin > 4 & ~isempty(varargin{5}) 84 | descrip = varargin{5}; 85 | end 86 | 87 | if ndims(ana.img) > 4 88 | error('NIfTI only allows a maximum of 4 Dimension matrix.'); 89 | end 90 | 91 | maxval = round(double(max(ana.img(:)))); 92 | minval = round(double(min(ana.img(:)))); 93 | 94 | ana.hdr = make_header(dims, voxel_size, origin, datatype, ... 95 | descrip, maxval, minval); 96 | ana.filetype = 0; 97 | ana.ext = []; 98 | ana.untouch = 1; 99 | 100 | switch ana.hdr.dime.datatype 101 | case 2 102 | ana.img = uint8(ana.img); 103 | case 4 104 | ana.img = int16(ana.img); 105 | case 8 106 | ana.img = int32(ana.img); 107 | case 16 108 | ana.img = single(ana.img); 109 | case 64 110 | ana.img = double(ana.img); 111 | case 128 112 | ana.img = uint8(ana.img); 113 | otherwise 114 | error('Datatype is not supported by make_ana.'); 115 | end 116 | 117 | return; % make_ana 118 | 119 | 120 | %--------------------------------------------------------------------- 121 | function hdr = make_header(dims, voxel_size, origin, datatype, ... 122 | descrip, maxval, minval) 123 | 124 | hdr.hk = header_key; 125 | hdr.dime = image_dimension(dims, voxel_size, datatype, maxval, minval); 126 | hdr.hist = data_history(origin, descrip); 127 | 128 | return; % make_header 129 | 130 | 131 | %--------------------------------------------------------------------- 132 | function hk = header_key 133 | 134 | hk.sizeof_hdr = 348; % must be 348! 135 | hk.data_type = ''; 136 | hk.db_name = ''; 137 | hk.extents = 0; 138 | hk.session_error = 0; 139 | hk.regular = 'r'; 140 | hk.hkey_un0 = '0'; 141 | 142 | return; % header_key 143 | 144 | 145 | %--------------------------------------------------------------------- 146 | function dime = image_dimension(dims, voxel_size, datatype, maxval, minval) 147 | 148 | dime.dim = dims; 149 | dime.vox_units = 'mm'; 150 | dime.cal_units = ''; 151 | dime.unused1 = 0; 152 | dime.datatype = datatype; 153 | 154 | switch dime.datatype 155 | case 2, 156 | dime.bitpix = 8; precision = 'uint8'; 157 | case 4, 158 | dime.bitpix = 16; precision = 'int16'; 159 | case 8, 160 | dime.bitpix = 32; precision = 'int32'; 161 | case 16, 162 | dime.bitpix = 32; precision = 'float32'; 163 | case 64, 164 | dime.bitpix = 64; precision = 'float64'; 165 | case 128 166 | dime.bitpix = 24; precision = 'uint8'; 167 | otherwise 168 | error('Datatype is not supported by make_ana.'); 169 | end 170 | 171 | dime.dim_un0 = 0; 172 | dime.pixdim = voxel_size; 173 | dime.vox_offset = 0; 174 | dime.roi_scale = 1; 175 | dime.funused1 = 0; 176 | dime.funused2 = 0; 177 | dime.cal_max = 0; 178 | dime.cal_min = 0; 179 | dime.compressed = 0; 180 | dime.verified = 0; 181 | dime.glmax = maxval; 182 | dime.glmin = minval; 183 | 184 | return; % image_dimension 185 | 186 | 187 | %--------------------------------------------------------------------- 188 | function hist = data_history(origin, descrip) 189 | 190 | hist.descrip = descrip; 191 | hist.aux_file = 'none'; 192 | hist.orient = 0; 193 | hist.originator = origin; 194 | hist.generated = ''; 195 | hist.scannum = ''; 196 | hist.patient_id = ''; 197 | hist.exp_date = ''; 198 | hist.exp_time = ''; 199 | hist.hist_un0 = ''; 200 | hist.views = 0; 201 | hist.vols_added = 0; 202 | hist.start_field = 0; 203 | hist.field_skip = 0; 204 | hist.omax = 0; 205 | hist.omin = 0; 206 | hist.smax = 0; 207 | hist.smin = 0; 208 | 209 | return; % data_history 210 | 211 | -------------------------------------------------------------------------------- /scripts_templates/save_untouch_nii.m: -------------------------------------------------------------------------------- 1 | % Save NIFTI or ANALYZE dataset that is loaded by "load_untouch_nii.m". 2 | % The output image format and file extension will be the same as the 3 | % input one (NIFTI.nii, NIFTI.img or ANALYZE.img). Therefore, any file 4 | % extension that you specified will be ignored. 5 | % 6 | % Usage: save_untouch_nii(nii, filename) 7 | % 8 | % nii - nii structure that is loaded by "load_untouch_nii.m" 9 | % 10 | % filename - NIFTI or ANALYZE file name. 11 | % 12 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 13 | % 14 | function save_untouch_nii(nii, filename) 15 | 16 | if ~exist('nii','var') | isempty(nii) | ~isfield(nii,'hdr') | ... 17 | ~isfield(nii,'img') | ~exist('filename','var') | isempty(filename) 18 | 19 | error('Usage: save_untouch_nii(nii, filename)'); 20 | end 21 | 22 | if ~isfield(nii,'untouch') | nii.untouch == 0 23 | error('Usage: please use ''save_nii.m'' for the modified structure.'); 24 | end 25 | 26 | if isfield(nii.hdr.hist,'magic') & strcmp(nii.hdr.hist.magic(1:3),'ni1') 27 | filetype = 1; 28 | elseif isfield(nii.hdr.hist,'magic') & strcmp(nii.hdr.hist.magic(1:3),'n+1') 29 | filetype = 2; 30 | else 31 | filetype = 0; 32 | end 33 | 34 | [p,f] = fileparts(filename); 35 | fileprefix = fullfile(p, f); 36 | 37 | write_nii(nii, filetype, fileprefix); 38 | 39 | % % So earlier versions of SPM can also open it with correct originator 40 | % % 41 | % if filetype == 0 42 | % M=[[diag(nii.hdr.dime.pixdim(2:4)) -[nii.hdr.hist.originator(1:3).*nii.hdr.dime.pixdim(2:4)]'];[0 0 0 1]]; 43 | % save(fileprefix, 'M'); 44 | % elseif filetype == 1 45 | % M=[]; 46 | % save(fileprefix, 'M'); 47 | %end 48 | 49 | return % save_untouch_nii 50 | 51 | 52 | %----------------------------------------------------------------------------------- 53 | function write_nii(nii, filetype, fileprefix) 54 | 55 | hdr = nii.hdr; 56 | 57 | if isfield(nii,'ext') & ~isempty(nii.ext) 58 | ext = nii.ext; 59 | [ext, esize_total] = verify_nii_ext(ext); 60 | else 61 | ext = []; 62 | end 63 | 64 | switch double(hdr.dime.datatype), 65 | case 1, 66 | hdr.dime.bitpix = int16(1 ); precision = 'ubit1'; 67 | case 2, 68 | hdr.dime.bitpix = int16(8 ); precision = 'uint8'; 69 | case 4, 70 | hdr.dime.bitpix = int16(16); precision = 'int16'; 71 | case 8, 72 | hdr.dime.bitpix = int16(32); precision = 'int32'; 73 | case 16, 74 | hdr.dime.bitpix = int16(32); precision = 'float32'; 75 | case 32, 76 | hdr.dime.bitpix = int16(64); precision = 'float32'; 77 | case 64, 78 | hdr.dime.bitpix = int16(64); precision = 'float64'; 79 | case 128, 80 | hdr.dime.bitpix = int16(24); precision = 'uint8'; 81 | case 256 82 | hdr.dime.bitpix = int16(8 ); precision = 'int8'; 83 | case 512 84 | hdr.dime.bitpix = int16(16); precision = 'uint16'; 85 | case 768 86 | hdr.dime.bitpix = int16(32); precision = 'uint32'; 87 | case 1024 88 | hdr.dime.bitpix = int16(64); precision = 'int64'; 89 | case 1280 90 | hdr.dime.bitpix = int16(64); precision = 'uint64'; 91 | case 1792, 92 | hdr.dime.bitpix = int16(128); precision = 'float64'; 93 | otherwise 94 | error('This datatype is not supported'); 95 | end 96 | 97 | % hdr.dime.glmax = round(double(max(nii.img(:)))); 98 | % hdr.dime.glmin = round(double(min(nii.img(:)))); 99 | 100 | if filetype == 2 101 | fid = fopen(sprintf('%s.nii',fileprefix),'w'); 102 | 103 | if fid < 0, 104 | msg = sprintf('Cannot open file %s.nii.',fileprefix); 105 | error(msg); 106 | end 107 | 108 | hdr.dime.vox_offset = 352; 109 | 110 | if ~isempty(ext) 111 | hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total; 112 | end 113 | 114 | hdr.hist.magic = 'n+1'; 115 | save_untouch_nii_hdr(hdr, fid); 116 | 117 | if ~isempty(ext) 118 | save_nii_ext(ext, fid); 119 | end 120 | elseif filetype == 1 121 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 122 | 123 | if fid < 0, 124 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 125 | error(msg); 126 | end 127 | 128 | hdr.dime.vox_offset = 0; 129 | hdr.hist.magic = 'ni1'; 130 | save_untouch_nii_hdr(hdr, fid); 131 | 132 | if ~isempty(ext) 133 | save_nii_ext(ext, fid); 134 | end 135 | 136 | fclose(fid); 137 | fid = fopen(sprintf('%s.img',fileprefix),'w'); 138 | else 139 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 140 | 141 | if fid < 0, 142 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 143 | error(msg); 144 | end 145 | 146 | save_untouch0_nii_hdr(hdr, fid); 147 | 148 | fclose(fid); 149 | fid = fopen(sprintf('%s.img',fileprefix),'w'); 150 | end 151 | 152 | ScanDim = double(hdr.dime.dim(5)); % t 153 | SliceDim = double(hdr.dime.dim(4)); % z 154 | RowDim = double(hdr.dime.dim(3)); % y 155 | PixelDim = double(hdr.dime.dim(2)); % x 156 | SliceSz = double(hdr.dime.pixdim(4)); 157 | RowSz = double(hdr.dime.pixdim(3)); 158 | PixelSz = double(hdr.dime.pixdim(2)); 159 | 160 | x = 1:PixelDim; 161 | 162 | if filetype == 2 & isempty(ext) 163 | skip_bytes = double(hdr.dime.vox_offset) - 348; 164 | else 165 | skip_bytes = 0; 166 | end 167 | 168 | if double(hdr.dime.datatype) == 128 169 | 170 | % RGB planes are expected to be in the 4th dimension of nii.img 171 | % 172 | if(size(nii.img,4)~=3) 173 | error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); 174 | end 175 | 176 | nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); 177 | end 178 | 179 | % For complex float32 or complex float64, voxel values 180 | % include [real, imag] 181 | % 182 | if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 183 | real_img = real(nii.img(:))'; 184 | nii.img = imag(nii.img(:))'; 185 | nii.img = [real_img; nii.img]; 186 | end 187 | 188 | if skip_bytes 189 | fwrite(fid, zeros(1,skip_bytes), 'uint8'); 190 | end 191 | 192 | fwrite(fid, nii.img, precision); 193 | % fwrite(fid, nii.img, precision, skip_bytes); % error using skip 194 | fclose(fid); 195 | 196 | return; % write_nii 197 | 198 | -------------------------------------------------------------------------------- /scripts_templates/collapse_nii_scan.m: -------------------------------------------------------------------------------- 1 | % Collapse multiple single-scan NIFTI files into a multiple-scan NIFTI file 2 | % 3 | % Usage: collapse_nii_scan(scan_file_pattern, [collapsed_fileprefix], [scan_file_folder]) 4 | % 5 | % Here, scan_file_pattern should look like: 'myscan_0*.img' 6 | % If collapsed_fileprefix is omit, 'multi_scan' will be used 7 | % If scan_file_folder is omit, current file folder will be used 8 | % 9 | % The order of volumes in the collapsed file will be the order of 10 | % corresponding filenames for those selected scan files. 11 | % 12 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 13 | % 14 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 15 | % 16 | function collapse_nii_scan(scan_pattern, fileprefix, scan_path) 17 | 18 | if ~exist('fileprefix','var') 19 | fileprefix = 'multi_scan'; 20 | else 21 | [tmp fileprefix] = fileparts(fileprefix); 22 | end 23 | 24 | if ~exist('scan_path','var'), scan_path = pwd; end 25 | pnfn = fullfile(scan_path, scan_pattern); 26 | 27 | file_lst = dir(pnfn); 28 | flist = {file_lst.name}; 29 | flist = flist(:); 30 | 31 | nii = load_untouch_nii(flist{1}); 32 | nii.hdr.dime.dim(5) = length(flist); 33 | 34 | if nii.hdr.dime.dim(1) < 4 35 | nii.hdr.dime.dim(1) = 4; 36 | end 37 | 38 | hdr = nii.hdr; 39 | filetype = nii.filetype; 40 | 41 | if isfield(nii,'ext') & ~isempty(nii.ext) 42 | ext = nii.ext; 43 | [ext, esize_total] = verify_nii_ext(ext); 44 | else 45 | ext = []; 46 | end 47 | 48 | switch double(hdr.dime.datatype), 49 | case 1, 50 | hdr.dime.bitpix = int16(1 ); precision = 'ubit1'; 51 | case 2, 52 | hdr.dime.bitpix = int16(8 ); precision = 'uint8'; 53 | case 4, 54 | hdr.dime.bitpix = int16(16); precision = 'int16'; 55 | case 8, 56 | hdr.dime.bitpix = int16(32); precision = 'int32'; 57 | case 16, 58 | hdr.dime.bitpix = int16(32); precision = 'float32'; 59 | case 32, 60 | hdr.dime.bitpix = int16(64); precision = 'float32'; 61 | case 64, 62 | hdr.dime.bitpix = int16(64); precision = 'float64'; 63 | case 128, 64 | hdr.dime.bitpix = int16(24); precision = 'uint8'; 65 | case 256 66 | hdr.dime.bitpix = int16(8 ); precision = 'int8'; 67 | case 512 68 | hdr.dime.bitpix = int16(16); precision = 'uint16'; 69 | case 768 70 | hdr.dime.bitpix = int16(32); precision = 'uint32'; 71 | case 1024 72 | hdr.dime.bitpix = int16(64); precision = 'int64'; 73 | case 1280 74 | hdr.dime.bitpix = int16(64); precision = 'uint64'; 75 | case 1792, 76 | hdr.dime.bitpix = int16(128); precision = 'float64'; 77 | otherwise 78 | error('This datatype is not supported'); 79 | end 80 | 81 | if filetype == 2 82 | fid = fopen(sprintf('%s.nii',fileprefix),'w'); 83 | 84 | if fid < 0, 85 | msg = sprintf('Cannot open file %s.nii.',fileprefix); 86 | error(msg); 87 | end 88 | 89 | hdr.dime.vox_offset = 352; 90 | 91 | if ~isempty(ext) 92 | hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total; 93 | end 94 | 95 | hdr.hist.magic = 'n+1'; 96 | save_untouch_nii_hdr(hdr, fid); 97 | 98 | if ~isempty(ext) 99 | save_nii_ext(ext, fid); 100 | end 101 | elseif filetype == 1 102 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 103 | 104 | if fid < 0, 105 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 106 | error(msg); 107 | end 108 | 109 | hdr.dime.vox_offset = 0; 110 | hdr.hist.magic = 'ni1'; 111 | save_untouch_nii_hdr(hdr, fid); 112 | 113 | if ~isempty(ext) 114 | save_nii_ext(ext, fid); 115 | end 116 | 117 | fclose(fid); 118 | fid = fopen(sprintf('%s.img',fileprefix),'w'); 119 | else 120 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 121 | 122 | if fid < 0, 123 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 124 | error(msg); 125 | end 126 | 127 | save_untouch0_nii_hdr(hdr, fid); 128 | 129 | fclose(fid); 130 | fid = fopen(sprintf('%s.img',fileprefix),'w'); 131 | end 132 | 133 | if filetype == 2 & isempty(ext) 134 | skip_bytes = double(hdr.dime.vox_offset) - 348; 135 | else 136 | skip_bytes = 0; 137 | end 138 | 139 | if skip_bytes 140 | fwrite(fid, zeros(1,skip_bytes), 'uint8'); 141 | end 142 | 143 | glmax = -inf; 144 | glmin = inf; 145 | 146 | for i = 1:length(flist) 147 | nii = load_untouch_nii(flist{i}); 148 | 149 | if double(hdr.dime.datatype) == 128 150 | 151 | % RGB planes are expected to be in the 4th dimension of nii.img 152 | % 153 | if(size(nii.img,4)~=3) 154 | error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); 155 | end 156 | 157 | nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); 158 | end 159 | 160 | % For complex float32 or complex float64, voxel values 161 | % include [real, imag] 162 | % 163 | if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 164 | real_img = real(nii.img(:))'; 165 | nii.img = imag(nii.img(:))'; 166 | nii.img = [real_img; nii.img]; 167 | end 168 | 169 | if nii.hdr.dime.glmax > glmax 170 | glmax = nii.hdr.dime.glmax; 171 | end 172 | 173 | if nii.hdr.dime.glmin < glmin 174 | glmin = nii.hdr.dime.glmin; 175 | end 176 | 177 | fwrite(fid, nii.img, precision); 178 | end 179 | 180 | hdr.dime.glmax = round(glmax); 181 | hdr.dime.glmin = round(glmin); 182 | 183 | if filetype == 2 184 | fseek(fid, 140, 'bof'); 185 | fwrite(fid, hdr.dime.glmax, 'int32'); 186 | fwrite(fid, hdr.dime.glmin, 'int32'); 187 | elseif filetype == 1 188 | fid2 = fopen(sprintf('%s.hdr',fileprefix),'w'); 189 | 190 | if fid2 < 0, 191 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 192 | error(msg); 193 | end 194 | 195 | save_untouch_nii_hdr(hdr, fid2); 196 | 197 | if ~isempty(ext) 198 | save_nii_ext(ext, fid2); 199 | end 200 | 201 | fclose(fid2); 202 | else 203 | fid2 = fopen(sprintf('%s.hdr',fileprefix),'w'); 204 | 205 | if fid2 < 0, 206 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 207 | error(msg); 208 | end 209 | 210 | save_untouch0_nii_hdr(hdr, fid2); 211 | 212 | fclose(fid2); 213 | end 214 | 215 | fclose(fid); 216 | 217 | return; % collapse_nii_scan 218 | 219 | -------------------------------------------------------------------------------- /scripts_templates/rri_orient_ui.m: -------------------------------------------------------------------------------- 1 | % Return orientation of the current image: 2 | % orient is orientation 1x3 matrix, in that: 3 | % Three elements represent: [x y z] 4 | % Element value: 1 - Left to Right; 2 - Posterior to Anterior; 5 | % 3 - Inferior to Superior; 4 - Right to Left; 6 | % 5 - Anterior to Posterior; 6 - Superior to Inferior; 7 | % e.g.: 8 | % Standard RAS Orientation: [1 2 3] 9 | % Standard RHOS Orientation: [2 4 3] 10 | 11 | % Jimmy Shen (jimmy@rotman-baycrest.on.ca), 26-APR-04 12 | % 13 | function orient = rri_orient_ui(varargin) 14 | 15 | if nargin == 0 16 | init; 17 | orient_ui_fig = gcf; 18 | uiwait; % wait for user finish 19 | 20 | orient = getappdata(gcf, 'orient'); 21 | 22 | if isempty(orient) 23 | orient = [1 2 3]; 24 | end 25 | 26 | if ishandle(orient_ui_fig) 27 | close(gcf); 28 | end 29 | 30 | return; 31 | end 32 | 33 | action = varargin{1}; 34 | 35 | if strcmp(action, 'done') 36 | click_done; 37 | elseif strcmp(action, 'cancel') 38 | uiresume; 39 | end 40 | 41 | return; % rri_orient_ui 42 | 43 | 44 | %---------------------------------------------------------------------- 45 | function init 46 | 47 | save_setting_status = 'on'; 48 | rri_orient_pos = []; 49 | 50 | try 51 | load('pls_profile'); 52 | catch 53 | end 54 | 55 | try 56 | load('rri_pos_profile'); 57 | catch 58 | end 59 | 60 | if ~isempty(rri_orient_pos) & strcmp(save_setting_status,'on') 61 | 62 | pos = rri_orient_pos; 63 | 64 | else 65 | 66 | w = 0.35; 67 | h = 0.4; 68 | x = (1-w)/2; 69 | y = (1-h)/2; 70 | 71 | pos = [x y w h]; 72 | 73 | end 74 | 75 | handles.figure = figure('Color',[0.8 0.8 0.8], ... 76 | 'Units','normal', ... 77 | 'Name', 'Convert to standard RAS orientation', ... 78 | 'NumberTitle','off', ... 79 | 'MenuBar','none', ... 80 | 'Position',pos, ... 81 | 'WindowStyle', 'normal', ... 82 | 'ToolBar','none'); 83 | 84 | h0 = handles.figure; 85 | Font.FontUnits = 'point'; 86 | Font.FontSize = 12; 87 | 88 | margin = .1; 89 | line_num = 6; 90 | line_ht = (1 - margin*2) / line_num; 91 | 92 | x = margin; 93 | y = 1 - margin - line_ht; 94 | w = 1 - margin * 2; 95 | h = line_ht * .7; 96 | 97 | pos = [x y w h]; 98 | 99 | handles.Ttit = uicontrol('parent', h0, ... 100 | 'style','text', ... 101 | 'unit', 'normal', ... 102 | Font, ... 103 | 'Position',pos, ... 104 | 'HorizontalAlignment','left',... 105 | 'background', [0.8 0.8 0.8], ... 106 | 'string', 'Please input orientation of the current image:'); 107 | 108 | y = y - line_ht; 109 | w = .2; 110 | 111 | pos = [x y w h]; 112 | 113 | handles.Tx_orient = uicontrol('parent', h0, ... 114 | 'style','text', ... 115 | 'unit', 'normal', ... 116 | Font, ... 117 | 'Position',pos, ... 118 | 'HorizontalAlignment','left',... 119 | 'background', [0.8 0.8 0.8], ... 120 | 'string', 'X Axes:'); 121 | 122 | y = y - line_ht; 123 | 124 | pos = [x y w h]; 125 | 126 | handles.Ty_orient = uicontrol('parent', h0, ... 127 | 'style','text', ... 128 | 'unit', 'normal', ... 129 | Font, ... 130 | 'Position',pos, ... 131 | 'HorizontalAlignment','left',... 132 | 'background', [0.8 0.8 0.8], ... 133 | 'string', 'Y Axes:'); 134 | 135 | y = y - line_ht; 136 | 137 | pos = [x y w h]; 138 | 139 | handles.Tz_orient = uicontrol('parent', h0, ... 140 | 'style','text', ... 141 | 'unit', 'normal', ... 142 | Font, ... 143 | 'Position',pos, ... 144 | 'HorizontalAlignment','left',... 145 | 'background', [0.8 0.8 0.8], ... 146 | 'string', 'Z Axes:'); 147 | 148 | choice = { 'From Left to Right', 'From Posterior to Anterior', ... 149 | 'From Inferior to Superior', 'From Right to Left', ... 150 | 'From Anterior to Posterior', 'From Superior to Inferior' }; 151 | 152 | y = 1 - margin - line_ht; 153 | y = y - line_ht; 154 | w = 1 - margin - x - w; 155 | x = 1 - margin - w; 156 | 157 | pos = [x y w h]; 158 | 159 | handles.x_orient = uicontrol('parent', h0, ... 160 | 'style','popupmenu', ... 161 | 'unit', 'normal', ... 162 | Font, ... 163 | 'Position',pos, ... 164 | 'HorizontalAlignment','left',... 165 | 'string', choice, ... 166 | 'value', 1, ... 167 | 'background', [1 1 1]); 168 | 169 | y = y - line_ht; 170 | 171 | pos = [x y w h]; 172 | 173 | handles.y_orient = uicontrol('parent', h0, ... 174 | 'style','popupmenu', ... 175 | 'unit', 'normal', ... 176 | Font, ... 177 | 'Position',pos, ... 178 | 'HorizontalAlignment','left',... 179 | 'string', choice, ... 180 | 'value', 2, ... 181 | 'background', [1 1 1]); 182 | 183 | y = y - line_ht; 184 | 185 | pos = [x y w h]; 186 | 187 | handles.z_orient = uicontrol('parent', h0, ... 188 | 'style','popupmenu', ... 189 | 'unit', 'normal', ... 190 | Font, ... 191 | 'Position',pos, ... 192 | 'HorizontalAlignment','left',... 193 | 'string', choice, ... 194 | 'value', 3, ... 195 | 'background', [1 1 1]); 196 | 197 | x = margin; 198 | y = y - line_ht * 1.5; 199 | w = .3; 200 | 201 | pos = [x y w h]; 202 | 203 | handles.done = uicontrol('parent', h0, ... 204 | 'unit', 'normal', ... 205 | Font, ... 206 | 'Position',pos, ... 207 | 'HorizontalAlignment','center',... 208 | 'callback', 'rri_orient_ui(''done'');', ... 209 | 'string', 'Done'); 210 | 211 | x = 1 - margin - w; 212 | 213 | pos = [x y w h]; 214 | 215 | handles.cancel = uicontrol('parent', h0, ... 216 | 'unit', 'normal', ... 217 | Font, ... 218 | 'Position',pos, ... 219 | 'HorizontalAlignment','center',... 220 | 'callback', 'rri_orient_ui(''cancel'');', ... 221 | 'string', 'Cancel'); 222 | 223 | setappdata(h0, 'handles', handles); 224 | setappdata(h0, 'orient', [1 2 3]); 225 | 226 | return; % init 227 | 228 | 229 | %---------------------------------------------------------------------- 230 | function click_done 231 | 232 | handles = getappdata(gcf, 'handles'); 233 | 234 | x_orient = get(handles.x_orient, 'value'); 235 | y_orient = get(handles.y_orient, 'value'); 236 | z_orient = get(handles.z_orient, 'value'); 237 | 238 | orient = [x_orient y_orient z_orient]; 239 | test_orient = [orient, orient + 3]; 240 | test_orient = mod(test_orient, 3); 241 | 242 | if length(unique(test_orient)) ~= 3 243 | msgbox('Please don''t choose same or opposite direction','Error','modal'); 244 | return; 245 | end 246 | 247 | setappdata(gcf, 'orient', [x_orient y_orient z_orient]); 248 | uiresume; 249 | 250 | return; % click_done 251 | 252 | -------------------------------------------------------------------------------- /fmreli.m: -------------------------------------------------------------------------------- 1 | function varargout = fmreli(varargin) 2 | % FMRELI MATLAB code for fmreli.fig 3 | % FMRELI, by itself, creates a new FMRELI or raises the existing 4 | % singleton*. 5 | % 6 | % H = FMRELI returns the handle to a new FMRELI or the handle to 7 | % the existing singleton*. 8 | % 9 | % FMRELI('CALLBACK',hObject,eventData,handles,...) calls the local 10 | % function named CALLBACK in FMRELI.M with the given input arguments. 11 | % 12 | % FMRELI('Property','Value',...) creates a new FMRELI or raises the 13 | % existing singleton*. Starting from the left, property value pairs are 14 | % applied to the GUI before fmreli_openingfcn gets called. An 15 | % unrecognized property name or invalid value makes property application 16 | % stop. All inputs are passed to fmreli_openingfcn via varargin. 17 | % 18 | % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one 19 | % instance to run (singleton)". 20 | % 21 | % See also: GUIDE, GUIDATA, GUIHANDLES 22 | 23 | % Edit the above text to modify the response to help fmreli 24 | 25 | % Last Modified by GUIDE v2.5 18-Jun-2018 11:23:09 26 | 27 | % Begin initialization code - DO NOT EDIT 28 | gui_Singleton = 1; 29 | gui_State = struct('gui_Name', mfilename, ... 30 | 'gui_Singleton', gui_Singleton, ... 31 | 'gui_OpeningFcn', @fmreli_OpeningFcn, ... 32 | 'gui_OutputFcn', @fmreli_OutputFcn, ... 33 | 'gui_LayoutFcn', [] , ... 34 | 'gui_Callback', []); 35 | if nargin && ischar(varargin{1}) 36 | gui_State.gui_Callback = str2func(varargin{1}); 37 | end 38 | 39 | if nargout 40 | [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); 41 | else 42 | gui_mainfcn(gui_State, varargin{:}); 43 | end 44 | % End initialization code - DO NOT EDIT 45 | 46 | 47 | % --- Executes just before fmreli is made visible. 48 | function fmreli_OpeningFcn(hObject, eventdata, handles, varargin) 49 | % This function has no output args, see OutputFcn. 50 | % hObject handle to figure 51 | % eventdata reserved - to be defined in a future version of MATLAB 52 | % handles structure with handles and user data (see GUIDATA) 53 | % varargin command line arguments to fmreli (see VARARGIN) 54 | 55 | % Choose default command line output for fmreli 56 | handles.output = hObject; 57 | 58 | % Update handles structure 59 | guidata(hObject, handles); 60 | 61 | % UIWAIT makes fmreli wait for user response (see UIRESUME) 62 | % uiwait(handles.figure1); 63 | 64 | % --- Outputs from this function are returned to the command line. 65 | function varargout = fmreli_OutputFcn(hObject, eventdata, handles) 66 | % varargout cell array for returning output args (see VARARGOUT); 67 | % hObject handle to figure 68 | % eventdata reserved - to be defined in a future version of MATLAB 69 | % handles structure with handles and user data (see GUIDATA) 70 | 71 | % Get default command line output from handles structure 72 | varargout{1} = handles.output; 73 | disp('Starting fMRelI...'); 74 | % Get toolbox path from Matlab pathfile 75 | matlab_paths = path; 76 | if contains(matlab_paths,';') 77 | matlab_paths_cell = strsplit(matlab_paths,';'); 78 | elseif contains(matlab_paths,':') 79 | matlab_paths_cell = strsplit(matlab_paths,':'); 80 | end 81 | path_index = find(contains(matlab_paths_cell, 'fmreli')); 82 | if isempty(path_index) 83 | path_index = find(contains(matlab_paths_cell, 'reliability-master')); 84 | end 85 | box_path = matlab_paths_cell{path_index(1)}; 86 | %box_path=pwd; 87 | assignin('base','box_path',box_path); 88 | 89 | set(handles.specify,'TooltipString','Specification of sample, data folders etc.'); 90 | set(handles.define,'TooltipString','Specification of contrast names and regressor numbers'); 91 | set(handles.split,'TooltipString','Use split-half procedure to look at within-session reliability'); 92 | set(handles.CorrMaps,'TooltipString','Calculation of correlations and ICCs voxel-/ROI-wise'); 93 | set(handles.dice_ROI,'TooltipString','Calculation of Dice-/Jaccard-coefficients'); 94 | set(handles.similarity,'TooltipString','Calculation of global similarity measures'); 95 | set(handles.summary,'TooltipString','Creates reliability summary for all ROIs in atlas'); 96 | set(handles.threshold,'TooltipString','Creates ROIs with certain reliability threshold'); 97 | 98 | 99 | 100 | 101 | 102 | 103 | % --- Executes on button press in specify. 104 | function specify_Callback(hObject, eventdata, handles) 105 | % hObject handle to specify (see GCBO) 106 | % eventdata reserved - to be defined in a future version of MATLAB 107 | % handles structure with handles and user data (see GUIDATA) 108 | design; 109 | 110 | % --- Executes on button press in CorrMaps. 111 | function CorrMaps_Callback(hObject, eventdata, handles) 112 | % hObject handle to CorrMaps (see GCBO) 113 | % eventdata reserved - to be defined in a future version of MATLAB 114 | % handles structure with handles and user data (see GUIDATA) 115 | CorrICC; 116 | 117 | 118 | % --- Executes on button press in split. 119 | function split_Callback(hObject, eventdata, handles) 120 | % hObject handle to split (see GCBO) 121 | % eventdata reserved - to be defined in a future version of MATLAB 122 | % handles structure with handles and user data (see GUIDATA) 123 | SplitHalf; 124 | 125 | 126 | % --- Executes on button press in dice_ROI. 127 | function dice_ROI_Callback(hObject, eventdata, handles) 128 | % hObject handle to dice_ROI (see GCBO) 129 | % eventdata reserved - to be defined in a future version of MATLAB 130 | % handles structure with handles and user data (see GUIDATA) 131 | Overlap; 132 | 133 | % --- Executes on button press in define. 134 | function define_Callback(hObject, eventdata, handles) 135 | % hObject handle to define (see GCBO) 136 | % eventdata reserved - to be defined in a future version of MATLAB 137 | % handles structure with handles and user data (see GUIDATA) 138 | Contrast_Def; 139 | 140 | % --- Executes on button press in similarity. 141 | function similarity_Callback(hObject, eventdata, handles) 142 | % hObject handle to similarity (see GCBO) 143 | % eventdata reserved - to be defined in a future version of MATLAB 144 | % handles structure with handles and user data (see GUIDATA) 145 | Similarity; 146 | 147 | % --- Executes on button press in summary. 148 | function summary_Callback(hObject, eventdata, handles) 149 | % hObject handle to summary (see GCBO) 150 | % eventdata reserved - to be defined in a future version of MATLAB 151 | % handles structure with handles and user data (see GUIDATA) 152 | Summary; 153 | 154 | % --- Executes on button press in threshold. 155 | function threshold_Callback(hObject, eventdata, handles) 156 | % hObject handle to threshold (see GCBO) 157 | % eventdata reserved - to be defined in a future version of MATLAB 158 | % handles structure with handles and user data (see GUIDATA) 159 | Corr2ROI; 160 | 161 | % --- Executes during object creation, after setting all properties. 162 | function axes2_CreateFcn(hObject, eventdata, handles) 163 | % hObject handle to axes1 (see GCBO) 164 | % eventdata reserved - to be defined in a future version of MATLAB 165 | % handles empty - handles not created until after all CreateFcns called 166 | 167 | % Hint: place code in OpeningFcn to populate axes1 168 | axes(hObject); 169 | imshow('logo.png'); 170 | 171 | 172 | % --- Executes on button press in desana. 173 | function desana_Callback(hObject, eventdata, handles) 174 | % hObject handle to desana (see GCBO) 175 | % eventdata reserved - to be defined in a future version of MATLAB 176 | % handles structure with handles and user data (see GUIDATA) 177 | design_ana; 178 | 179 | function desana_CreateFcn(hObject, eventdata, handles) 180 | -------------------------------------------------------------------------------- /scripts_templates/make_nii.m: -------------------------------------------------------------------------------- 1 | % Make NIfTI structure specified by an N-D matrix. Usually, N is 3 for 2 | % 3D matrix [x y z], or 4 for 4D matrix with time series [x y z t]. 3 | % Optional parameters can also be included, such as: voxel_size, 4 | % origin, datatype, and description. 5 | % 6 | % Once the NIfTI structure is made, it can be saved into NIfTI file 7 | % using "save_nii" command (for more detail, type: help save_nii). 8 | % 9 | % Usage: nii = make_nii(img, [voxel_size], [origin], [datatype], [description]) 10 | % 11 | % Where: 12 | % 13 | % img: Usually, img is a 3D matrix [x y z], or a 4D 14 | % matrix with time series [x y z t]. However, 15 | % NIfTI allows a maximum of 7D matrix. When the 16 | % image is in RGB format, make sure that the size 17 | % of 4th dimension is always 3 (i.e. [R G B]). In 18 | % that case, make sure that you must specify RGB 19 | % datatype, which is either 128 or 511. 20 | % 21 | % voxel_size (optional): Voxel size in millimeter for each 22 | % dimension. Default is [1 1 1]. 23 | % 24 | % origin (optional): The AC origin. Default is [0 0 0]. 25 | % 26 | % datatype (optional): Storage data type: 27 | % 2 - uint8, 4 - int16, 8 - int32, 16 - float32, 28 | % 32 - complex64, 64 - float64, 128 - RGB24, 29 | % 256 - int8, 511 - RGB96, 512 - uint16, 30 | % 768 - uint32, 1792 - complex128 31 | % Default will use the data type of 'img' matrix 32 | % For RGB image, you must specify it to either 128 33 | % or 511. 34 | % 35 | % description (optional): Description of data. Default is ''. 36 | % 37 | % e.g.: 38 | % origin = [33 44 13]; datatype = 64; 39 | % nii = make_nii(img, [], origin, datatype); % default voxel_size 40 | % 41 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 42 | % 43 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 44 | % 45 | function nii = make_nii(varargin) 46 | 47 | nii.img = varargin{1}; 48 | dims = size(nii.img); 49 | dims = [length(dims) dims ones(1,8)]; 50 | dims = dims(1:8); 51 | 52 | voxel_size = [0 ones(1,7)]; 53 | origin = zeros(1,5); 54 | descrip = ''; 55 | 56 | switch class(nii.img) 57 | case 'uint8' 58 | datatype = 2; 59 | case 'int16' 60 | datatype = 4; 61 | case 'int32' 62 | datatype = 8; 63 | case 'single' 64 | if isreal(nii.img) 65 | datatype = 16; 66 | else 67 | datatype = 32; 68 | end 69 | case 'double' 70 | if isreal(nii.img) 71 | datatype = 64; 72 | else 73 | datatype = 1792; 74 | end 75 | case 'int8' 76 | datatype = 256; 77 | case 'uint16' 78 | datatype = 512; 79 | case 'uint32' 80 | datatype = 768; 81 | otherwise 82 | error('Datatype is not supported by make_nii.'); 83 | end 84 | 85 | if nargin > 1 & ~isempty(varargin{2}) 86 | voxel_size(2:4) = double(varargin{2}); 87 | end 88 | 89 | if nargin > 2 & ~isempty(varargin{3}) 90 | origin(1:3) = double(varargin{3}); 91 | end 92 | 93 | if nargin > 3 & ~isempty(varargin{4}) 94 | datatype = double(varargin{4}); 95 | 96 | if datatype == 128 | datatype == 511 97 | dims(5) = []; 98 | dims(1) = dims(1) - 1; 99 | dims = [dims 1]; 100 | end 101 | end 102 | 103 | if nargin > 4 & ~isempty(varargin{5}) 104 | descrip = varargin{5}; 105 | end 106 | 107 | if ndims(nii.img) > 7 108 | error('NIfTI only allows a maximum of 7 Dimension matrix.'); 109 | end 110 | 111 | maxval = round(double(max(nii.img(:)))); 112 | minval = round(double(min(nii.img(:)))); 113 | 114 | nii.hdr = make_header(dims, voxel_size, origin, datatype, ... 115 | descrip, maxval, minval); 116 | 117 | switch nii.hdr.dime.datatype 118 | case 2 119 | nii.img = uint8(nii.img); 120 | case 4 121 | nii.img = int16(nii.img); 122 | case 8 123 | nii.img = int32(nii.img); 124 | case 16 125 | nii.img = single(nii.img); 126 | case 32 127 | nii.img = single(nii.img); 128 | case 64 129 | nii.img = double(nii.img); 130 | case 128 131 | nii.img = uint8(nii.img); 132 | case 256 133 | nii.img = int8(nii.img); 134 | case 511 135 | img = double(nii.img(:)); 136 | img = single((img - min(img))/(max(img) - min(img))); 137 | nii.img = reshape(img, size(nii.img)); 138 | nii.hdr.dime.glmax = double(max(img)); 139 | nii.hdr.dime.glmin = double(min(img)); 140 | case 512 141 | nii.img = uint16(nii.img); 142 | case 768 143 | nii.img = uint32(nii.img); 144 | case 1792 145 | nii.img = double(nii.img); 146 | otherwise 147 | error('Datatype is not supported by make_nii.'); 148 | end 149 | 150 | return; % make_nii 151 | 152 | 153 | %--------------------------------------------------------------------- 154 | function hdr = make_header(dims, voxel_size, origin, datatype, ... 155 | descrip, maxval, minval) 156 | 157 | hdr.hk = header_key; 158 | hdr.dime = image_dimension(dims, voxel_size, datatype, maxval, minval); 159 | hdr.hist = data_history(origin, descrip); 160 | 161 | return; % make_header 162 | 163 | 164 | %--------------------------------------------------------------------- 165 | function hk = header_key 166 | 167 | hk.sizeof_hdr = 348; % must be 348! 168 | hk.data_type = ''; 169 | hk.db_name = ''; 170 | hk.extents = 0; 171 | hk.session_error = 0; 172 | hk.regular = 'r'; 173 | hk.dim_info = 0; 174 | 175 | return; % header_key 176 | 177 | 178 | %--------------------------------------------------------------------- 179 | function dime = image_dimension(dims, voxel_size, datatype, maxval, minval) 180 | 181 | dime.dim = dims; 182 | dime.intent_p1 = 0; 183 | dime.intent_p2 = 0; 184 | dime.intent_p3 = 0; 185 | dime.intent_code = 0; 186 | dime.datatype = datatype; 187 | 188 | switch dime.datatype 189 | case 2, 190 | dime.bitpix = 8; precision = 'uint8'; 191 | case 4, 192 | dime.bitpix = 16; precision = 'int16'; 193 | case 8, 194 | dime.bitpix = 32; precision = 'int32'; 195 | case 16, 196 | dime.bitpix = 32; precision = 'float32'; 197 | case 32, 198 | dime.bitpix = 64; precision = 'float32'; 199 | case 64, 200 | dime.bitpix = 64; precision = 'float64'; 201 | case 128 202 | dime.bitpix = 24; precision = 'uint8'; 203 | case 256 204 | dime.bitpix = 8; precision = 'int8'; 205 | case 511 206 | dime.bitpix = 96; precision = 'float32'; 207 | case 512 208 | dime.bitpix = 16; precision = 'uint16'; 209 | case 768 210 | dime.bitpix = 32; precision = 'uint32'; 211 | case 1792, 212 | dime.bitpix = 128; precision = 'float64'; 213 | otherwise 214 | error('Datatype is not supported by make_nii.'); 215 | end 216 | 217 | dime.slice_start = 0; 218 | dime.pixdim = voxel_size; 219 | dime.vox_offset = 0; 220 | dime.scl_slope = 0; 221 | dime.scl_inter = 0; 222 | dime.slice_end = 0; 223 | dime.slice_code = 0; 224 | dime.xyzt_units = 0; 225 | dime.cal_max = 0; 226 | dime.cal_min = 0; 227 | dime.slice_duration = 0; 228 | dime.toffset = 0; 229 | dime.glmax = maxval; 230 | dime.glmin = minval; 231 | 232 | return; % image_dimension 233 | 234 | 235 | %--------------------------------------------------------------------- 236 | function hist = data_history(origin, descrip) 237 | 238 | hist.descrip = descrip; 239 | hist.aux_file = 'none'; 240 | hist.qform_code = 0; 241 | hist.sform_code = 0; 242 | hist.quatern_b = 0; 243 | hist.quatern_c = 0; 244 | hist.quatern_d = 0; 245 | hist.qoffset_x = 0; 246 | hist.qoffset_y = 0; 247 | hist.qoffset_z = 0; 248 | hist.srow_x = zeros(1,4); 249 | hist.srow_y = zeros(1,4); 250 | hist.srow_z = zeros(1,4); 251 | hist.intent_name = ''; 252 | hist.magic = ''; 253 | hist.originator = origin; 254 | 255 | return; % data_history 256 | 257 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fmreli toolbox beta v1.0 2 | 3 | ## What is the fmreli toolbox? 4 | 5 | The toolbox was designed to simplify the assessment of reliability and similarity of fMRI data across different sessions and contrasts. It incorporates common measures of global and local reliability. Moreover, it implements the assessment of reliability for cross-sectional designs with only a single run by randomly splitting the trials in half. fmreli offers a graphical user interface (GUI) and incorporates functions provided by [*SPM*](http://www.fil.ion.ucl.ac.uk/spm/software/spm12/) and and the [*Nifti and ANALYZE toolbox*](https://de.mathworks.com/matlabcentral/fileexchange/8797-tools-for-nifti-and-analyze-image). A preprint of the paper detailing the use of the toolbox is available at [bioRxiv.org](https://doi.org/10.1101/215053). 6 | 7 | ## Dependencies 8 | 9 | To use the toolbox, you need to have MATLAB (v2015 or later) and SPM12 installed (see instructions). 10 | 11 | ## Installing the toolbox 12 | 13 | 1. Make sure that you have [SPM12](http://www.fil.ion.ucl.ac.uk/spm/software/download/) installed. 14 | 1. Download the latest version of the toolbox on [github](https://github.com/nkroemer/reliability/) and save it into your intended directory. 15 | 1. In the MATLAB 'Home' tab, click on the 'Set path' button and select 'Add with subfolders…'. Now, select the fmreli toolbox folder, save, and close. Windows users might have to open MATLAB as an administrator (by right-clicking on the MATLAB icon) to make permanent changes. 16 | Alternatively, you may use the command line to add the path: 17 | ``` 18 | pathtool 19 | addpath(genpath('fmreli toolbox folder')) 20 | savepath fmreli toolbox folder/pathdef.m 21 | ``` 22 | 23 | By default, the toolbox comes with the [CONN](https://www.nitrc.org/projects/conn/) atlas (i.e., Harvard-Oxford brain atlas + AAL cerebellum atlas). Other customized atlases can be used, if you provide an 'atlas.nii' and a corresponding 'labels.mat' file containing the atlas labels. 24 | 25 | That's it, you are good to go. 26 | 27 | ## Basic setup 28 | 29 | 1. After installing, you can call the toolbox by entering *fmreli* in the command line. 30 | 31 | 1. The toolbox was developed to work primarily with first-level statistics in SPM12. 32 | The required folder structure is (at the moment) as follows: 33 | 1. Project folder containing one subfolder for every participant 34 | 1. Within every participant folder, there should be one folder for every session. The session should be given in the folder name and contain the first-level SPM stats including all outputs. 35 | For example: C:\user\projects\fmreli\subj_123\new_paradigm_1 36 | 37 | 1. Next, you can specify the design: 38 | 1. Click on the 'Design' dialog. 39 | 1. Enter the number of subjects. 40 | 1. Click on the 'load subject list' dialog and load a \*.mat file containing the subject IDs as a (N-by-1) vector. 41 | 1. Specify the number of sessions. 42 | 1. Specify the directory where your first-level outputs are stored. 43 | 1. Pick a prefix to be added to all output files and choose a directory where output files from the toolbox will be saved. 44 | 1. Save your study design and close the dialog box. A \*.mat file containing the information on your study design will be saved to your output folder. 45 | 46 | 1. Now that you have specified the design, you can open it as a template and define the contrasts of interest for the following analysis. 47 | 1. Click on the 'Contrast(s) of interest' dialog. 48 | 1. Define the contrast(s) by the name they were given in the first-level SPM contrast manager. In case you renamed the output files, you can adjust the prefix accordingly in the dialog on the left. 49 | 1. Click on the 'Save contrast definition' dialog. This saves a \*.mat file to your fmreli output folder containing your contrast information. 50 | 51 | ### If no first-level statistics with design matrices are available (e.g., resting state or DWI) 52 | 53 | 1. *fmreli beta 1.0* offers the possibility to use existing 4D files as input as well. Since this function was not at the heart of the development, there is only a limited work flow available at the moment. 54 | 1. Please save your 4D files for the analysis in the defined results directory. 55 | 1. If you have several conditions, please name the 4D files accordingly. For example, when there is data for two sessions in a placebo and drug condition: 4D_int_1.nii, 4D_int_2.nii, 4D_pla_1.nii, 4D_pla_2.nii 56 | 1. If you have only one condition for several sessions, just denote the sessions by 4D_1.nii, 4D_2.nii ... 57 | 1. Please also provide an exemplary 3D nifti called 'template_3D.nii' to facilitate creating result images with the image dimensions of your study. This can be simply one image of the 4D.nii (this will be fixed in a future version) 58 | 1. In the GUI, please select design, enter the number of sessions, enter the number of subjects, and select the "yes" checkbox for only 4D data as input. As result directory, you will have to enter the directory where the corresponding 4D niftis are stored. 59 | 1. Please note that if you do not provide the first-level statistics, the features split-half and overlap cannot be used, at least in the current version. 60 | 61 | ### Split-half reliability: Assessing reliability within a single contrast and session 62 | 63 | If you have only data from one fMRI run/session and are interested in the reliability of one contrast/condition, the toolbox offers the option to split the data. 64 | 65 | 1. Click on the 'Split-Half' dialog. 66 | 1. Load your study design. 67 | 1. Indicate the number of the condition you want to split (according to the design information in the SPM.mat). 68 | 1. Define a name for the split-half output file. 69 | 1. Always check the 'split data' box throughout the use in different modules in analyzing split-half data. 70 | 1. Click 'RUN' to start. 71 | 72 | ### Assessment of global brain reliability 73 | 74 | #### Whole-brain/ROI similarity of brain response patterns 75 | 76 | The similarity module computes the global similarity of activation maps between participants across runs or sessions. 77 | 78 | 1. Define the study design and contrasts of interest. 79 | 1. OPTIONAL Select 'use ROI' and define the ROI name and directory if you want to restrict the analysis to a subset of voxels. 80 | 1. Click 'RUN'. 81 | 82 | The output from this module includes heatmaps, density plots, and histograms depicting the similarity between participants across runs or sessions. Moreover, a \*.mat file will be saved containing the correlation coefficients and corresponding p-values. 83 | 84 | #### Whole-brain/ROI overlap 85 | 86 | In this module, the Dice and Jaccard coefficients of overlap of activated voxels can be computed. 87 | 88 | 1. Define the study design and contrasts of interest. 89 | 1. Set a p-value used as threshold for significant activation of a voxel. By default, it is applied to the first-level statistics, but you can choose to apply the threshold to the group-level statistics as well. 90 | 1. OPTIONAL Select 'use ROI' and define the ROI name and directory if you want to restrict the analysis to a subset of voxels. 91 | 1. Click 'RUN'. 92 | 93 | In the output folder, you will find a file containing the coefficients for every subject. 94 | 95 | ### Voxel-wise/ROI reliability 96 | 97 | This module is used to calculate the correlation coefficients (intra-class coefficient, Pearson & Spearman correlation coefficients) on the voxel level within subjects and between contrasts. 98 | 99 | 1. Define the study design and contrasts of interest. 100 | 1. Check the boxes to select coefficients you want to analyze. 101 | 1. OPTIONAL Select 'use ROI' and define the ROI name and directory if you want to restrict the analysis to a subset of voxels. 102 | 1. Click 'RUN'. 103 | 104 | This module will create several 3D-nifti output files named after the coefficient you had selected. 105 | 106 | ### Summary functions 107 | 108 | #### Atlas-based reliability 109 | 110 | With this module, you can create an output aggregated for ROIs provided by the atlas. The output is a matrix containing the reliability coefficients for every ROI in the atlas for every analysis. 111 | 112 | ## Bug report, suggestions & questions 113 | 114 | Please do not hesitate to email us ( & ) regarding questions, feature requests or bug reports. We are happy to receive your feedback to improve fmreli. In case something does not work or you find a bug or error in the toolbox, please let us know via the [issues page](https://github.com/nkroemer/reliability/issues). 115 | -------------------------------------------------------------------------------- /scripts_templates/load_untouch0_nii_hdr.m: -------------------------------------------------------------------------------- 1 | % internal function 2 | 3 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 4 | 5 | function hdr = load_nii_hdr(fileprefix, machine) 6 | 7 | fn = sprintf('%s.hdr',fileprefix); 8 | fid = fopen(fn,'r',machine); 9 | 10 | if fid < 0, 11 | msg = sprintf('Cannot open file %s.',fn); 12 | error(msg); 13 | else 14 | fseek(fid,0,'bof'); 15 | hdr = read_header(fid); 16 | fclose(fid); 17 | end 18 | 19 | return % load_nii_hdr 20 | 21 | 22 | %--------------------------------------------------------------------- 23 | function [ dsr ] = read_header(fid) 24 | 25 | % Original header structures 26 | % struct dsr 27 | % { 28 | % struct header_key hk; /* 0 + 40 */ 29 | % struct image_dimension dime; /* 40 + 108 */ 30 | % struct data_history hist; /* 148 + 200 */ 31 | % }; /* total= 348 bytes*/ 32 | 33 | dsr.hk = header_key(fid); 34 | dsr.dime = image_dimension(fid); 35 | dsr.hist = data_history(fid); 36 | 37 | return % read_header 38 | 39 | 40 | %--------------------------------------------------------------------- 41 | function [ hk ] = header_key(fid) 42 | 43 | fseek(fid,0,'bof'); 44 | 45 | % Original header structures 46 | % struct header_key /* header key */ 47 | % { /* off + size */ 48 | % int sizeof_hdr /* 0 + 4 */ 49 | % char data_type[10]; /* 4 + 10 */ 50 | % char db_name[18]; /* 14 + 18 */ 51 | % int extents; /* 32 + 4 */ 52 | % short int session_error; /* 36 + 2 */ 53 | % char regular; /* 38 + 1 */ 54 | % char hkey_un0; /* 39 + 1 */ 55 | % }; /* total=40 bytes */ 56 | % 57 | % int sizeof_header Should be 348. 58 | % char regular Must be 'r' to indicate that all images and 59 | % volumes are the same size. 60 | 61 | v6 = version; 62 | if str2num(v6(1))<6 63 | directchar = '*char'; 64 | else 65 | directchar = 'uchar=>char'; 66 | end 67 | 68 | hk.sizeof_hdr = fread(fid, 1,'int32')'; % should be 348! 69 | hk.data_type = deblank(fread(fid,10,directchar)'); 70 | hk.db_name = deblank(fread(fid,18,directchar)'); 71 | hk.extents = fread(fid, 1,'int32')'; 72 | hk.session_error = fread(fid, 1,'int16')'; 73 | hk.regular = fread(fid, 1,directchar)'; 74 | hk.hkey_un0 = fread(fid, 1,directchar)'; 75 | 76 | return % header_key 77 | 78 | 79 | %--------------------------------------------------------------------- 80 | function [ dime ] = image_dimension(fid) 81 | 82 | %struct image_dimension 83 | % { /* off + size */ 84 | % short int dim[8]; /* 0 + 16 */ 85 | % /* 86 | % dim[0] Number of dimensions in database; usually 4. 87 | % dim[1] Image X dimension; number of *pixels* in an image row. 88 | % dim[2] Image Y dimension; number of *pixel rows* in slice. 89 | % dim[3] Volume Z dimension; number of *slices* in a volume. 90 | % dim[4] Time points; number of volumes in database 91 | % */ 92 | % char vox_units[4]; /* 16 + 4 */ 93 | % char cal_units[8]; /* 20 + 8 */ 94 | % short int unused1; /* 28 + 2 */ 95 | % short int datatype; /* 30 + 2 */ 96 | % short int bitpix; /* 32 + 2 */ 97 | % short int dim_un0; /* 34 + 2 */ 98 | % float pixdim[8]; /* 36 + 32 */ 99 | % /* 100 | % pixdim[] specifies the voxel dimensions: 101 | % pixdim[1] - voxel width, mm 102 | % pixdim[2] - voxel height, mm 103 | % pixdim[3] - slice thickness, mm 104 | % pixdim[4] - volume timing, in msec 105 | % ..etc 106 | % */ 107 | % float vox_offset; /* 68 + 4 */ 108 | % float roi_scale; /* 72 + 4 */ 109 | % float funused1; /* 76 + 4 */ 110 | % float funused2; /* 80 + 4 */ 111 | % float cal_max; /* 84 + 4 */ 112 | % float cal_min; /* 88 + 4 */ 113 | % int compressed; /* 92 + 4 */ 114 | % int verified; /* 96 + 4 */ 115 | % int glmax; /* 100 + 4 */ 116 | % int glmin; /* 104 + 4 */ 117 | % }; /* total=108 bytes */ 118 | 119 | v6 = version; 120 | if str2num(v6(1))<6 121 | directchar = '*char'; 122 | else 123 | directchar = 'uchar=>char'; 124 | end 125 | 126 | dime.dim = fread(fid,8,'int16')'; 127 | dime.vox_units = deblank(fread(fid,4,directchar)'); 128 | dime.cal_units = deblank(fread(fid,8,directchar)'); 129 | dime.unused1 = fread(fid,1,'int16')'; 130 | dime.datatype = fread(fid,1,'int16')'; 131 | dime.bitpix = fread(fid,1,'int16')'; 132 | dime.dim_un0 = fread(fid,1,'int16')'; 133 | dime.pixdim = fread(fid,8,'float32')'; 134 | dime.vox_offset = fread(fid,1,'float32')'; 135 | dime.roi_scale = fread(fid,1,'float32')'; 136 | dime.funused1 = fread(fid,1,'float32')'; 137 | dime.funused2 = fread(fid,1,'float32')'; 138 | dime.cal_max = fread(fid,1,'float32')'; 139 | dime.cal_min = fread(fid,1,'float32')'; 140 | dime.compressed = fread(fid,1,'int32')'; 141 | dime.verified = fread(fid,1,'int32')'; 142 | dime.glmax = fread(fid,1,'int32')'; 143 | dime.glmin = fread(fid,1,'int32')'; 144 | 145 | return % image_dimension 146 | 147 | 148 | %--------------------------------------------------------------------- 149 | function [ hist ] = data_history(fid) 150 | 151 | %struct data_history 152 | % { /* off + size */ 153 | % char descrip[80]; /* 0 + 80 */ 154 | % char aux_file[24]; /* 80 + 24 */ 155 | % char orient; /* 104 + 1 */ 156 | % char originator[10]; /* 105 + 10 */ 157 | % char generated[10]; /* 115 + 10 */ 158 | % char scannum[10]; /* 125 + 10 */ 159 | % char patient_id[10]; /* 135 + 10 */ 160 | % char exp_date[10]; /* 145 + 10 */ 161 | % char exp_time[10]; /* 155 + 10 */ 162 | % char hist_un0[3]; /* 165 + 3 */ 163 | % int views /* 168 + 4 */ 164 | % int vols_added; /* 172 + 4 */ 165 | % int start_field; /* 176 + 4 */ 166 | % int field_skip; /* 180 + 4 */ 167 | % int omax; /* 184 + 4 */ 168 | % int omin; /* 188 + 4 */ 169 | % int smax; /* 192 + 4 */ 170 | % int smin; /* 196 + 4 */ 171 | % }; /* total=200 bytes */ 172 | 173 | v6 = version; 174 | if str2num(v6(1))<6 175 | directchar = '*char'; 176 | else 177 | directchar = 'uchar=>char'; 178 | end 179 | 180 | hist.descrip = deblank(fread(fid,80,directchar)'); 181 | hist.aux_file = deblank(fread(fid,24,directchar)'); 182 | hist.orient = fread(fid, 1,'char')'; 183 | hist.originator = fread(fid, 5,'int16')'; 184 | hist.generated = deblank(fread(fid,10,directchar)'); 185 | hist.scannum = deblank(fread(fid,10,directchar)'); 186 | hist.patient_id = deblank(fread(fid,10,directchar)'); 187 | hist.exp_date = deblank(fread(fid,10,directchar)'); 188 | hist.exp_time = deblank(fread(fid,10,directchar)'); 189 | hist.hist_un0 = deblank(fread(fid, 3,directchar)'); 190 | hist.views = fread(fid, 1,'int32')'; 191 | hist.vols_added = fread(fid, 1,'int32')'; 192 | hist.start_field = fread(fid, 1,'int32')'; 193 | hist.field_skip = fread(fid, 1,'int32')'; 194 | hist.omax = fread(fid, 1,'int32')'; 195 | hist.omin = fread(fid, 1,'int32')'; 196 | hist.smax = fread(fid, 1,'int32')'; 197 | hist.smin = fread(fid, 1,'int32')'; 198 | 199 | return % data_history 200 | 201 | -------------------------------------------------------------------------------- /scripts_templates/extra_nii_hdr.m: -------------------------------------------------------------------------------- 1 | % Decode extra NIFTI header information into hdr.extra 2 | % 3 | % Usage: hdr = extra_nii_hdr(hdr) 4 | % 5 | % hdr can be obtained from load_nii_hdr 6 | % 7 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 8 | % 9 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 10 | % 11 | function hdr = extra_nii_hdr(hdr) 12 | 13 | switch hdr.dime.datatype 14 | case 1 15 | extra.NIFTI_DATATYPES = 'DT_BINARY'; 16 | case 2 17 | extra.NIFTI_DATATYPES = 'DT_UINT8'; 18 | case 4 19 | extra.NIFTI_DATATYPES = 'DT_INT16'; 20 | case 8 21 | extra.NIFTI_DATATYPES = 'DT_INT32'; 22 | case 16 23 | extra.NIFTI_DATATYPES = 'DT_FLOAT32'; 24 | case 32 25 | extra.NIFTI_DATATYPES = 'DT_COMPLEX64'; 26 | case 64 27 | extra.NIFTI_DATATYPES = 'DT_FLOAT64'; 28 | case 128 29 | extra.NIFTI_DATATYPES = 'DT_RGB24'; 30 | case 256 31 | extra.NIFTI_DATATYPES = 'DT_INT8'; 32 | case 512 33 | extra.NIFTI_DATATYPES = 'DT_UINT16'; 34 | case 768 35 | extra.NIFTI_DATATYPES = 'DT_UINT32'; 36 | case 1024 37 | extra.NIFTI_DATATYPES = 'DT_INT64'; 38 | case 1280 39 | extra.NIFTI_DATATYPES = 'DT_UINT64'; 40 | case 1536 41 | extra.NIFTI_DATATYPES = 'DT_FLOAT128'; 42 | case 1792 43 | extra.NIFTI_DATATYPES = 'DT_COMPLEX128'; 44 | case 2048 45 | extra.NIFTI_DATATYPES = 'DT_COMPLEX256'; 46 | otherwise 47 | extra.NIFTI_DATATYPES = 'DT_UNKNOWN'; 48 | end 49 | 50 | switch hdr.dime.intent_code 51 | case 2 52 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CORREL'; 53 | case 3 54 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_TTEST'; 55 | case 4 56 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_FTEST'; 57 | case 5 58 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_ZSCORE'; 59 | case 6 60 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CHISQ'; 61 | case 7 62 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_BETA'; 63 | case 8 64 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_BINOM'; 65 | case 9 66 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_GAMMA'; 67 | case 10 68 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_POISSON'; 69 | case 11 70 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_NORMAL'; 71 | case 12 72 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_FTEST_NONC'; 73 | case 13 74 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CHISQ_NONC'; 75 | case 14 76 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LOGISTIC'; 77 | case 15 78 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LAPLACE'; 79 | case 16 80 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_UNIFORM'; 81 | case 17 82 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_TTEST_NONC'; 83 | case 18 84 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_WEIBULL'; 85 | case 19 86 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CHI'; 87 | case 20 88 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_INVGAUSS'; 89 | case 21 90 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_EXTVAL'; 91 | case 22 92 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_PVAL'; 93 | case 23 94 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LOGPVAL'; 95 | case 24 96 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LOG10PVAL'; 97 | case 1001 98 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_ESTIMATE'; 99 | case 1002 100 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LABEL'; 101 | case 1003 102 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_NEURONAME'; 103 | case 1004 104 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_GENMATRIX'; 105 | case 1005 106 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_SYMMATRIX'; 107 | case 1006 108 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_DISPVECT'; 109 | case 1007 110 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_VECTOR'; 111 | case 1008 112 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_POINTSET'; 113 | case 1009 114 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_TRIANGLE'; 115 | case 1010 116 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_QUATERNION'; 117 | case 1011 118 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_DIMLESS'; 119 | otherwise 120 | extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_NONE'; 121 | end 122 | 123 | extra.NIFTI_INTENT_NAMES = hdr.hist.intent_name; 124 | 125 | if hdr.hist.sform_code > 0 126 | switch hdr.hist.sform_code 127 | case 1 128 | extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_SCANNER_ANAT'; 129 | case 2 130 | extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_ALIGNED_ANAT'; 131 | case 3 132 | extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_TALAIRACH'; 133 | case 4 134 | extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_MNI_152'; 135 | otherwise 136 | extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; 137 | end 138 | 139 | extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; 140 | elseif hdr.hist.qform_code > 0 141 | extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; 142 | 143 | switch hdr.hist.qform_code 144 | case 1 145 | extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_SCANNER_ANAT'; 146 | case 2 147 | extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_ALIGNED_ANAT'; 148 | case 3 149 | extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_TALAIRACH'; 150 | case 4 151 | extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_MNI_152'; 152 | otherwise 153 | extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; 154 | end 155 | else 156 | extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; 157 | extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; 158 | end 159 | 160 | switch bitand(hdr.dime.xyzt_units, 7) % mask with 0x07 161 | case 1 162 | extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_METER'; 163 | case 2 164 | extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_MM'; % millimeter 165 | case 3 166 | extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_MICRO'; 167 | otherwise 168 | extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_UNKNOWN'; 169 | end 170 | 171 | switch bitand(hdr.dime.xyzt_units, 56) % mask with 0x38 172 | case 8 173 | extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_SEC'; 174 | case 16 175 | extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_MSEC'; 176 | case 24 177 | extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_USEC'; % microsecond 178 | otherwise 179 | extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_UNKNOWN'; 180 | end 181 | 182 | switch hdr.dime.xyzt_units 183 | case 32 184 | extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_HZ'; 185 | case 40 186 | extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_PPM'; % part per million 187 | case 48 188 | extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_RADS'; % radians per second 189 | otherwise 190 | extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_UNKNOWN'; 191 | end 192 | 193 | % MRI-specific spatial and temporal information 194 | % 195 | dim_info = hdr.hk.dim_info; 196 | extra.NIFTI_FREQ_DIM = bitand(dim_info, 3); 197 | extra.NIFTI_PHASE_DIM = bitand(bitshift(dim_info, -2), 3); 198 | extra.NIFTI_SLICE_DIM = bitand(bitshift(dim_info, -4), 3); 199 | 200 | % Check slice code 201 | % 202 | switch hdr.dime.slice_code 203 | case 1 204 | extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_SEQ_INC'; % sequential increasing 205 | case 2 206 | extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_SEQ_DEC'; % sequential decreasing 207 | case 3 208 | extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_INC'; % alternating increasing 209 | case 4 210 | extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_DEC'; % alternating decreasing 211 | case 5 212 | extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_INC2'; % ALT_INC # 2 213 | case 6 214 | extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_DEC2'; % ALT_DEC # 2 215 | otherwise 216 | extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_UNKNOWN'; 217 | end 218 | 219 | % Check NIFTI version 220 | % 221 | if ~isempty(hdr.hist.magic) & strcmp(hdr.hist.magic(1),'n') & ... 222 | ( strcmp(hdr.hist.magic(2),'i') | strcmp(hdr.hist.magic(2),'+') ) & ... 223 | str2num(hdr.hist.magic(3)) >= 1 & str2num(hdr.hist.magic(3)) <= 9 224 | 225 | extra.NIFTI_VERSION = str2num(hdr.hist.magic(3)); 226 | else 227 | extra.NIFTI_VERSION = 0; 228 | end 229 | 230 | % Check if data stored in the same file (*.nii) or separate 231 | % files (*.hdr/*.img) 232 | % 233 | if isempty(hdr.hist.magic) 234 | extra.NIFTI_ONEFILE = 0; 235 | else 236 | extra.NIFTI_ONEFILE = strcmp(hdr.hist.magic(2), '+'); 237 | end 238 | 239 | % Swap has been taken care of by checking whether sizeof_hdr is 240 | % 348 (machine is 'ieee-le' or 'ieee-be' etc) 241 | % 242 | % extra.NIFTI_NEEDS_SWAP = (hdr.dime.dim(1) < 0 | hdr.dime.dim(1) > 7); 243 | 244 | % Check NIFTI header struct contains a 5th (vector) dimension 245 | % 246 | if hdr.dime.dim(1) > 4 & hdr.dime.dim(6) > 1 247 | extra.NIFTI_5TH_DIM = hdr.dime.dim(6); 248 | else 249 | extra.NIFTI_5TH_DIM = 0; 250 | end 251 | 252 | hdr.extra = extra; 253 | 254 | return; % extra_nii_hdr 255 | 256 | -------------------------------------------------------------------------------- /scripts_templates/reslice_nii.m: -------------------------------------------------------------------------------- 1 | % The basic application of the 'reslice_nii.m' program is to perform 2 | % any 3D affine transform defined by a NIfTI format image. 3 | % 4 | % In addition, the 'reslice_nii.m' program can also be applied to 5 | % generate an isotropic image from either a NIfTI format image or 6 | % an ANALYZE format image. 7 | % 8 | % The resliced NIfTI file will always be in RAS orientation. 9 | % 10 | % This program only supports real integer or floating-point data type. 11 | % For other data type, the program will exit with an error message 12 | % "Transform of this NIFTI data is not supported by the program". 13 | % 14 | % Usage: reslice_nii(old_fn, new_fn, [voxel_size], [verbose], [bg], ... 15 | % [method], [img_idx], [preferredForm]); 16 | % 17 | % old_fn - filename for original NIfTI file 18 | % 19 | % new_fn - filename for resliced NIfTI file 20 | % 21 | % voxel_size (optional) - size of a voxel in millimeter along x y z 22 | % direction for resliced NIfTI file. 'voxel_size' will use 23 | % the rounded minimum voxel_size in original NIfTI header, 24 | % if it is default or empty. 25 | % 26 | % verbose (optional) - 1, 0 27 | % 1: show transforming progress in percentage 28 | % 2: progress will not be displayed 29 | % 'verbose' is 1 if it is default or empty. 30 | % 31 | % bg (optional) - background voxel intensity in any extra corner that 32 | % is caused by 3D interpolation. 0 in most cases. 'bg' 33 | % will be the average of two corner voxel intensities 34 | % in original image volume, if it is default or empty. 35 | % 36 | % method (optional) - 1, 2, or 3 37 | % 1: for Trilinear interpolation 38 | % 2: for Nearest Neighbor interpolation 39 | % 3: for Fischer's Bresenham interpolation 40 | % 'method' is 1 if it is default or empty. 41 | % 42 | % img_idx (optional) - a numerical array of image volume indices. Only 43 | % the specified volumes will be loaded. All available image 44 | % volumes will be loaded, if it is default or empty. 45 | % 46 | % The number of images scans can be obtained from get_nii_frame.m, 47 | % or simply: hdr.dime.dim(5). 48 | % 49 | % preferredForm (optional) - selects which transformation from voxels 50 | % to RAS coordinates; values are s,q,S,Q. Lower case s,q indicate 51 | % "prefer sform or qform, but use others if preferred not present". 52 | % Upper case indicate the program is forced to use the specificied 53 | % tranform or fail loading. 'preferredForm' will be 's', if it is 54 | % default or empty. - Jeff Gunter 55 | % 56 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 57 | % 58 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 59 | % 60 | function reslice_nii(old_fn, new_fn, voxel_size, verbose, bg, method, img_idx, preferredForm) 61 | 62 | if ~exist('old_fn','var') | ~exist('new_fn','var') 63 | error('Usage: reslice_nii(old_fn, new_fn, [voxel_size], [verbose], [bg], [method], [img_idx])'); 64 | end 65 | 66 | if ~exist('method','var') | isempty(method) 67 | method = 1; 68 | end 69 | 70 | if ~exist('img_idx','var') | isempty(img_idx) 71 | img_idx = []; 72 | end 73 | 74 | if ~exist('verbose','var') | isempty(verbose) 75 | verbose = 1; 76 | end 77 | 78 | if ~exist('preferredForm','var') | isempty(preferredForm) 79 | preferredForm= 's'; % Jeff 80 | end 81 | 82 | nii = load_nii_no_xform(old_fn, img_idx, 0, preferredForm); 83 | 84 | if ~ismember(nii.hdr.dime.datatype, [2,4,8,16,64,256,512,768]) 85 | error('Transform of this NIFTI data is not supported by the program.'); 86 | end 87 | 88 | if ~exist('voxel_size','var') | isempty(voxel_size) 89 | voxel_size = round(min(nii.hdr.dime.pixdim(2:4)))*ones(1,3); 90 | elseif length(voxel_size) < 3 91 | voxel_size = voxel_size(1)*ones(1,3); 92 | end 93 | 94 | if ~exist('bg','var') | isempty(bg) 95 | bg = mean([nii.img(1) nii.img(end)]); 96 | end 97 | 98 | old_M = nii.hdr.hist.old_affine; 99 | 100 | if nii.hdr.dime.dim(5) > 1 101 | for i = 1:nii.hdr.dime.dim(5) 102 | if verbose 103 | fprintf('Reslicing %d of %d volumes.\n', i, nii.hdr.dime.dim(5)); 104 | end 105 | 106 | [img(:,:,:,i) M] = ... 107 | affine(nii.img(:,:,:,i), old_M, voxel_size, verbose, bg, method); 108 | end 109 | else 110 | [img M] = affine(nii.img, old_M, voxel_size, verbose, bg, method); 111 | end 112 | 113 | new_dim = size(img); 114 | nii.img = img; 115 | nii.hdr.dime.dim(2:4) = new_dim(1:3); 116 | nii.hdr.dime.datatype = 16; 117 | nii.hdr.dime.bitpix = 32; 118 | nii.hdr.dime.pixdim(2:4) = voxel_size(:)'; 119 | nii.hdr.dime.glmax = max(img(:)); 120 | nii.hdr.dime.glmin = min(img(:)); 121 | nii.hdr.hist.qform_code = 0; 122 | nii.hdr.hist.sform_code = 1; 123 | nii.hdr.hist.srow_x = M(1,:); 124 | nii.hdr.hist.srow_y = M(2,:); 125 | nii.hdr.hist.srow_z = M(3,:); 126 | nii.hdr.hist.new_affine = M; 127 | 128 | save_nii(nii, new_fn); 129 | 130 | return; % reslice_nii 131 | 132 | 133 | %-------------------------------------------------------------------- 134 | function [nii] = load_nii_no_xform(filename, img_idx, old_RGB, preferredForm) 135 | 136 | if ~exist('filename','var'), 137 | error('Usage: [nii] = load_nii(filename, [img_idx], [old_RGB])'); 138 | end 139 | 140 | if ~exist('img_idx','var'), img_idx = []; end 141 | if ~exist('old_RGB','var'), old_RGB = 0; end 142 | if ~exist('preferredForm','var'), preferredForm= 's'; end % Jeff 143 | 144 | % Read the dataset header 145 | % 146 | [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); 147 | 148 | % Read the header extension 149 | % 150 | % nii.ext = load_nii_ext(filename); 151 | 152 | % Read the dataset body 153 | % 154 | [nii.img,nii.hdr] = ... 155 | load_nii_img(nii.hdr,nii.filetype,nii.fileprefix,nii.machine,img_idx,'','','',old_RGB); 156 | 157 | % Perform some of sform/qform transform 158 | % 159 | % nii = xform_nii(nii, preferredForm); 160 | 161 | 162 | hdr = nii.hdr; 163 | 164 | % NIFTI can have both sform and qform transform. This program 165 | % will check sform_code prior to qform_code by default. 166 | % 167 | % If user specifys "preferredForm", user can then choose the 168 | % priority. - Jeff 169 | % 170 | useForm=[]; % Jeff 171 | 172 | if isequal(preferredForm,'S') 173 | if isequal(hdr.hist.sform_code,0) 174 | error('User requires sform, sform not set in header'); 175 | else 176 | useForm='s'; 177 | end 178 | end % Jeff 179 | 180 | if isequal(preferredForm,'Q') 181 | if isequal(hdr.hist.qform_code,0) 182 | error('User requires sform, sform not set in header'); 183 | else 184 | useForm='q'; 185 | end 186 | end % Jeff 187 | 188 | if isequal(preferredForm,'s') 189 | if hdr.hist.sform_code > 0 190 | useForm='s'; 191 | elseif hdr.hist.qform_code > 0 192 | useForm='q'; 193 | end 194 | end % Jeff 195 | 196 | if isequal(preferredForm,'q') 197 | if hdr.hist.qform_code > 0 198 | useForm='q'; 199 | elseif hdr.hist.sform_code > 0 200 | useForm='s'; 201 | end 202 | end % Jeff 203 | 204 | if isequal(useForm,'s') 205 | R = [hdr.hist.srow_x(1:3) 206 | hdr.hist.srow_y(1:3) 207 | hdr.hist.srow_z(1:3)]; 208 | 209 | T = [hdr.hist.srow_x(4) 210 | hdr.hist.srow_y(4) 211 | hdr.hist.srow_z(4)]; 212 | 213 | nii.hdr.hist.old_affine = [ [R;[0 0 0]] [T;1] ]; 214 | 215 | elseif isequal(useForm,'q') 216 | b = hdr.hist.quatern_b; 217 | c = hdr.hist.quatern_c; 218 | d = hdr.hist.quatern_d; 219 | 220 | if 1.0-(b*b+c*c+d*d) < 0 221 | if abs(1.0-(b*b+c*c+d*d)) < 1e-5 222 | a = 0; 223 | else 224 | error('Incorrect quaternion values in this NIFTI data.'); 225 | end 226 | else 227 | a = sqrt(1.0-(b*b+c*c+d*d)); 228 | end 229 | 230 | qfac = hdr.dime.pixdim(1); 231 | i = hdr.dime.pixdim(2); 232 | j = hdr.dime.pixdim(3); 233 | k = qfac * hdr.dime.pixdim(4); 234 | 235 | R = [a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c 236 | 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b 237 | 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b]; 238 | 239 | T = [hdr.hist.qoffset_x 240 | hdr.hist.qoffset_y 241 | hdr.hist.qoffset_z]; 242 | 243 | nii.hdr.hist.old_affine = [ [R * diag([i j k]);[0 0 0]] [T;1] ]; 244 | 245 | elseif nii.filetype == 0 & exist([nii.fileprefix '.mat'],'file') 246 | load([nii.fileprefix '.mat']); % old SPM affine matrix 247 | R=M(1:3,1:3); 248 | T=M(1:3,4); 249 | T=R*ones(3,1)+T; 250 | M(1:3,4)=T; 251 | nii.hdr.hist.old_affine = M; 252 | 253 | else 254 | M = diag(hdr.dime.pixdim(2:5)); 255 | M(1:3,4) = -M(1:3,1:3)*(hdr.hist.originator(1:3)-1)'; 256 | M(4,4) = 1; 257 | nii.hdr.hist.old_affine = M; 258 | end 259 | 260 | return % load_nii_no_xform 261 | 262 | -------------------------------------------------------------------------------- /scripts_templates/save_untouch_nii_hdr.m: -------------------------------------------------------------------------------- 1 | % internal function 2 | 3 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 4 | 5 | function save_nii_hdr(hdr, fid) 6 | 7 | if ~isequal(hdr.hk.sizeof_hdr,348), 8 | error('hdr.hk.sizeof_hdr must be 348.'); 9 | end 10 | 11 | write_header(hdr, fid); 12 | 13 | return; % save_nii_hdr 14 | 15 | 16 | %--------------------------------------------------------------------- 17 | function write_header(hdr, fid) 18 | 19 | % Original header structures 20 | % struct dsr /* dsr = hdr */ 21 | % { 22 | % struct header_key hk; /* 0 + 40 */ 23 | % struct image_dimension dime; /* 40 + 108 */ 24 | % struct data_history hist; /* 148 + 200 */ 25 | % }; /* total= 348 bytes*/ 26 | 27 | header_key(fid, hdr.hk); 28 | image_dimension(fid, hdr.dime); 29 | data_history(fid, hdr.hist); 30 | 31 | % check the file size is 348 bytes 32 | % 33 | fbytes = ftell(fid); 34 | 35 | if ~isequal(fbytes,348), 36 | msg = sprintf('Header size is not 348 bytes.'); 37 | warning(msg); 38 | end 39 | 40 | return; % write_header 41 | 42 | 43 | %--------------------------------------------------------------------- 44 | function header_key(fid, hk) 45 | 46 | fseek(fid,0,'bof'); 47 | 48 | % Original header structures 49 | % struct header_key /* header key */ 50 | % { /* off + size */ 51 | % int sizeof_hdr /* 0 + 4 */ 52 | % char data_type[10]; /* 4 + 10 */ 53 | % char db_name[18]; /* 14 + 18 */ 54 | % int extents; /* 32 + 4 */ 55 | % short int session_error; /* 36 + 2 */ 56 | % char regular; /* 38 + 1 */ 57 | % char dim_info; % char hkey_un0; /* 39 + 1 */ 58 | % }; /* total=40 bytes */ 59 | 60 | fwrite(fid, hk.sizeof_hdr(1), 'int32'); % must be 348. 61 | 62 | % data_type = sprintf('%-10s',hk.data_type); % ensure it is 10 chars from left 63 | % fwrite(fid, data_type(1:10), 'uchar'); 64 | pad = zeros(1, 10-length(hk.data_type)); 65 | hk.data_type = [hk.data_type char(pad)]; 66 | fwrite(fid, hk.data_type(1:10), 'uchar'); 67 | 68 | % db_name = sprintf('%-18s', hk.db_name); % ensure it is 18 chars from left 69 | % fwrite(fid, db_name(1:18), 'uchar'); 70 | pad = zeros(1, 18-length(hk.db_name)); 71 | hk.db_name = [hk.db_name char(pad)]; 72 | fwrite(fid, hk.db_name(1:18), 'uchar'); 73 | 74 | fwrite(fid, hk.extents(1), 'int32'); 75 | fwrite(fid, hk.session_error(1), 'int16'); 76 | fwrite(fid, hk.regular(1), 'uchar'); % might be uint8 77 | 78 | % fwrite(fid, hk.hkey_un0(1), 'uchar'); 79 | % fwrite(fid, hk.hkey_un0(1), 'uint8'); 80 | fwrite(fid, hk.dim_info(1), 'uchar'); 81 | 82 | return; % header_key 83 | 84 | 85 | %--------------------------------------------------------------------- 86 | function image_dimension(fid, dime) 87 | 88 | % Original header structures 89 | % struct image_dimension 90 | % { /* off + size */ 91 | % short int dim[8]; /* 0 + 16 */ 92 | % float intent_p1; % char vox_units[4]; /* 16 + 4 */ 93 | % float intent_p2; % char cal_units[8]; /* 20 + 4 */ 94 | % float intent_p3; % char cal_units[8]; /* 24 + 4 */ 95 | % short int intent_code; % short int unused1; /* 28 + 2 */ 96 | % short int datatype; /* 30 + 2 */ 97 | % short int bitpix; /* 32 + 2 */ 98 | % short int slice_start; % short int dim_un0; /* 34 + 2 */ 99 | % float pixdim[8]; /* 36 + 32 */ 100 | % /* 101 | % pixdim[] specifies the voxel dimensions: 102 | % pixdim[1] - voxel width 103 | % pixdim[2] - voxel height 104 | % pixdim[3] - interslice distance 105 | % pixdim[4] - volume timing, in msec 106 | % ..etc 107 | % */ 108 | % float vox_offset; /* 68 + 4 */ 109 | % float scl_slope; % float roi_scale; /* 72 + 4 */ 110 | % float scl_inter; % float funused1; /* 76 + 4 */ 111 | % short slice_end; % float funused2; /* 80 + 2 */ 112 | % char slice_code; % float funused2; /* 82 + 1 */ 113 | % char xyzt_units; % float funused2; /* 83 + 1 */ 114 | % float cal_max; /* 84 + 4 */ 115 | % float cal_min; /* 88 + 4 */ 116 | % float slice_duration; % int compressed; /* 92 + 4 */ 117 | % float toffset; % int verified; /* 96 + 4 */ 118 | % int glmax; /* 100 + 4 */ 119 | % int glmin; /* 104 + 4 */ 120 | % }; /* total=108 bytes */ 121 | 122 | fwrite(fid, dime.dim(1:8), 'int16'); 123 | fwrite(fid, dime.intent_p1(1), 'float32'); 124 | fwrite(fid, dime.intent_p2(1), 'float32'); 125 | fwrite(fid, dime.intent_p3(1), 'float32'); 126 | fwrite(fid, dime.intent_code(1), 'int16'); 127 | fwrite(fid, dime.datatype(1), 'int16'); 128 | fwrite(fid, dime.bitpix(1), 'int16'); 129 | fwrite(fid, dime.slice_start(1), 'int16'); 130 | fwrite(fid, dime.pixdim(1:8), 'float32'); 131 | fwrite(fid, dime.vox_offset(1), 'float32'); 132 | fwrite(fid, dime.scl_slope(1), 'float32'); 133 | fwrite(fid, dime.scl_inter(1), 'float32'); 134 | fwrite(fid, dime.slice_end(1), 'int16'); 135 | fwrite(fid, dime.slice_code(1), 'uchar'); 136 | fwrite(fid, dime.xyzt_units(1), 'uchar'); 137 | fwrite(fid, dime.cal_max(1), 'float32'); 138 | fwrite(fid, dime.cal_min(1), 'float32'); 139 | fwrite(fid, dime.slice_duration(1), 'float32'); 140 | fwrite(fid, dime.toffset(1), 'float32'); 141 | fwrite(fid, dime.glmax(1), 'int32'); 142 | fwrite(fid, dime.glmin(1), 'int32'); 143 | 144 | return; % image_dimension 145 | 146 | 147 | %--------------------------------------------------------------------- 148 | function data_history(fid, hist) 149 | 150 | % Original header structures 151 | %struct data_history 152 | % { /* off + size */ 153 | % char descrip[80]; /* 0 + 80 */ 154 | % char aux_file[24]; /* 80 + 24 */ 155 | % short int qform_code; /* 104 + 2 */ 156 | % short int sform_code; /* 106 + 2 */ 157 | % float quatern_b; /* 108 + 4 */ 158 | % float quatern_c; /* 112 + 4 */ 159 | % float quatern_d; /* 116 + 4 */ 160 | % float qoffset_x; /* 120 + 4 */ 161 | % float qoffset_y; /* 124 + 4 */ 162 | % float qoffset_z; /* 128 + 4 */ 163 | % float srow_x[4]; /* 132 + 16 */ 164 | % float srow_y[4]; /* 148 + 16 */ 165 | % float srow_z[4]; /* 164 + 16 */ 166 | % char intent_name[16]; /* 180 + 16 */ 167 | % char magic[4]; % int smin; /* 196 + 4 */ 168 | % }; /* total=200 bytes */ 169 | 170 | % descrip = sprintf('%-80s', hist.descrip); % 80 chars from left 171 | % fwrite(fid, descrip(1:80), 'uchar'); 172 | pad = zeros(1, 80-length(hist.descrip)); 173 | hist.descrip = [hist.descrip char(pad)]; 174 | fwrite(fid, hist.descrip(1:80), 'uchar'); 175 | 176 | % aux_file = sprintf('%-24s', hist.aux_file); % 24 chars from left 177 | % fwrite(fid, aux_file(1:24), 'uchar'); 178 | pad = zeros(1, 24-length(hist.aux_file)); 179 | hist.aux_file = [hist.aux_file char(pad)]; 180 | fwrite(fid, hist.aux_file(1:24), 'uchar'); 181 | 182 | fwrite(fid, hist.qform_code, 'int16'); 183 | fwrite(fid, hist.sform_code, 'int16'); 184 | fwrite(fid, hist.quatern_b, 'float32'); 185 | fwrite(fid, hist.quatern_c, 'float32'); 186 | fwrite(fid, hist.quatern_d, 'float32'); 187 | fwrite(fid, hist.qoffset_x, 'float32'); 188 | fwrite(fid, hist.qoffset_y, 'float32'); 189 | fwrite(fid, hist.qoffset_z, 'float32'); 190 | fwrite(fid, hist.srow_x(1:4), 'float32'); 191 | fwrite(fid, hist.srow_y(1:4), 'float32'); 192 | fwrite(fid, hist.srow_z(1:4), 'float32'); 193 | 194 | % intent_name = sprintf('%-16s', hist.intent_name); % 16 chars from left 195 | % fwrite(fid, intent_name(1:16), 'uchar'); 196 | pad = zeros(1, 16-length(hist.intent_name)); 197 | hist.intent_name = [hist.intent_name char(pad)]; 198 | fwrite(fid, hist.intent_name(1:16), 'uchar'); 199 | 200 | % magic = sprintf('%-4s', hist.magic); % 4 chars from left 201 | % fwrite(fid, magic(1:4), 'uchar'); 202 | pad = zeros(1, 4-length(hist.magic)); 203 | hist.magic = [hist.magic char(pad)]; 204 | fwrite(fid, hist.magic(1:4), 'uchar'); 205 | 206 | return; % data_history 207 | 208 | -------------------------------------------------------------------------------- /scripts_templates/load_untouch_nii_hdr.m: -------------------------------------------------------------------------------- 1 | % internal function 2 | 3 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 4 | 5 | function hdr = load_nii_hdr(fileprefix, machine, filetype) 6 | 7 | if filetype == 2 8 | fn = sprintf('%s.nii',fileprefix); 9 | 10 | if ~exist(fn) 11 | msg = sprintf('Cannot find file "%s.nii".', fileprefix); 12 | error(msg); 13 | end 14 | else 15 | fn = sprintf('%s.hdr',fileprefix); 16 | 17 | if ~exist(fn) 18 | msg = sprintf('Cannot find file "%s.hdr".', fileprefix); 19 | error(msg); 20 | end 21 | end 22 | 23 | fid = fopen(fn,'r',machine); 24 | 25 | if fid < 0, 26 | msg = sprintf('Cannot open file %s.',fn); 27 | error(msg); 28 | else 29 | fseek(fid,0,'bof'); 30 | hdr = read_header(fid); 31 | fclose(fid); 32 | end 33 | 34 | return % load_nii_hdr 35 | 36 | 37 | %--------------------------------------------------------------------- 38 | function [ dsr ] = read_header(fid) 39 | 40 | % Original header structures 41 | % struct dsr 42 | % { 43 | % struct header_key hk; /* 0 + 40 */ 44 | % struct image_dimension dime; /* 40 + 108 */ 45 | % struct data_history hist; /* 148 + 200 */ 46 | % }; /* total= 348 bytes*/ 47 | 48 | dsr.hk = header_key(fid); 49 | dsr.dime = image_dimension(fid); 50 | dsr.hist = data_history(fid); 51 | 52 | % For Analyze data format 53 | % 54 | if ~strcmp(dsr.hist.magic, 'n+1') & ~strcmp(dsr.hist.magic, 'ni1') 55 | dsr.hist.qform_code = 0; 56 | dsr.hist.sform_code = 0; 57 | end 58 | 59 | return % read_header 60 | 61 | 62 | %--------------------------------------------------------------------- 63 | function [ hk ] = header_key(fid) 64 | 65 | fseek(fid,0,'bof'); 66 | 67 | % Original header structures 68 | % struct header_key /* header key */ 69 | % { /* off + size */ 70 | % int sizeof_hdr /* 0 + 4 */ 71 | % char data_type[10]; /* 4 + 10 */ 72 | % char db_name[18]; /* 14 + 18 */ 73 | % int extents; /* 32 + 4 */ 74 | % short int session_error; /* 36 + 2 */ 75 | % char regular; /* 38 + 1 */ 76 | % char dim_info; % char hkey_un0; /* 39 + 1 */ 77 | % }; /* total=40 bytes */ 78 | % 79 | % int sizeof_header Should be 348. 80 | % char regular Must be 'r' to indicate that all images and 81 | % volumes are the same size. 82 | 83 | v6 = version; 84 | if str2num(v6(1))<6 85 | directchar = '*char'; 86 | else 87 | directchar = 'uchar=>char'; 88 | end 89 | 90 | hk.sizeof_hdr = fread(fid, 1,'int32')'; % should be 348! 91 | hk.data_type = deblank(fread(fid,10,directchar)'); 92 | hk.db_name = deblank(fread(fid,18,directchar)'); 93 | hk.extents = fread(fid, 1,'int32')'; 94 | hk.session_error = fread(fid, 1,'int16')'; 95 | hk.regular = fread(fid, 1,directchar)'; 96 | hk.dim_info = fread(fid, 1,'uchar')'; 97 | 98 | return % header_key 99 | 100 | 101 | %--------------------------------------------------------------------- 102 | function [ dime ] = image_dimension(fid) 103 | 104 | % Original header structures 105 | % struct image_dimension 106 | % { /* off + size */ 107 | % short int dim[8]; /* 0 + 16 */ 108 | % /* 109 | % dim[0] Number of dimensions in database; usually 4. 110 | % dim[1] Image X dimension; number of *pixels* in an image row. 111 | % dim[2] Image Y dimension; number of *pixel rows* in slice. 112 | % dim[3] Volume Z dimension; number of *slices* in a volume. 113 | % dim[4] Time points; number of volumes in database 114 | % */ 115 | % float intent_p1; % char vox_units[4]; /* 16 + 4 */ 116 | % float intent_p2; % char cal_units[8]; /* 20 + 4 */ 117 | % float intent_p3; % char cal_units[8]; /* 24 + 4 */ 118 | % short int intent_code; % short int unused1; /* 28 + 2 */ 119 | % short int datatype; /* 30 + 2 */ 120 | % short int bitpix; /* 32 + 2 */ 121 | % short int slice_start; % short int dim_un0; /* 34 + 2 */ 122 | % float pixdim[8]; /* 36 + 32 */ 123 | % /* 124 | % pixdim[] specifies the voxel dimensions: 125 | % pixdim[1] - voxel width, mm 126 | % pixdim[2] - voxel height, mm 127 | % pixdim[3] - slice thickness, mm 128 | % pixdim[4] - volume timing, in msec 129 | % ..etc 130 | % */ 131 | % float vox_offset; /* 68 + 4 */ 132 | % float scl_slope; % float roi_scale; /* 72 + 4 */ 133 | % float scl_inter; % float funused1; /* 76 + 4 */ 134 | % short slice_end; % float funused2; /* 80 + 2 */ 135 | % char slice_code; % float funused2; /* 82 + 1 */ 136 | % char xyzt_units; % float funused2; /* 83 + 1 */ 137 | % float cal_max; /* 84 + 4 */ 138 | % float cal_min; /* 88 + 4 */ 139 | % float slice_duration; % int compressed; /* 92 + 4 */ 140 | % float toffset; % int verified; /* 96 + 4 */ 141 | % int glmax; /* 100 + 4 */ 142 | % int glmin; /* 104 + 4 */ 143 | % }; /* total=108 bytes */ 144 | 145 | dime.dim = fread(fid,8,'int16')'; 146 | dime.intent_p1 = fread(fid,1,'float32')'; 147 | dime.intent_p2 = fread(fid,1,'float32')'; 148 | dime.intent_p3 = fread(fid,1,'float32')'; 149 | dime.intent_code = fread(fid,1,'int16')'; 150 | dime.datatype = fread(fid,1,'int16')'; 151 | dime.bitpix = fread(fid,1,'int16')'; 152 | dime.slice_start = fread(fid,1,'int16')'; 153 | dime.pixdim = fread(fid,8,'float32')'; 154 | dime.vox_offset = fread(fid,1,'float32')'; 155 | dime.scl_slope = fread(fid,1,'float32')'; 156 | dime.scl_inter = fread(fid,1,'float32')'; 157 | dime.slice_end = fread(fid,1,'int16')'; 158 | dime.slice_code = fread(fid,1,'uchar')'; 159 | dime.xyzt_units = fread(fid,1,'uchar')'; 160 | dime.cal_max = fread(fid,1,'float32')'; 161 | dime.cal_min = fread(fid,1,'float32')'; 162 | dime.slice_duration = fread(fid,1,'float32')'; 163 | dime.toffset = fread(fid,1,'float32')'; 164 | dime.glmax = fread(fid,1,'int32')'; 165 | dime.glmin = fread(fid,1,'int32')'; 166 | 167 | return % image_dimension 168 | 169 | 170 | %--------------------------------------------------------------------- 171 | function [ hist ] = data_history(fid) 172 | 173 | % Original header structures 174 | % struct data_history 175 | % { /* off + size */ 176 | % char descrip[80]; /* 0 + 80 */ 177 | % char aux_file[24]; /* 80 + 24 */ 178 | % short int qform_code; /* 104 + 2 */ 179 | % short int sform_code; /* 106 + 2 */ 180 | % float quatern_b; /* 108 + 4 */ 181 | % float quatern_c; /* 112 + 4 */ 182 | % float quatern_d; /* 116 + 4 */ 183 | % float qoffset_x; /* 120 + 4 */ 184 | % float qoffset_y; /* 124 + 4 */ 185 | % float qoffset_z; /* 128 + 4 */ 186 | % float srow_x[4]; /* 132 + 16 */ 187 | % float srow_y[4]; /* 148 + 16 */ 188 | % float srow_z[4]; /* 164 + 16 */ 189 | % char intent_name[16]; /* 180 + 16 */ 190 | % char magic[4]; % int smin; /* 196 + 4 */ 191 | % }; /* total=200 bytes */ 192 | 193 | v6 = version; 194 | if str2num(v6(1))<6 195 | directchar = '*char'; 196 | else 197 | directchar = 'uchar=>char'; 198 | end 199 | 200 | hist.descrip = deblank(fread(fid,80,directchar)'); 201 | hist.aux_file = deblank(fread(fid,24,directchar)'); 202 | hist.qform_code = fread(fid,1,'int16')'; 203 | hist.sform_code = fread(fid,1,'int16')'; 204 | hist.quatern_b = fread(fid,1,'float32')'; 205 | hist.quatern_c = fread(fid,1,'float32')'; 206 | hist.quatern_d = fread(fid,1,'float32')'; 207 | hist.qoffset_x = fread(fid,1,'float32')'; 208 | hist.qoffset_y = fread(fid,1,'float32')'; 209 | hist.qoffset_z = fread(fid,1,'float32')'; 210 | hist.srow_x = fread(fid,4,'float32')'; 211 | hist.srow_y = fread(fid,4,'float32')'; 212 | hist.srow_z = fread(fid,4,'float32')'; 213 | hist.intent_name = deblank(fread(fid,16,directchar)'); 214 | hist.magic = deblank(fread(fid,4,directchar)'); 215 | 216 | return % data_history 217 | 218 | -------------------------------------------------------------------------------- /scripts_templates/save_nii.m: -------------------------------------------------------------------------------- 1 | % Save NIFTI dataset. Support both *.nii and *.hdr/*.img file extension. 2 | % If file extension is not provided, *.hdr/*.img will be used as default. 3 | % 4 | % Usage: save_nii(nii, filename, [old_RGB]) 5 | % 6 | % nii.hdr - struct with NIFTI header fields (from load_nii.m or make_nii.m) 7 | % 8 | % nii.img - 3D (or 4D) matrix of NIFTI data. 9 | % 10 | % filename - NIFTI file name. 11 | % 12 | % old_RGB - an optional boolean variable to handle special RGB data 13 | % sequence [R1 R2 ... G1 G2 ... B1 B2 ...] that is used only by 14 | % AnalyzeDirect (Analyze Software). Since both NIfTI and Analyze 15 | % file format use RGB triple [R1 G1 B1 R2 G2 B2 ...] sequentially 16 | % for each voxel, this variable is set to FALSE by default. If you 17 | % would like the saved image only to be opened by AnalyzeDirect 18 | % Software, set old_RGB to TRUE (or 1). It will be set to 0, if it 19 | % is default or empty. 20 | % 21 | % Tip: to change the data type, set nii.hdr.dime.datatype, 22 | % and nii.hdr.dime.bitpix to: 23 | % 24 | % 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN 25 | % 1 Binary (ubit1, bitpix=1) % DT_BINARY 26 | % 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 27 | % 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 28 | % 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 29 | % 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 30 | % 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 31 | % 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 32 | % 128 uint RGB (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 33 | % 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 34 | % 511 Single RGB (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96 35 | % 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 36 | % 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 37 | % 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 38 | % 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 39 | % 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 40 | % 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 41 | % 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 42 | % 43 | % Part of this file is copied and modified from: 44 | % http://www.mathworks.com/matlabcentral/fileexchange/1878-mri-analyze-tools 45 | % 46 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 47 | % 48 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 49 | % - "old_RGB" related codes in "save_nii.m" are added by Mike Harms (2006.06.28) 50 | % 51 | function save_nii(nii, fileprefix, old_RGB) 52 | 53 | if ~exist('nii','var') | isempty(nii) | ~isfield(nii,'hdr') | ... 54 | ~isfield(nii,'img') | ~exist('fileprefix','var') | isempty(fileprefix) 55 | 56 | error('Usage: save_nii(nii, filename, [old_RGB])'); 57 | end 58 | 59 | if isfield(nii,'untouch') & nii.untouch == 1 60 | error('Usage: please use ''save_untouch_nii.m'' for the untouched structure.'); 61 | end 62 | 63 | if ~exist('old_RGB','var') | isempty(old_RGB) 64 | old_RGB = 0; 65 | end 66 | 67 | filetype = 1; 68 | 69 | % Note: fileprefix is actually the filename you want to save 70 | % 71 | if findstr('.nii',fileprefix) 72 | filetype = 2; 73 | fileprefix = strrep(fileprefix,'.nii',''); 74 | end 75 | 76 | if findstr('.hdr',fileprefix) 77 | fileprefix = strrep(fileprefix,'.hdr',''); 78 | end 79 | 80 | if findstr('.img',fileprefix) 81 | fileprefix = strrep(fileprefix,'.img',''); 82 | end 83 | 84 | write_nii(nii, filetype, fileprefix, old_RGB); 85 | 86 | if filetype == 1 87 | 88 | % So earlier versions of SPM can also open it with correct originator 89 | % 90 | M=[[diag(nii.hdr.dime.pixdim(2:4)) -[nii.hdr.hist.originator(1:3).*nii.hdr.dime.pixdim(2:4)]'];[0 0 0 1]]; 91 | save([fileprefix '.mat'], 'M'); 92 | end 93 | 94 | return % save_nii 95 | 96 | 97 | %----------------------------------------------------------------------------------- 98 | function write_nii(nii, filetype, fileprefix, old_RGB) 99 | 100 | hdr = nii.hdr; 101 | 102 | if isfield(nii,'ext') & ~isempty(nii.ext) 103 | ext = nii.ext; 104 | [ext, esize_total] = verify_nii_ext(ext); 105 | else 106 | ext = []; 107 | end 108 | 109 | switch double(hdr.dime.datatype), 110 | case 1, 111 | hdr.dime.bitpix = int16(1 ); precision = 'ubit1'; 112 | case 2, 113 | hdr.dime.bitpix = int16(8 ); precision = 'uint8'; 114 | case 4, 115 | hdr.dime.bitpix = int16(16); precision = 'int16'; 116 | case 8, 117 | hdr.dime.bitpix = int16(32); precision = 'int32'; 118 | case 16, 119 | hdr.dime.bitpix = int16(32); precision = 'float32'; 120 | case 32, 121 | hdr.dime.bitpix = int16(64); precision = 'float32'; 122 | case 64, 123 | hdr.dime.bitpix = int16(64); precision = 'float64'; 124 | case 128, 125 | hdr.dime.bitpix = int16(24); precision = 'uint8'; 126 | case 256 127 | hdr.dime.bitpix = int16(8 ); precision = 'int8'; 128 | case 511, 129 | hdr.dime.bitpix = int16(96); precision = 'float32'; 130 | case 512 131 | hdr.dime.bitpix = int16(16); precision = 'uint16'; 132 | case 768 133 | hdr.dime.bitpix = int16(32); precision = 'uint32'; 134 | case 1024 135 | hdr.dime.bitpix = int16(64); precision = 'int64'; 136 | case 1280 137 | hdr.dime.bitpix = int16(64); precision = 'uint64'; 138 | case 1792, 139 | hdr.dime.bitpix = int16(128); precision = 'float64'; 140 | otherwise 141 | error('This datatype is not supported'); 142 | end 143 | 144 | hdr.dime.glmax = round(double(max(nii.img(:)))); 145 | hdr.dime.glmin = round(double(min(nii.img(:)))); 146 | 147 | if filetype == 2 148 | fid = fopen(sprintf('%s.nii',fileprefix),'w'); 149 | 150 | if fid < 0, 151 | msg = sprintf('Cannot open file %s.nii.',fileprefix); 152 | error(msg); 153 | end 154 | 155 | hdr.dime.vox_offset = 352; 156 | 157 | if ~isempty(ext) 158 | hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total; 159 | end 160 | 161 | hdr.hist.magic = 'n+1'; 162 | save_nii_hdr(hdr, fid); 163 | 164 | if ~isempty(ext) 165 | save_nii_ext(ext, fid); 166 | end 167 | else 168 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 169 | 170 | if fid < 0, 171 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 172 | error(msg); 173 | end 174 | 175 | hdr.dime.vox_offset = 0; 176 | hdr.hist.magic = 'ni1'; 177 | save_nii_hdr(hdr, fid); 178 | 179 | if ~isempty(ext) 180 | save_nii_ext(ext, fid); 181 | end 182 | 183 | fclose(fid); 184 | fid = fopen(sprintf('%s.img',fileprefix),'w'); 185 | end 186 | 187 | ScanDim = double(hdr.dime.dim(5)); % t 188 | SliceDim = double(hdr.dime.dim(4)); % z 189 | RowDim = double(hdr.dime.dim(3)); % y 190 | PixelDim = double(hdr.dime.dim(2)); % x 191 | SliceSz = double(hdr.dime.pixdim(4)); 192 | RowSz = double(hdr.dime.pixdim(3)); 193 | PixelSz = double(hdr.dime.pixdim(2)); 194 | 195 | x = 1:PixelDim; 196 | 197 | if filetype == 2 & isempty(ext) 198 | skip_bytes = double(hdr.dime.vox_offset) - 348; 199 | else 200 | skip_bytes = 0; 201 | end 202 | 203 | if double(hdr.dime.datatype) == 128 204 | 205 | % RGB planes are expected to be in the 4th dimension of nii.img 206 | % 207 | if(size(nii.img,4)~=3) 208 | error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); 209 | end 210 | 211 | if old_RGB 212 | nii.img = permute(nii.img, [1 2 4 3 5 6 7 8]); 213 | else 214 | nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); 215 | end 216 | end 217 | 218 | if double(hdr.dime.datatype) == 511 219 | 220 | % RGB planes are expected to be in the 4th dimension of nii.img 221 | % 222 | if(size(nii.img,4)~=3) 223 | error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); 224 | end 225 | 226 | if old_RGB 227 | nii.img = permute(nii.img, [1 2 4 3 5 6 7 8]); 228 | else 229 | nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); 230 | end 231 | end 232 | 233 | % For complex float32 or complex float64, voxel values 234 | % include [real, imag] 235 | % 236 | if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 237 | real_img = real(nii.img(:))'; 238 | nii.img = imag(nii.img(:))'; 239 | nii.img = [real_img; nii.img]; 240 | end 241 | 242 | if skip_bytes 243 | fwrite(fid, zeros(1,skip_bytes), 'uint8'); 244 | end 245 | 246 | fwrite(fid, nii.img, precision); 247 | % fwrite(fid, nii.img, precision, skip_bytes); % error using skip 248 | fclose(fid); 249 | 250 | return; % write_nii 251 | 252 | -------------------------------------------------------------------------------- /scripts_templates/save_untouch0_nii_hdr.m: -------------------------------------------------------------------------------- 1 | % internal function 2 | 3 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 4 | 5 | function save_nii_hdr(hdr, fid) 6 | 7 | if ~isequal(hdr.hk.sizeof_hdr,348), 8 | error('hdr.hk.sizeof_hdr must be 348.'); 9 | end 10 | 11 | write_header(hdr, fid); 12 | 13 | return; % save_nii_hdr 14 | 15 | 16 | %--------------------------------------------------------------------- 17 | function write_header(hdr, fid) 18 | 19 | % Original header structures 20 | % struct dsr /* dsr = hdr */ 21 | % { 22 | % struct header_key hk; /* 0 + 40 */ 23 | % struct image_dimension dime; /* 40 + 108 */ 24 | % struct data_history hist; /* 148 + 200 */ 25 | % }; /* total= 348 bytes*/ 26 | 27 | header_key(fid, hdr.hk); 28 | image_dimension(fid, hdr.dime); 29 | data_history(fid, hdr.hist); 30 | 31 | % check the file size is 348 bytes 32 | % 33 | fbytes = ftell(fid); 34 | 35 | if ~isequal(fbytes,348), 36 | msg = sprintf('Header size is not 348 bytes.'); 37 | warning(msg); 38 | end 39 | 40 | return; % write_header 41 | 42 | 43 | %--------------------------------------------------------------------- 44 | function header_key(fid, hk) 45 | 46 | fseek(fid,0,'bof'); 47 | 48 | % Original header structures 49 | % struct header_key /* header key */ 50 | % { /* off + size */ 51 | % int sizeof_hdr /* 0 + 4 */ 52 | % char data_type[10]; /* 4 + 10 */ 53 | % char db_name[18]; /* 14 + 18 */ 54 | % int extents; /* 32 + 4 */ 55 | % short int session_error; /* 36 + 2 */ 56 | % char regular; /* 38 + 1 */ 57 | % char hkey_un0; /* 39 + 1 */ 58 | % }; /* total=40 bytes */ 59 | 60 | fwrite(fid, hk.sizeof_hdr(1), 'int32'); % must be 348. 61 | 62 | % data_type = sprintf('%-10s',hk.data_type); % ensure it is 10 chars from left 63 | % fwrite(fid, data_type(1:10), 'uchar'); 64 | pad = zeros(1, 10-length(hk.data_type)); 65 | hk.data_type = [hk.data_type char(pad)]; 66 | fwrite(fid, hk.data_type(1:10), 'uchar'); 67 | 68 | % db_name = sprintf('%-18s', hk.db_name); % ensure it is 18 chars from left 69 | % fwrite(fid, db_name(1:18), 'uchar'); 70 | pad = zeros(1, 18-length(hk.db_name)); 71 | hk.db_name = [hk.db_name char(pad)]; 72 | fwrite(fid, hk.db_name(1:18), 'uchar'); 73 | 74 | fwrite(fid, hk.extents(1), 'int32'); 75 | fwrite(fid, hk.session_error(1), 'int16'); 76 | fwrite(fid, hk.regular(1), 'uchar'); 77 | 78 | fwrite(fid, hk.hkey_un0(1), 'uchar'); 79 | 80 | return; % header_key 81 | 82 | 83 | %--------------------------------------------------------------------- 84 | function image_dimension(fid, dime) 85 | 86 | %struct image_dimension 87 | % { /* off + size */ 88 | % short int dim[8]; /* 0 + 16 */ 89 | % char vox_units[4]; /* 16 + 4 */ 90 | % char cal_units[8]; /* 20 + 8 */ 91 | % short int unused1; /* 28 + 2 */ 92 | % short int datatype; /* 30 + 2 */ 93 | % short int bitpix; /* 32 + 2 */ 94 | % short int dim_un0; /* 34 + 2 */ 95 | % float pixdim[8]; /* 36 + 32 */ 96 | % /* 97 | % pixdim[] specifies the voxel dimensions: 98 | % pixdim[1] - voxel width 99 | % pixdim[2] - voxel height 100 | % pixdim[3] - interslice distance 101 | % ..etc 102 | % */ 103 | % float vox_offset; /* 68 + 4 */ 104 | % float roi_scale; /* 72 + 4 */ 105 | % float funused1; /* 76 + 4 */ 106 | % float funused2; /* 80 + 4 */ 107 | % float cal_max; /* 84 + 4 */ 108 | % float cal_min; /* 88 + 4 */ 109 | % int compressed; /* 92 + 4 */ 110 | % int verified; /* 96 + 4 */ 111 | % int glmax; /* 100 + 4 */ 112 | % int glmin; /* 104 + 4 */ 113 | % }; /* total=108 bytes */ 114 | 115 | fwrite(fid, dime.dim(1:8), 'int16'); 116 | 117 | pad = zeros(1, 4-length(dime.vox_units)); 118 | dime.vox_units = [dime.vox_units char(pad)]; 119 | fwrite(fid, dime.vox_units(1:4), 'uchar'); 120 | 121 | pad = zeros(1, 8-length(dime.cal_units)); 122 | dime.cal_units = [dime.cal_units char(pad)]; 123 | fwrite(fid, dime.cal_units(1:8), 'uchar'); 124 | 125 | fwrite(fid, dime.unused1(1), 'int16'); 126 | fwrite(fid, dime.datatype(1), 'int16'); 127 | fwrite(fid, dime.bitpix(1), 'int16'); 128 | fwrite(fid, dime.dim_un0(1), 'int16'); 129 | fwrite(fid, dime.pixdim(1:8), 'float32'); 130 | fwrite(fid, dime.vox_offset(1), 'float32'); 131 | fwrite(fid, dime.roi_scale(1), 'float32'); 132 | fwrite(fid, dime.funused1(1), 'float32'); 133 | fwrite(fid, dime.funused2(1), 'float32'); 134 | fwrite(fid, dime.cal_max(1), 'float32'); 135 | fwrite(fid, dime.cal_min(1), 'float32'); 136 | fwrite(fid, dime.compressed(1), 'int32'); 137 | fwrite(fid, dime.verified(1), 'int32'); 138 | fwrite(fid, dime.glmax(1), 'int32'); 139 | fwrite(fid, dime.glmin(1), 'int32'); 140 | 141 | return; % image_dimension 142 | 143 | 144 | %--------------------------------------------------------------------- 145 | function data_history(fid, hist) 146 | 147 | % Original header structures - ANALYZE 7.5 148 | %struct data_history 149 | % { /* off + size */ 150 | % char descrip[80]; /* 0 + 80 */ 151 | % char aux_file[24]; /* 80 + 24 */ 152 | % char orient; /* 104 + 1 */ 153 | % char originator[10]; /* 105 + 10 */ 154 | % char generated[10]; /* 115 + 10 */ 155 | % char scannum[10]; /* 125 + 10 */ 156 | % char patient_id[10]; /* 135 + 10 */ 157 | % char exp_date[10]; /* 145 + 10 */ 158 | % char exp_time[10]; /* 155 + 10 */ 159 | % char hist_un0[3]; /* 165 + 3 */ 160 | % int views /* 168 + 4 */ 161 | % int vols_added; /* 172 + 4 */ 162 | % int start_field; /* 176 + 4 */ 163 | % int field_skip; /* 180 + 4 */ 164 | % int omax; /* 184 + 4 */ 165 | % int omin; /* 188 + 4 */ 166 | % int smax; /* 192 + 4 */ 167 | % int smin; /* 196 + 4 */ 168 | % }; /* total=200 bytes */ 169 | 170 | % descrip = sprintf('%-80s', hist.descrip); % 80 chars from left 171 | % fwrite(fid, descrip(1:80), 'uchar'); 172 | pad = zeros(1, 80-length(hist.descrip)); 173 | hist.descrip = [hist.descrip char(pad)]; 174 | fwrite(fid, hist.descrip(1:80), 'uchar'); 175 | 176 | % aux_file = sprintf('%-24s', hist.aux_file); % 24 chars from left 177 | % fwrite(fid, aux_file(1:24), 'uchar'); 178 | pad = zeros(1, 24-length(hist.aux_file)); 179 | hist.aux_file = [hist.aux_file char(pad)]; 180 | fwrite(fid, hist.aux_file(1:24), 'uchar'); 181 | 182 | fwrite(fid, hist.orient(1), 'uchar'); 183 | fwrite(fid, hist.originator(1:5), 'int16'); 184 | 185 | pad = zeros(1, 10-length(hist.generated)); 186 | hist.generated = [hist.generated char(pad)]; 187 | fwrite(fid, hist.generated(1:10), 'uchar'); 188 | 189 | pad = zeros(1, 10-length(hist.scannum)); 190 | hist.scannum = [hist.scannum char(pad)]; 191 | fwrite(fid, hist.scannum(1:10), 'uchar'); 192 | 193 | pad = zeros(1, 10-length(hist.patient_id)); 194 | hist.patient_id = [hist.patient_id char(pad)]; 195 | fwrite(fid, hist.patient_id(1:10), 'uchar'); 196 | 197 | pad = zeros(1, 10-length(hist.exp_date)); 198 | hist.exp_date = [hist.exp_date char(pad)]; 199 | fwrite(fid, hist.exp_date(1:10), 'uchar'); 200 | 201 | pad = zeros(1, 10-length(hist.exp_time)); 202 | hist.exp_time = [hist.exp_time char(pad)]; 203 | fwrite(fid, hist.exp_time(1:10), 'uchar'); 204 | 205 | pad = zeros(1, 3-length(hist.hist_un0)); 206 | hist.hist_un0 = [hist.hist_un0 char(pad)]; 207 | fwrite(fid, hist.hist_un0(1:3), 'uchar'); 208 | 209 | fwrite(fid, hist.views(1), 'int32'); 210 | fwrite(fid, hist.vols_added(1), 'int32'); 211 | fwrite(fid, hist.start_field(1),'int32'); 212 | fwrite(fid, hist.field_skip(1), 'int32'); 213 | fwrite(fid, hist.omax(1), 'int32'); 214 | fwrite(fid, hist.omin(1), 'int32'); 215 | fwrite(fid, hist.smax(1), 'int32'); 216 | fwrite(fid, hist.smin(1), 'int32'); 217 | 218 | return; % data_history 219 | 220 | -------------------------------------------------------------------------------- /scripts_templates/save_nii_hdr.m: -------------------------------------------------------------------------------- 1 | % internal function 2 | 3 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 4 | 5 | function save_nii_hdr(hdr, fid) 6 | 7 | if ~exist('hdr','var') | ~exist('fid','var') 8 | error('Usage: save_nii_hdr(hdr, fid)'); 9 | end 10 | 11 | if ~isequal(hdr.hk.sizeof_hdr,348), 12 | error('hdr.hk.sizeof_hdr must be 348.'); 13 | end 14 | 15 | if hdr.hist.qform_code == 0 & hdr.hist.sform_code == 0 16 | hdr.hist.sform_code = 1; 17 | hdr.hist.srow_x(1) = hdr.dime.pixdim(2); 18 | hdr.hist.srow_x(2) = 0; 19 | hdr.hist.srow_x(3) = 0; 20 | hdr.hist.srow_y(1) = 0; 21 | hdr.hist.srow_y(2) = hdr.dime.pixdim(3); 22 | hdr.hist.srow_y(3) = 0; 23 | hdr.hist.srow_z(1) = 0; 24 | hdr.hist.srow_z(2) = 0; 25 | hdr.hist.srow_z(3) = hdr.dime.pixdim(4); 26 | hdr.hist.srow_x(4) = (1-hdr.hist.originator(1))*hdr.dime.pixdim(2); 27 | hdr.hist.srow_y(4) = (1-hdr.hist.originator(2))*hdr.dime.pixdim(3); 28 | hdr.hist.srow_z(4) = (1-hdr.hist.originator(3))*hdr.dime.pixdim(4); 29 | end 30 | 31 | write_header(hdr, fid); 32 | 33 | return; % save_nii_hdr 34 | 35 | 36 | %--------------------------------------------------------------------- 37 | function write_header(hdr, fid) 38 | 39 | % Original header structures 40 | % struct dsr /* dsr = hdr */ 41 | % { 42 | % struct header_key hk; /* 0 + 40 */ 43 | % struct image_dimension dime; /* 40 + 108 */ 44 | % struct data_history hist; /* 148 + 200 */ 45 | % }; /* total= 348 bytes*/ 46 | 47 | header_key(fid, hdr.hk); 48 | image_dimension(fid, hdr.dime); 49 | data_history(fid, hdr.hist); 50 | 51 | % check the file size is 348 bytes 52 | % 53 | fbytes = ftell(fid); 54 | 55 | if ~isequal(fbytes,348), 56 | msg = sprintf('Header size is not 348 bytes.'); 57 | warning(msg); 58 | end 59 | 60 | return; % write_header 61 | 62 | 63 | %--------------------------------------------------------------------- 64 | function header_key(fid, hk) 65 | 66 | fseek(fid,0,'bof'); 67 | 68 | % Original header structures 69 | % struct header_key /* header key */ 70 | % { /* off + size */ 71 | % int sizeof_hdr /* 0 + 4 */ 72 | % char data_type[10]; /* 4 + 10 */ 73 | % char db_name[18]; /* 14 + 18 */ 74 | % int extents; /* 32 + 4 */ 75 | % short int session_error; /* 36 + 2 */ 76 | % char regular; /* 38 + 1 */ 77 | % char dim_info; % char hkey_un0; /* 39 + 1 */ 78 | % }; /* total=40 bytes */ 79 | 80 | fwrite(fid, hk.sizeof_hdr(1), 'int32'); % must be 348. 81 | 82 | % data_type = sprintf('%-10s',hk.data_type); % ensure it is 10 chars from left 83 | % fwrite(fid, data_type(1:10), 'uchar'); 84 | pad = zeros(1, 10-length(hk.data_type)); 85 | hk.data_type = [hk.data_type char(pad)]; 86 | fwrite(fid, hk.data_type(1:10), 'uchar'); 87 | 88 | % db_name = sprintf('%-18s', hk.db_name); % ensure it is 18 chars from left 89 | % fwrite(fid, db_name(1:18), 'uchar'); 90 | pad = zeros(1, 18-length(hk.db_name)); 91 | hk.db_name = [hk.db_name char(pad)]; 92 | fwrite(fid, hk.db_name(1:18), 'uchar'); 93 | 94 | fwrite(fid, hk.extents(1), 'int32'); 95 | fwrite(fid, hk.session_error(1), 'int16'); 96 | fwrite(fid, hk.regular(1), 'uchar'); % might be uint8 97 | 98 | % fwrite(fid, hk.hkey_un0(1), 'uchar'); 99 | % fwrite(fid, hk.hkey_un0(1), 'uint8'); 100 | fwrite(fid, hk.dim_info(1), 'uchar'); 101 | 102 | return; % header_key 103 | 104 | 105 | %--------------------------------------------------------------------- 106 | function image_dimension(fid, dime) 107 | 108 | % Original header structures 109 | % struct image_dimension 110 | % { /* off + size */ 111 | % short int dim[8]; /* 0 + 16 */ 112 | % float intent_p1; % char vox_units[4]; /* 16 + 4 */ 113 | % float intent_p2; % char cal_units[8]; /* 20 + 4 */ 114 | % float intent_p3; % char cal_units[8]; /* 24 + 4 */ 115 | % short int intent_code; % short int unused1; /* 28 + 2 */ 116 | % short int datatype; /* 30 + 2 */ 117 | % short int bitpix; /* 32 + 2 */ 118 | % short int slice_start; % short int dim_un0; /* 34 + 2 */ 119 | % float pixdim[8]; /* 36 + 32 */ 120 | % /* 121 | % pixdim[] specifies the voxel dimensions: 122 | % pixdim[1] - voxel width 123 | % pixdim[2] - voxel height 124 | % pixdim[3] - interslice distance 125 | % pixdim[4] - volume timing, in msec 126 | % ..etc 127 | % */ 128 | % float vox_offset; /* 68 + 4 */ 129 | % float scl_slope; % float roi_scale; /* 72 + 4 */ 130 | % float scl_inter; % float funused1; /* 76 + 4 */ 131 | % short slice_end; % float funused2; /* 80 + 2 */ 132 | % char slice_code; % float funused2; /* 82 + 1 */ 133 | % char xyzt_units; % float funused2; /* 83 + 1 */ 134 | % float cal_max; /* 84 + 4 */ 135 | % float cal_min; /* 88 + 4 */ 136 | % float slice_duration; % int compressed; /* 92 + 4 */ 137 | % float toffset; % int verified; /* 96 + 4 */ 138 | % int glmax; /* 100 + 4 */ 139 | % int glmin; /* 104 + 4 */ 140 | % }; /* total=108 bytes */ 141 | 142 | fwrite(fid, dime.dim(1:8), 'int16'); 143 | fwrite(fid, dime.intent_p1(1), 'float32'); 144 | fwrite(fid, dime.intent_p2(1), 'float32'); 145 | fwrite(fid, dime.intent_p3(1), 'float32'); 146 | fwrite(fid, dime.intent_code(1), 'int16'); 147 | fwrite(fid, dime.datatype(1), 'int16'); 148 | fwrite(fid, dime.bitpix(1), 'int16'); 149 | fwrite(fid, dime.slice_start(1), 'int16'); 150 | fwrite(fid, dime.pixdim(1:8), 'float32'); 151 | fwrite(fid, dime.vox_offset(1), 'float32'); 152 | fwrite(fid, dime.scl_slope(1), 'float32'); 153 | fwrite(fid, dime.scl_inter(1), 'float32'); 154 | fwrite(fid, dime.slice_end(1), 'int16'); 155 | fwrite(fid, dime.slice_code(1), 'uchar'); 156 | fwrite(fid, dime.xyzt_units(1), 'uchar'); 157 | fwrite(fid, dime.cal_max(1), 'float32'); 158 | fwrite(fid, dime.cal_min(1), 'float32'); 159 | fwrite(fid, dime.slice_duration(1), 'float32'); 160 | fwrite(fid, dime.toffset(1), 'float32'); 161 | fwrite(fid, dime.glmax(1), 'int32'); 162 | fwrite(fid, dime.glmin(1), 'int32'); 163 | 164 | return; % image_dimension 165 | 166 | 167 | %--------------------------------------------------------------------- 168 | function data_history(fid, hist) 169 | 170 | % Original header structures 171 | %struct data_history 172 | % { /* off + size */ 173 | % char descrip[80]; /* 0 + 80 */ 174 | % char aux_file[24]; /* 80 + 24 */ 175 | % short int qform_code; /* 104 + 2 */ 176 | % short int sform_code; /* 106 + 2 */ 177 | % float quatern_b; /* 108 + 4 */ 178 | % float quatern_c; /* 112 + 4 */ 179 | % float quatern_d; /* 116 + 4 */ 180 | % float qoffset_x; /* 120 + 4 */ 181 | % float qoffset_y; /* 124 + 4 */ 182 | % float qoffset_z; /* 128 + 4 */ 183 | % float srow_x[4]; /* 132 + 16 */ 184 | % float srow_y[4]; /* 148 + 16 */ 185 | % float srow_z[4]; /* 164 + 16 */ 186 | % char intent_name[16]; /* 180 + 16 */ 187 | % char magic[4]; % int smin; /* 196 + 4 */ 188 | % }; /* total=200 bytes */ 189 | 190 | % descrip = sprintf('%-80s', hist.descrip); % 80 chars from left 191 | % fwrite(fid, descrip(1:80), 'uchar'); 192 | pad = zeros(1, 80-length(hist.descrip)); 193 | hist.descrip = [hist.descrip char(pad)]; 194 | fwrite(fid, hist.descrip(1:80), 'uchar'); 195 | 196 | % aux_file = sprintf('%-24s', hist.aux_file); % 24 chars from left 197 | % fwrite(fid, aux_file(1:24), 'uchar'); 198 | pad = zeros(1, 24-length(hist.aux_file)); 199 | hist.aux_file = [hist.aux_file char(pad)]; 200 | fwrite(fid, hist.aux_file(1:24), 'uchar'); 201 | 202 | fwrite(fid, hist.qform_code, 'int16'); 203 | fwrite(fid, hist.sform_code, 'int16'); 204 | fwrite(fid, hist.quatern_b, 'float32'); 205 | fwrite(fid, hist.quatern_c, 'float32'); 206 | fwrite(fid, hist.quatern_d, 'float32'); 207 | fwrite(fid, hist.qoffset_x, 'float32'); 208 | fwrite(fid, hist.qoffset_y, 'float32'); 209 | fwrite(fid, hist.qoffset_z, 'float32'); 210 | fwrite(fid, hist.srow_x(1:4), 'float32'); 211 | fwrite(fid, hist.srow_y(1:4), 'float32'); 212 | fwrite(fid, hist.srow_z(1:4), 'float32'); 213 | 214 | % intent_name = sprintf('%-16s', hist.intent_name); % 16 chars from left 215 | % fwrite(fid, intent_name(1:16), 'uchar'); 216 | pad = zeros(1, 16-length(hist.intent_name)); 217 | hist.intent_name = [hist.intent_name char(pad)]; 218 | fwrite(fid, hist.intent_name(1:16), 'uchar'); 219 | 220 | % magic = sprintf('%-4s', hist.magic); % 4 chars from left 221 | % fwrite(fid, magic(1:4), 'uchar'); 222 | pad = zeros(1, 4-length(hist.magic)); 223 | hist.magic = [hist.magic char(pad)]; 224 | fwrite(fid, hist.magic(1:4), 'uchar'); 225 | 226 | return; % data_history 227 | 228 | -------------------------------------------------------------------------------- /scripts_templates/load_nii_hdr.m: -------------------------------------------------------------------------------- 1 | % internal function 2 | 3 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 4 | 5 | function [hdr, filetype, fileprefix, machine] = load_nii_hdr(fileprefix) 6 | 7 | if ~exist('fileprefix','var'), 8 | error('Usage: [hdr, filetype, fileprefix, machine] = load_nii_hdr(filename)'); 9 | end 10 | 11 | machine = 'ieee-le'; 12 | new_ext = 0; 13 | 14 | if findstr('.nii',fileprefix) 15 | new_ext = 1; 16 | fileprefix = strrep(fileprefix,'.nii',''); 17 | end 18 | 19 | if findstr('.hdr',fileprefix) 20 | fileprefix = strrep(fileprefix,'.hdr',''); 21 | end 22 | 23 | if findstr('.img',fileprefix) 24 | fileprefix = strrep(fileprefix,'.img',''); 25 | end 26 | 27 | if new_ext 28 | fn = sprintf('%s.nii',fileprefix); 29 | 30 | if ~exist(fn) 31 | msg = sprintf('Cannot find file "%s.nii".', fileprefix); 32 | error(msg); 33 | end 34 | else 35 | fn = sprintf('%s.hdr',fileprefix); 36 | 37 | if ~exist(fn) 38 | msg = sprintf('Cannot find file "%s.hdr".', fileprefix); 39 | error(msg); 40 | end 41 | end 42 | 43 | fid = fopen(fn,'r',machine); 44 | 45 | if fid < 0, 46 | msg = sprintf('Cannot open file %s.',fn); 47 | error(msg); 48 | else 49 | fseek(fid,0,'bof'); 50 | 51 | if fread(fid,1,'int32') == 348 52 | hdr = read_header(fid); 53 | fclose(fid); 54 | else 55 | fclose(fid); 56 | 57 | % first try reading the opposite endian to 'machine' 58 | % 59 | switch machine, 60 | case 'ieee-le', machine = 'ieee-be'; 61 | case 'ieee-be', machine = 'ieee-le'; 62 | end 63 | 64 | fid = fopen(fn,'r',machine); 65 | 66 | if fid < 0, 67 | msg = sprintf('Cannot open file %s.',fn); 68 | error(msg); 69 | else 70 | fseek(fid,0,'bof'); 71 | 72 | if fread(fid,1,'int32') ~= 348 73 | 74 | % Now throw an error 75 | % 76 | msg = sprintf('File "%s" is corrupted.',fn); 77 | error(msg); 78 | end 79 | 80 | hdr = read_header(fid); 81 | fclose(fid); 82 | end 83 | end 84 | end 85 | 86 | if strcmp(hdr.hist.magic, 'n+1') 87 | filetype = 2; 88 | elseif strcmp(hdr.hist.magic, 'ni1') 89 | filetype = 1; 90 | else 91 | filetype = 0; 92 | end 93 | 94 | return % load_nii_hdr 95 | 96 | 97 | %--------------------------------------------------------------------- 98 | function [ dsr ] = read_header(fid) 99 | 100 | % Original header structures 101 | % struct dsr 102 | % { 103 | % struct header_key hk; /* 0 + 40 */ 104 | % struct image_dimension dime; /* 40 + 108 */ 105 | % struct data_history hist; /* 148 + 200 */ 106 | % }; /* total= 348 bytes*/ 107 | 108 | dsr.hk = header_key(fid); 109 | dsr.dime = image_dimension(fid); 110 | dsr.hist = data_history(fid); 111 | 112 | % For Analyze data format 113 | % 114 | if ~strcmp(dsr.hist.magic, 'n+1') & ~strcmp(dsr.hist.magic, 'ni1') 115 | dsr.hist.qform_code = 0; 116 | dsr.hist.sform_code = 0; 117 | end 118 | 119 | return % read_header 120 | 121 | 122 | %--------------------------------------------------------------------- 123 | function [ hk ] = header_key(fid) 124 | 125 | fseek(fid,0,'bof'); 126 | 127 | % Original header structures 128 | % struct header_key /* header key */ 129 | % { /* off + size */ 130 | % int sizeof_hdr /* 0 + 4 */ 131 | % char data_type[10]; /* 4 + 10 */ 132 | % char db_name[18]; /* 14 + 18 */ 133 | % int extents; /* 32 + 4 */ 134 | % short int session_error; /* 36 + 2 */ 135 | % char regular; /* 38 + 1 */ 136 | % char dim_info; % char hkey_un0; /* 39 + 1 */ 137 | % }; /* total=40 bytes */ 138 | % 139 | % int sizeof_header Should be 348. 140 | % char regular Must be 'r' to indicate that all images and 141 | % volumes are the same size. 142 | 143 | v6 = version; 144 | if str2num(v6(1))<6 145 | directchar = '*char'; 146 | else 147 | directchar = 'uchar=>char'; 148 | end 149 | 150 | hk.sizeof_hdr = fread(fid, 1,'int32')'; % should be 348! 151 | hk.data_type = deblank(fread(fid,10,directchar)'); 152 | hk.db_name = deblank(fread(fid,18,directchar)'); 153 | hk.extents = fread(fid, 1,'int32')'; 154 | hk.session_error = fread(fid, 1,'int16')'; 155 | hk.regular = fread(fid, 1,directchar)'; 156 | hk.dim_info = fread(fid, 1,'uchar')'; 157 | 158 | return % header_key 159 | 160 | 161 | %--------------------------------------------------------------------- 162 | function [ dime ] = image_dimension(fid) 163 | 164 | % Original header structures 165 | % struct image_dimension 166 | % { /* off + size */ 167 | % short int dim[8]; /* 0 + 16 */ 168 | % /* 169 | % dim[0] Number of dimensions in database; usually 4. 170 | % dim[1] Image X dimension; number of *pixels* in an image row. 171 | % dim[2] Image Y dimension; number of *pixel rows* in slice. 172 | % dim[3] Volume Z dimension; number of *slices* in a volume. 173 | % dim[4] Time points; number of volumes in database 174 | % */ 175 | % float intent_p1; % char vox_units[4]; /* 16 + 4 */ 176 | % float intent_p2; % char cal_units[8]; /* 20 + 4 */ 177 | % float intent_p3; % char cal_units[8]; /* 24 + 4 */ 178 | % short int intent_code; % short int unused1; /* 28 + 2 */ 179 | % short int datatype; /* 30 + 2 */ 180 | % short int bitpix; /* 32 + 2 */ 181 | % short int slice_start; % short int dim_un0; /* 34 + 2 */ 182 | % float pixdim[8]; /* 36 + 32 */ 183 | % /* 184 | % pixdim[] specifies the voxel dimensions: 185 | % pixdim[1] - voxel width, mm 186 | % pixdim[2] - voxel height, mm 187 | % pixdim[3] - slice thickness, mm 188 | % pixdim[4] - volume timing, in msec 189 | % ..etc 190 | % */ 191 | % float vox_offset; /* 68 + 4 */ 192 | % float scl_slope; % float roi_scale; /* 72 + 4 */ 193 | % float scl_inter; % float funused1; /* 76 + 4 */ 194 | % short slice_end; % float funused2; /* 80 + 2 */ 195 | % char slice_code; % float funused2; /* 82 + 1 */ 196 | % char xyzt_units; % float funused2; /* 83 + 1 */ 197 | % float cal_max; /* 84 + 4 */ 198 | % float cal_min; /* 88 + 4 */ 199 | % float slice_duration; % int compressed; /* 92 + 4 */ 200 | % float toffset; % int verified; /* 96 + 4 */ 201 | % int glmax; /* 100 + 4 */ 202 | % int glmin; /* 104 + 4 */ 203 | % }; /* total=108 bytes */ 204 | 205 | dime.dim = fread(fid,8,'int16')'; 206 | dime.intent_p1 = fread(fid,1,'float32')'; 207 | dime.intent_p2 = fread(fid,1,'float32')'; 208 | dime.intent_p3 = fread(fid,1,'float32')'; 209 | dime.intent_code = fread(fid,1,'int16')'; 210 | dime.datatype = fread(fid,1,'int16')'; 211 | dime.bitpix = fread(fid,1,'int16')'; 212 | dime.slice_start = fread(fid,1,'int16')'; 213 | dime.pixdim = fread(fid,8,'float32')'; 214 | dime.vox_offset = fread(fid,1,'float32')'; 215 | dime.scl_slope = fread(fid,1,'float32')'; 216 | dime.scl_inter = fread(fid,1,'float32')'; 217 | dime.slice_end = fread(fid,1,'int16')'; 218 | dime.slice_code = fread(fid,1,'uchar')'; 219 | dime.xyzt_units = fread(fid,1,'uchar')'; 220 | dime.cal_max = fread(fid,1,'float32')'; 221 | dime.cal_min = fread(fid,1,'float32')'; 222 | dime.slice_duration = fread(fid,1,'float32')'; 223 | dime.toffset = fread(fid,1,'float32')'; 224 | dime.glmax = fread(fid,1,'int32')'; 225 | dime.glmin = fread(fid,1,'int32')'; 226 | 227 | return % image_dimension 228 | 229 | 230 | %--------------------------------------------------------------------- 231 | function [ hist ] = data_history(fid) 232 | 233 | % Original header structures 234 | % struct data_history 235 | % { /* off + size */ 236 | % char descrip[80]; /* 0 + 80 */ 237 | % char aux_file[24]; /* 80 + 24 */ 238 | % short int qform_code; /* 104 + 2 */ 239 | % short int sform_code; /* 106 + 2 */ 240 | % float quatern_b; /* 108 + 4 */ 241 | % float quatern_c; /* 112 + 4 */ 242 | % float quatern_d; /* 116 + 4 */ 243 | % float qoffset_x; /* 120 + 4 */ 244 | % float qoffset_y; /* 124 + 4 */ 245 | % float qoffset_z; /* 128 + 4 */ 246 | % float srow_x[4]; /* 132 + 16 */ 247 | % float srow_y[4]; /* 148 + 16 */ 248 | % float srow_z[4]; /* 164 + 16 */ 249 | % char intent_name[16]; /* 180 + 16 */ 250 | % char magic[4]; % int smin; /* 196 + 4 */ 251 | % }; /* total=200 bytes */ 252 | 253 | v6 = version; 254 | if str2num(v6(1))<6 255 | directchar = '*char'; 256 | else 257 | directchar = 'uchar=>char'; 258 | end 259 | 260 | hist.descrip = deblank(fread(fid,80,directchar)'); 261 | hist.aux_file = deblank(fread(fid,24,directchar)'); 262 | hist.qform_code = fread(fid,1,'int16')'; 263 | hist.sform_code = fread(fid,1,'int16')'; 264 | hist.quatern_b = fread(fid,1,'float32')'; 265 | hist.quatern_c = fread(fid,1,'float32')'; 266 | hist.quatern_d = fread(fid,1,'float32')'; 267 | hist.qoffset_x = fread(fid,1,'float32')'; 268 | hist.qoffset_y = fread(fid,1,'float32')'; 269 | hist.qoffset_z = fread(fid,1,'float32')'; 270 | hist.srow_x = fread(fid,4,'float32')'; 271 | hist.srow_y = fread(fid,4,'float32')'; 272 | hist.srow_z = fread(fid,4,'float32')'; 273 | hist.intent_name = deblank(fread(fid,16,directchar)'); 274 | hist.magic = deblank(fread(fid,4,directchar)'); 275 | 276 | fseek(fid,253,'bof'); 277 | hist.originator = fread(fid, 5,'int16')'; 278 | 279 | return % data_history 280 | 281 | -------------------------------------------------------------------------------- /Summary.m: -------------------------------------------------------------------------------- 1 | function varargout = Summary(varargin) 2 | % SUMMARY MATLAB code for Summary.fig 3 | % SUMMARY, by itself, creates a new SUMMARY or raises the existing 4 | % singleton*. 5 | % 6 | % H = SUMMARY returns the handle to a new SUMMARY or the handle to 7 | % the existing singleton*. 8 | % 9 | % SUMMARY('CALLBACK',hObject,eventData,handles,...) calls the local 10 | % function named CALLBACK in SUMMARY.M with the given input arguments. 11 | % 12 | % SUMMARY('Property','Value',...) creates a new SUMMARY or raises the 13 | % existing singleton*. Starting from the left, property value pairs are 14 | % applied to the GUI before Summary_OpeningFcn gets called. An 15 | % unrecognized property name or invalid value makes property application 16 | % stop. All inputs are passed to Summary_OpeningFcn via varargin. 17 | % 18 | % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one 19 | % instance to run (singleton)". 20 | % 21 | % See also: GUIDE, GUIDATA, GUIHANDLES 22 | 23 | % Edit the above text to modify the response to help Summary 24 | 25 | % Last Modified by GUIDE v2.5 26-Jul-2017 09:54:02 26 | 27 | % Begin initialization code - DO NOT EDIT 28 | gui_Singleton = 1; 29 | gui_State = struct('gui_Name', mfilename, ... 30 | 'gui_Singleton', gui_Singleton, ... 31 | 'gui_OpeningFcn', @Summary_OpeningFcn, ... 32 | 'gui_OutputFcn', @Summary_OutputFcn, ... 33 | 'gui_LayoutFcn', [] , ... 34 | 'gui_Callback', []); 35 | if nargin && ischar(varargin{1}) 36 | gui_State.gui_Callback = str2func(varargin{1}); 37 | end 38 | 39 | if nargout 40 | [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); 41 | else 42 | gui_mainfcn(gui_State, varargin{:}); 43 | end 44 | % End initialization code - DO NOT EDIT 45 | 46 | 47 | % --- Executes just before Summary is made visible. 48 | function Summary_OpeningFcn(hObject, eventdata, handles, varargin) 49 | % This function has no output args, see OutputFcn. 50 | % hObject handle to figure 51 | % eventdata reserved - to be defined in a future version of MATLAB 52 | % handles structure with handles and user data (see GUIDATA) 53 | % varargin command line arguments to Summary (see VARARGIN) 54 | 55 | % Choose default command line output for Summary 56 | handles.output = hObject; 57 | 58 | % Update handles structure 59 | guidata(hObject, handles); 60 | 61 | % UIWAIT makes Summary wait for user response (see UIRESUME) 62 | % uiwait(handles.figure1); 63 | 64 | 65 | % --- Outputs from this function are returned to the command line. 66 | function varargout = Summary_OutputFcn(hObject, eventdata, handles) 67 | % varargout cell array for returning output args (see VARARGOUT); 68 | % hObject handle to figure 69 | % eventdata reserved - to be defined in a future version of MATLAB 70 | % handles structure with handles and user data (see GUIDATA) 71 | 72 | % Get default command line output from handles structure 73 | varargout{1} = handles.output; 74 | 75 | 76 | % --- Executes on button press in design. 77 | function design_Callback(hObject, eventdata, handles) 78 | % hObject handle to design (see GCBO) 79 | % eventdata reserved - to be defined in a future version of MATLAB 80 | % handles structure with handles and user data (see GUIDATA) 81 | study_design = cellstr(spm_select(1,'mat','load study design')); 82 | load(study_design{1}); 83 | assignin('base','study_design',study_design); 84 | 85 | % --- Executes on button press in pushbutton2. 86 | function pushbutton2_Callback(hObject, eventdata, handles) 87 | % hObject handle to pushbutton2 (see GCBO) 88 | % eventdata reserved - to be defined in a future version of MATLAB 89 | % handles structure with handles and user data (see GUIDATA) 90 | con_def = cellstr(spm_select(1,'mat','load contrast definition')); 91 | load(con_def{1}); 92 | assignin('base','contrast_def',contrast_def); 93 | 94 | % --- Executes on button press in icc. 95 | function icc_Callback(hObject, eventdata, handles) 96 | % hObject handle to icc (see GCBO) 97 | % eventdata reserved - to be defined in a future version of MATLAB 98 | % handles structure with handles and user data (see GUIDATA) 99 | 100 | % Hint: get(hObject,'Value') returns toggle state of icc 101 | 102 | 103 | % --- Executes on button press in corr. 104 | function corr_Callback(hObject, eventdata, handles) 105 | % hObject handle to corr (see GCBO) 106 | % eventdata reserved - to be defined in a future version of MATLAB 107 | % handles structure with handles and user data (see GUIDATA) 108 | 109 | % Hint: get(hObject,'Value') returns toggle state of corr 110 | % --- Executes on button press in run. 111 | function run_Callback(hObject, eventdata, handles) 112 | % hObject handle to run (see GCBO) 113 | % eventdata reserved - to be defined in a future version of MATLAB 114 | % handles structure with handles and user data (see GUIDATA) 115 | 116 | disp('Starting reliability summary...'); 117 | %% define file seperator 118 | f = filesep; 119 | box_path=evalin('base','box_path'); 120 | 121 | study_design = evalin('base','study_design'); 122 | contrast_def = evalin('base','contrast_def'); 123 | 124 | %% get study design info 125 | results_dir = study_design.results_directory; 126 | load(study_design.subject_list); % loads id list 127 | exStats = study_design.exist_stats; 128 | ex4D = study_design.exist_4D; 129 | if exStats == 1 130 | stats_path = study_design.stats_path; 131 | stats_filled = sprintf(study_design.stats_directory,1); 132 | two_cons = contrast_def.two_contrasts; 133 | if two_cons == 1 134 | con = [contrast_def.contrast1 contrast_def.contrast_format]; 135 | 136 | else 137 | con = contrast_def.contrast; 138 | end; 139 | end; 140 | 141 | 142 | nr_runs = study_design.number_sessions; 143 | 144 | 145 | 146 | 147 | %% reslice atlas and move to results directory 148 | disp('...reslicing atlas...'); 149 | cd(box_path); 150 | cd('atlas'); 151 | atlas_dir = pwd; 152 | atlas_name = 'atlas.nii'; 153 | atlas_compl = [atlas_dir f atlas_name]; 154 | if exStats == 1 155 | matlabbatch{1}.spm.spatial.coreg.write.ref = {[stats_path f id{1} f stats_filled f con ',1']}; 156 | else 157 | matlabbatch{1}.spm.spatial.coreg.write.ref = {[results_dir f 'template_3D.nii' ',1']}; 158 | end; 159 | matlabbatch{1}.spm.spatial.coreg.write.source = {[atlas_compl ',1']}; 160 | matlabbatch{1}.spm.spatial.coreg.write.roptions.interp = 4; 161 | matlabbatch{1}.spm.spatial.coreg.write.roptions.wrap = [0 0 0]; 162 | matlabbatch{1}.spm.spatial.coreg.write.roptions.mask = 0; 163 | matlabbatch{1}.spm.spatial.coreg.write.roptions.prefix = 'r'; 164 | 165 | % save batch 166 | save('batch_reslice_atlas','matlabbatch'); 167 | 168 | % run batch 169 | spm_jobman('serial',matlabbatch); 170 | 171 | % load resliced atlas 172 | atlas_r = [atlas_dir f f 'r' atlas_name]; 173 | movefile (atlas_r,results_dir,'f'); 174 | cd(results_dir); 175 | atlas = load_untouch_nii(sprintf('r%s',atlas_name)); 176 | atlas = atlas.img; 177 | 178 | cd(atlas_dir); 179 | load('labels.mat'); 180 | load('labels_yeo.mat'); 181 | 182 | rel_summary={}; 183 | 184 | rel_summary(2:length(Labels)+1,1) = Labels; 185 | rel_summary(1,1) = {'atlas regions'}; 186 | rel_summary(2:length(Labels_yeo)+1,2) = Labels_yeo(:,3); 187 | rel_summary(1,2) = {'yeo networks'}; 188 | 189 | %% get GUI input 190 | corr = get(handles.corr,'Value'); 191 | if corr == 1 192 | cd(results_dir); 193 | %corrs = dir('CorrMap*'); 194 | corrsZ = dir('z_Corr*'); 195 | %list_corrs = cell(1,length(corrs)); 196 | % for ind_corrs = 1:length(corrs) 197 | % tmp = load_untouch_nii(corrs(ind_corrs).name); 198 | % [pathstr,name,ext] = fileparts(corrs(ind_corrs).name) ; 199 | % eval(sprintf('%s = tmp.img;',name)); 200 | % list_corrs{1,ind_corrs} = name; 201 | % end; 202 | %rel_summary(1,3:length(list_corrs)+2) = list_corrs; 203 | list_corrsZ = cell(1,length(corrsZ)); 204 | for ind_corrsZ = 1:length(corrsZ) 205 | tmp = load_untouch_nii(corrsZ(ind_corrsZ).name); 206 | [pathstr,name,ext] = fileparts(corrsZ(ind_corrsZ).name) ; 207 | [a,b]=strtok(name,'z_'); 208 | name=[a b]; 209 | eval(sprintf('%s = tmp.img;',name)); 210 | list_corrsZ{1,ind_corrsZ} = name; 211 | end; 212 | rel_summary(1,end+1:length(rel_summary(1,:))+length(list_corrsZ)) = list_corrsZ; 213 | end; 214 | icc = get(handles.icc,'Value'); 215 | if icc == 1 216 | cd(results_dir); 217 | %iccs = dir('ICC*'); 218 | iccsZ = dir('z_ICC*'); 219 | %list_iccs = cell(1,length(iccs)); 220 | % for ind_iccs = 1:length(iccs) 221 | % tmp = load_untouch_nii(iccs(ind_iccs).name); 222 | % [pathstr,name,ext] = fileparts(iccs(ind_iccs).name) ; 223 | % eval(sprintf('%s = tmp.img;',name)); 224 | % list_iccs{1,ind_iccs} = name; 225 | % end; 226 | % rel_summary(1,end+1:length(rel_summary(1,:))+length(list_iccs)) = list_iccs; 227 | list_iccsZ = cell(1,length(iccsZ)); 228 | for ind_iccsZ = 1:length(iccsZ) 229 | tmp = load_untouch_nii(iccsZ(ind_iccsZ).name); 230 | [pathstr,name,ext] = fileparts(iccsZ(ind_iccsZ).name) ; 231 | [a,b]=strtok(name,'z_'); 232 | name=[a b]; 233 | eval(sprintf('%s = tmp.img;',name)); 234 | list_iccsZ{1,ind_iccsZ} = name; 235 | end; 236 | rel_summary(1,end+1:length(rel_summary(1,:))+length(list_iccsZ)) = list_iccsZ; 237 | end; 238 | %% calculate reliability for ROIs 239 | 240 | for ind_labels = 1:length(Labels) 241 | fprintf('...analyzing voxels in %s...\n',Labels{ind_labels}) 242 | fprintf('...corresponding to yeo network %d...\n',Labels_yeo{ind_labels,2}) 243 | [x,y,z] = ind2sub([size(atlas,1),size(atlas,2),size(atlas,3)],find(atlas==ind_labels)); 244 | if icc == 1 245 | icc_vox = zeros(length(find(atlas==ind_labels)),length(list_iccsZ)); 246 | end; 247 | if corr == 1 248 | corr_vox = zeros(length(find(atlas==ind_labels)),length(list_corrsZ)); 249 | end; 250 | for ind_vox = 1:length(find(atlas==ind_labels)) 251 | if icc == 1 252 | % for ind_list = 1:length(list_iccs) 253 | % eval(sprintf('tmp = %s;',list_iccs{1,ind_list})); 254 | % icc_vox(ind_vox,ind_list) = mean(tmp(x(ind_vox),y(ind_vox),z(ind_vox),:),'omitnan'); 255 | % end; 256 | for ind_list = 1:length(list_iccsZ) 257 | eval(sprintf('icc_vox(ind_vox,ind_list) = mean(%s(x(ind_vox),y(ind_vox),z(ind_vox),:));',list_iccsZ{1,ind_list})); 258 | end; 259 | end; 260 | if corr == 1 261 | % for ind_list = 1:length(list_corrs) 262 | % eval(sprintf('corr_vox(ind_vox,ind_list) = mean(%s(x(ind_vox),y(ind_vox),z(ind_vox),:));',list_corrs{1,ind_list})); 263 | % end; 264 | for ind_list = 1:length(list_corrsZ) 265 | eval(sprintf('corr_vox(ind_vox,ind_list) = mean(%s(x(ind_vox),y(ind_vox),z(ind_vox),:));',list_corrsZ{1,ind_list})); 266 | end; 267 | end; 268 | end 269 | 270 | if corr == 1 && icc == 1 271 | for ind_list = 1:length(corr_vox(1,:)) 272 | temp=mean(corr_vox(:,ind_list),'omitnan'); 273 | rel_summary{ind_labels+1,ind_list+2} = (exp(2*temp)-1)./(exp(2*temp)+1); 274 | end; 275 | for ind_list = 1:length(icc_vox(1,:)) 276 | temp = mean(icc_vox(:,ind_list),'omitnan'); 277 | rel_summary{ind_labels+1,length(corr_vox(1,:))+ind_list+2} = (exp(2*temp)-1)./(exp(2*temp)+1); 278 | end; 279 | elseif corr == 1 280 | for ind_list = 1:length(corr_vox(1,:)) 281 | temp = mean(corr_vox(:,ind_list),'omitnan'); 282 | rel_summary{ind_labels+1,ind_list+2} =(exp(2*temp)-1)./(exp(2*temp)+1); 283 | end; 284 | elseif icc == 1 285 | for ind_list = 1:length(icc_vox(1,:)) 286 | temp = mean(icc_vox(:,ind_list),'omitnan'); 287 | rel_summary{ind_labels+1,ind_list+2} = (exp(2*temp)-1)./(exp(2*temp)+1); 288 | end; 289 | end; 290 | 291 | end; 292 | 293 | cd(results_dir); 294 | save reliability_summary.mat rel_summary; 295 | cd(box_path); 296 | 297 | disp('DONE'); 298 | 299 | % --- Executes during object creation, after setting all properties. 300 | function axes1_CreateFcn(hObject, eventdata, handles) 301 | % hObject handle to axes1 (see GCBO) 302 | % eventdata reserved - to be defined in a future version of MATLAB 303 | % handles empty - handles not created until after all CreateFcns called 304 | 305 | % Hint: place code in OpeningFcn to populate axes1 306 | axes(hObject); 307 | imshow('logo.png'); 308 | --------------------------------------------------------------------------------