collapse_nii_scan.m 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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. if ~exist('fileprefix','var')
  18. fileprefix = 'multi_scan';
  19. else
  20. [tmp fileprefix] = fileparts(fileprefix);
  21. end
  22. if ~exist('scan_path','var'), scan_path = pwd; end
  23. pnfn = fullfile(scan_path, scan_pattern);
  24. file_lst = dir(pnfn);
  25. flist = {file_lst.name};
  26. flist = flist(:);
  27. filename = flist{1};
  28. v = version;
  29. % Check file extension. If .gz, unpack it into temp folder
  30. %
  31. if length(filename) > 2 & strcmp(filename(end-2:end), '.gz')
  32. if ~strcmp(filename(end-6:end), '.img.gz') & ...
  33. ~strcmp(filename(end-6:end), '.hdr.gz') & ...
  34. ~strcmp(filename(end-6:end), '.nii.gz')
  35. error('Please check filename.');
  36. end
  37. if str2num(v(1:3)) < 7.1 | ~usejava('jvm')
  38. error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.');
  39. else
  40. gzFile = 1;
  41. end
  42. else
  43. if ~strcmp(filename(end-3:end), '.img') & ...
  44. ~strcmp(filename(end-3:end), '.hdr') & ...
  45. ~strcmp(filename(end-3:end), '.nii')
  46. error('Please check filename.');
  47. end
  48. end
  49. nii = load_untouch_nii(fullfile(scan_path,filename));
  50. nii.hdr.dime.dim(5) = length(flist);
  51. if nii.hdr.dime.dim(1) < 4
  52. nii.hdr.dime.dim(1) = 4;
  53. end
  54. hdr = nii.hdr;
  55. filetype = nii.filetype;
  56. if isfield(nii,'ext') & ~isempty(nii.ext)
  57. ext = nii.ext;
  58. [ext, esize_total] = verify_nii_ext(ext);
  59. else
  60. ext = [];
  61. end
  62. switch double(hdr.dime.datatype),
  63. case 1,
  64. hdr.dime.bitpix = int16(1 ); precision = 'ubit1';
  65. case 2,
  66. hdr.dime.bitpix = int16(8 ); precision = 'uint8';
  67. case 4,
  68. hdr.dime.bitpix = int16(16); precision = 'int16';
  69. case 8,
  70. hdr.dime.bitpix = int16(32); precision = 'int32';
  71. case 16,
  72. hdr.dime.bitpix = int16(32); precision = 'float32';
  73. case 32,
  74. hdr.dime.bitpix = int16(64); precision = 'float32';
  75. case 64,
  76. hdr.dime.bitpix = int16(64); precision = 'float64';
  77. case 128,
  78. hdr.dime.bitpix = int16(24); precision = 'uint8';
  79. case 256
  80. hdr.dime.bitpix = int16(8 ); precision = 'int8';
  81. case 512
  82. hdr.dime.bitpix = int16(16); precision = 'uint16';
  83. case 768
  84. hdr.dime.bitpix = int16(32); precision = 'uint32';
  85. case 1024
  86. hdr.dime.bitpix = int16(64); precision = 'int64';
  87. case 1280
  88. hdr.dime.bitpix = int16(64); precision = 'uint64';
  89. case 1792,
  90. hdr.dime.bitpix = int16(128); precision = 'float64';
  91. otherwise
  92. error('This datatype is not supported');
  93. end
  94. if filetype == 2
  95. fid = fopen(sprintf('%s.nii',fileprefix),'w');
  96. if fid < 0,
  97. msg = sprintf('Cannot open file %s.nii.',fileprefix);
  98. error(msg);
  99. end
  100. hdr.dime.vox_offset = 352;
  101. if ~isempty(ext)
  102. hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total;
  103. end
  104. hdr.hist.magic = 'n+1';
  105. save_untouch_nii_hdr(hdr, fid);
  106. if ~isempty(ext)
  107. save_nii_ext(ext, fid);
  108. end
  109. elseif filetype == 1
  110. fid = fopen(sprintf('%s.hdr',fileprefix),'w');
  111. if fid < 0,
  112. msg = sprintf('Cannot open file %s.hdr.',fileprefix);
  113. error(msg);
  114. end
  115. hdr.dime.vox_offset = 0;
  116. hdr.hist.magic = 'ni1';
  117. save_untouch_nii_hdr(hdr, fid);
  118. if ~isempty(ext)
  119. save_nii_ext(ext, fid);
  120. end
  121. fclose(fid);
  122. fid = fopen(sprintf('%s.img',fileprefix),'w');
  123. else
  124. fid = fopen(sprintf('%s.hdr',fileprefix),'w');
  125. if fid < 0,
  126. msg = sprintf('Cannot open file %s.hdr.',fileprefix);
  127. error(msg);
  128. end
  129. save_untouch0_nii_hdr(hdr, fid);
  130. fclose(fid);
  131. fid = fopen(sprintf('%s.img',fileprefix),'w');
  132. end
  133. if filetype == 2 & isempty(ext)
  134. skip_bytes = double(hdr.dime.vox_offset) - 348;
  135. else
  136. skip_bytes = 0;
  137. end
  138. if skip_bytes
  139. fwrite(fid, zeros(1,skip_bytes), 'uint8');
  140. end
  141. glmax = -inf;
  142. glmin = inf;
  143. for i = 1:length(flist)
  144. nii = load_untouch_nii(fullfile(scan_path,flist{i}));
  145. if double(hdr.dime.datatype) == 128
  146. % RGB planes are expected to be in the 4th dimension of nii.img
  147. %
  148. if(size(nii.img,4)~=3)
  149. error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']);
  150. end
  151. nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]);
  152. end
  153. % For complex float32 or complex float64, voxel values
  154. % include [real, imag]
  155. %
  156. if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792
  157. real_img = real(nii.img(:))';
  158. nii.img = imag(nii.img(:))';
  159. nii.img = [real_img; nii.img];
  160. end
  161. if nii.hdr.dime.glmax > glmax
  162. glmax = nii.hdr.dime.glmax;
  163. end
  164. if nii.hdr.dime.glmin < glmin
  165. glmin = nii.hdr.dime.glmin;
  166. end
  167. fwrite(fid, nii.img, precision);
  168. end
  169. hdr.dime.glmax = round(glmax);
  170. hdr.dime.glmin = round(glmin);
  171. if filetype == 2
  172. fseek(fid, 140, 'bof');
  173. fwrite(fid, hdr.dime.glmax, 'int32');
  174. fwrite(fid, hdr.dime.glmin, 'int32');
  175. elseif filetype == 1
  176. fid2 = fopen(sprintf('%s.hdr',fileprefix),'w');
  177. if fid2 < 0,
  178. msg = sprintf('Cannot open file %s.hdr.',fileprefix);
  179. error(msg);
  180. end
  181. save_untouch_nii_hdr(hdr, fid2);
  182. if ~isempty(ext)
  183. save_nii_ext(ext, fid2);
  184. end
  185. fclose(fid2);
  186. else
  187. fid2 = fopen(sprintf('%s.hdr',fileprefix),'w');
  188. if fid2 < 0,
  189. msg = sprintf('Cannot open file %s.hdr.',fileprefix);
  190. error(msg);
  191. end
  192. save_untouch0_nii_hdr(hdr, fid2);
  193. fclose(fid2);
  194. end
  195. fclose(fid);
  196. % gzip output file if requested
  197. %
  198. if exist('gzFile', 'var')
  199. if filetype == 1
  200. gzip([fileprefix, '.img']);
  201. delete([fileprefix, '.img']);
  202. gzip([fileprefix, '.hdr']);
  203. delete([fileprefix, '.hdr']);
  204. elseif filetype == 2
  205. gzip([fileprefix, '.nii']);
  206. delete([fileprefix, '.nii']);
  207. end;
  208. end;
  209. return; % collapse_nii_scan