ChannelArray.m 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. classdef ChannelArray < Entry
  2. %CHANNELARRAY Class that represents a list of loaded Channels in a BlockVectorDataSet
  3. %
  4. % PlateType: Numeric ID of the loaded plate that thes channels are
  5. % associated with.
  6. %
  7. % Channels: Vector of Channelmapping objects in the order that they
  8. % are included in continuous file.
  9. properties (GetAccess = private, SetAccess = private)
  10. electrodeHashMap
  11. channelHashMap
  12. end
  13. properties(GetAccess = public, SetAccess = private)
  14. PlateType
  15. Channels
  16. end
  17. methods(Static, Access = private)
  18. function varagout = HandleVarargin(varargin)
  19. if(nargin == 0)
  20. varagout = {};
  21. elseif(nargin == 2)
  22. varagout{1} = varargin{1};
  23. varagout{2} = int64(ftell( varargin{2}));
  24. else
  25. error('Argument Error')
  26. end
  27. end
  28. end
  29. methods (Access = public)
  30. function this = ChannelArray(varargin)
  31. entryConstructorArgs = ChannelArray.HandleVarargin(varargin{:}); ...
  32. this = this@Entry(entryConstructorArgs{:});
  33. if(nargin == 0)
  34. this.PlateType = [];
  35. this.Channels = [];
  36. this.electrodeHashMap = [];
  37. this.channelHashMap = [];
  38. elseif(nargin == 2)
  39. aFileID = varargin{2};
  40. this.PlateType = fread(aFileID, 1, 'uint32=>uint32');
  41. fNnumChannels = fread(aFileID, 1, 'uint32=>uint32');
  42. this.Channels = ChannelMapping.empty(0, fNnumChannels);
  43. fIndices = int32(1:fNnumChannels);
  44. for i = fIndices
  45. this.Channels(i) = ChannelMapping(aFileID);
  46. end
  47. this.RebuildHashMaps();
  48. if(ftell(aFileID) ~= (this.Start + this.EntryRecord.Length))
  49. error('Unexpected Channel array length')
  50. end
  51. else
  52. error('Argument Error')
  53. end
  54. end
  55. function index = LookupElectrode(this, ...
  56. aWellColumn, aWellRow,...
  57. aElectrodeColumn, aElectrodeRow)
  58. %LookupElectrode: Quickly finds the index Channels of a given
  59. % electrode position
  60. index = this.electrodeHashMap(ChannelMapping.HashElectrode(...
  61. aWellColumn, aWellRow, aElectrodeColumn, aElectrodeRow));
  62. end
  63. function index = LookupChannel(this, ...
  64. aChannelAchk, aChannelIndex)
  65. %LookupChannel: Quickly finds the index Channels of a given
  66. % Amplifier (Artichoke) channel
  67. index = this.channelHashMap(ChannelArray.HashChannel(...
  68. aChannelAchk, aChannelIndex));
  69. end
  70. end
  71. methods(Access = private)
  72. function RebuildHashMaps(this)
  73. this.electrodeHashMap = containers.Map('KeyType', 'int32', 'ValueType', 'int32');
  74. this.channelHashMap = containers.Map('KeyType', 'int32', 'ValueType', 'int32');
  75. fIndices = 1 : length(this.Channels);
  76. for fIndex = fIndices
  77. fElectrodeHash = ChannelArray.HashElectrode( ...
  78. this.Channels(fIndex).WellColumn,...
  79. this.Channels(fIndex).WellRow,...
  80. this.Channels(fIndex).ElectrodeColumn,...
  81. this.Channels(fIndex).ElectrodeRow);
  82. fChannelHash = ChannelArray.HashChannel( ...
  83. this.Channels(fIndex).ChannelAchk,...
  84. this.Channels(fIndex).ChannelIndex);
  85. if (this.electrodeHashMap.isKey(fElectrodeHash) || this.channelHashMap.isKey(fElectrodeHash))
  86. error('Key already added')
  87. end
  88. this.electrodeHashMap(fElectrodeHash) = fIndex;
  89. this.channelHashMap(fChannelHash) = fIndex;
  90. end
  91. end
  92. end
  93. methods(Access = private, Static = true)
  94. function hash = HashElectrode( ...
  95. aWellColumn, aWellRow,...
  96. aElectrodeColumn, aElectrodeRow)
  97. hash = bitshift(uint32(aWellColumn), 24);
  98. hash = bitor(bitshift(uint32(aWellRow), 16), hash);
  99. hash = bitor(bitshift(uint32(aElectrodeColumn), 8), hash);
  100. hash = bitor(uint32(aElectrodeRow), hash);
  101. hash = uint32(hash);
  102. end
  103. function hash = HashChannel( ...
  104. aChannelAchk, aChannelIndex)
  105. hash = bitshift(uint32(aChannelAchk), 8);
  106. hash = bitor(uint32(aChannelIndex), hash);
  107. hash = uint32(hash);
  108. end
  109. end
  110. methods (Static)
  111. function fChannelArray = version_0_1_channel_array()
  112. fChannelArray = ChannelArray();
  113. % Hardware-to-grid channel mapping. This is a constant only for Muse Beta (AxIS v0.1)
  114. % and file format version 0.1. For later versions, mapping is loaded from the file itself.
  115. fChannelMapping = LegacySupport.P200D30S_CHANNEL_MAPPING;
  116. fChannelArray.PlateType = LegacySupport.P200D30S_PLATE_TYPE;
  117. fChannelArray.Channels = ChannelMapping.empty(0,(length(fChannelMapping)));
  118. for fiCol = 1:size(fChannelMapping, 1)
  119. for fiRow = 1:size(fChannelMapping, 2)
  120. fCurrentChannelIndex = fChannelMapping(fiRow, fiCol);
  121. fNewMapping = ChannelMapping(...
  122. 1, 1,...
  123. fiCol, fiRow,...
  124. 0, fCurrentChannelIndex);
  125. fChannelArray.Channels(fCurrentChannelIndex + 1) = fNewMapping;
  126. end
  127. end
  128. fChannelArray.RebuildHashMaps();
  129. end
  130. end
  131. end