FileRunner.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. classdef FileRunner
  2. % Summary of this class goes here
  3. % Detailed explanation goes here
  4. properties (SetAccess = private)
  5. files; % lista tiedostoista, jotka luetaan
  6. last_file; % viimeinen onnistunut, alotetaan 0:sta
  7. file_read_error; % alotetaan 0:sta
  8. type; % type of file reading now
  9. spkdetconf; % configuration for detecting spikes
  10. recordtime; % timestamp for the current recording
  11. duration; % duration of current file
  12. samplerate;
  13. file_finished; % alotetaan 1:st?
  14. % axionfileille OpenAxionFile-metodissa
  15. first_ch_col; % alotus 1
  16. final_ch_col; % luetaan maksimi tiedoston tiedoista
  17. first_ch_row; % alotus 1
  18. final_ch_row; % luetaan maksimi tiedoston tiedoista
  19. first_well_col; % alotus 1
  20. final_well_col; % luetaan maksimi tiedoston tiedoista
  21. first_well_row; % alotus 1
  22. final_well_row; % luetaan maksimi tiedoston tiedoista
  23. last_ch_col; % alotus 0
  24. last_ch_row; % alotus 0
  25. last_well_row; % alotus 0
  26. last_well_col; % alotus 0
  27. Plate_type
  28. T; %added by andrey table for csv
  29. csv_directory; %where to save the csv files
  30. end
  31. methods
  32. function obj = FileRunner(p_SpikeDetConfiguration, p_TargetFiles,csv_directory)
  33. obj.files = p_TargetFiles;
  34. obj.last_file = 0;
  35. obj.spkdetconf = p_SpikeDetConfiguration;
  36. obj.file_read_error = 0;
  37. obj.file_finished = 1;
  38. obj.T=table;
  39. obj.csv_directory=csv_directory;
  40. end
  41. function r_fname = getCurrentFile(obj)
  42. % files; % lista tiedostoista, jotka luetaan
  43. % last_file; % viimeinen onnistunut, alotetaan 0:sta
  44. r_fname = obj.files{obj.last_file};
  45. end
  46. %function r_durr = getCurrentFileDuration(obj) %NOT IN USE ?!!!!!!!!!!!
  47. %r_durr = obj.duration;
  48. %end
  49. % onnistuiko,indexes,spikes,chlabel,duration,record_time,detection threshold,noise
  50. function [r_result, obj] = ReadSpikesFromNextChannel(obj) % palauttaa seuraavan kanavan indexes & waves etc
  51. % onko viel? elektrodeita, jotka pit?isi lukea
  52. if obj.file_finished &&...% jos oli viimeinen tai eka kanava
  53. obj.last_file >= length(obj.files) % ja jos ei ole tiedostoja jotka pit?isi lukea
  54. Finalcsv=sortrows(obj.T, 2);
  55. thefilenamefull=strsplit(obj.getCurrentFile(), '.');
  56. thefilename=strsplit(thefilenamefull{1}, '\');
  57. thefilename=thefilename{end};
  58. writetable(Finalcsv, strcat(obj.csv_directory, '\',thefilename,'_', 'spikes.csv'));
  59. disp('All files have been read from!');
  60. r_result = [];
  61. else % ei ole eka tai vika kanava, tai on tiedostoja joista pit?isi lukea
  62. % Tarvitseeko avata uusi tiedosto
  63. if obj.file_finished&&...
  64. obj.last_file>0
  65. Finalcsv=sortrows(obj.T, 2);
  66. thefilename=strsplit(obj.getCurrentFile(), '.');
  67. thefilename=thefilename{1};
  68. writetable(Finalcsv, strcat(obj.csv_directory, '\',thefilename,'_', 'spikes.csv'));
  69. obj.T=table; %zeroing the table
  70. obj = obj.OpenNewFile();
  71. end
  72. if obj.file_finished
  73. obj = obj.OpenNewFile(); %( obj.files(obj.last_file+1) );
  74. end
  75. %if ~obj.file_read_error
  76. %Reading the channel
  77. [r_result.error,m_data, r_result.chlabel, obj] = obj.ReadAxionChannel();
  78. %disp(r_result.chlabel)
  79. obj = obj.SiirraOsoittimetSeuraavaan();
  80. if ~r_result.error
  81. % check if the channel is behaving properly or if is noisy
  82. obj.spkdetconf.sr = obj.samplerate;
  83. [r_result.indexes, r_result.spikes, r_result.threshold, ~, r_result.noise, ~] = DetectSpikes_Amp(m_data, obj.spkdetconf);
  84. Time=r_result.indexes;
  85. Channel=string(repmat(r_result.chlabel, numel(r_result.indexes),1));
  86. %repeating the channel label as many times %as the number
  87. %of the detected spikes. (For the table creation)
  88. TT=table(Channel, Time);
  89. obj.T=[obj.T; TT];
  90. end
  91. %end
  92. end
  93. end
  94. function [error,data,chlabel, obj] = ReadAxionChannel(obj)
  95. %well does not exist jump to another and display...might be not
  96. %recorded or so
  97. %jump to the next
  98. %if channel (single)does not exist then display channel not recorded
  99. %next
  100. disp(obj.getCurrentFile())
  101. data = []; %there in Meeri's code to return at least something with e.g. error=1
  102. %error = 0;
  103. %duration = [];
  104. m_well=strcat(char(64+obj.last_well_row+1),num2str(obj.last_well_col+1));
  105. splitter=@(x) strsplit(x, '/');
  106. while ~any(strcmp(cellfun(@(z) z{end}, cellfun(splitter,{h5info(obj.getCurrentFile()).Groups(1).Groups.Name}, 'UniformOutput',false), 'UniformOutput',false), m_well))
  107. fprintf([m_well '_' 'seems to be excluded\n']);
  108. obj = obj.JumpNextWell;
  109. m_well=strcat(char(64+obj.last_well_row+1),num2str(obj.last_well_col+1));
  110. end
  111. m_ch=strcat(num2str(obj.last_ch_col+1),num2str(obj.last_ch_row+1));
  112. chlabel = strcat(m_well,'_',m_ch); % which well which electrode
  113. disp(['now reading: ' chlabel]);
  114. try
  115. data = h5read(obj.getCurrentFile(),['/Data/' m_well '/' m_ch]);
  116. %if isempty(obj.duration)
  117. %duration = length(data)/obj.samplerate;
  118. %obj.duration = duration;
  119. %else
  120. %duration = obj.duration;%better when open file?????
  121. %end
  122. error = 0;
  123. catch %err
  124. error = 1;
  125. InactiveChannels=h5read(obj.getCurrentFile(), '/DataInfo/InactiveChannels');
  126. if any(contains(InactiveChannels, chlabel))
  127. disp(['Channel' ' ' chlabel ' ' 'is inactive, it is not recorded in the initial analysed file.'])
  128. else
  129. disp(['Smth wrong with' ' ' chlabel ' ' 'channel reading!']); %ADDED
  130. end
  131. end
  132. end
  133. function obj = SiirraOsoittimetSeuraavaan(obj)
  134. if obj.final_ch_row-1 <= obj.last_ch_row % viimeinen elektrodi, otetaan seuraavalta sarakkeelta
  135. obj.last_ch_row = obj.first_ch_row-1;
  136. if obj.final_ch_col-1 <= obj.last_ch_col % viimeinen sarake, otetaan seuraava kaivo
  137. obj.last_ch_col = obj.first_ch_col-1;
  138. if obj.final_well_col-1 <= obj.last_well_col % viimeinen kaivosarake, otetaan seuraavalta rivilt?
  139. obj.last_well_col = obj.first_well_col-1;
  140. if obj.final_well_row-1 <= obj.last_well_row
  141. disp('All channels have been read from!');
  142. obj.file_finished = 1;
  143. else
  144. obj.last_well_row = obj.last_well_row+1;
  145. end
  146. else
  147. obj.last_well_col = obj.last_well_col+1;
  148. end
  149. else
  150. obj.last_ch_col = obj.last_ch_col+1;
  151. end
  152. else
  153. obj.last_ch_row = obj.last_ch_row+1; % riveitt?in seuraava electrodi
  154. end
  155. end
  156. function obj = OpenNewFile(obj)
  157. obj.file_finished = 0;
  158. obj.file_read_error = 1; %setting it to 1 if everything successful it will be switched to 0 during OpenAxionFile
  159. while obj.file_read_error && obj.last_file < length(obj.files) %&& obj.spkdetconf.MinTime > obj.duration
  160. disp(['Opening new file: ' obj.files{obj.last_file+1}]);
  161. obj.type = strsplit(obj.files{obj.last_file+1},'.');
  162. obj.type = cell2mat(obj.type(end));
  163. %strcmp('raw',obj.type) % axion files
  164. obj = obj.OpenAxionFile(obj.files{obj.last_file+1});
  165. obj.last_file = obj.last_file+1;
  166. end
  167. if obj.file_read_error && obj.last_file == length(obj.files)
  168. error('NOT A SINGLE FILE WAS OPENED SUCCESSFULLY!')
  169. end
  170. end
  171. function obj = OpenAxionFile(obj, p_TargetFile) % sets also sample rate, voltageScale, recordtime
  172. try
  173. %obj.AxisFileData=AxisFile(p_TargetFile);
  174. obj.Plate_type=h5readatt(p_TargetFile, '/DataInfo/', 'Plate type');
  175. obj.first_ch_col = 1;
  176. obj.first_ch_row = 1;
  177. obj.first_well_col = 1;
  178. obj.first_well_row = 1;
  179. obj.last_ch_col = 0;
  180. obj.last_ch_row = 0;
  181. obj.last_well_row = 0;
  182. obj.last_well_col = 0;
  183. if strcmp(obj.Plate_type, '12-well plate')
  184. obj.final_ch_col = 8;
  185. obj.final_ch_row = 8;
  186. obj.final_well_col = 4;
  187. obj.final_well_row = 3;
  188. elseif strcmp(obj.Plate_type, '48-well plate')
  189. obj.final_ch_col = 4;
  190. obj.final_ch_row = 4;
  191. obj.final_well_col = 8;
  192. obj.final_well_row = 6;
  193. else
  194. disp('Unknown MEA layout!')
  195. end
  196. obj.duration = h5readatt(p_TargetFile, '/DataInfo/','DurationInSec');
  197. obj.samplerate = h5readatt(p_TargetFile, '/DataInfo/','SamplingFrequencyInHz');
  198. %obj.recordtime = ...;
  199. obj.file_read_error = 0;
  200. catch %err
  201. disp (['File ' p_TargetFile ' could not be opened successfully!']);
  202. obj.file_read_error = 1;
  203. end
  204. end
  205. function obj = JumpNextWell(obj)
  206. if obj.final_well_col-1 <= obj.last_well_col
  207. obj.last_well_col = obj.first_well_col-1;
  208. if obj.final_well_row-1 <= obj.last_well_row
  209. disp('All channels have been read from!');
  210. obj.file_finished = 1;
  211. else
  212. obj.last_well_row = obj.last_well_row+1;
  213. end
  214. else
  215. obj.last_well_col = obj.last_well_col+1;
  216. end
  217. end
  218. end
  219. end