readNexFile.m 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. function [nexFile] = readNexFile(fileName)
  2. % [nexfile] = readNexFile(fileName) -- read .nex file and return file data
  3. % in nexfile structure
  4. %
  5. % INPUT:
  6. % fileName - if empty string, will use File Open dialog
  7. %
  8. % OUTPUT:
  9. % nexFile - a structure containing .nex file data
  10. % nexFile.version - file version
  11. % nexFile.comment - file comment
  12. % nexFile.tbeg - beginning of recording session (in seconds)
  13. % nexFile.teng - end of resording session (in seconds)
  14. %
  15. % nexFile.neurons - array of neuron structures
  16. % neuron.name - name of a neuron variable
  17. % neuron.timestamps - array of neuron timestamps (in seconds)
  18. % to access timestamps for neuron 2 use {n} notation:
  19. % nexFile.neurons{2}.timestamps
  20. %
  21. % nexFile.events - array of event structures
  22. % event.name - name of neuron variable
  23. % event.timestamps - array of event timestamps (in seconds)
  24. % to access timestamps for event 3 use {n} notation:
  25. % nexFile.events{3}.timestamps
  26. %
  27. % nexFile.intervals - array of interval structures
  28. % interval.name - name of neuron variable
  29. % interval.intStarts - array of interval starts (in seconds)
  30. % interval.intEnds - array of interval ends (in seconds)
  31. %
  32. % nexFile.waves - array of wave structures
  33. % wave.name - name of neuron variable
  34. % wave.NPointsWave - number of data points in each wave
  35. % wave.WFrequency - A/D frequency for wave data points
  36. % wave.timestamps - array of wave timestamps (in seconds)
  37. % wave.waveforms - matrix of waveforms (in milliVolts), each
  38. % waveform is a vector
  39. %
  40. % nexFile.contvars - array of contvar structures
  41. % contvar.name - name of neuron variable
  42. % contvar.ADFrequency - A/D frequency for data points
  43. %
  44. % continuous (a/d) data come in fragments. Each fragment has a timestamp
  45. % and an index of the a/d data points in data array. The timestamp corresponds to
  46. % the time of recording of the first a/d value in this fragment.
  47. %
  48. % contvar.timestamps - array of timestamps (fragments start times in seconds)
  49. % contvar.fragmentStarts - array of start indexes for fragments in contvar.data array
  50. % contvar.data - array of data points (in milliVolts)
  51. %
  52. % nexFile.popvectors - array of popvector (population vector) structures
  53. % popvector.name - name of popvector variable
  54. % popvector.weights - array of population vector weights
  55. %
  56. % nexFile.markers - array of marker structures
  57. % marker.name - name of marker variable
  58. % marker.timestamps - array of marker timestamps (in seconds)
  59. % marker.values - array of marker value structures
  60. % marker.value.name - name of marker value
  61. % marker.value.strings - array of marker value strings
  62. %
  63. nexFile = [];
  64. if (nargin == 0 | length(fileName) == 0)
  65. [fname, pathname] = uigetfile('*.nex', 'Select a NeuroExplorer file');
  66. fileName = strcat(pathname, fname);
  67. end
  68. fid = fopen(fileName, 'r');
  69. if(fid == -1)
  70. error 'Unable to open file'
  71. return
  72. end
  73. magic = fread(fid, 1, 'int32');
  74. if magic ~= 827868494
  75. error 'The file is not a valid .nex file'
  76. end
  77. nexFile.version = fread(fid, 1, 'int32');
  78. nexFile.comment = deblank(char(fread(fid, 256, 'char')'));
  79. nexFile.freq = fread(fid, 1, 'double');
  80. nexFile.tbeg = fread(fid, 1, 'int32')./nexFile.freq;
  81. nexFile.tend = fread(fid, 1, 'int32')./nexFile.freq;
  82. nvar = fread(fid, 1, 'int32');
  83. % skip location of next header and padding
  84. fseek(fid, 260, 'cof');
  85. neuronCount = 0;
  86. eventCount = 0;
  87. intervalCount = 0;
  88. waveCount = 0;
  89. popCount = 0;
  90. contCount = 0;
  91. markerCount = 0;
  92. % real all variables
  93. for i=1:nvar
  94. type = fread(fid, 1, 'int32');
  95. varVersion = fread(fid, 1, 'int32');
  96. name = deblank(char(fread(fid, 64, 'char')'));
  97. offset = fread(fid, 1, 'int32');
  98. n = fread(fid, 1, 'int32');
  99. WireNumber = fread(fid, 1, 'int32');
  100. UnitNumber = fread(fid, 1, 'int32');
  101. Gain = fread(fid, 1, 'int32');
  102. Filter = fread(fid, 1, 'int32');
  103. XPos = fread(fid, 1, 'double');
  104. YPos = fread(fid, 1, 'double');
  105. WFrequency = fread(fid, 1, 'double'); % wf sampling fr.
  106. ADtoMV = fread(fid, 1, 'double'); % coeff to convert from AD values to Millivolts.
  107. NPointsWave = fread(fid, 1, 'int32'); % number of points in each wave
  108. NMarkers = fread(fid, 1, 'int32'); % how many values are associated with each marker
  109. MarkerLength = fread(fid, 1, 'int32'); % how many characters are in each marker value
  110. MVOfffset = fread(fid, 1, 'double'); % coeff to shift AD values in Millivolts: mv = raw*ADtoMV+MVOfffset
  111. filePosition = ftell(fid);
  112. switch type
  113. case 0 % neuron
  114. neuronCount = neuronCount+1;
  115. nexFile.neurons{neuronCount,1}.name = name;
  116. fseek(fid, offset, 'bof');
  117. nexFile.neurons{neuronCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
  118. fseek(fid, filePosition, 'bof');
  119. case 1 % event
  120. eventCount = eventCount+1;
  121. nexFile.events{eventCount,1}.name = name;
  122. fseek(fid, offset, 'bof');
  123. nexFile.events{eventCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
  124. fseek(fid, filePosition, 'bof');
  125. case 2 % interval
  126. intervalCount = intervalCount+1;
  127. nexFile.intervals{intervalCount,1}.name = name;
  128. fseek(fid, offset, 'bof');
  129. nexFile.intervals{intervalCount,1}.intStarts = fread(fid, [n 1], 'int32')./nexFile.freq;
  130. nexFile.intervals{intervalCount,1}.intEnds = fread(fid, [n 1], 'int32')./nexFile.freq;
  131. fseek(fid, filePosition, 'bof');
  132. case 3 % waveform
  133. waveCount = waveCount+1;
  134. nexFile.waves{waveCount,1}.name = name;
  135. nexFile.waves{waveCount,1}.NPointsWave = NPointsWave;
  136. nexFile.waves{waveCount,1}.WFrequency = WFrequency;
  137. fseek(fid, offset, 'bof');
  138. nexFile.waves{waveCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
  139. nexFile.waves{waveCount,1}.waveforms = fread(fid, [NPointsWave n], 'int16').*ADtoMV + MVOfffset;
  140. fseek(fid, filePosition, 'bof');
  141. case 4 % population vector
  142. popCount = popCount+1;
  143. nexFile.popvectors{popCount,1}.name = name;
  144. fseek(fid, offset, 'bof');
  145. nexFile.popvectors{popCount,1}.weights = fread(fid, [n 1], 'double');
  146. fseek(fid, filePosition, 'bof');
  147. case 5 % continuous variable
  148. contCount = contCount+1;
  149. nexFile.contvars{contCount,1}.name = name;
  150. nexFile.contvars{contCount,1}.ADFrequency = WFrequency;
  151. fseek(fid, offset, 'bof');
  152. nexFile.contvars{contCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
  153. nexFile.contvars{contCount,1}.fragmentStarts = fread(fid, [n 1], 'int32') + 1;
  154. nexFile.contvars{contCount,1}.data = fread(fid, [NPointsWave 1], 'int16').*ADtoMV + MVOfffset;
  155. fseek(fid, filePosition, 'bof');
  156. case 6 % marker
  157. markerCount = markerCount+1;
  158. nexFile.markers{markerCount,1}.name = name;
  159. fseek(fid, offset, 'bof');
  160. nexFile.markers{markerCount,1}.timestamps = fread(fid, [n 1], 'int32')./nexFile.freq;
  161. for i=1:NMarkers
  162. nexFile.markers{markerCount,1}.values{i,1}.name = deblank(char(fread(fid, 64, 'char')'));
  163. for p = 1:n
  164. nexFile.markers{markerCount,1}.values{i,1}.strings{p, 1} = deblank(char(fread(fid, MarkerLength, 'char')'));
  165. end
  166. end
  167. fseek(fid, filePosition, 'bof');
  168. otherwise
  169. disp (['unknown variable type ' num2str(type)]);
  170. end
  171. dummy = fread(fid, 60, 'char');
  172. end
  173. fclose(fid);