mergeNSxNEV.m 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. %
  2. % mergeNSxNEV(filename1, filename2)
  3. %
  4. % This function loads two NSx and NEV files and it will combine them
  5. % together into one file. The resulting file will be saved as new NSx
  6. % and NEV files onto the disk. To combine two NSx and NEV files into
  7. % indivual NSx and NEV variables in MATLAB see combineNSxNEV. The time
  8. % difference between the two sets of recordings is removed. To determine
  9. % the time differnce between the two data files, use
  10. % NSx.MetaTags.DateTimeRaw or NEV.MetaTags.DateTimeRaw variables.
  11. %
  12. %
  13. % filename1: The name of the first NSx file. This input is optional. In
  14. % its absense, a dialog will open and will prompt the user to
  15. % select an NSx file.
  16. % (OPTIONAL)
  17. %
  18. % filename2: The name of the second NSx file. This input is also
  19. % optional. In its absense, a dialog will open and will
  20. % prompt the user to select an NSx file.
  21. % (OPTIONAL)
  22. %
  23. % Example:
  24. %
  25. % mergeNSxNEV('c:\data\saveddata1.ns5', 'c:\data\saveddata2.ns5');
  26. %
  27. % The above example reads the two files (full path needed)
  28. % c:\data\saveddata1.ns5 and c:\data\saveddata2.ns5 and their corresponding
  29. % NEV files (saveddata1.nev and saveddata2.nev) in the same folder and
  30. % merges them into a single file called firstrecording001-combined.ns2
  31. % and firstrecording001-combined.nev.
  32. %
  33. % Kian Torab
  34. % ktorab@blackrockmicro.com
  35. % Blackrock Microsystems
  36. %
  37. % Version 1.2.2.0
  38. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  39. % Kian Torab
  40. % support@blackrockmicro.com
  41. % Blackrock Microsystems
  42. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  43. % Version History
  44. %
  45. % 1.0.0.0: Initial release
  46. %
  47. % 1.2.2.0: August 3, 2016
  48. % - Fixed a bug that resulted in a crash if one of two NEV files weren't
  49. % available.
  50. %
  51. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  52. function mergeNSxNEV(varargin)
  53. if nargin == 3
  54. if strcmpi(varargin{1}, 'nowarning')
  55. warningMessage = varargin{1};
  56. filename1 = varargin{2};
  57. filename2 = varargin{3};
  58. elseif strcmpi(varargin{3}, 'nowarning')
  59. filename1 = varargin{1};
  60. filename2 = varargin{2};
  61. warningMessage = varargin{3};
  62. else
  63. disp('Invalid arguments. See help by typing ''help mergeNSxNEV''');
  64. return;
  65. end
  66. elseif nargin == 2
  67. filename1 = varargin{1};
  68. filename2 = varargin{2};
  69. warningMessage = 'warning';
  70. elseif nargin == 1
  71. warningMessage = varargin{1};
  72. elseif nargin == 0
  73. warningMessage = 'warning';
  74. else
  75. disp('Invalid number of arguments. See help by typing ''help mergeNSxNEV''');
  76. return;
  77. end
  78. %% Warning
  79. if ~strcmpi(warningMessage, 'nowarning')
  80. fprintf(2, '\nCaution! This scripts assumes that the two segments of NSx ');
  81. fprintf(2, '\nand NEV files are from the same recording session. The settings ');
  82. fprintf(2, '\nmust be identical. Always verify the merge to assure it was done');
  83. fprintf(2, '\ncorrectly. To suppress this message, run mergeNSxNEV with command');
  84. fprintf(2, '\n''nowarning''. Ex: mergeNSxNEV(''nowarning'').\n\n');
  85. end
  86. %% Getting the file names
  87. if exist('filename1', 'var') && exist('filename2', 'var')
  88. if exist(filename1, 'file') && exist(filename2, 'file')
  89. NSx1FullName = filename1;
  90. NEV1FullName = [NSx1FullName(1:end-3) 'nev'];
  91. NSx2FullName = filename2;
  92. NEV2FullName = [NSx2FullName(1:end-3) 'nev'];
  93. else
  94. disp('One or both files do not exist.');
  95. return;
  96. end
  97. else
  98. disp('Load the first NSx file.');
  99. if ~ismac
  100. [NSx1dataFilename, NSx1dataFolder] = getFile('*.ns*', 'Choose the first NSx file...');
  101. else
  102. [NSx1dataFilename, NSx1dataFolder] = getFile('*.*', 'Choose the first NSx file...');
  103. end
  104. if NSx1dataFilename == 0
  105. disp('No file was selected.');
  106. return;
  107. end
  108. disp('Load the second NSx file.');
  109. if ~ismac
  110. [NSx2dataFilename, NSx2dataFolder] = getFile('*.ns*', 'Choose the second NSx file...');
  111. else
  112. [NSx2dataFilename, NSx2dataFolder] = getFile('*.*', 'Choose the second NSx file...');
  113. end
  114. if NSx2dataFilename == 0
  115. disp('No file was selected.');
  116. return;
  117. end
  118. NSx1FullName = strcat(NSx1dataFolder, NSx1dataFilename);
  119. NSx2FullName = strcat(NSx2dataFolder, NSx2dataFilename);
  120. NEV1FullName = [NSx1FullName(1:end-3) 'nev'];
  121. NEV2FullName = [NSx2FullName(1:end-3) 'nev'];
  122. end
  123. %% Reading NSx1
  124. NSx1 = openNSx(NSx1FullName);
  125. FID1 = fopen(NSx1FullName, 'r', 'ieee-le');
  126. fread(FID1, 10, '*int8');
  127. NSx1HeaderBytes = typecast(NSx1.RawData.Headers(11:14), 'uint32');
  128. fread(FID1, NSx1HeaderBytes+5, '*int8');
  129. NSx1DataLength = NSx1.MetaTags.DataPoints;
  130. fseek(FID1, 0, 'bof');
  131. NSx1Data = fread(FID1, '*int8');
  132. fclose(FID1);
  133. NSx1LengthIn30k = NSx1DataLength * (NSx1.MetaTags.TimeRes / NSx1.MetaTags.SamplingFreq);
  134. %% Reading NSx2
  135. FID2 = fopen(NSx2FullName, 'r', 'ieee-le');
  136. fread(FID2, 10, '*int8');
  137. NSx2HeaderBytes = fread(FID2, 1, '*int32');
  138. fseek(FID2, 0, 'bof');
  139. fread(FID2, NSx2HeaderBytes+5, '*int8');
  140. NSx2DataLength = fread(FID2, 1, '*uint32');
  141. NSx2Data = fread(FID2, '*int8');
  142. fclose(FID2);
  143. %% Combining the two files and adjusting data length
  144. NSx1Data(NSx1HeaderBytes + 5 + 1:NSx1HeaderBytes + 9) = typecast((NSx1DataLength + NSx2DataLength), 'int8');
  145. NSx1Data = [NSx1Data; NSx2Data];
  146. %% Writing data back to combined file
  147. % Writing header into the file
  148. newFilename = [NSx1FullName(1:end-4) '-combined.' NSx1FullName(end-2:end)];
  149. if exist(newFilename, 'file') == 2
  150. overwriteFlag = input('The NSx file already exists. Overwrite? ', 's');
  151. if ~strcmpi(overwriteFlag, 'y')
  152. clear all;
  153. return;
  154. end
  155. end
  156. % Writing combined NSx
  157. FIDw = fopen(newFilename, 'w+', 'ieee-le');
  158. disp('Writing NSx data back into the combined file...');
  159. fwrite(FIDw, NSx1Data, 'int8');
  160. fclose(FIDw);
  161. %% Opening the NEV files
  162. if ~exist('NEV1FullName', 'var')
  163. disp('Load the first NEV file.');
  164. [NEV1dataFilename NEV1dataFolder] = getFile('*.*');
  165. disp('Load the second NEV file.');
  166. [NEV2dataFilename NEV2dataFolder] = getFile('*.*');
  167. NEV1FullName = strcat(NEV1dataFolder, NEV1dataFilename);
  168. NEV2FullName = strcat(NEV2dataFolder, NEV2dataFilename);
  169. end
  170. %% Reading NEV1
  171. FID1 = fopen(NEV1FullName, 'r', 'ieee-le');
  172. FID2 = fopen(NEV2FullName, 'r', 'ieee-le');
  173. okNEV = (FID1 ~= -1) && (FID2 ~= -1);
  174. if okNEV
  175. NEV1Data = fread(FID1, '*int8');
  176. fclose(FID1);
  177. %% Reading NEV2
  178. fseek(FID2, 12, 'bof');
  179. NEV2HeaderBytes = fread(FID2, 1, '*int32');
  180. NEV2BytesinDataPackets = fread(FID2, 1, '*int32');
  181. fseek(FID2, NEV2HeaderBytes, 'bof');
  182. NEV2Data = fread(FID2, '*int8');
  183. fclose(FID2);
  184. %% Adding the timestamp of the first file to the second file
  185. NEV2Data = typecast(NEV2Data, 'uint32');
  186. NEV2Data = reshape(NEV2Data, NEV2BytesinDataPackets/4, length(NEV2Data)/(NEV2BytesinDataPackets/4));
  187. NEV2Data(1,:) = NEV2Data(1,:) + NSx1LengthIn30k;
  188. NEV2Data = reshape(NEV2Data, size(NEV2Data, 1) * size(NEV2Data, 2), 1);
  189. NEV2Data = typecast(NEV2Data, 'int8');
  190. NEV3Data = [NEV1Data; NEV2Data];
  191. %% Writing data back to combined NEV file
  192. % Writing header into the file
  193. newFilename = [NEV1FullName(1:end-4) '-combined.' NEV1FullName(end-2:end)];
  194. if exist(newFilename, 'file') == 2
  195. overwriteFlag = input('The NEV file already exists. Overwrite? ', 's');
  196. if ~strcmpi(overwriteFlag, 'y')
  197. clear all;
  198. return;
  199. end
  200. end
  201. % Writing combined NEV
  202. FIDCombined = fopen(newFilename, 'w+', 'ieee-le');
  203. disp('Writing NEV data back into the combined file...');
  204. fwrite(FIDCombined, NEV3Data, 'int8');
  205. fclose(FIDCombined);
  206. clear all;
  207. else
  208. disp('One or more NEV files were not found. Skipping NEV merging.');
  209. end