function NSx = saveChNSx(varargin) % saveNSx % % Saves a given continuous NSx file and saves a subset of the channels in % the given file into a new NSx file. Ths NSx file has to be opened with % openNSx version 5.1.1.0 or later. % % All input arguments are optional. Input arguments can be in any order. % % NSx: The data structure holding the channel information % % fname: Name of the file to be saved. If the fname is omitted % the program will automaticallyl save the file using the % original file name with -mod added to the end of the % file. % DEFAULT: Will automatically choose the name. % % reset: If argument 'reset' is passed to the function then the % channel IDs are reset. For example, when reading channels % 2, 5, and 9 only, normally the file will indicate that the % newly saved file will contains channels 2, 5, and 9. If % 'reset' is used, then the file will labels those channels % as 1, 2 and 3 respectively. This is a requirement for OFS % compatibility when a tetrode file is loaded. % DEFAULT: The channel labels are not reset. % % Example: % % saveChNSx('c:\data\sample.ns5', [1,5:9], 'reset'); % % In the example above, the file c:\data\sample.ns5 will be opened and % channels 1,5,6,7,8,9 out of all the channels in this file will be saved % as a new file. If the new file already exists then the user will be % prompted if the new file should be overwritten or not. The new file % will label the channels as 1, 2, 3, 4, 5, and 6. % % Kian Torab % Blackrock Microsystems % kian@blackrockmicro.com % % Version 2.1.0.1 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Version History % % 1.0.0.0: % - Initial release. % % 2.1.0.1: % - Added the flag 'reset' as an optional argument to OFS compatibility.. % % 2.1.1.0: % - Fixed the "numberic" bug. % - Fixed saved file name bug. % - Fixed other reading bugs. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Validating input arguments if isempty(varargin) [path fname fext] = openFile; channels = getChannels; resetFlag = 'noreset'; elseif length(varargin) == 1 if isnumeric(varargin{1}) [path fname fext] = openFile; channels = varargin{1}; resetFlag = 'noreset'; else channels = getChannels; if strcmpi(varargin{1}, 'reset') resetFlag = 'reset'; else [path fname fext] = fileparts(varargin{1}); end end elseif length(varargin) == 2 if isnumeric(varargin{1}) channels = varargin{1}; if strcmpi(varargin{2}, 'reset') resetFlag = 'reset'; [path fname fext] = openFile; else [path fname fext] = fileparts(varargin{2}); resetFlag = 'noreset'; end elseif strcmpi(varargin{1}, 'reset') resetFlag = 'reset'; if isnumeric(varargin{2}) channels = varargin{2}; [path fname fext] = openFile; else [path fname fext] = fileparts(varargin{2}); end else [path fname fext] = fileparts(varargin{1}); if isnumeric(varargin{2}) channels = varargin{2}; resetFlag = 'noreset'; else resetFlag = varargin{2}; end end elseif length(varargin) == 3 if isnumeric(varargin{1}) channels = varargin{1}; if strcmpi(varargin{2}, 'reset') resetFlag = 'reset'; [path fname fext] = fileparts(varargin{3}); else [path fname fext] = fileparts(varargin{2}); resetFlag = varargin{3}; end elseif strcmpi(varargin{1}, 'reset') resetFlag = 'reset'; if isnumeric(varargin{2}) channels = varargin{2}; [path fname fext] = fileparts(varargin{3}); else [path fname fext] = fileparts(varargin{2}); channels = varargin{3}; end else [path fname fext] = fileparts(varargin{1}); if isnumeric(varargin{2}) channels = varargin{2}; resetFlag = varargin{3}; else resetFlag = varargin{2}; channels = varargin{3}; end end end % Validating file name if fname == 0 disp('No file was selected.'); if nargout clear variables; end return; end if exist(fullfile(path, [fname, fext]), 'file') ~= 2 disp('File cannot be found.'); if nargout clear variables; end return; end % Validating and fixing resetFlag input if ~strcmpi(resetFlag, 'reset') resetFlag = 'noreset'; end % Opening the original file disp('Openning the original file...'); NSx = openNSx(fullfile(path, [fname fext]), ['c:' num2str(channels)], 'read'); if NSx.RawData.PausedFile disp('At this time it is not possible to extract channels from files that have pauses in them.'); return; end % Writing header into the file newFilename = fullfile(path, [fname '-chandec' fext]); if exist(newFilename, 'file') == 2 overwriteFlag = input('The file already exists. Overwrite? ', 's'); if ~strcmpi(overwriteFlag, 'y') clear all; return; end end FIDw = fopen(newFilename, 'w+', 'ieee-le'); % Removing the extra channels from the header channelHeaderBytes = 66; currentPosition = length(NSx.RawData.Headers); totalNumberOfChannels = NSx.RawData.Headers(311); NSx.RawData.Headers(311) = uint8(length(channels)); allChannels = totalNumberOfChannels:-1:1; thChannelToKeep = 0; for chanIDX = 1:totalNumberOfChannels if ~ismember(allChannels(chanIDX), channels) NSx.RawData.Headers(currentPosition-channelHeaderBytes+1:currentPosition) = []; else if strcmpi(resetFlag, 'reset') NSx.RawData.Headers(currentPosition-channelHeaderBytes+3:currentPosition-channelHeaderBytes+4) = typecast(int16(length(channels)-thChannelToKeep), 'int8'); thChannelToKeep = thChannelToKeep + 1; end end currentPosition = currentPosition - channelHeaderBytes; end % Writing the header information fwrite(FIDw, NSx.RawData.Headers, 'uint8'); fwrite(FIDw, NSx.RawData.DataHeader, 'uint8'); % Writing data into file disp('Writing into the new file...'); fwrite(FIDw, NSx.Data, 'int16'); fclose(FIDw); clear all; function [path fname fext] = openFile % Getting the file name if ~ismac [fname, path] = getFile('*.ns*', 'Choose an NSx file...'); else [fname, path] = getFile('*.*', 'Choose an NSx file...'); end fext = fname(end-3:end); fname = fname(1:end-4); function channels = getChannels channels = input('What channels would you like to save as a separate file? '); while ~isnumeric(channels) disp('The response should be a numberical value (e.g. 3 or [4,6:10]).'); channels = input('What channels would you like to save as a separate file? '); end