286 lines
12 KiB
Matlab
286 lines
12 KiB
Matlab
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{:})
|
|
|
|
%% =====================================================================
|
|
% 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: recover a value from corrupted "-8NaN"-style
|
|
% entries (via the leading integer); false: NaN those out.
|
|
% Clean values (e.g. "32.072") are ALWAYS parsed in full,
|
|
% decimals included, regardless of this toggle -- it only
|
|
% affects what happens to the corrupted "<int>NaN" case.
|
|
|
|
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) parseTemperature(s), data{4});
|
|
else
|
|
temperature = cellfun(@(s) parseTemperature(s, false), data{4});
|
|
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);
|
|
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
|
|
|
|
% =========================================================================
|
|
% LOCAL FUNCTION
|
|
% =========================================================================
|
|
function val = parseTemperature(s, recoverCorrupted)
|
|
%PARSETEMPERATURE Parse one temperature field from the new-format file.
|
|
%
|
|
% Handles two cases seen in the "temperature (degC)" column across
|
|
% different logging sessions:
|
|
% * CLEAN value, e.g. "32.072" -> parsed in full, decimals included.
|
|
% * CORRUPTED value, e.g. "-8NaN" (an integer immediately followed by
|
|
% the literal text "NaN", from an older logger bug) -> if
|
|
% recoverCorrupted is true (default), the leading integer is
|
|
% recovered (e.g. -8); if false, this returns NaN instead.
|
|
% * Legitimate "NaN" (a genuinely missing reading) -> always NaN.
|
|
%
|
|
% A field is only treated as "clean" if str2double can parse the WHOLE
|
|
% string as a number, so this never accidentally truncates a valid
|
|
% decimal reading -- it only engages the leading-integer fallback for
|
|
% strings that fail a full numeric parse (the corrupted pattern).
|
|
|
|
if nargin < 2
|
|
recoverCorrupted = true;
|
|
end
|
|
|
|
val = str2double(s); % succeeds for clean floats AND for 'NaN' itself
|
|
if ~isnan(val)
|
|
return % clean numeric value (decimals intact) -- done
|
|
end
|
|
if strcmpi(strtrim(s), 'NaN')
|
|
return % genuinely missing reading -- stays NaN
|
|
end
|
|
|
|
% Anything else that failed a full parse is treated as the corrupted
|
|
% "<int>NaN" pattern.
|
|
if recoverCorrupted
|
|
val = str2double(regexp(s, '^-?\d+', 'match', 'once'));
|
|
else
|
|
val = NaN;
|
|
end
|
|
end
|
|
|