Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

KTUEAMapFile.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. classdef KTUEAMapFile
  2. % UEAMAPFILE -- Defines a class that contains information on a UEA
  3. % electrode array using CMP files provided by Blackrock Microsystems.
  4. %
  5. % To load a CMP file type 'MapName = UEAMapFile' where MapName is the name
  6. % of the variable that will be created and will contain the map class.
  7. %
  8. % Example: myArrayMap = UEAMapFile;
  9. %
  10. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  11. % METHODS:
  12. %
  13. % There are several available methods for mapfiles. Here's a list and a
  14. % description of what they perform.
  15. %
  16. % Electrode2Channel(Electrode):
  17. % Will return the Channel number corresponding to a passed Electrode.
  18. %
  19. % Channel2Electrode(Channel):
  20. % Will return the Electrode number corresponding to a passed Channel.
  21. %
  22. % GetChannelBankID(Channel):
  23. % Returns the BankID for a passed Channel.
  24. %
  25. % GetChannelPin(Channel):
  26. % Returns the Pin for a passed Channel.
  27. %
  28. % GetChannelLabel(Channel):
  29. % Returns the Label for a passed Channel.
  30. %
  31. % GenerateChannelSubplot(Channel):
  32. % Returns a subplot handle for the passed Channel to be used in plotting
  33. % UEA-like maps.
  34. %
  35. % GenerateChannelSubplotNames(Channel):
  36. % Plots the names of channels and electrodes on the subplot corresponding
  37. % to the passed Channel.
  38. %
  39. % GetChannelColumnRow(Channel):
  40. % Returns the Column and Row positions of the passed number that is used
  41. % to plot UEA-like maps.
  42. %
  43. % PlotCMP:
  44. % Will plot a map of the CMP Map with all the electrode and channel
  45. % names.
  46. %
  47. % Kian Torab
  48. % Blackrock Microsystems
  49. % ktorab@blackrockmicro.com
  50. %
  51. % Version 1.6.1.0
  52. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  53. % Version History
  54. %
  55. % 1.0.0.0:
  56. % - Initial release.
  57. %
  58. % 1.6.1.0:
  59. % - Minor bug fix.
  60. %
  61. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  62. %%
  63. properties (SetAccess = private)
  64. ElecNum
  65. ChanNum
  66. Column
  67. Row
  68. Bank
  69. Pin
  70. Label
  71. pathHandle
  72. fileHandle
  73. end
  74. methods (Hidden)
  75. function obj = KTUEAMapFile(fileName)
  76. if ~exist('fileName', 'var')
  77. if exist('getFile.m', 'file') == 2
  78. [obj.fileHandle obj.pathHandle] = getFile('*.cmp', 'Open a CMP Mapfile...');
  79. else
  80. [obj.fileHandle obj.pathHandle] = uigetfile('*.cmp', 'Open a CMP Mapfile...');
  81. end
  82. if ~obj.fileHandle
  83. disp('No file was selected.');
  84. return;
  85. end
  86. mapfileDataCell = importdata([obj.pathHandle obj.fileHandle], ' ', 200);
  87. else
  88. mapfileDataCell = importdata(fileName, ' ', 200);
  89. end
  90. mapfileDataCellParsed = regexp(mapfileDataCell, '\t', 'split');
  91. if size(mapfileDataCellParsed, 2) == 1
  92. mapfileDataCellParsed = regexp(mapfileDataCell, '\s+', 'split');
  93. end
  94. lastJunkIDX = 1;
  95. while 1
  96. if size(mapfileDataCellParsed{lastJunkIDX}, 2) == 6 || size(mapfileDataCellParsed{lastJunkIDX}, 2) == 5
  97. if ~isempty(str2num(mapfileDataCellParsed{lastJunkIDX}{1})) && ...
  98. ~isempty(str2num(mapfileDataCellParsed{lastJunkIDX}{2})) && ...
  99. ~isempty(str2num(mapfileDataCellParsed{lastJunkIDX}{4}))
  100. lastJunkIDX = lastJunkIDX - 1;
  101. break;
  102. end
  103. end
  104. lastJunkIDX = lastJunkIDX + 1;
  105. end
  106. mapfileDataCellParsed(1:lastJunkIDX) = [];
  107. for i = 1:size(mapfileDataCellParsed, 1)
  108. if ~all(isspace(mapfileDataCellParsed{i}))
  109. obj.Column(i) = str2num(mapfileDataCellParsed{i,:}{1});
  110. obj.Row(i) = str2num(mapfileDataCellParsed{i,:}{2});
  111. obj.Bank(i) = mapfileDataCellParsed{i,:}{3}-'@';
  112. obj.Pin(i) = str2num(mapfileDataCellParsed{i,:}{4});
  113. ElectNum = str2num(mapfileDataCellParsed{i,:}{5}(5:end));
  114. if isempty(ElectNum)
  115. obj.ElecNum(i) = str2num(mapfileDataCellParsed{i,:}{5}(2:end-4));
  116. else
  117. obj.ElecNum(i) = ElectNum;
  118. end
  119. obj.ChanNum(i) = (obj.Bank(i) - 1) * 32 + obj.Pin(i);
  120. obj.Label{i} = mapfileDataCellParsed{i,:}{5};
  121. end
  122. end
  123. end
  124. end
  125. methods
  126. function validFlag = isValid(obj)
  127. if ~obj.getFilename
  128. validFlag = 0;
  129. else
  130. validFlag = 1;
  131. end
  132. end
  133. function FilePath = getPathName(obj)
  134. FilePath = obj.pathHandle;
  135. end
  136. function FileName = getFilename(obj)
  137. FileName = obj.fileHandle;
  138. end
  139. function Channel = Electrode2Channel(obj, Electrode)
  140. if ~exist('Electrode', 'var'); disp('Electrode is a required input. Refer to help for more information.'); return; end;
  141. if isempty(obj.ChanNum(obj.ElecNum == Electrode(1)))
  142. disp('Electrode number is invalid.');
  143. Channel = [];
  144. return;
  145. end
  146. for ElecIDX = 1:length(Electrode)
  147. Channel(ElecIDX) = obj.ChanNum(obj.ElecNum == Electrode(ElecIDX));
  148. end
  149. end
  150. function Electrode = Channel2Electrode(obj, Channel)
  151. if isempty(obj.ElecNum(obj.ChanNum == Channel(1)))
  152. disp('Channel number is invalid.');
  153. Electrode = [];
  154. return;
  155. end
  156. if ~exist('Channel', 'var'); disp('Channel is a required input. Refer to help for more information.'); return; end;
  157. for ChanIDX = 1:length(Channel)
  158. Electrode(ChanIDX) = obj.ElecNum(obj.ChanNum == Channel(ChanIDX));
  159. end
  160. end
  161. function BankID = getChannelBankID(obj, Channel)
  162. BankID = obj.Bank(obj.ChanNum == Channel);
  163. end
  164. function Label = getChannelLabel(obj, Channel)
  165. Label = char(obj.Label{obj.ChanNum == Channel});
  166. end
  167. function Pin = getChannelPin(obj, Channel)
  168. Pin = obj.Pin(obj.ChanNum == Channel);
  169. end
  170. function spHandle = GenerateChannelSubplot(obj, Channel)
  171. if ~exist('Channel', 'var'); disp('Channel is a required input. Refer to help for more information.'); return; end;
  172. [x, y] = getChannelColumnRow(obj, Channel);
  173. spHandle=subplot('position', [x/10+0.004, y/10+0.004, 1/10-0.004, 1/10-0.004]);
  174. axis off;
  175. box on;
  176. set(spHandle,'XTickLabel', []);
  177. set(spHandle,'YTickLabel', []);
  178. %%
  179. end
  180. function GenerateChannelSubplotNames(obj, Channel, fColor)
  181. if ~exist('Channel', 'var'); disp('Channel is a required input. Refer to help for more information.'); return; end;
  182. if ~exist('fColor', 'var'); fColor = [1,1,1]; end
  183. Electrode = Channel2Electrode(obj, Channel);
  184. text(0.13, 0.23, ['elec ', num2str(Electrode)], 'Color', fColor, 'FontSize', 8);
  185. text(0.13, 0.10, ['chan ', num2str(Channel)], 'Color', fColor, 'FontSize', 8);
  186. end
  187. function [x, y] = getChannelColumnRow(obj, Channel)
  188. if ~exist('Channel', 'var'); disp('Channel is a required input. Refer to help for more information.'); return; end;
  189. x = obj.Column(obj.ChanNum == Channel);
  190. y = obj.Row(obj.ChanNum == Channel);
  191. end
  192. function PlotCMP(obj)
  193. figure;
  194. for Channel = 1:96
  195. GenerateChannelSubplot(obj, Channel);
  196. GenerateChannelSubplotNames(obj, Channel, [0,0,0]);
  197. end
  198. end
  199. function setAxisBackgroundColor(~, curColor)
  200. if isa(curColor, 'double') && (length(curColor) == 3)
  201. if all(curColor <= 1) && all(curColor >= 0)
  202. set(gca, 'Color', curColor);
  203. else
  204. disp('The color values have to be between 0 and 1.');
  205. end
  206. elseif isa(curColor, 'char')
  207. try
  208. set(gca, 'Color', curColor);
  209. catch
  210. disp('Color is not valid. Type ''doc color'' for more information.');
  211. end
  212. else
  213. disp('The input needs to be a valid color input.');
  214. disp('A valid color input is a vector of length 3 of values between 0 and 1.');
  215. end
  216. end
  217. function setXAxisColor(~, curColor)
  218. if isa(curColor, 'double') && (length(curColor) == 3)
  219. if all(curColor <= 1) && all(curColor >= 0)
  220. set(gca, 'XColor', curColor);
  221. else
  222. disp('The color values have to be between 0 and 1.');
  223. end
  224. elseif isa(curColor, 'char')
  225. try
  226. set(gca, 'XColor', curColor);
  227. catch
  228. disp('Color is not valid. Type ''doc color'' for more information.');
  229. end
  230. else
  231. disp('The input needs to be a valid color input.');
  232. disp('A valid color input is a vector of length 3 of values between 0 and 1.');
  233. end
  234. end
  235. function setYAxisColor(~, curColor)
  236. if isa(curColor, 'double') && (length(curColor) == 3)
  237. if all(curColor <= 1) && all(curColor >= 0)
  238. set(gca, 'YColor', curColor);
  239. else
  240. disp('The color values have to be between 0 and 1.');
  241. end
  242. elseif isa(curColor, 'char')
  243. try
  244. set(gca, 'YColor', curColor);
  245. catch
  246. disp('Color is not valid. Type ''doc color'' for more information.');
  247. end
  248. else
  249. disp('The input needs to be a valid color input.');
  250. disp('A valid color input is a vector of length 3 of values between 0 and 1.');
  251. end
  252. end
  253. function setAxesColor(~, curColor)
  254. if isa(curColor, 'double') && (length(curColor) == 3)
  255. if all(curColor <= 1) && all(curColor >= 0)
  256. set(gca, 'YColor', curColor);
  257. set(gca, 'XColor', curColor);
  258. else
  259. disp('The color values have to be between 0 and 1.');
  260. end
  261. elseif isa(curColor, 'char')
  262. try
  263. set(gca, 'YColor', curColor);
  264. set(gca, 'XColor', curColor);
  265. catch
  266. disp('Color is not valid. Type ''doc color'' for more information.');
  267. end
  268. else
  269. disp('The input needs to be a valid color input.');
  270. disp('A valid color input is a vector of length 3 of values between 0 and 1.');
  271. end
  272. end
  273. end
  274. end