ProcessBinary - Process binary data file. Process binary data file, e.g. filter LFP file. This function loads the binary file segment by segment, calls a user-supplied function to process each data segment, and optionally saves the result to a new file. If the function requires overlapping segments (e.g. to avoid edge effects), it will receive data in the form [o1;s;o2], where s is the segment to process, and o1 and o2 are portions of the previous and next segments (half the overlap size each). The function should return the processed segment, WITHOUT the overlapping portions. USAGE ProcessBinary(inputName,outputName,nChannels,f,<options>) inputName binary input file outputName binary output file (optional, see below) nChannels number of channels in the input file f function handle <options> optional list of property-value pairs (see table below) ========================================================================= Properties Values ------------------------------------------------------------------------- 'parameters' additional parameters for f (cell array) 'overlap' overlap in # samples (default = 0) 'segment' segment length in # samples (default = 2^16) ========================================================================= EXAMPLES % Change sign (using an anonymous function) ProcessBinary('input.dat','output.dat',1,@(x) -x); % Low-pass filter and square using the following funtion: % function y = CustomFilter(x,b,a) % y = filtfilt(b,a,x).^2; % y = y(251:end-250); ProcessBinary('input.dat','output.dat',1,@CustomFilter,'parameters',{b,a},'overlap',500); % If you require more elaborate functionality than just saving the processed % segment (e.g. save several files, or use a custom file format), pass an % empty output filename and include the appropriate code in your function. % For instance, % function y = SaveMax(x,f) % m = max(x); % fwrite(f,m); ProcessBinary('input.dat','',1,@SaveMax,'parameters',{'output.dat'});
0001 function ProcessBinary(inputName,outputName,nChannels,f,varargin) 0002 0003 %ProcessBinary - Process binary data file. 0004 % 0005 % Process binary data file, e.g. filter LFP file. This function loads the 0006 % binary file segment by segment, calls a user-supplied function to process 0007 % each data segment, and optionally saves the result to a new file. 0008 % 0009 % If the function requires overlapping segments (e.g. to avoid edge effects), 0010 % it will receive data in the form [o1;s;o2], where s is the segment to process, 0011 % and o1 and o2 are portions of the previous and next segments (half the overlap 0012 % size each). The function should return the processed segment, WITHOUT the 0013 % overlapping portions. 0014 % 0015 % USAGE 0016 % 0017 % ProcessBinary(inputName,outputName,nChannels,f,<options>) 0018 % 0019 % inputName binary input file 0020 % outputName binary output file (optional, see below) 0021 % nChannels number of channels in the input file 0022 % f function handle 0023 % <options> optional list of property-value pairs (see table below) 0024 % 0025 % ========================================================================= 0026 % Properties Values 0027 % ------------------------------------------------------------------------- 0028 % 'parameters' additional parameters for f (cell array) 0029 % 'overlap' overlap in # samples (default = 0) 0030 % 'segment' segment length in # samples (default = 2^16) 0031 % ========================================================================= 0032 % 0033 % EXAMPLES 0034 % 0035 % % Change sign (using an anonymous function) 0036 % ProcessBinary('input.dat','output.dat',1,@(x) -x); 0037 % 0038 % % Low-pass filter and square using the following funtion: 0039 % % function y = CustomFilter(x,b,a) 0040 % % y = filtfilt(b,a,x).^2; 0041 % % y = y(251:end-250); 0042 % ProcessBinary('input.dat','output.dat',1,@CustomFilter,'parameters',{b,a},'overlap',500); 0043 % 0044 % % If you require more elaborate functionality than just saving the processed 0045 % % segment (e.g. save several files, or use a custom file format), pass an 0046 % % empty output filename and include the appropriate code in your function. 0047 % % For instance, 0048 % % function y = SaveMax(x,f) 0049 % % m = max(x); 0050 % % fwrite(f,m); 0051 % ProcessBinary('input.dat','',1,@SaveMax,'parameters',{'output.dat'}); 0052 % 0053 0054 % Copyright (C) 2004-2018 by Michaƫl Zugaro 0055 % 0056 % This program is free software; you can redistribute it and/or modify 0057 % it under the terms of the GNU General Public License as published by 0058 % the Free Software Foundation; either version 3 of the License, or 0059 % (at your option) any later version. 0060 0061 % Default values 0062 nOverlap = 0; 0063 segmentLength = 2^16; 0064 parameters = {}; 0065 0066 % Check parameters 0067 if nargin < 4, 0068 error('Incorrect number of parameters (type ''help <a href="matlab:help ProcessBinary">ProcessBinary</a>'' for details).'); 0069 end 0070 0071 % Parse parameter list 0072 for i = 1:2:length(varargin), 0073 if ~ischar(varargin{i}), 0074 error(['Parameter ' num2str(i+1) ' is not a property (type ''help <a href="matlab:help ProcessBinary">ProcessBinary</a>'' for details).']); 0075 end 0076 switch(lower(varargin{i})), 0077 case 'overlap', 0078 nOverlap = varargin{i+1}; 0079 if ~isiscalar(nOverlap,'>0'), 0080 error('Incorrect value for property ''overlap'' (type ''help <a href="matlab:help ProcessBinary">ProcessBinary</a>'' for details).'); 0081 end 0082 if rem(nOverlap,2) ~= 0, 0083 error('Overlap must be even (type ''help <a href="matlab:help ProcessBinary">ProcessBinary</a>'' for details).'); 0084 end 0085 case 'segment', 0086 segmentLength = varargin{i+1}; 0087 if ~isiscalar(segmentLength,'>0'), 0088 error('Incorrect value for property ''segment'' (type ''help <a href="matlab:help ProcessBinary">ProcessBinary</a>'' for details).'); 0089 end 0090 case 'parameters', 0091 parameters = varargin{i+1}; 0092 if ~iscell(parameters), 0093 error('Incorrect value for property ''parameters'' (type ''help <a href="matlab:help ProcessBinary">ProcessBinary</a>'' for details).'); 0094 end 0095 otherwise, 0096 error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help <a href="matlab:help ProcessBinary">ProcessBinary</a>'' for details).']); 0097 end 0098 end 0099 0100 % Open input and output files 0101 inputFile = fopen(inputName,'r'); 0102 if ~isempty(outputName), outputFile = fopen(outputName,'w'); end 0103 0104 % Process first segment 0105 if nOverlap == 0, 0106 overlap = zeros(nChannels,0); 0107 else 0108 % Flip first segment LR and prepend it to avoid edge effects 0109 overlap = fread(inputFile,[nChannels,nOverlap/2],'int16'); 0110 overlap = fliplr(overlap); 0111 frewind(inputFile); 0112 end 0113 segment = fread(inputFile,[nChannels,segmentLength],'int16'); 0114 segment = [overlap,segment]'; 0115 processed = feval(f,segment,parameters{:}); 0116 if ~isempty(outputName), fwrite(outputFile,processed,'int16'); end 0117 overlap = segment(end-(nOverlap-1):end,:); 0118 0119 % Process subsequent segments 0120 while ~feof(inputFile), 0121 segment = fread(inputFile,[nChannels,segmentLength],'int16'); 0122 segment = [overlap;segment']; 0123 processed = feval(f,segment,parameters{:}); 0124 if ~isempty(outputName), fwrite(outputFile,processed,'int16'); end 0125 overlap = segment(end-(nOverlap-1):end,:); 0126 end 0127 0128 % Process trailing unprocessed segment 0129 if nOverlap ~= 0, 0130 % Flip last segment UD and append it to avoid edge effects 0131 segment = segment(end-(nOverlap-1):end,:); 0132 tail = flipud(segment(end-(nOverlap/2-1):end,:)); 0133 segment = [segment;tail]; 0134 processed = feval(f,segment,parameters{:}); 0135 if ~isempty(outputName), fwrite(outputFile,processed,'int16'); end 0136 end 0137 0138 % Close input and output files 0139 fclose(inputFile); 0140 if ~isempty(outputName), fclose(outputFile); end 0141