function [loggedData] = parse_log(filename, params, expData) %parse_log This independent function parses the data stored in the file and %returns a structure containing the data % filename - this is the complete path of the file with the filename % params - this is the params structure which holds the analysis % configuration options % Check if file exists if (~exist(filename,'file')) error(strcat(filename, ' does not exist')); end % Open file FileID = fopen(filename, 'r'); % Gets the first line of the file string = fgetl(FileID); % Test first line, if not formatted correctly, reject if(size(regexp(string, '^#')) == 0) error(strcat(filename, ' is not properly formatted, and does not contain "#" headers')); end % Loop through header lines while( regexp(string, '^#') == 1 ) %Print out string and move on disp(string) old = string; string = fgetl(FileID); end % Two possibilities for the next two lines: % 1) line of headers % 2) line of units foundHeaders = 0; foundUnits = 0; % Checking current line's type: identifier = string(1); if (regexp(identifier,'%')) foundHeaders = 1; % this is a line of headers; extract headers: headers = strsplit(string); headers{1} = strrep(headers{1},'%', ''); numOfHeaders = length(headers); else if (regexp(identifier,'&')) foundUnits = 1; % this is a line of units; extract units: units = strsplit(string); units{1} = strrep(units{1},'&',''); else error(strcat(filename, ' is not properly formatted, contains undefined line identifier.')); end end % Obtaining the next line string = fgetl(FileID); identifier = string(1); if(foundHeaders) if(regexp(identifier,'&')) foundUnits = 1; % this is a line of units; extract units: units = strsplit(string); units{1} = strrep(units{1},'&',''); else error(strcat(filename, ' is not properly formatted, contains or undefined/excessive line identifiers.')); end else if(foundUnits) if(regexp(identifier,'%')) % this is a line of headers; extract headers: headers = strsplit(string); headers{1} = strrep(headers{1},'%', ''); numOfHeaders = length(headers); end else error('Should never be able to get here'); end end % sanity check and clean up if(numOfHeaders ~= length(units)) error(strcat(filename, ' is not properly formatted, contains unmatched number of units and headers')); end clear foundHeaders foundUnits; % Get all data into a single matrix called "log" log = []; line = zeros(1,numOfHeaders); while ~feof(FileID) line = textscan(FileID, '%f', numOfHeaders); line = transpose(cell2mat(line)); log = [log;line]; end % Converting the log matrix into a expData structure. for i = 1:numOfHeaders eval(['loggedData.' headers{i} '.data = log(:,i);']); % adding data eval(['loggedData.' headers{i} '.unit = cell2mat(units(i));']); % adding unit eval(['loggedData.' headers{i} '.params.plot = 0;']); % adding params.plot eval(['loggedData.' headers{i} '.params.style = ''-'';']); % adding params.style eval(['loggedData.' headers{i} '.params.color = ''b'';']); % adding params.color eval(['loggedData.' headers{i} '.params.marker = '''';']); % adding params.marker eval(['loggedData.' headers{i} '.params.backgnd = [1 1 1];']); % adding params.backgnd end % data types are set if exist('params', 'var') % setting the value of <header-name>.params.plot value if(params.plotting.plot == 1) if(params.plotting.subPlot == 1) if(isempty(params.plotting.subData)) if(isempty(params.plotting.multiData)) if(isempty(params.plotting.separateData)) for i = 1:numOfHeaders eval(['loggedData.' headers{i} '.params.plot = 1;']); end else for i = 1:length(params.plotting.separateData) eval(['loggedData.' params.plotting.separateData{i} '.params.plot = 1;']); end end else for i = 1:length(params.plotting.multiData) eval(['loggedData.' params.plotting.multiData{i} '.params.plot = 1;']); end end else for i = 1:length(params.plotting.subData) eval(['loggedData.' params.plotting.subData{i} '.params.plot = 1;']); end end end if(params.plotting.multiPlot == 1) if(isempty(params.plotting.multiData)) if(isempty(params.plotting.separateData)) for i = 1:numOfHeaders eval(['loggedData.' headers{i} '.params.plot = 1;']); end else for i = 1:length(params.plotting.separateData) eval(['loggedData.' params.plotting.separateData{i} '.params.plot = 1;']); end end else for i = 1:length(params.plotting.multiData) eval(['loggedData.' params.plotting.multiData{i} '.params.plot = 1;']); end end end if(params.plotting.separatePlot == 1) if(isempty(params.plotting.separateData)) for i = 1:numOfHeaders eval(['loggedData.' headers{i} '.params.plot = 1;']); end else for i = 1:length(params.plotting.separateData) eval(['loggedData.' params.plotting.separateData{i} '.params.plot = 1;']); end end end else % nothing really needed to do here since the default value of % <header-name>.params.plot is 0 end % setting the following values to those set in DataAnalysis.m % 1) <header-name>.params.style % 2) <header-name>.params.color % 3) <header-name>.params.marker % 4) <header-name>.params.backgnd for i = 1:numOfHeaders eval(['loggedData.' headers{i} '.params.style = params.plotting.style;']); eval(['loggedData.' headers{i} '.params.color = params.plotting.color;']); eval(['loggedData.' headers{i} '.params.marker = params.plotting.marker;']); eval(['loggedData.' headers{i} '.params.backgnd = params.plotting.backgnd;']); end end % converting time to relative time loggedData.Time.data = loggedData.Time.data - loggedData.Time.data(1); % this is to parse the Marker field, if it exists if (isfield(loggedData,'Marker')) c = zeros(numel(loggedData.Marker.data),1); for i = 2: numel(loggedData.Marker.data) if (loggedData.Marker.data(i)>loggedData.Marker.data(i-1)) c(i) = loggedData.Marker.data(i); end end loggedData.Marker.data = c; end % if expData was sent in as a variable, then update the plotting parameters % of loggedData to be the same as that in the existing data structure if (exist('expData','var')) if(isempty(setdiff(headers,expData.datafields))) for i = 1:numOfHeaders eval(['loggedData.' headers{i} '.params.style = expData.' headers{i} '.params.style;']); eval(['loggedData.' headers{i} '.params.color = expData.' headers{i} '.params.color;']); eval(['loggedData.' headers{i} '.params.marker = expData.' headers{i} '.params.marker;']); eval(['loggedData.' headers{i} '.params.backgnd = expData.' headers{i} '.params.backgnd;']); end end end end