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

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 commentaires

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.
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

Connectez-vous pour commenter.

 Réponse acceptée

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 commentaires

Thats works, thankyou.
Is there any reason why in my command window its not aligned up like your:
Voss
Voss le 14 Fév 2025
Modifié(e) : Voss le 14 Fév 2025
You're welcome! Please remember to "Accept" this answer. Thanks!
I'm not sure why the table is misaligned in your command window. It looks ok for me wherever I run it (here, desktop, MATLAB online, live script).
@Jason: it looks like you are using a variable-width font. If you want text in the command window to align then use a monospaced font.
Jason
Jason le 14 Fév 2025
Modifié(e) : Jason le 14 Fév 2025

Thats a great catch! I did change my font to "Dialog".

Thankyou very much

Could I ask one follow on question please.
If I have the creation of the table in a loop and wanted to access any one of them after the loop, is there a way to do this i.e. create some strucure / array or nested table to dump each table in?
TableData=[];
for i=1:100
%get data for table
T = table(count,FrameNumber,DT,Type) % then create table
%??? How to add table to some structure/array or neseted table?
TableData(i)=T ?
end
thanks
Yes, you can use a cell array, e.g.:
i_max = 100;
TableData = cell(1,i_max); % pre-allocate cell array
for i = 1:i_max
% get data for table
TableData{i} = table(count,FrameNumber,DT,Type); % store table in cell array
end
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]

Yes, I would pad a zero or NaN to the start of DiffDT, as you suggest.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Creating, Deleting, and Querying Graphics Objects dans Centre d'aide et File Exchange

Produits

Version

R2023b

Tags

Question posée :

le 14 Fév 2025

Commenté :

le 15 Fév 2025

Community Treasure Hunt

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

Start Hunting!

Translated by