123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- function [nexFile] = readNexFile(fileName)
- % [nexfile] = readNexFile(fileName) -- read .nex file and return file data
- % in nexfile structure
- %
- % INPUT:
- % fileName - if empty string, will use File Open dialog
- %
- % OUTPUT:
- % nexFile - a structure containing .nex file data
- % nexFile.version - file version
- % nexFile.comment - file comment
- % nexFile.tbeg - beginning of recording session (in seconds)
- % nexFile.teng - end of resording session (in seconds)
- %
- % nexFile.neurons - array of neuron structures
- % neuron.name - name of a neuron variable
- % neuron.timestamps - array of neuron timestamps (in seconds)
- % to access timestamps for neuron 2 use {n} notation:
- % nexFile.neurons{2}.timestamps
- %
- % nexFile.events - array of event structures
- % event.name - name of neuron variable
- % event.timestamps - array of event timestamps (in seconds)
- % to access timestamps for event 3 use {n} notation:
- % nexFile.events{3}.timestamps
- %
- % nexFile.intervals - array of interval structures
- % interval.name - name of neuron variable
- % interval.intStarts - array of interval starts (in seconds)
- % interval.intEnds - array of interval ends (in seconds)
- %
- % nexFile.waves - array of wave structures
- % wave.name - name of neuron variable
- % wave.NPointsWave - number of data points in each wave
- % wave.WFrequency - A/D frequency for wave data points
- % wave.timestamps - array of wave timestamps (in seconds)
- % wave.waveforms - matrix of waveforms (in milliVolts), each
- % waveform is a vector
- %
- % nexFile.contvars - array of contvar structures
- % contvar.name - name of neuron variable
- % contvar.ADFrequency - A/D frequency for data points
- %
- % continuous (a/d) data come in fragments. Each fragment has a timestamp
- % and an index of the a/d data points in data array. The timestamp corresponds to
- % the time of recording of the first a/d value in this fragment.
- %
- % contvar.timestamps - array of timestamps (fragments start times in seconds)
- % contvar.fragmentStarts - array of start indexes for fragments in contvar.data array
- % contvar.data - array of data points (in milliVolts)
- %
- % nexFile.popvectors - array of popvector (population vector) structures
- % popvector.name - name of popvector variable
- % popvector.weights - array of population vector weights
- %
- % nexFile.markers - array of marker structures
- % marker.name - name of marker variable
- % marker.timestamps - array of marker timestamps (in seconds)
- % marker.values - array of marker value structures
- % marker.value.name - name of marker value
- % marker.value.strings - array of marker value strings
- %
- nexFile = [];
- if (nargin == 0 | length(fileName) == 0)
- [fname, pathname] = uigetfile('*.nex', 'Select a NeuroExplorer file');
- fileName = strcat(pathname, fname);
- end
- fid = fopen(fileName, 'r');
- if(fid == -1)
- error 'Unable to open file'
- return
- end
- magic = fread(fid, 1, 'int32');
- if magic ~= 827868494
- error 'The file is not a valid .nex file'
- end
- nexFile.version = fread(fid, 1, 'int32');
- nexFile.comment = deblank(char(fread(fid, 256, 'char')'));
- nexFile.freq = fread(fid, 1, 'double');
- nexFile.tbeg = fread(fid, 1, 'int32')./nexFile.freq;
- nexFile.tend = fread(fid, 1, 'int32')./nexFile.freq;
- nvar = fread(fid, 1, 'int32');
- % skip location of next header and padding
- fseek(fid, 260, 'cof');
- neuronCount = 0;
- eventCount = 0;
- intervalCount = 0;
- waveCount = 0;
- popCount = 0;
- contCount = 0;
- markerCount = 0;
- % real all variables
- for i=1:nvar
- type = fread(fid, 1, 'int32');
- varVersion = fread(fid, 1, 'int32');
- name = deblank(char(fread(fid, 64, 'char')'));
- offset = fread(fid, 1, 'int32');
- n = fread(fid, 1, 'int32');
- WireNumber = fread(fid, 1, 'int32');
- UnitNumber = fread(fid, 1, 'int32');
- Gain = fread(fid, 1, 'int32');
- Filter = fread(fid, 1, 'int32');
- XPos = fread(fid, 1, 'double');
- YPos = fread(fid, 1, 'double');
- WFrequency = fread(fid, 1, 'double'); % wf sampling fr.
- ADtoMV = fread(fid, 1, 'double'); % coeff to convert from AD values to Millivolts.
- NPointsWave = fread(fid, 1, 'int32'); % number of points in each wave
- NMarkers = fread(fid, 1, 'int32'); % how many values are associated with each marker
- MarkerLength = fread(fid, 1, 'int32'); % how many characters are in each marker value
- MVOfffset = fread(fid, 1, 'double'); % coeff to shift AD values in Millivolts: mv = raw*ADtoMV+MVOfffset
- filePosition = ftell(fid);
- switch type
- case 0 % neuron
- neuronCount = neuronCount+1;
- nexFile.neurons{neuronCount,1}.name = name;
- fseek(fid, offset, 'bof');
- nexFile.neurons{neuronCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
- fseek(fid, filePosition, 'bof');
-
- case 1 % event
- eventCount = eventCount+1;
- nexFile.events{eventCount,1}.name = name;
- fseek(fid, offset, 'bof');
- nexFile.events{eventCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
- fseek(fid, filePosition, 'bof');
-
- case 2 % interval
- intervalCount = intervalCount+1;
- nexFile.intervals{intervalCount,1}.name = name;
- fseek(fid, offset, 'bof');
- nexFile.intervals{intervalCount,1}.intStarts = fread(fid, [n 1], 'int32')./nexFile.freq;
- nexFile.intervals{intervalCount,1}.intEnds = fread(fid, [n 1], 'int32')./nexFile.freq;
- fseek(fid, filePosition, 'bof');
-
- case 3 % waveform
- waveCount = waveCount+1;
- nexFile.waves{waveCount,1}.name = name;
- nexFile.waves{waveCount,1}.NPointsWave = NPointsWave;
- nexFile.waves{waveCount,1}.WFrequency = WFrequency;
-
- fseek(fid, offset, 'bof');
- nexFile.waves{waveCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
- nexFile.waves{waveCount,1}.waveforms = fread(fid, [NPointsWave n], 'int16').*ADtoMV + MVOfffset;
- fseek(fid, filePosition, 'bof');
-
- case 4 % population vector
- popCount = popCount+1;
- nexFile.popvectors{popCount,1}.name = name;
- fseek(fid, offset, 'bof');
- nexFile.popvectors{popCount,1}.weights = fread(fid, [n 1], 'double');
- fseek(fid, filePosition, 'bof');
-
- case 5 % continuous variable
- contCount = contCount+1;
- nexFile.contvars{contCount,1}.name = name;
- nexFile.contvars{contCount,1}.ADFrequency = WFrequency;
- fseek(fid, offset, 'bof');
- nexFile.contvars{contCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
- nexFile.contvars{contCount,1}.fragmentStarts = fread(fid, [n 1], 'int32') + 1;
- nexFile.contvars{contCount,1}.data = fread(fid, [NPointsWave 1], 'int16').*ADtoMV + MVOfffset;
- fseek(fid, filePosition, 'bof');
-
- case 6 % marker
- markerCount = markerCount+1;
- nexFile.markers{markerCount,1}.name = name;
- fseek(fid, offset, 'bof');
- nexFile.markers{markerCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
- for i=1:NMarkers
- nexFile.markers{markerCount,1}.values{i,1}.name = deblank(char(fread(fid, 64, 'char')'));
- for p = 1:n
- nexFile.markers{markerCount,1}.values{i,1}.strings{p, 1} = deblank(char(fread(fid, MarkerLength, 'char')'));
- end
- end
- fseek(fid, filePosition, 'bof');
-
- otherwise
- disp (['unknown variable type ' num2str(type)]);
- end
- dummy = fread(fid, 60, 'char');
- end
- fclose(fid);
|