123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- function saveNSx(NSx,varargin)
- %%
- % Save an .NSx file from an NSx structure (gained by using openNSx)
- % Works with file spec 2.3 and 3.0
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Use: saveNSx(NSx,optionalinputarguments)
- % NSx: The NSx data structure.
- % All arguments below are optional:
- % Filename: A complete filepath for the output file.
- % Default: CurrentFilename-Modified.NSx
- % Filespec: Save the file using the filespec specified e.g. 2.3 or 3.0
- % Default: same as the filespec loaded
- %saveNSx version = '1.0.0.1';
- % Version History
- %
- % 1.0.0.1:
- % - Added ability to save to a specific filespec
- %
- %%
- % Verify FilePath and establish overwrite paramaters
- FilePath = [fullfile(NSx.MetaTags.FilePath,NSx.MetaTags.Filename) '-modified' NSx.MetaTags.FileExt];
- if length(varargin) >= 1
- if not(isempty(varargin{1}))
- FilePath = varargin{1};
- end
- end
- % save to a specific filespec
- if length(varargin) >= 2
- if (varargin{2} == 2.3)
- NSx.MetaTags.FileTypeID(1:8) = 'NEURALCD';
- NSx.MetaTags.FileSpec(1:3) = '2.3';
- end
- if (varargin{2} == 3.0)
- NSx.MetaTags.FileTypeID(1:8) = 'BRSMPGRP';
- NSx.MetaTags.FileSpec(1:3) = '3.0';
- end
- end
- disp('This script will save a new file with the proper .NSx extensions');
- disp('but you should retain the previous file. Do you acknowledge the');
- Accept = input('risk inherent in saving modified versions of data files? (Y/N)','s');
- if strcmpi(Accept,'y')
- else
- disp('Ending Script...');
- return
- end
- %%
- % Write the basic header into the file
- %FullFile
- Debug = 0;
- if exist(FilePath)
- if exist(FilePath)
- disp('File already exists!');
- OverwritePrompt = input('Would you like to overwrite? (Y/N)','s');
- if strcmpi(OverwritePrompt,'y')
- Overwrite = 1;
- delete(FilePath);
- else
- return
- end
- end
- end
- clear Overwrite
- clear OverwritePrompt
- clear varargin
- %PausedFile?
- if iscell(NSx.Data)
- Paused = 1;
- NumberOfSegments = length(NSx.Data);
- else
- Paused = 0;
-
- end
- FileID = fopen(FilePath, 'w', 'ieee-le');
- %Basic header stuff
- BytesInBasicHeader = 8+2+4+16+256+4+4+16+4;
- BytesInExtendedHeader = 2+2+16+1+1+2+2+2+2+16+4+4+2+4+4+2;
- if Paused == 1
- for SegmentCount = 1:NumberOfSegments
- [NumberOfChannels,LengthOfData{SegmentCount}] = size(NSx.Data{SegmentCount});
- end
- elseif Paused == 0
- [NumberOfChannels,LengthOfData] = size(NSx.Data);
- end
- %Identify filespec
- fspec = NSx.MetaTags.FileTypeID(1:8);
- if strcmp(fspec,'BRSMPGRP')
- tspres = 'uint64';
- else
- tspres = 'uint32';
- end
- %File Type ID
- Before = 0;
- fwrite(FileID,fspec);
- After = ftell(FileID);
- if After-Before ~= 8 && Debug == 1
- disp('error FildID')
- end
- %File spec
- Before = ftell(FileID);
- fwrite(FileID, [str2double(NSx.MetaTags.FileSpec(1)) str2double(NSx.MetaTags.FileSpec(3))], 'uint8');
- After = ftell(FileID);
- if After-Before ~= 2 && Debug == 1
- disp('error File Spec')
- end
- %Bytes in Headers
- Before = ftell(FileID);
- fwrite(FileID, BytesInBasicHeader+NumberOfChannels*BytesInExtendedHeader,'uint32');
- After = ftell(FileID);
- if After-Before ~= 4 && Debug == 1
- disp('error BytesInHeaders')
- end
- %Label
- Before = ftell(FileID);
- fwrite(FileID, NSx.MetaTags.SamplingLabel);
- After = ftell(FileID);
- if After-Before ~= 16 && Debug == 1
- disp('error label')
- end
- %Comment
- Before = ftell(FileID);
- if ~isempty(NSx.MetaTags.Comment)
- fwrite(FileID, NSx.MetaTags.Comment);
- else
- fwrite(FileID, repmat(' ', 1, 256));
- end
- After = ftell(FileID);
- if After-Before ~= 256 && Debug == 1
- disp('error comment')
- end
- %Period
- Before = ftell(FileID);
- fwrite(FileID, (1/NSx.MetaTags.SamplingFreq)*30000, 'uint32');
- After = ftell(FileID);
- if After-Before ~= 4 && Debug == 1
- disp('error period')
- end
- %Time Resolution of time stamps
- Before = ftell(FileID);
- fwrite(FileID, NSx.MetaTags.TimeRes,'uint32');
- After = ftell(FileID);
- if After-Before ~= 4 && Debug == 1
- disp('error time resolution')
- end
- %Time Origin
- Before = ftell(FileID);
- if ~isempty(NSx.MetaTags.DateTimeRaw)
- fwrite(FileID, NSx.MetaTags.DateTimeRaw,'uint16');
- else
- fwrite(FileID, [1900 1 1 0 0 0 0 0],'uint16');
- end
- After = ftell(FileID);
- if After-Before ~= 16 && Debug == 1
- disp('error Time Origin')
- end
- %Channel Count
- Before = ftell(FileID);
- fwrite(FileID, NumberOfChannels,'uint32');
- After = ftell(FileID);
- if After-Before ~= 4 && Debug == 1
- disp('error Channel Count')
- end
- %Extended header stuff
- %Number of these equal to number of channels
- for i = 1:NumberOfChannels
- % Type
- Before = ftell(FileID);
- fwrite(FileID, 'CC');
- After = ftell(FileID);
- if After-Before ~= 2 && Debug == 1
- disp('error Type')
- end
- % ElectrodeID
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).ElectrodeID,'uint16');
- catch
- fwrite(FileID, i,'uint16');
- end
- After = ftell(FileID);
- if After-Before ~= 2 && Debug == 1
- disp('error ElectrodeID')
- end
- % Electrode label
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).Label);
- catch
- templabel = ['chan' num2str(i) ' '];
- templabel(17:end) = [];
- fwrite(FileID, templabel);
- end
- After = ftell(FileID);
- if After-Before ~= 16 && Debug == 1
- disp('error Electrode Label')
- end
- % Physical connector
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).ConnectorBank, 'uint8');
- catch
- if i > 0 && i <= 32
- fwrite(FileID, 1, 'uint8');
- elseif i > 32 && i <= 64
- fwrite(FileID, 2, 'uint8');
- elseif i > 64 && i <= 96
- fwrite(FileID, 3, 'uint8');
- elseif i > 96 && i <= 128
- fwrite(FileID, 4, 'uint8');
- end
- end
- After = ftell(FileID);
- if After-Before ~= 1 && Debug == 1
- disp('error Physical Connector')
- end
- %Physical pin
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).ConnectorPin, 'uint8');
- catch
- fwrite(FileID, int2str((i-floor(i/32)*32)), 'uint8');
- end
- After = ftell(FileID);
- if After-Before ~= 1 && Debug == 1
- disp('error Physical Pin')
- end
- %Min Digital Value
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).MinDigiValue,'int16');
- catch
- fwrite(FileID, -32764,'int16');
- end
- After = ftell(FileID);
- if After-Before ~= 2 && Debug == 1
- disp('error min Digital Value')
- end
- %Max Digital Value
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).MaxDigiValue,'int16');
- catch
- fwrite(FileID, 32764,'int16');
- end
- After = ftell(FileID);
- if After-Before ~= 2 && Debug == 1
- disp('error Max Digital value')
- end
- %Min Analog Value
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).MinAnalogValue,'int16');
- catch
- fwrite(FileID, -8191,'int16');
- end
- After = ftell(FileID);
- if After-Before ~= 2 && Debug == 1
- disp('error Min Analog Value')
- end
- %Max Analog Value
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).MaxAnalogValue,'int16');
- catch
- fwrite(FileID, 8191,'int16');
- end
- After = ftell(FileID);
- if After-Before ~= 2 && Debug == 1
- disp('error Max Aanalog value')
- end
- %Units
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).AnalogUnits,'char');
- catch
- fwrite(FileID, 'uv ');
- end
- After = ftell(FileID);
- if After-Before ~= 16 && Debug == 1
- disp('error Units')
- end
- %High Freq Corner (High frequency cutoff in mHz)
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).HighFreqCorner,'uint32');
- catch
- fwrite(FileID, 0,'uint32');
- end
- After = ftell(FileID);
- if After-Before ~= 4 && Debug == 1
- disp('error High Corner')
- end
- %High Freq Order (Order of the filter used)
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).HighFreqOrder,'uint32');
- catch
- fwrite(FileID, 0,'uint32');
- end
- After = ftell(FileID);
- if After-Before ~= 4 && Debug == 1
- disp('error high Order')
- end
- %High Filter Type (0 = none, 1 = butterworth)
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).HighFilterType,'uint16');
- catch
- fwrite(FileID, 0,'uint16');
- end
- After = ftell(FileID);
- if After-Before ~= 2 && Debug == 1
- disp('error High Type')
- end
- %Low Freq Corner (Low frequency cutoff in mHz)
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).LowFreqCorner,'uint32');
- catch
- fwrite(FileID, 0,'uint32');
- end
- After = ftell(FileID);
- if After-Before ~= 4 && Debug == 1
- disp('error Low Corner')
- end
- %Low Freq Order (0 = none)
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).LowFreqOrder,'uint32');
- catch
- fwrite(FileID, 0,'uint32');
- end
- After = ftell(FileID);
- if After-Before ~= 4 && Debug == 1
- disp('error Low Order')
- end
- %Low Filter Type (0 = none, 1 = butterworth)
- Before = ftell(FileID);
- try
- fwrite(FileID, NSx.ElectrodesInfo(i).LowFilterType,'uint16');
- catch
- fwrite(FileID, 0,'uint16');
- end
- After = ftell(FileID);
- if After-Before ~= 2 && Debug == 1
- disp('error Low Type')
- end
- end
- %DataPackets
- if Paused == 0
- %Header
- fwrite(FileID, NSx.RawData.DataHeader(1));
- %Timestamp
- fwrite(FileID, NSx.MetaTags.Timestamp,tspres);
- %Number of data points
- fwrite(FileID, LengthOfData, 'uint32');
- %for i = 1:TotalDataPoints
- %Data points
- %fwrite(FileID, NSx.Data(i),'int16');
- fwrite(FileID, NSx.Data,'int16');
- %end
- elseif Paused == 1
- for SegmentNumber = 1:NumberOfSegments
- %Header
- fwrite(FileID, 1, 'uint8');
- %Timestamp
- fwrite(FileID, NSx.MetaTags.Timestamp(SegmentNumber),tspres);
- %Number of data points
- fwrite(FileID, LengthOfData{SegmentNumber}, 'uint32');
- %for i = 1:TotalDataPoints
- %Data points
- %fwrite(FileID, NSx.Data(i),'int16');
- fwrite(FileID, NSx.Data{SegmentNumber},'int16');
- %end
- end
- end
- fclose(FileID);
|