FileRunner.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  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. %curr_well=strcat(char(64+obj.last_well_row+1),num2str(obj.last_well_col+1));
  52. %splitter=@(x) strsplit(x, '/');
  53. %while ~any(strcmp(cellfun(@(z) z{end}, cellfun(splitter,{h5info(obj.getCurrentFile()).Groups(1).Groups.Name}, 'UniformOutput',false), 'UniformOutput',false), curr_well))
  54. %fprintf([curr_well '_' 'seems to be excluded\n']);
  55. %obj = obj.JumpNextWell;
  56. %curr_well=strcat(char(64+obj.last_well_row+1),num2str(obj.last_well_col+1));
  57. %end
  58. % onko viel? elektrodeita, jotka pit?isi lukea
  59. if obj.file_finished &&...% jos oli viimeinen tai eka kanava
  60. obj.last_file >= length(obj.files) % ja jos ei ole tiedostoja jotka pit?isi lukea
  61. Finalcsv=sortrows(obj.T, 2);
  62. thefilenamefull=strsplit(obj.getCurrentFile(), '.');
  63. thefilename=strsplit(thefilenamefull{1}, '\');
  64. thefilename=thefilename{end};
  65. writetable(Finalcsv, strcat(obj.csv_directory, '\',thefilename,'_', 'spikes.csv'));
  66. disp('All files have been read from!');
  67. r_result = [];
  68. else % ei ole eka tai vika kanava, tai on tiedostoja joista pit?isi lukea
  69. % Tarvitseeko avata uusi tiedosto
  70. if obj.file_finished&&...
  71. obj.last_file>0
  72. Finalcsv=sortrows(obj.T, 2);
  73. thefilenamefull=strsplit(obj.getCurrentFile(), '.');
  74. thefilename=strsplit(thefilenamefull{1}, '\');
  75. thefilename=thefilename{end};
  76. writetable(Finalcsv, strcat(obj.csv_directory, '\',thefilename,'_', 'spikes.csv'));
  77. obj.T=table; %zeroing the table
  78. obj = obj.OpenNewFile();
  79. end
  80. if obj.file_finished
  81. obj = obj.OpenNewFile(); %( obj.files(obj.last_file+1) );
  82. end
  83. %if ~obj.file_read_error
  84. %Reading the channel
  85. [r_result.error,m_data, r_result.chlabel, obj] = obj.ReadAxionChannel();
  86. %disp(r_result.chlabel)
  87. obj = obj.SiirraOsoittimetSeuraavaan();
  88. if ~r_result.error
  89. % check if the channel is behaving properly or if is noisy
  90. obj.spkdetconf.sr = obj.samplerate;
  91. [r_result.indexes, r_result.spikes, r_result.threshold, ~, r_result.noise, ~] = DetectSpikes_Amp(m_data, obj.spkdetconf);
  92. Time=r_result.indexes;
  93. Channel=string(repmat(r_result.chlabel, numel(r_result.indexes),1));
  94. %repeating the channel label as many times %as the number
  95. %of the detected spikes. (For the table creation)
  96. TT=table(Channel, Time);
  97. obj.T=[obj.T; TT];
  98. end
  99. %end
  100. end
  101. end
  102. function [errorread,data,chlabel, obj] = ReadAxionChannel(obj)
  103. %well does not exist jump to another and display...might be not
  104. %recorded or so
  105. %jump to the next
  106. %if channel (single)does not exist then display channel not recorded
  107. %next
  108. disp(obj.getCurrentFile())
  109. data = []; %there in Meeri's code to return at least something with e.g. error=1
  110. %error = 0;
  111. %duration = [];
  112. m_well=strcat(char(64+obj.last_well_row+1),num2str(obj.last_well_col+1));
  113. splitter=@(x) strsplit(x, '/');
  114. while ~any(strcmp(cellfun(@(z) z{end}, cellfun(splitter,{h5info(obj.getCurrentFile()).Groups(1).Groups.Name}, 'UniformOutput',false), 'UniformOutput',false), m_well))
  115. fprintf([m_well '_' 'seems to be excluded\n']);
  116. obj = obj.JumpNextWell;
  117. m_well=strcat(char(64+obj.last_well_row+1),num2str(obj.last_well_col+1));
  118. if obj.file_finished == 1
  119. errorread = 1;%to show that the file finished and nothing to readhere
  120. chlabel=[];
  121. return
  122. end
  123. end
  124. m_ch=strcat(num2str(obj.last_ch_col+1),num2str(obj.last_ch_row+1));
  125. chlabel = strcat(m_well,'_',m_ch); % which well which electrode
  126. disp(['now reading: ' chlabel]);
  127. try
  128. data = h5read(obj.getCurrentFile(),['/Data/' m_well '/' m_ch]);
  129. %if isempty(obj.duration)
  130. %duration = length(data)/obj.samplerate;
  131. %obj.duration = duration;
  132. %else
  133. %duration = obj.duration;%better when open file?????
  134. %end
  135. errorread = 0;
  136. catch %err
  137. errorread = 1;
  138. InactiveChannels=h5read(obj.getCurrentFile(), '/DataInfo/InactiveChannels');
  139. if any(contains(InactiveChannels, chlabel))
  140. disp(['Channel' ' ' chlabel ' ' 'is inactive, it is not recorded in the initial analysed file.'])
  141. else
  142. error(['Smth wrong with' ' ' chlabel ' ' 'channel reading!']); %ADDED
  143. end
  144. end
  145. end
  146. function obj = SiirraOsoittimetSeuraavaan(obj)
  147. if obj.final_ch_row-1 <= obj.last_ch_row % viimeinen elektrodi, otetaan seuraavalta sarakkeelta
  148. obj.last_ch_row = obj.first_ch_row-1;
  149. if obj.final_ch_col-1 <= obj.last_ch_col % viimeinen sarake, otetaan seuraava kaivo
  150. obj.last_ch_col = obj.first_ch_col-1;
  151. if obj.final_well_col-1 <= obj.last_well_col % viimeinen kaivosarake, otetaan seuraavalta rivilt?
  152. obj.last_well_col = obj.first_well_col-1;
  153. if obj.final_well_row-1 <= obj.last_well_row
  154. disp('All channels have been read from!');
  155. obj.file_finished = 1;
  156. else
  157. obj.last_well_row = obj.last_well_row+1;
  158. end
  159. else
  160. obj.last_well_col = obj.last_well_col+1;
  161. end
  162. else
  163. obj.last_ch_col = obj.last_ch_col+1;
  164. end
  165. else
  166. obj.last_ch_row = obj.last_ch_row+1; % riveitt?in seuraava electrodi
  167. end
  168. end
  169. function obj = OpenNewFile(obj)
  170. obj.file_finished = 0;
  171. obj.file_read_error = 1; %setting it to 1 if everything successful it will be switched to 0 during OpenAxionFile
  172. while obj.file_read_error && obj.last_file < length(obj.files) %&& obj.spkdetconf.MinTime > obj.duration
  173. disp(['Opening new file: ' obj.files{obj.last_file+1}]);
  174. obj.type = strsplit(obj.files{obj.last_file+1},'.');
  175. obj.type = cell2mat(obj.type(end));
  176. %strcmp('raw',obj.type) % axion files
  177. obj = obj.OpenAxionFile(obj.files{obj.last_file+1});
  178. obj.last_file = obj.last_file+1;
  179. end
  180. if obj.file_read_error && obj.last_file == length(obj.files)
  181. error('NOT A SINGLE FILE WAS OPENED SUCCESSFULLY!')
  182. end
  183. end
  184. function obj = OpenAxionFile(obj, p_TargetFile) % sets also sample rate, voltageScale, recordtime
  185. try
  186. %obj.AxisFileData=AxisFile(p_TargetFile);
  187. obj.Plate_type=h5readatt(p_TargetFile, '/DataInfo/', 'Plate type');
  188. obj.first_ch_col = 1;
  189. obj.first_ch_row = 1;
  190. obj.first_well_col = 1;
  191. obj.first_well_row = 1;
  192. obj.last_ch_col = 0;
  193. obj.last_ch_row = 0;
  194. obj.last_well_row = 0;
  195. obj.last_well_col = 0;
  196. if strcmp(obj.Plate_type, '12-well plate')
  197. obj.final_ch_col = 8;
  198. obj.final_ch_row = 8;
  199. obj.final_well_col = 4;
  200. obj.final_well_row = 3;
  201. elseif strcmp(obj.Plate_type, '48-well plate')
  202. obj.final_ch_col = 4;
  203. obj.final_ch_row = 4;
  204. obj.final_well_col = 8;
  205. obj.final_well_row = 6;
  206. else
  207. disp('Unknown MEA layout!')
  208. end
  209. obj.duration = h5readatt(p_TargetFile, '/DataInfo/','DurationInSec');
  210. obj.samplerate = h5readatt(p_TargetFile, '/DataInfo/','SamplingFrequencyInHz');
  211. %obj.recordtime = ...;
  212. obj.file_read_error = 0;
  213. catch %err
  214. disp (['File ' p_TargetFile ' could not be opened successfully!']);
  215. obj.file_read_error = 1;
  216. end
  217. end
  218. function obj = JumpNextWell(obj)
  219. if obj.final_well_col-1 <= obj.last_well_col
  220. obj.last_well_col = obj.first_well_col-1;
  221. if obj.final_well_row-1 <= obj.last_well_row
  222. disp('All channels have been read from!');
  223. obj.file_finished = 1;
  224. else
  225. obj.last_well_row = obj.last_well_row+1;
  226. end
  227. else
  228. obj.last_well_col = obj.last_well_col+1;
  229. end
  230. end
  231. end
  232. end