ISS 2.0 ready

This commit is contained in:
bartels-rausch committed 2026-07-03 21:54:47 +02:00
1 parent 9d6d271461
commit 3ad96b3890
7 files changed
+609 -202

No files matched your search

@@ -1,7 +1,7 @@
function LabView = LabView_importData(fullFileName,varargin)
%
% LabView_importData reads data log ASCII files stored by LabView into
% a Matlab time series.
% a Matlab time series.
%
% LabView = LabView_importData(A) imports file A
% and stores its content as time series in a structure called "LabView".
@@ -77,6 +77,64 @@ addOptional(p,'appendToStructure',defaultAppendToStructure,@isstruct);
% Parse the inputs.
parse(p,fullFileName,varargin{:})
%% =====================================================================
% NEW FILE FORMAT (added 2026-07-02)
% ---------------------------------------------------------------------
% Detect the mid-2026 LabView format from its header and import it here,
% then return early so none of the older-format logic below is touched.
% New file: ISO-8859-1 encoded, 2 header lines, tab-delimited, 16 data
% columns + trailing tab, CRLF. The temperature column is written
% corrupted as "<int>NaN" (e.g. "-8NaN"); the leading integer is the real
% ice-sample temperature. Channels no longer logged are filled with NaN so
% the output keeps the same 13-column ts.Data layout, field naming and
% .Name as older files.
% col 3 pressure_cell (hPa) -> ts.Data:4 col 4 temperature -> ts.Data:1
% col 5-7 x/y/z (mm) -> ts.Data:10-12 col 8 Tsealing -> ts.Data:13
% col 9 flow cryo (l/min) -> ts.Data:7
% =====================================================================
keepTemperatureInteger = true; % true: use leading integer of "-8NaN"; false: NaN
if isstruct(p.Results.appendToStructure)
LabView = p.Results.appendToStructure;
end
fidChk = fopen(p.Results.fullFileName,'r','n','ISO-8859-1');
hdrLine1 = fgetl(fidChk);
hdrLine2 = fgetl(fidChk);
fclose(fidChk);
if (ischar(hdrLine2) && contains(hdrLine2,'pressure_cell')) || ...
(ischar(hdrLine1) && contains(hdrLine1,'gas name'))
fid = fopen(p.Results.fullFileName,'r','n','ISO-8859-1');
data = textscan(fid, ...
'%s %s %f %s %f %f %f %f %f %f %f %f %f %f %f %f %*s', ...
'HeaderLines', 2, 'Delimiter', '\t', 'EndOfLine', '\r\n');
fclose(fid);
if keepTemperatureInteger
temperature = cellfun(@(s) str2double(regexp(s,'^-?\d+','match','once')), data{4});
else
temperature = nan(numel(data{4}),1);
end
nanCol = nan(numel(data{3}),1);
tsName = ['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})], ...
'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')];
LabView.(tsName) = timeseries( ...
[ temperature nanCol nanCol data{3} nanCol nanCol data{9} ...
nanCol nanCol data{5} data{6} data{7} data{8} ], ...
datestr(datenum([char(data{1}), char(data{2})],'dd.mm.yyyyHH:MM:SS'),0));
LabView.(tsName).Name = 'Readout Napp Chamber raw signal';
clearvars fid data temperature nanCol tsName hdrLine1 hdrLine2 fidChk ...
keepTemperatureInteger
return
end
%% =====================================================================
%%
% get filedate
[~,name,~] = fileparts(p.Results.fullFileName);
@@ -93,7 +151,7 @@ if isstruct(p.Results.appendToStructure)
end
%%
if datenum(filedate) <= datenum('04-Mar-2019 13:30:00')
fid = fopen(p.Results.fullFileName);
data = textscan(fid, ...
'%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
@@ -109,49 +167,73 @@ if datenum(filedate) <= datenum('04-Mar-2019 13:30:00')
= 'Readout Napp Chamber raw signal';
clear fid ans formatOut nans t x
elseif datenum(filedate) >= datenum('15-Sep-2021 01:00:00')
elseif datenum(filedate) >= datenum('15-Sep-2021 01:00:00') && datenum(filedate) <= datenum('01-Apr-2023 01:00:00')
% during this time, date and time were in american format.
fid = fopen(p.Results.fullFileName);
data = textscan(fid, ...
'%s %s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
'HeaderLines',1); %
'HeaderLines',1); %
fclose(fid);
% the date formating in the dat file is really messed up. Try to make
% it consitent with MATLAB. The problem is that MATLAB does not
% understand 1 digit month and hours.
%
%
%
% Split the date in column 1 into year,month,day
newDateSplit = cellfun(@(x) split(char(x),'/'),data{1},'UniformOutput', false);
% Split the time in column 2 into hours, minutes, seconds
newTimeSplit = cellfun(@(x) split(char(x),':'),data{2},'UniformOutput', false);
% combine both with the am/pm string in column 3 to a new datestring
customDateStr = cellfun(@(x,y,z) [datestr(datenum([str2double(x{3}),str2double(x{1}),str2double(x{2}),str2double(y{1}),str2double(y{2}),str2double(y{3})])), ' ', char(z)], newDateSplit,newTimeSplit,data{3}, 'uniformOutput',false) ;
% define time series
% define time series
LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]) ...
= timeseries([data{10} data{4} data{5} data{6} data{12} ...
data{13} data{14} data{7} data{8} data{17} data{18} data{19} data{21}], ...
data{13} data{14} data{7} data{8} data{17} data{18} data{19} data{21}], ...
customDateStr);
LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]).Name ...
= 'Readout Napp Chamber raw signal';
clearvars fid ans formatOut nans t x new* custom*
elseif datenum(filedate) >= datenum('01-Apr-2023 02:00:00')
fid = fopen(p.Results.fullFileName);
data = textscan(fid, ...
'%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
'HeaderLines',1);
% data file has 2 text columns, followed by 18 numeric columns (THE AM
% PM IS MISSING and some changes to the LabView file. Confirm with Luca....)
fclose(fid);
% define time series
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ...
= timeseries([data{9} data{3} data{4} data{5} data{11} ...
data{12} data{20} data{6} data{7} data{15} data{16} data{17} data{19}] , ...
datestr(datenum([char(data{1}), char(data{2})],...
'dd.mm.yyyyHH:MM:SS'),0));
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ...
= 'Readout Napp Chamber raw signal';
clear fid ans formatOut nans t x
else
fid = fopen(p.Results.fullFileName);
data = textscan(fid, ...
'%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
'HeaderLines',1); % data file has 2 text columns, followed by 16 numeric columns
'HeaderLines',1); % data file has 2 text columns, followed by 14 numeric columns
fclose(fid);
% define time series
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ...
= timeseries([data{9} data{3} data{4} data{5} data{11} ...
data{12} data{13} data{6} data{7} data{16} data{17} data{18} data{20}] , ...
datestr(datenum([char(data{1}), char(data{2})],...
'dd.mm.yyyyHH:MM:SS'),0));
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ...
= timeseries([data{9} data{3} data{4} data{5} data{11} ...
data{12} data{13} data{6} data{7} data{16} data{17} data{18} data{20}] , ...
datestr(datenum([char(data{1}), char(data{2})],...
'dd.mm.yyyyHH:MM:SS'),0));
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ...
= 'Readout Napp Chamber raw signal';
clear fid ans formatOut nans t x
end
end
end
+1 -1
View File
@@ -29,7 +29,7 @@ function createBeamtimeFolder(projectName)
% List of subfolders to create
subFolders = {'Analysis', 'Images', 'LabBook', 'NEXAFS', ...
'Photos', 'pressure', 'PShell', 'RGA', 'SES'};
'Photos', 'Pressure', 'PShell', 'RGA', 'SES'};
% Create main project folder
if ~exist(projectRoot, 'dir')
@@ -140,7 +140,7 @@ tmpFitParameters.backgroundRange = [12 6]; % <- selects fit range aro
% Bounds for background
tmpFitParameters.bkgrd = [0 0];
tmpFitParameters.pbkgrdLowerBound = [0 0];
tmpFitParameters.bkgrdUpperBound = [0 0];
tmpFitParameters.bkgrdUpperBound = [0 0];
FitList = nappFitGaussXps(FitList,tmpFitParameters,tmpDataSelection,...
'tableVariable','spectrum_countsNorm','energyScale','kinetic',...
@@ -283,6 +283,63 @@ tmpFitParameters.backgroundRange = [12 6];
FitList = nappFitGaussXps(FitList,tmpFitParameters,tmpDataSelection,...
'tableVariable','spectrum_counts','energyScale','binding',...
'mode','unconstrained','backgroundMode','linear','showFigures','on');
%% TEST 1.5.3: Split unconstrained binding Gauss linear
% Gaussian + Linear, individual area/width/position per peak
% peak #1 -> Write into FitList
clearvars tmpFitParameters;
clc
tmpFitParameters.peakArea = 1e5;
tmpFitParameters.peakWidth = 1.6;
tmpFitParameters.peakPos = 38;
% Bounds for areas (lower and upper)
tmpFitParameters.peakAreaLowerBound = 0.01;
tmpFitParameters.peakAreaUpperBound = Inf;
% Bounds for widths
tmpFitParameters.peakWidthLowerBound = 0.2;
tmpFitParameters.peakWidthUpperBound = 2.0;
% Bounds for positions
tmpFitParameters.peakPosLowerBound = 37;
tmpFitParameters.peakPosUpperBound = 39;
% fit range
tmpFitParameters.backgroundRange = [1 5];
% fit
FitList = nappFitGaussXps(FitList,tmpFitParameters,tmpDataSelection,...
'tableVariable','spectrum_counts','energyScale','binding',... % <- process binding energy
'mode','unconstrained','backgroundMode','linear','showFigures','on');
% peak #2 -> Write into new list, then copy to FitList
clearvars tmpFitParameters;
clc
tmpFitParameters.peakArea = 1e5;
tmpFitParameters.peakWidth = 1.6;
tmpFitParameters.peakPos = 36;
% Bounds for areas (lower and upper)
tmpFitParameters.peakAreaLowerBound = 0.01;
tmpFitParameters.peakAreaUpperBound = Inf;
% Bounds for widths
tmpFitParameters.peakWidthLowerBound = 0.2;
tmpFitParameters.peakWidthUpperBound = 2.0;
% Bounds for positions
tmpFitParameters.peakPosLowerBound = 35;
tmpFitParameters.peakPosUpperBound = 37;
% fit range
tmpFitParameters.backgroundRange = [5 1];
% fit
FitListTmp = nappFitGaussXps(FitList,tmpFitParameters,tmpDataSelection,...
'tableVariable','spectrum_counts','energyScale','binding',... % <- process binding energy
'mode','unconstrained','backgroundMode','linear','showFigures','on');
% merge fit results
disp(FitList(tmpDataSelection,{'name','peakPosition'}))
disp(FitListTmp(tmpDataSelection,{'name','peakPosition'}))
FitList(tmpDataSelection,:).peakPosition(2) = FitListTmp(tmpDataSelection,:).peakPosition(1);
FitList(tmpDataSelection,:).peakArea(2) = FitListTmp(tmpDataSelection,:).peakArea(1);
FitList(tmpDataSelection,:).peakFWHM(2) = FitListTmp(tmpDataSelection,:).peakFWHM(1);
clearvars FitListTmp
disp(FitList(tmpDataSelection,{'name','peakPosition'}))
%% TEST 1.6: Unconstrained binding PV linear
% Pseudo-Voigt + Linear, individual area/width/eta/position per peak
+191 -182
View File
@@ -1281,7 +1281,16 @@ if matches(p.Results.importLabView,'on')
try
% Get list of all files in that folder
TmpFileList = dir([dataPath_LabView filesep '**' filesep 'logfile*.txt']);
TmpFileList = [ ...
dir([dataPath_LabView filesep '**' filesep 'logfile*.txt']); ...
dir([dataPath_LabView filesep '**' filesep '*datafile.txt'])];
if ~isempty(TmpFileList)
keep = ~startsWith({TmpFileList.name}, {'.','~'}) & ...
~startsWith({TmpFileList.name}, 'LabView_T_RH', 'IgnoreCase', true);
TmpFileList = TmpFileList(keep);
[~, iu] = unique(fullfile({TmpFileList.folder}, {TmpFileList.name}), 'stable');
TmpFileList = TmpFileList(iu);
end
% import LabView data
LabView = LabView_importData(fullfile(TmpFileList(1).folder,TmpFileList(1).name)); % Overwrite LabView data in workspace, if this is the first import
@@ -1509,187 +1518,187 @@ disp('*************************************************')
end
function LabView = LabView_importData(fullFileName,varargin)
%
% LabView_importData reads data log ASCII files stored by LabView into
% a Matlab time series.
%
% LabView = LabView_importData(A) imports file A
% and stores its content as time series in a structure called "LabView".
%
% LabView = LabView_importData(A,LabView) imports file A
% and appends its content as time series to the LabView structure.
%
%
% Example
% LabView = LabView_importData('exmpl.dat',LabView)
%
% Input
% * Napp_chamber_file: Complete and absolute path to the Napp chamber log file.
% * LabView: name of output structure. Always call this'LabView'
%
% Output
% * LabView: time series, the name starting with "ts"
% followed by date and time the recording started.
%
% See also LABVIEW_COMBINE, LABVIEW_PLOT, LABVIEW_CUTDATA
%
%% Data Structure
%
% Data structure before 4.3.2019
% col 1: Date
% col 2: Time
% col 3: Reservoir "Pressure 1" - Unit "1 water" - mbar -> ts.Data:2
% col 4: Reservoir "Pressure 2" - Unit "2 other" - mbar -> ts.Data:3
% col 5: Baratron 1 - cell - 1mbar max - mbar -> ts.Data:4
% col 6: Baratron 2 - cell - 10mbar max - mbar -> ts.Data:8
% col 7: Baratron 3 - cell - 0.05mbar max - mbar -> ts.Data:9
% col 8: Baratron 4 - - mbar
% col 9: Temp.Ice Sample - °C -> ts.Data:1
% col 10: Temp.Heated Sample
% col 11: none
% col 12: Temp. Reservoir "Cooler 1" - °C -> ts.Data:5
% col 13: Temp. Reservoir "Cooler 2" - °C -> ts.Data:6
% col 14: Flow He(cryoholder) - l/min -> ts.Data:7
% col 15: none
% col 16: none
%
% Data structure after 4.3.2019
% col 1: Date
% col 2: Time
% col 3: Reservoir "Pressure 1" - Unit "1 water" - mbar -> ts.Data:2
% col 4: Reservoir "Pressure 2" - Unit "2 other" - mbar -> ts.Data:3
% col 5: Baratron 1 - cell - 1mbar max - mbar -> ts.Data:4
% col 6: Baratron 2 - cell - 10mbar max - mbar -> ts.Data:8
% col 7: Baratron 3 - cell - 0.05mbar max - mbar -> ts.Data:9
% col 8: Baratron 4 - - mbar
% col 9: Temp.Ice Sample - °C -> ts.Data:1
% col 10: Temp.Heated Sample
% col 11: Temp. Reservoir "Cooler 1" - °C -> ts.Data:5
% col 12: Temp. Reservoir "Cooler 2" - °C -> ts.Data:6
% col 13: Flow He(cryoholder) - l/min -> ts.Data:7
% col 14: Flow gas 1
% col 15: Pressure chamber - mbar
% col 16: x-position of cryoholder - mm -> ts.Data:10
% col 17: y-position of cryoholder - mm -> ts.Data:11
% col 18: z-position of cryoholder - mm -> ts.Data:12
% col 19: nothing
% col 20: Temp.Sealing - °C -> ts.Data:13
%%
% Create an InputParser object
p = inputParser;
% Add inputs to the scheme.
defaultAppendToStructure = 0;
addRequired(p,'fullFileName',@isfile);
addOptional(p,'appendToStructure',defaultAppendToStructure,@isstruct);
% Parse the inputs.
parse(p,fullFileName,varargin{:})
%%
% get filedate
[~,name,~] = fileparts(p.Results.fullFileName);
tmp = strsplit(name,'_PC');
filedate = datenum(tmp{1},'yyyy-mm-dd_HH.MM.SS');
clearvars name tmp
%%
% parse structure to append to
if isstruct(p.Results.appendToStructure)
LabView = p.Results.appendToStructure;
end
%%
if datenum(filedate) <= datenum('04-Mar-2019 13:30:00')
fid = fopen(p.Results.fullFileName);
data = textscan(fid, ...
'%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
'HeaderLines',1); % data file has 2 text columns, followed by 14 numeric columns
fclose(fid);
% define time series
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ...
= timeseries([data{9} data{3} data{4} data{5} data{12} ...
data{13} data{14} data{6} data{7}] , ...
datestr(datenum([char(data{1}), char(data{2})],...
'dd.mm.yyyyHH:MM:SS'),0));
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ...
= 'Readout Napp Chamber raw signal';
clear fid ans formatOut nans t x
elseif datenum(filedate) >= datenum('15-Sep-2021 01:00:00') && datenum(filedate) <= datenum('01-Apr-2023 01:00:00')
% during this time, date and time were in american format.
fid = fopen(p.Results.fullFileName);
data = textscan(fid, ...
'%s %s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
'HeaderLines',1); %
fclose(fid);
% the date formating in the dat file is really messed up. Try to make
% it consitent with MATLAB. The problem is that MATLAB does not
% understand 1 digit month and hours.
%
%
% Split the date in column 1 into year,month,day
newDateSplit = cellfun(@(x) split(char(x),'/'),data{1},'UniformOutput', false);
% Split the time in column 2 into hours, minutes, seconds
newTimeSplit = cellfun(@(x) split(char(x),':'),data{2},'UniformOutput', false);
% combine both with the am/pm string in column 3 to a new datestring
customDateStr = cellfun(@(x,y,z) [datestr(datenum([str2double(x{3}),str2double(x{1}),str2double(x{2}),str2double(y{1}),str2double(y{2}),str2double(y{3})])), ' ', char(z)], newDateSplit,newTimeSplit,data{3}, 'uniformOutput',false) ;
% define time series
LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]) ...
= timeseries([data{10} data{4} data{5} data{6} data{12} ...
data{13} data{14} data{7} data{8} data{17} data{18} data{19} data{21}], ...
customDateStr);
LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]).Name ...
= 'Readout Napp Chamber raw signal';
clearvars fid ans formatOut nans t x new* custom*
elseif datenum(filedate) >= datenum('01-Apr-2023 02:00:00')
fid = fopen(p.Results.fullFileName);
data = textscan(fid, ...
'%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
'HeaderLines',1);
% data file has 2 text columns, followed by 18 numeric columns (THE AM
% PM IS MISSING and some changes to the LabView file. Confirm with Luca....)
fclose(fid);
% define time series
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ...
= timeseries([data{9} data{3} data{4} data{5} data{11} ...
data{12} data{20} data{6} data{7} data{15} data{16} data{17} data{19}] , ...
datestr(datenum([char(data{1}), char(data{2})],...
'dd.mm.yyyyHH:MM:SS'),0));
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ...
= 'Readout Napp Chamber raw signal';
clear fid ans formatOut nans t x
else
fid = fopen(p.Results.fullFileName);
data = textscan(fid, ...
'%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
'HeaderLines',1); % data file has 2 text columns, followed by 14 numeric columns
fclose(fid);
% define time series
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ...
= timeseries([data{9} data{3} data{4} data{5} data{11} ...
data{12} data{13} data{6} data{7} data{16} data{17} data{18} data{20}] , ...
datestr(datenum([char(data{1}), char(data{2})],...
'dd.mm.yyyyHH:MM:SS'),0));
LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ...
= 'Readout Napp Chamber raw signal';
clear fid ans formatOut nans t x
end
end
% function LabView = LabView_importData(fullFileName,varargin)
% %
% % LabView_importData reads data log ASCII files stored by LabView into
% % a Matlab time series.
% %
% % LabView = LabView_importData(A) imports file A
% % and stores its content as time series in a structure called "LabView".
% %
% % LabView = LabView_importData(A,LabView) imports file A
% % and appends its content as time series to the LabView structure.
% %
% %
% % Example
% % LabView = LabView_importData('exmpl.dat',LabView)
% %
% % Input
% % * Napp_chamber_file: Complete and absolute path to the Napp chamber log file.
% % * LabView: name of output structure. Always call this'LabView'
% %
% % Output
% % * LabView: time series, the name starting with "ts"
% % followed by date and time the recording started.
% %
% % See also LABVIEW_COMBINE, LABVIEW_PLOT, LABVIEW_CUTDATA
% %
% %% Data Structure
% %
% % Data structure before 4.3.2019
% % col 1: Date
% % col 2: Time
% % col 3: Reservoir "Pressure 1" - Unit "1 water" - mbar -> ts.Data:2
% % col 4: Reservoir "Pressure 2" - Unit "2 other" - mbar -> ts.Data:3
% % col 5: Baratron 1 - cell - 1mbar max - mbar -> ts.Data:4
% % col 6: Baratron 2 - cell - 10mbar max - mbar -> ts.Data:8
% % col 7: Baratron 3 - cell - 0.05mbar max - mbar -> ts.Data:9
% % col 8: Baratron 4 - - mbar
% % col 9: Temp.Ice Sample - °C -> ts.Data:1
% % col 10: Temp.Heated Sample
% % col 11: none
% % col 12: Temp. Reservoir "Cooler 1" - °C -> ts.Data:5
% % col 13: Temp. Reservoir "Cooler 2" - °C -> ts.Data:6
% % col 14: Flow He(cryoholder) - l/min -> ts.Data:7
% % col 15: none
% % col 16: none
% %
% % Data structure after 4.3.2019
% % col 1: Date
% % col 2: Time
% % col 3: Reservoir "Pressure 1" - Unit "1 water" - mbar -> ts.Data:2
% % col 4: Reservoir "Pressure 2" - Unit "2 other" - mbar -> ts.Data:3
% % col 5: Baratron 1 - cell - 1mbar max - mbar -> ts.Data:4
% % col 6: Baratron 2 - cell - 10mbar max - mbar -> ts.Data:8
% % col 7: Baratron 3 - cell - 0.05mbar max - mbar -> ts.Data:9
% % col 8: Baratron 4 - - mbar
% % col 9: Temp.Ice Sample - °C -> ts.Data:1
% % col 10: Temp.Heated Sample
% % col 11: Temp. Reservoir "Cooler 1" - °C -> ts.Data:5
% % col 12: Temp. Reservoir "Cooler 2" - °C -> ts.Data:6
% % col 13: Flow He(cryoholder) - l/min -> ts.Data:7
% % col 14: Flow gas 1
% % col 15: Pressure chamber - mbar
% % col 16: x-position of cryoholder - mm -> ts.Data:10
% % col 17: y-position of cryoholder - mm -> ts.Data:11
% % col 18: z-position of cryoholder - mm -> ts.Data:12
% % col 19: nothing
% % col 20: Temp.Sealing - °C -> ts.Data:13
%
%
% %%
%
% % Create an InputParser object
% p = inputParser;
% % Add inputs to the scheme.
% defaultAppendToStructure = 0;
% addRequired(p,'fullFileName',@isfile);
% addOptional(p,'appendToStructure',defaultAppendToStructure,@isstruct);
% % Parse the inputs.
% parse(p,fullFileName,varargin{:})
%
% %%
% % get filedate
% [~,name,~] = fileparts(p.Results.fullFileName);
% tmp = strsplit(name,'_PC');
% filedate = datenum(tmp{1},'yyyy-mm-dd_HH.MM.SS');
%
% clearvars name tmp
%
% %%
% % parse structure to append to
%
% if isstruct(p.Results.appendToStructure)
% LabView = p.Results.appendToStructure;
% end
% %%
% if datenum(filedate) <= datenum('04-Mar-2019 13:30:00')
%
% fid = fopen(p.Results.fullFileName);
% data = textscan(fid, ...
% '%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
% 'HeaderLines',1); % data file has 2 text columns, followed by 14 numeric columns
% fclose(fid);
% % define time series
% LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ...
% = timeseries([data{9} data{3} data{4} data{5} data{12} ...
% data{13} data{14} data{6} data{7}] , ...
% datestr(datenum([char(data{1}), char(data{2})],...
% 'dd.mm.yyyyHH:MM:SS'),0));
% LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ...
% = 'Readout Napp Chamber raw signal';
% clear fid ans formatOut nans t x
%
% elseif datenum(filedate) >= datenum('15-Sep-2021 01:00:00') && datenum(filedate) <= datenum('01-Apr-2023 01:00:00')
% % during this time, date and time were in american format.
% fid = fopen(p.Results.fullFileName);
% data = textscan(fid, ...
% '%s %s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
% 'HeaderLines',1); %
%
% fclose(fid);
% % the date formating in the dat file is really messed up. Try to make
% % it consitent with MATLAB. The problem is that MATLAB does not
% % understand 1 digit month and hours.
% %
% %
% % Split the date in column 1 into year,month,day
% newDateSplit = cellfun(@(x) split(char(x),'/'),data{1},'UniformOutput', false);
% % Split the time in column 2 into hours, minutes, seconds
% newTimeSplit = cellfun(@(x) split(char(x),':'),data{2},'UniformOutput', false);
% % combine both with the am/pm string in column 3 to a new datestring
% customDateStr = cellfun(@(x,y,z) [datestr(datenum([str2double(x{3}),str2double(x{1}),str2double(x{2}),str2double(y{1}),str2double(y{2}),str2double(y{3})])), ' ', char(z)], newDateSplit,newTimeSplit,data{3}, 'uniformOutput',false) ;
%
% % define time series
% LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]) ...
% = timeseries([data{10} data{4} data{5} data{6} data{12} ...
% data{13} data{14} data{7} data{8} data{17} data{18} data{19} data{21}], ...
% customDateStr);
% LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]).Name ...
% = 'Readout Napp Chamber raw signal';
% clearvars fid ans formatOut nans t x new* custom*
%
%
% elseif datenum(filedate) >= datenum('01-Apr-2023 02:00:00')
%
% fid = fopen(p.Results.fullFileName);
% data = textscan(fid, ...
% '%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
% 'HeaderLines',1);
% % data file has 2 text columns, followed by 18 numeric columns (THE AM
% % PM IS MISSING and some changes to the LabView file. Confirm with Luca....)
% fclose(fid);
% % define time series
%
% LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ...
% = timeseries([data{9} data{3} data{4} data{5} data{11} ...
% data{12} data{20} data{6} data{7} data{15} data{16} data{17} data{19}] , ...
% datestr(datenum([char(data{1}), char(data{2})],...
% 'dd.mm.yyyyHH:MM:SS'),0));
%
% LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ...
% = 'Readout Napp Chamber raw signal';
% clear fid ans formatOut nans t x
%
% else
% fid = fopen(p.Results.fullFileName);
% data = textscan(fid, ...
% '%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',...
% 'HeaderLines',1); % data file has 2 text columns, followed by 14 numeric columns
% fclose(fid);
% % define time series
%
% LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ...
% = timeseries([data{9} data{3} data{4} data{5} data{11} ...
% data{12} data{13} data{6} data{7} data{16} data{17} data{18} data{20}] , ...
% datestr(datenum([char(data{1}), char(data{2})],...
% 'dd.mm.yyyyHH:MM:SS'),0));
%
% LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ...
% = 'Readout Napp Chamber raw signal';
% clear fid ans formatOut nans t x
% end
% end
function data_structure = LabView_combine(data_structure)
% LabView_combine can be used to merge time series into one.
+95
View File
@@ -3,6 +3,18 @@ function ax = plotCryoData(tbl, tStart, tEnd)
%
% [ax] = plotCryoData(tbl, tStart, tEnd)
% Returns struct with handles to the 3 axes for easy limit modification.
%
% The first input may be EITHER:
% * a table with the columns datetime, pressure_cell_hPa_,
% temperature__C_, x_mm_, y_mm_, z_mm_, flowCryo_l_min_, OR
% * a LabView structure produced by LabView_importData (optionally
% combined with LabView_combine). In that case it is converted to the
% required table on the fly (see the local function labviewToTable).
%--- Accept a LabView timeseries structure and convert it to a table ---
if isstruct(tbl)
tbl = labviewToTable(tbl);
end
%--- Extract datetime column ---
dt = tbl.datetime;
@@ -67,3 +79,86 @@ function ax = plotCryoData(tbl, tStart, tEnd)
% Improve datetime formatting on x-axis
ax.flow.XAxis.TickLabelFormat = 'dd-MMM HH:mm';
end
% =========================================================================
% LOCAL FUNCTIONS
% =========================================================================
function tbl = labviewToTable(LabView, tsName)
%LABVIEWTOTABLE Convert a LabView cryo-log timeseries into a plotCryoData table.
%
% Uses LabView.merge if present (created by LabView_combine); otherwise the
% timeseries field named tsName, or the first timeseries in the structure.
% The mapping uses the FIXED ts.Data column order that LabView_importData
% produces for every file format:
% [IceTemp, ResP1, ResP2, cell/Baratron1, Cooler1, Cooler2, FlowHe, ...
% Baratron2, Baratron3, x, y, z, Tsealing]
% so it works for old and new files alike. Channels a given file does not
% contain (e.g. x/y/z in pre-2019 logs) are returned as NaN.
%--- Select which timeseries to convert ---
if nargin >= 2 && ~isempty(tsName)
if ~isfield(LabView, tsName)
error('plotCryoData:noSuchField', ...
'LabView has no timeseries field "%s".', tsName);
end
ts = LabView.(tsName);
elseif isfield(LabView, 'merge')
ts = LabView.merge; % combined log (preferred)
else
fn = fieldnames(LabView);
if isempty(fn)
error('plotCryoData:emptyStruct', ...
'LabView structure contains no timeseries.');
end
ts = LabView.(fn{1}); % single-file case
end
%--- Absolute time as a datetime column ---
try
dt = datetime(getabstime(ts));
catch
dt = datetime(ts.TimeInfo.StartDate) + ...
seconds(ts.Time * unitToSeconds(ts.TimeInfo.Units));
end
dt = dt(:);
%--- Pull channels by their fixed ts.Data column index ---
D = ts.Data;
tbl = table( ...
dt, ...
getCol(D, 4), ... % pressure_cell (hPa) <- cell / Baratron-1 slot
getCol(D, 1), ... % temperature (degC) <- ice sample
getCol(D, 10), ... % x (mm)
getCol(D, 11), ... % y (mm)
getCol(D, 12), ... % z (mm)
getCol(D, 7), ... % flow cryo (l/min) <- He cryoholder
'VariableNames', {'datetime', 'pressure_cell_hPa_', 'temperature__C_', ...
'x_mm_', 'y_mm_', 'z_mm_', 'flowCryo_l_min_'});
end
function c = getCol(D, k)
% Return column k of D, or a NaN column if that channel is absent
% (e.g. pre-2019 logs have only 9 columns, so no x/y/z).
if size(D, 2) >= k
c = D(:, k);
else
c = nan(size(D, 1), 1);
end
end
function s = unitToSeconds(u)
% Convert timeseries TimeInfo.Units to seconds (fallback path only).
switch lower(u)
case 'seconds', s = 1;
case 'minutes', s = 60;
case 'hours', s = 3600;
case 'days', s = 86400;
case 'milliseconds', s = 1e-3;
otherwise, s = 1; % assume seconds
end
end
+67
View File
@@ -0,0 +1,67 @@
function ax = plotRgaData(tbl, tStart, tEnd)
%PLOTRGADATA Plot RGA partial pressures vs time (companion to plotCryoData).
%
% ax = plotRgaData(tbl, tStart, tEnd)
% Plots every channel column of an rgaImportData table against its shared
% datetime axis. tStart/tEnd (datetime) optionally subset the range, just
% like plotCryoData. Returns a struct with the axes handle.
%
% By default the y-axis is linear (RGA scans contain small near-noise
% negatives that a log axis cannot show). To switch to the classic
% semilog view afterwards:
% set(ax.partial, 'YScale', 'log');
% (values <= 0 are simply not drawn on a log axis).
%
% EXAMPLE
% tbl = rgaImportData('rga1_Jul_01_2026_08-23-06_AM.txt');
% ax = plotRgaData(tbl);
% ax = plotRgaData(tbl, t1, t2); % zoom to a window
%
% See also RGAIMPORTDATA, PLOTCRYODATA
%--- Extract datetime column ---
dt = tbl.datetime;
%--- If start/stop provided, subset the table ---
if nargin >= 3 && ~isempty(tStart) && ~isempty(tEnd)
mask = dt >= tStart & dt <= tEnd;
tbl = tbl(mask, :);
dt = dt(mask);
end
%--- Channel columns = everything except datetime & time_s ---
chVars = setdiff(tbl.Properties.VariableNames, {'datetime','time_s'}, 'stable');
units = 'a.u.';
if isfield(tbl.Properties.UserData, 'units')
units = tbl.Properties.UserData.units;
end
%--- Plot ---
figure;
tl = tiledlayout(1, 1);
tl.TileSpacing = 'compact';
tl.Padding = 'compact';
ax.partial = nexttile;
hold on;
for k = 1:numel(chVars)
plot(dt, tbl.(chVars{k}), '-', 'LineWidth', 1, ...
'DisplayName', prettyName(chVars{k}));
end
grid on;
ylabel(sprintf('Partial pressure [%s]', units));
xlabel('Date & Time');
title('RGA partial pressures');
legend('Location', 'best', 'Interpreter', 'none');
% Match plotCryoData's datetime tick style
ax.partial.XAxis.TickLabelFormat = 'dd-MMM HH:mm';
end
% -------------------------------------------------------------------------
function s = prettyName(v)
% "Water_m18" -> "Water (m18)"
s = regexprep(v, '_m(\d+)$', ' (m$1)');
s = strrep(s, '_', ' ');
end
+97
View File
@@ -0,0 +1,97 @@
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