[789] | 1 | % read_lvm: read data from the output files of labview (file extension .lvm) |
---|
[809] | 2 | |
---|
| 3 | %======================================================================= |
---|
[1107] | 4 | % Copyright 2008-2022, LEGI UMR 5519 / CNRS UGA G-INP, Grenoble, France |
---|
[809] | 5 | % http://www.legi.grenoble-inp.fr |
---|
| 6 | % Joel.Sommeria - Joel.Sommeria (A) legi.cnrs.fr |
---|
| 7 | % |
---|
| 8 | % This file is part of the toolbox UVMAT. |
---|
| 9 | % |
---|
| 10 | % UVMAT is free software; you can redistribute it and/or modify |
---|
| 11 | % it under the terms of the GNU General Public License as published |
---|
| 12 | % by the Free Software Foundation; either version 2 of the license, |
---|
| 13 | % or (at your option) any later version. |
---|
| 14 | % |
---|
| 15 | % UVMAT is distributed in the hope that it will be useful, |
---|
| 16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 18 | % GNU General Public License (see LICENSE.txt) for more details. |
---|
| 19 | %======================================================================= |
---|
| 20 | |
---|
[789] | 21 | function Data=read_lvm(filename) |
---|
| 22 | Data.ListGlobalAttribute={'FileName','Experiment','DateTime'}; |
---|
| 23 | [Path,Data.FileName] = fileparts(filename);% record the file name |
---|
| 24 | [tild,Data.Experiment]=fileparts(Path);% record the experient name |
---|
| 25 | |
---|
| 26 | %% read the full text of the file as a char string txt |
---|
| 27 | txt = fileread(filename); |
---|
| 28 | |
---|
| 29 | %% get time string (date and time of the experiment) |
---|
| 30 | |
---|
| 31 | Date_pos=regexp(txt,'Date\s','once');%find the char string 'Date' followed by a blank |
---|
| 32 | txt(1:Date_pos+length('Date'))=[]; %remove the header until 'Date'; |
---|
| 33 | DateString=txt(1:regexp(txt,'\n','once')-1);% read char until the next line break |
---|
| 34 | r1=regexp(DateString,'(?<DateDat>\S+)','names');% keep the non blank string |
---|
| 35 | Time_pos=regexp(txt,'Time\s','once');%find the char string 'Time' followed by a blank |
---|
| 36 | txt(1:Time_pos+length('Time'))=[]; %remove the header until 'Time'; |
---|
| 37 | TimeString=txt(1:regexp(txt,'\n','once')-1);% read char until the next line break |
---|
| 38 | r2=regexp(TimeString,'(?<TimeDat>\S+)','names');% keep the non blank string |
---|
| 39 | TimeString=regexprep(r2.TimeDat,',','.');% replace ',' by '.' |
---|
| 40 | Dot_pos=regexp(TimeString,'\.'); |
---|
| 41 | TimeString=TimeString(1:Dot_pos+2); % round to 1/100 s |
---|
[794] | 42 | r1.DateDat=regexprep(r1.DateDat,'/','-');%replace '/' by '-' (to get standard date representation recognized by Matlab) |
---|
[789] | 43 | Data.DateTime=[r1.DateDat ' ' TimeString];%insert date to the time string (separated by a blank) |
---|
| 44 | |
---|
| 45 | %% remove header text |
---|
| 46 | Header_pos=regexp(txt,'***End_of_Header***','once');%find the first '***End_of_Header***' |
---|
| 47 | txt(1:Header_pos+length('***End_of_Header***')+1)=[];%remove header |
---|
| 48 | Header_pos=regexp(txt,'***End_of_Header***','once');%find the second '***End_of_Header***' |
---|
| 49 | txt(1:Header_pos+length('***End_of_Header***')+1)=[];%remove header |
---|
| 50 | title_pos=regexp(txt,'\S','once');% find the next non blank char |
---|
| 51 | txt(1:title_pos-1)=[];% remove the blank char at the beginning |
---|
| 52 | |
---|
| 53 | %% get the list of channel names |
---|
| 54 | Break_pos=regexp(txt,'\n','once');%find the line break |
---|
[884] | 55 | VarNameCell=textscan(txt(1:Break_pos-2),'%s');% read list of variable names (until next line break) |
---|
[789] | 56 | Data.ListVarName=VarNameCell{1}; |
---|
| 57 | Data.ListVarName(end)=[]; %remove last name (Comment) |
---|
| 58 | Data.ListVarName{1}='Time'; %replace first name ('X_Value') by 'Time') |
---|
| 59 | NbChannel=numel(Data.ListVarName); |
---|
| 60 | for ivar=1:NbChannel |
---|
| 61 | Data.VarDimName{ivar}='nb_sample'; |
---|
| 62 | end |
---|
| 63 | |
---|
| 64 | %% get the data |
---|
| 65 | txt(1:Break_pos-1)=[];%removes line of channel names |
---|
| 66 | txt=regexprep(txt,',','.');%replace comma by dots (French to English notation) |
---|
| 67 | txt=textscan(txt,'%s');% transform txt in a cell of strings |
---|
| 68 | txt=reshape(txt{1},NbChannel,[]); |
---|
| 69 | txt=cellfun(@str2double,txt);% transform char to a matrix of numbers |
---|
| 70 | txt=txt'; %transpose matrix |
---|
| 71 | for ivar=1:NbChannel |
---|
| 72 | Data.(Data.ListVarName{ivar})=txt(:,ivar); |
---|
| 73 | end |
---|
| 74 | |
---|
| 75 | %% calculate position in case of a non-zero motor signal |
---|
| 76 | % To plot profiles(e;g.for C5): plot(Data.Position(Data.Speed<0),Data.C5(Data.Speed<0)) |
---|
| 77 | SpeedDown=-1; %motot speed 1 cm/s |
---|
| 78 | SpeedUp=1; %motot speed 1 cm/s |
---|
| 79 | if isfield(Data,'Motor_profile')% Motor_profile signal =0 (no motion), -5 (down), +5(up) |
---|
| 80 | Data.ListVarName=[Data.ListVarName' {'Position','Speed'}]; |
---|
| 81 | Data.VarDimName=[Data.VarDimName {'nb_sample','nb_sample'}]; |
---|
| 82 | Speed=zeros(size(Data.Motor_profile)); |
---|
| 83 | if ~isempty(find(Data.Motor_profile>2.5|Data.Motor_profile<-2.5)) |
---|
[799] | 84 | Speed(Data.Motor_profile>2.5)=SpeedDown;% threshold at 2.5 to avoid noise effects |
---|
| 85 | Speed(Data.Motor_profile<-2.5)=SpeedUp; |
---|
| 86 | Data.Speed=Speed; |
---|
| 87 | Speed(end)=[]; |
---|
| 88 | Data.Position=[0; cumsum(Speed.*diff(Data.Time))]; |
---|
| 89 | Data.Position=Data.Position-min(Data.Position);% set minimum to 0 |
---|
[789] | 90 | end |
---|
| 91 | end |
---|
[809] | 92 | |
---|