saveChNSx.m 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. function NSx = saveChNSx(varargin)
  2. % saveNSx
  3. %
  4. % Saves a given continuous NSx file and saves a subset of the channels in
  5. % the given file into a new NSx file. Ths NSx file has to be opened with
  6. % openNSx version 5.1.1.0 or later.
  7. %
  8. % All input arguments are optional. Input arguments can be in any order.
  9. %
  10. % NSx: The data structure holding the channel information
  11. %
  12. % fname: Name of the file to be saved. If the fname is omitted
  13. % the program will automaticallyl save the file using the
  14. % original file name with -mod added to the end of the
  15. % file.
  16. % DEFAULT: Will automatically choose the name.
  17. %
  18. % reset: If argument 'reset' is passed to the function then the
  19. % channel IDs are reset. For example, when reading channels
  20. % 2, 5, and 9 only, normally the file will indicate that the
  21. % newly saved file will contains channels 2, 5, and 9. If
  22. % 'reset' is used, then the file will labels those channels
  23. % as 1, 2 and 3 respectively. This is a requirement for OFS
  24. % compatibility when a tetrode file is loaded.
  25. % DEFAULT: The channel labels are not reset.
  26. %
  27. % Example:
  28. %
  29. % saveChNSx('c:\data\sample.ns5', [1,5:9], 'reset');
  30. %
  31. % In the example above, the file c:\data\sample.ns5 will be opened and
  32. % channels 1,5,6,7,8,9 out of all the channels in this file will be saved
  33. % as a new file. If the new file already exists then the user will be
  34. % prompted if the new file should be overwritten or not. The new file
  35. % will label the channels as 1, 2, 3, 4, 5, and 6.
  36. %
  37. % Kian Torab
  38. % Blackrock Microsystems
  39. % kian@blackrockmicro.com
  40. %
  41. % Version 2.1.0.1
  42. %
  43. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  44. % Version History
  45. %
  46. % 1.0.0.0:
  47. % - Initial release.
  48. %
  49. % 2.1.0.1:
  50. % - Added the flag 'reset' as an optional argument to OFS compatibility..
  51. %
  52. % 2.1.1.0:
  53. % - Fixed the "numberic" bug.
  54. % - Fixed saved file name bug.
  55. % - Fixed other reading bugs.
  56. %
  57. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  58. % Validating input arguments
  59. if isempty(varargin)
  60. [path fname fext] = openFile;
  61. channels = getChannels;
  62. resetFlag = 'noreset';
  63. elseif length(varargin) == 1
  64. if isnumeric(varargin{1})
  65. [path fname fext] = openFile;
  66. channels = varargin{1};
  67. resetFlag = 'noreset';
  68. else
  69. channels = getChannels;
  70. if strcmpi(varargin{1}, 'reset')
  71. resetFlag = 'reset';
  72. else
  73. [path fname fext] = fileparts(varargin{1});
  74. end
  75. end
  76. elseif length(varargin) == 2
  77. if isnumeric(varargin{1})
  78. channels = varargin{1};
  79. if strcmpi(varargin{2}, 'reset')
  80. resetFlag = 'reset';
  81. [path fname fext] = openFile;
  82. else
  83. [path fname fext] = fileparts(varargin{2});
  84. resetFlag = 'noreset';
  85. end
  86. elseif strcmpi(varargin{1}, 'reset')
  87. resetFlag = 'reset';
  88. if isnumeric(varargin{2})
  89. channels = varargin{2};
  90. [path fname fext] = openFile;
  91. else
  92. [path fname fext] = fileparts(varargin{2});
  93. end
  94. else
  95. [path fname fext] = fileparts(varargin{1});
  96. if isnumeric(varargin{2})
  97. channels = varargin{2};
  98. resetFlag = 'noreset';
  99. else
  100. resetFlag = varargin{2};
  101. end
  102. end
  103. elseif length(varargin) == 3
  104. if isnumeric(varargin{1})
  105. channels = varargin{1};
  106. if strcmpi(varargin{2}, 'reset')
  107. resetFlag = 'reset';
  108. [path fname fext] = fileparts(varargin{3});
  109. else
  110. [path fname fext] = fileparts(varargin{2});
  111. resetFlag = varargin{3};
  112. end
  113. elseif strcmpi(varargin{1}, 'reset')
  114. resetFlag = 'reset';
  115. if isnumeric(varargin{2})
  116. channels = varargin{2};
  117. [path fname fext] = fileparts(varargin{3});
  118. else
  119. [path fname fext] = fileparts(varargin{2});
  120. channels = varargin{3};
  121. end
  122. else
  123. [path fname fext] = fileparts(varargin{1});
  124. if isnumeric(varargin{2})
  125. channels = varargin{2};
  126. resetFlag = varargin{3};
  127. else
  128. resetFlag = varargin{2};
  129. channels = varargin{3};
  130. end
  131. end
  132. end
  133. % Validating file name
  134. if fname == 0
  135. disp('No file was selected.');
  136. if nargout
  137. clear variables;
  138. end
  139. return;
  140. end
  141. if exist(fullfile(path, [fname, fext]), 'file') ~= 2
  142. disp('File cannot be found.');
  143. if nargout
  144. clear variables;
  145. end
  146. return;
  147. end
  148. % Validating and fixing resetFlag input
  149. if ~strcmpi(resetFlag, 'reset')
  150. resetFlag = 'noreset';
  151. end
  152. % Opening the original file
  153. disp('Openning the original file...');
  154. NSx = openNSx(fullfile(path, [fname fext]), ['c:' num2str(channels)], 'read');
  155. if NSx.RawData.PausedFile
  156. disp('At this time it is not possible to extract channels from files that have pauses in them.');
  157. return;
  158. end
  159. % Writing header into the file
  160. newFilename = fullfile(path, [fname '-chandec' fext]);
  161. if exist(newFilename, 'file') == 2
  162. overwriteFlag = input('The file already exists. Overwrite? ', 's');
  163. if ~strcmpi(overwriteFlag, 'y')
  164. clear all;
  165. return;
  166. end
  167. end
  168. FIDw = fopen(newFilename, 'w+', 'ieee-le');
  169. % Removing the extra channels from the header
  170. channelHeaderBytes = 66;
  171. currentPosition = length(NSx.RawData.Headers);
  172. totalNumberOfChannels = NSx.RawData.Headers(311);
  173. NSx.RawData.Headers(311) = uint8(length(channels));
  174. allChannels = totalNumberOfChannels:-1:1;
  175. thChannelToKeep = 0;
  176. for chanIDX = 1:totalNumberOfChannels
  177. if ~ismember(allChannels(chanIDX), channels)
  178. NSx.RawData.Headers(currentPosition-channelHeaderBytes+1:currentPosition) = [];
  179. else
  180. if strcmpi(resetFlag, 'reset')
  181. NSx.RawData.Headers(currentPosition-channelHeaderBytes+3:currentPosition-channelHeaderBytes+4) = typecast(int16(length(channels)-thChannelToKeep), 'int8');
  182. thChannelToKeep = thChannelToKeep + 1;
  183. end
  184. end
  185. currentPosition = currentPosition - channelHeaderBytes;
  186. end
  187. % Writing the header information
  188. fwrite(FIDw, NSx.RawData.Headers, 'uint8');
  189. fwrite(FIDw, NSx.RawData.DataHeader, 'uint8');
  190. % Writing data into file
  191. disp('Writing into the new file...');
  192. fwrite(FIDw, NSx.Data, 'int16');
  193. fclose(FIDw);
  194. clear all;
  195. function [path fname fext] = openFile
  196. % Getting the file name
  197. if ~ismac
  198. [fname, path] = getFile('*.ns*', 'Choose an NSx file...');
  199. else
  200. [fname, path] = getFile('*.*', 'Choose an NSx file...');
  201. end
  202. fext = fname(end-3:end);
  203. fname = fname(1:end-4);
  204. function channels = getChannels
  205. channels = input('What channels would you like to save as a separate file? ');
  206. while ~isnumeric(channels)
  207. disp('The response should be a numberical value (e.g. 3 or [4,6:10]).');
  208. channels = input('What channels would you like to save as a separate file? ');
  209. end