Files
2026-07-03 21:54:47 +02:00

98 lines
3.7 KiB
Matlab

function tbl = rgaImportData(fullFileName)
%RGAIMPORTDATA Import an SRS RGA "Pressure vs Time" scan (.txt) into a table.
%
% tbl = rgaImportData(fullFileName) reads an RGA ASCII log and returns a
% table ready for plotRgaData, with:
% datetime - absolute time (start time + Time(s))
% time_s - elapsed scan time in seconds
% one column per active channel, named <Name>_m<mass> (e.g. Water_m18),
% holding the partial pressure in the file's units (usually Torr).
%
% The scan units and channel metadata are stored in
% tbl.Properties.VariableUnits and tbl.Properties.UserData.
%
% Two quirks of this file format are handled:
% * multi-word species names in the channel table (e.g. "Carbn dio")
% * adjacent negative values in the data run together with no space
% (e.g. "-2.8663e-010-2.3529e-010"); values are recovered by matching
% scientific-notation tokens rather than by splitting on whitespace.
%
% EXAMPLE
% tbl = rgaImportData('rga1_Jul_01_2026_08-23-06_AM.txt');
% ax = plotRgaData(tbl);
%
% See also PLOTRGADATA, PLOTCRYODATA
lines = readlines(fullFileName); % string array, keeps blanks
%--- Locate the data block header "Time(s) Channel#1 ..." ---
iData = find(startsWith(strip(lines),'Time(s)'), 1);
if isempty(iData)
error('rgaImportData:noData','Could not find the "Time(s)" data header.');
end
header = lines(1:iData-1); % metadata + channel table
%--- Start time (absolute) ---
iStart = find(startsWith(strip(header),'Start time,'), 1);
if isempty(iStart)
startStr = strip(header(1)); % fall back to first line
else
startStr = strip(extractAfter(header(iStart),','));
end
startStr = regexprep(startStr,'\s+',' '); % collapse the double space
startTime = datetime(startStr, ...
'InputFormat','MMM d, yyyy h:mm:ss a', 'Locale','en_US');
%--- Units ---
units = 'a.u.';
iu = find(startsWith(strip(header),'Units,'), 1);
if ~isempty(iu)
p = strip(split(header(iu),','));
units = char(p(end));
end
%--- Channel definitions (e.g. "1 28.00 Nitrogen 1.00 3 OFF") ---
chanPat = '^\s*(\d+)\s+([\d.]+)\s+(.+?)\s+[\d.]+\s+\d+\s+\w+\s*$';
tok = regexp(header, chanPat, 'tokens', 'once');
tok = tok(~cellfun(@isempty, tok));
nCh = numel(tok);
if nCh == 0
error('rgaImportData:noChannels','No channel definitions found.');
end
chMass = zeros(nCh,1); chName = strings(nCh,1);
for k = 1:nCh
chMass(k) = str2double(tok{k}{2});
chName(k) = strip(string(tok{k}{3}));
end
%--- Data: time before the comma + N scientific-notation values ---
dataLines = lines(iData+1:end);
dataLines = dataLines(strlength(strip(dataLines)) > 0);
n = numel(dataLines);
time_s = str2double(extractBefore(dataLines, ','));
matches = regexp(dataLines, '[-+]?\d+\.\d+[eE][-+]?\d+', 'match');
vals = nan(n, nCh);
for r = 1:n
v = str2double(matches{r});
nn = min(numel(v), nCh);
vals(r,1:nn) = v(1:nn);
end
%--- Assemble table ---
dt = startTime + seconds(time_s);
varNames = arrayfun(@(k) matlab.lang.makeValidName( ...
sprintf('%s_m%d', chName(k), round(chMass(k)))), 1:nCh, 'UniformOutput', false);
tbl = table(dt, time_s, 'VariableNames', {'datetime','time_s'});
for k = 1:nCh
tbl.(varNames{k}) = vals(:,k);
end
tbl.Properties.VariableUnits = [{'', 's'}, repmat({char(units)}, 1, nCh)];
tbl.Properties.UserData = struct( ...
'units', char(units), 'startTime', startTime, ...
'channelName', chName, 'channelMass', chMass);
end