Assigning Columns to a table without using loops - and perform i.e. diff on a column

75 views (last 30 days)
Hello, I have an events log that I want to be able to pull out relevant times and types of triggers into an array of some sort. As its a mixture of text and numbers I originally thought of using a cell array, but have since preferred the idea of using a table.
Ultimately I want a table showing
[count, FrameNumber, (AbsTime-AbsTime_from_1st event) trigger type
All of this info is available in the events.Data and events.type fields
This was my basic attempt to get going
Type=events(:).Type
AbsTime=datetime(events(:).Data.AbsTime)
T0=datetime(events(1).Data.AbsTime)
D=diff(T0)
table(Type,AbsTime,T0,D)
But I see an error
Intermediate dot '.' indexing produced a comma-separated list with 5 values, but it must produce a single value when followed by subsequent indexing
operations.
Error in HTS_TestSoftware/StopVidButtonPushed (line 8572)
AbsTime=datetime(events(:).Data.AbsTime)
Does this mean I have to use loops then?
Also how do I include the diff of the abs time to get each individual time difference?
events =
1×5 struct array with fields:
Type
Data
ans =
struct with fields:
% Here is events.Data-----------------------------------------------
AbsTime: [2025 2 14 15 22 54.8366]
FrameNumber: 0
RelativeFrame: 0
TriggerIndex: 0
ans =
struct with fields:
AbsTime: [2025 2 14 15 22 55.0519]
FrameNumber: 0
RelativeFrame: 0
TriggerIndex: 0
ans =
struct with fields:
AbsTime: [2025 2 14 15 22 55.1534]
FrameNumber: 1
RelativeFrame: 0
TriggerIndex: 1
ans =
struct with fields:
AbsTime: [2025 2 14 15 22 55.2520]
FrameNumber: 2
RelativeFrame: 0
TriggerIndex: 2
ans =
struct with fields:
AbsTime: [2025 2 14 15 22 55.4438]
FrameNumber: 3
RelativeFrame: 1
TriggerIndex: 3
% Here is events.Type-----------------------------------------------
ans =
'Start'
ans =
'Trigger'
ans =
'Trigger'
ans =
'Trigger'
ans =
'Stop'
Type =
'Start'
  2 Comments
Cris LaPierre
Cris LaPierre on 14 Feb 2025 at 16:40
Please attach your data file and the code you are using to import it.
It is hard to provide a solution specific to your use case without having your data.
Jason
Jason on 14 Feb 2025 at 16:55
Edited: Jason on 14 Feb 2025 at 16:58
Hi Chris, Its actually from an IMAQ video object.
vid=app.vidobj1;
start(vid)
%....wait a few sconds
stop(vid);
bool=isrunning(vid);
switch bool
case 1
ReportMessage(app,'Vid Obj RUNNING');
case 0
ReportMessage(app,'Vid Obj STOPPED');
end
% Testing event log
clc;
events = vid.EventLog
events.Data
events.Type

Sign in to comment.

Accepted Answer

Voss
Voss on 14 Feb 2025 at 16:59
A struct array similar to your variable events:
tmp = num2cell([2025 2 14 15 22 54.8366; 2025 2 14 15 22 55.0519; 2025 2 14 15 22 55.1534; 2025 2 14 15 22 55.2520; 2025 2 14 15 22 55.4438],2).';
events = struct( ...
'Type',{'Start','Trigger','Trigger','Trigger','Stop'}, ...
'Data',num2cell(struct('AbsTime',tmp,'FrameNumber',{0,0,1,2,3},'RelativeFrame',{0,0,0,0,1},'TriggerIndex',{0,0,1,2,3})))
events = 1x5 struct array with fields:
Type Data
events(1), events(1).Data
ans = struct with fields:
Type: 'Start' Data: [1x1 struct]
ans = struct with fields:
AbsTime: [2025 2 14 15 22 54.8366] FrameNumber: 0 RelativeFrame: 0 TriggerIndex: 0
events(end), events(end).Data
ans = struct with fields:
Type: 'Stop' Data: [1x1 struct]
ans = struct with fields:
AbsTime: [2025 2 14 15 22 55.4438] FrameNumber: 3 RelativeFrame: 1 TriggerIndex: 3
One way to build something like the table you're trying to build:
Type = {events.Type}.'
Type = 5x1 cell array
{'Start' } {'Trigger'} {'Trigger'} {'Trigger'} {'Stop' }
Data = [events.Data]
Data = 1x5 struct array with fields:
AbsTime FrameNumber RelativeFrame TriggerIndex
AbsTime = datetime(vertcat(Data.AbsTime))
AbsTime = 5x1 datetime array
14-Feb-2025 15:22:54 14-Feb-2025 15:22:55 14-Feb-2025 15:22:55 14-Feb-2025 15:22:55 14-Feb-2025 15:22:55
% T0 = datetime(events(1).Data.AbsTime)
T0 = AbsTime(1) % same
T0 = datetime
14-Feb-2025 15:22:54
DT = AbsTime-T0
DT = 5x1 duration array
00:00:00 00:00:00 00:00:00 00:00:00 00:00:00
DT.Format = 'mm:ss.SSSS'
DT = 5x1 duration array
00:00.0000 00:00.2153 00:00.3167 00:00.4154 00:00.6072
count = (1:numel(events)).';
FrameNumber = vertcat(Data.FrameNumber);
T = table(count,FrameNumber,DT,Type)
T = 5x4 table
count FrameNumber DT Type _____ ___________ __________ ___________ 1 0 00:00.0000 {'Start' } 2 0 00:00.2153 {'Trigger'} 3 1 00:00.3167 {'Trigger'} 4 2 00:00.4154 {'Trigger'} 5 3 00:00.6072 {'Stop' }
  10 Comments
Jason
Jason on 15 Feb 2025 at 7:26
Edited: Jason on 15 Feb 2025 at 7:42
Sorry, last question. I also want to create a column with the difference time from the previous one (DiffDT). But its length is one short so won't add to the table
function [T,count]=EventsLogTable(app,vid)
events = vid.EventLog;
% events.Data
% events.Type
Type = {events.Type}.';
Data = [events.Data];
AbsTime = datetime(vertcat(Data.AbsTime));
T0 = AbsTime(1); % same
DT = milliseconds(AbsTime-T0);
DiffDT=diff(DT) % ***************** NEW LINE
%DT.Format = 'mm:ss.SSSS'; % 'mm:ss.SSSS';
count = (1:numel(events)).';
FrameNumber = vertcat(Data.FrameNumber);
T = table(count,FrameNumber,DT,DiffDT,Type);
end
Is it a matter of just padding a zero to the start, or is there a more elegant way?
DiffDT=[0;DiffDT]

Sign in to comment.

More Answers (0)

Categories

Find more on Tables in Help Center and File Exchange

Tags

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!