classdef FileRunner % Summary of this class goes here % Detailed explanation goes here properties (SetAccess = private) files; % lista tiedostoista, jotka luetaan last_file; % viimeinen onnistunut, alotetaan 0:sta file_read_error; % alotetaan 0:sta type; % type of file reading now spkdetconf; % configuration for detecting spikes recordtime; % timestamp for the current recording duration; % duration of current file samplerate; file_finished; % alotetaan 1:st? % axionfileille OpenAxionFile-metodissa first_ch_col; % alotus 1 final_ch_col; % luetaan maksimi tiedoston tiedoista first_ch_row; % alotus 1 final_ch_row; % luetaan maksimi tiedoston tiedoista first_well_col; % alotus 1 final_well_col; % luetaan maksimi tiedoston tiedoista first_well_row; % alotus 1 final_well_row; % luetaan maksimi tiedoston tiedoista last_ch_col; % alotus 0 last_ch_row; % alotus 0 last_well_row; % alotus 0 last_well_col; % alotus 0 Plate_type T; %added by andrey table for csv csv_directory; %where to save the csv files end methods function obj = FileRunner(p_SpikeDetConfiguration, p_TargetFiles,csv_directory) obj.files = p_TargetFiles; obj.last_file = 0; obj.spkdetconf = p_SpikeDetConfiguration; obj.file_read_error = 0; obj.file_finished = 1; obj.T=table; obj.csv_directory=csv_directory; end function r_fname = getCurrentFile(obj) % files; % lista tiedostoista, jotka luetaan % last_file; % viimeinen onnistunut, alotetaan 0:sta r_fname = obj.files{obj.last_file}; end %function r_durr = getCurrentFileDuration(obj) %NOT IN USE ?!!!!!!!!!!! %r_durr = obj.duration; %end % onnistuiko,indexes,spikes,chlabel,duration,record_time,detection threshold,noise function [r_result, obj] = ReadSpikesFromNextChannel(obj) % palauttaa seuraavan kanavan indexes & waves etc % onko viel? elektrodeita, jotka pit?isi lukea if obj.file_finished &&...% jos oli viimeinen tai eka kanava obj.last_file >= length(obj.files) % ja jos ei ole tiedostoja jotka pit?isi lukea Finalcsv=sortrows(obj.T, 2); thefilenamefull=strsplit(obj.getCurrentFile(), '.'); thefilename=strsplit(thefilenamefull{1}, '\'); thefilename=thefilename{end}; writetable(Finalcsv, strcat(obj.csv_directory, '\',thefilename,'_', 'spikes.csv')); disp('All files have been read from!'); r_result = []; else % ei ole eka tai vika kanava, tai on tiedostoja joista pit?isi lukea % Tarvitseeko avata uusi tiedosto if obj.file_finished&&... obj.last_file>0 Finalcsv=sortrows(obj.T, 2); thefilename=strsplit(obj.getCurrentFile(), '.'); thefilename=thefilename{1}; writetable(Finalcsv, strcat(obj.csv_directory, '\',thefilename,'_', 'spikes.csv')); obj.T=table; %zeroing the table obj = obj.OpenNewFile(); end if obj.file_finished obj = obj.OpenNewFile(); %( obj.files(obj.last_file+1) ); end %if ~obj.file_read_error %Reading the channel [r_result.error,m_data, r_result.chlabel, obj] = obj.ReadAxionChannel(); %disp(r_result.chlabel) obj = obj.SiirraOsoittimetSeuraavaan(); if ~r_result.error % check if the channel is behaving properly or if is noisy obj.spkdetconf.sr = obj.samplerate; [r_result.indexes, r_result.spikes, r_result.threshold, ~, r_result.noise, ~] = DetectSpikes_Amp(m_data, obj.spkdetconf); Time=r_result.indexes; Channel=string(repmat(r_result.chlabel, numel(r_result.indexes),1)); %repeating the channel label as many times %as the number %of the detected spikes. (For the table creation) TT=table(Channel, Time); obj.T=[obj.T; TT]; end %end end end function [error,data,chlabel, obj] = ReadAxionChannel(obj) %well does not exist jump to another and display...might be not %recorded or so %jump to the next %if channel (single)does not exist then display channel not recorded %next disp(obj.getCurrentFile()) data = []; %there in Meeri's code to return at least something with e.g. error=1 %error = 0; %duration = []; m_well=strcat(char(64+obj.last_well_row+1),num2str(obj.last_well_col+1)); splitter=@(x) strsplit(x, '/'); while ~any(strcmp(cellfun(@(z) z{end}, cellfun(splitter,{h5info(obj.getCurrentFile()).Groups(1).Groups.Name}, 'UniformOutput',false), 'UniformOutput',false), m_well)) fprintf([m_well '_' 'seems to be excluded\n']); obj = obj.JumpNextWell; m_well=strcat(char(64+obj.last_well_row+1),num2str(obj.last_well_col+1)); end m_ch=strcat(num2str(obj.last_ch_col+1),num2str(obj.last_ch_row+1)); chlabel = strcat(m_well,'_',m_ch); % which well which electrode disp(['now reading: ' chlabel]); try data = h5read(obj.getCurrentFile(),['/Data/' m_well '/' m_ch]); %if isempty(obj.duration) %duration = length(data)/obj.samplerate; %obj.duration = duration; %else %duration = obj.duration;%better when open file????? %end error = 0; catch %err error = 1; InactiveChannels=h5read(obj.getCurrentFile(), '/DataInfo/InactiveChannels'); if any(contains(InactiveChannels, chlabel)) disp(['Channel' ' ' chlabel ' ' 'is inactive, it is not recorded in the initial analysed file.']) else disp(['Smth wrong with' ' ' chlabel ' ' 'channel reading!']); %ADDED end end end function obj = SiirraOsoittimetSeuraavaan(obj) if obj.final_ch_row-1 <= obj.last_ch_row % viimeinen elektrodi, otetaan seuraavalta sarakkeelta obj.last_ch_row = obj.first_ch_row-1; if obj.final_ch_col-1 <= obj.last_ch_col % viimeinen sarake, otetaan seuraava kaivo obj.last_ch_col = obj.first_ch_col-1; if obj.final_well_col-1 <= obj.last_well_col % viimeinen kaivosarake, otetaan seuraavalta rivilt? obj.last_well_col = obj.first_well_col-1; if obj.final_well_row-1 <= obj.last_well_row disp('All channels have been read from!'); obj.file_finished = 1; else obj.last_well_row = obj.last_well_row+1; end else obj.last_well_col = obj.last_well_col+1; end else obj.last_ch_col = obj.last_ch_col+1; end else obj.last_ch_row = obj.last_ch_row+1; % riveitt?in seuraava electrodi end end function obj = OpenNewFile(obj) obj.file_finished = 0; obj.file_read_error = 1; %setting it to 1 if everything successful it will be switched to 0 during OpenAxionFile while obj.file_read_error && obj.last_file < length(obj.files) %&& obj.spkdetconf.MinTime > obj.duration disp(['Opening new file: ' obj.files{obj.last_file+1}]); obj.type = strsplit(obj.files{obj.last_file+1},'.'); obj.type = cell2mat(obj.type(end)); %strcmp('raw',obj.type) % axion files obj = obj.OpenAxionFile(obj.files{obj.last_file+1}); obj.last_file = obj.last_file+1; end if obj.file_read_error && obj.last_file == length(obj.files) error('NOT A SINGLE FILE WAS OPENED SUCCESSFULLY!') end end function obj = OpenAxionFile(obj, p_TargetFile) % sets also sample rate, voltageScale, recordtime try %obj.AxisFileData=AxisFile(p_TargetFile); obj.Plate_type=h5readatt(p_TargetFile, '/DataInfo/', 'Plate type'); obj.first_ch_col = 1; obj.first_ch_row = 1; obj.first_well_col = 1; obj.first_well_row = 1; obj.last_ch_col = 0; obj.last_ch_row = 0; obj.last_well_row = 0; obj.last_well_col = 0; if strcmp(obj.Plate_type, '12-well plate') obj.final_ch_col = 8; obj.final_ch_row = 8; obj.final_well_col = 4; obj.final_well_row = 3; elseif strcmp(obj.Plate_type, '48-well plate') obj.final_ch_col = 4; obj.final_ch_row = 4; obj.final_well_col = 8; obj.final_well_row = 6; else disp('Unknown MEA layout!') end obj.duration = h5readatt(p_TargetFile, '/DataInfo/','DurationInSec'); obj.samplerate = h5readatt(p_TargetFile, '/DataInfo/','SamplingFrequencyInHz'); %obj.recordtime = ...; obj.file_read_error = 0; catch %err disp (['File ' p_TargetFile ' could not be opened successfully!']); obj.file_read_error = 1; end end function obj = JumpNextWell(obj) if obj.final_well_col-1 <= obj.last_well_col obj.last_well_col = obj.first_well_col-1; if obj.final_well_row-1 <= obj.last_well_row disp('All channels have been read from!'); obj.file_finished = 1; else obj.last_well_row = obj.last_well_row+1; end else obj.last_well_col = obj.last_well_col+1; end end end end