function trajectory_detailed_classification( traj_labels_fn, labels_fn, seg_len, ovlp, feat, clusters, grps )
%CLASSIFY_TRAJECTORIES Summary of this function goes here
% Detailed explanation goes here
global g_trajectories;
cache_trajectories;
addpath(fullfile(fileparts(mfilename('fullpath')), '../extern'));
if isempty(grps)
traj = g_trajectories;
else
% filter trajectories
x = arrayfun( @(t) any(grps == t.group), g_trajectories.items);
traj = trajectories(g_trajectories.items(x == 1));
end
% select trajectories with at least length >= seg_len
len = arrayfun( @(t) t.compute_feature(g_config.FEATURE_LENGTH), traj.items);
traj = trajectories( traj.items(len >= seg_len));
% read tags for full trajectories
[labels_data, full_tags] = traj.read_tags(traj_labels_fn);
traj_map = traj.match_tags(labels_data, full_tags);
beh_idx = find( arrayfun( @(t) t.type == g_config.TAG_TYPE_BEHAVIOUR_CLASS, full_tags) );
full_tags = full_tags(beh_idx);
traj_map = traj_map(:, beh_idx);
[segments, partitions] = traj.divide_into_segments(seg_len, ovlp, 2);
% remove trajectories with only 1 partition
cumpart = zeros(1, length(partitions));
for i = 2:length(partitions)
cumpart(i) = cumpart(i - 1) + partitions(i - 1);
end
% classifiy
[class_idx, tags, ~, ~, ~, cluster_miss] = segments.classify(labels_fn, feat, clusters);
tag_map = repmat({}, 1, length(full_tags));
for k = 1:length(full_tags)
% look for tags matching the current one and ones that have it as parent as well
tmp = find( arrayfun( @(t) strcmp(t.abbreviation, full_tags(k).abbreviation), tags) | ...
arrayfun( @(t) strcmp(t.parent, full_tags(k).abbreviation), tags) );
if ~isempty(tmp)
tag_map{k} = tmp;
else
tag_map{k} = -1;
fprintf('class not present in classification: %s\n', full_tags(k).description);
end
end
% create main window
f = figure('Visible','off', 'name', 'Trajectories classification', ...
'Position', [200, 200, 900, 800], 'Menubar', 'none', 'Toolbar', 'none');
% create controls
uicontrol('Style', 'pushbutton', 'Units', 'normalized', 'String', '<- prev',...
'Position', [0.25, 0.02, 0.08, 0.06], ...
'Callback',{@previous_callback});
uicontrol('Style', 'pushbutton', 'Units', 'normalized', 'String', '-> next',...
'Position', [0.67, 0.02, 0.08, 0.06], ...
'Callback',{@next_callback});
uicontrol('Style', 'pushbutton', 'Units', 'normalized', 'String', '<<-',...
'Position', [0.20, 0.02, 0.05, 0.06], ...
'Callback',{@previous2_callback});
uicontrol('Style', 'pushbutton', 'Units', 'normalized', 'String', '->>',...
'Position', [0.75, 0.02, 0.05, 0.06], ...
'Callback',{@next2_callback});
hpos = uicontrol('Style', 'text', 'Units', 'normalized', 'String', '', ...
'Position', [0.33, 0.02, 0.34, 0.06]);
align([hpos], 'Center','Bottom');
m = 8;
n = 5;
ha = zeros(1, m*n);
hs = zeros(1, m*n);
for i = 1:n
for j = 1:m
x = 0.01 + (j - 1.)/m;
y = 1. - i*0.9/n + 0.01;
w = 1./m - 0.01;
ha((i - 1)*m + j) = axes('Parent', f, 'Units', 'normalized', 'Position', [x, y + 0.08, w, 0.9/n - 0.07]);
hs((i - 1)*m + j) = uicontrol('Style', 'text', 'Units', 'normalized', 'String', '----', ...
'Position', [x, y, w, 0.06]);
end
end
cur = 1;
show_segments;
set(f,'Visible','on');
function show_segments
% for all segments of current trajectory
set(f, 'currentaxes', ha(1));
traj.items(cur).plot;
for i = 1:(m*n - 1)
set(f, 'currentaxes', ha(i + 1));
if i <= partitions(cur)
pos = cumpart(cur) + i;
segments.items(pos).plot;
if class_idx(pos) == 0
set(hs(i + 1), 'String', '** undefined **');
else
set(hs(i + 1), 'String', tags(class_idx(pos)).description);
end
else
axis off;
set(hs(i + 1), 'String', '');
cla;
end
end
% update full trajectory
str = '';
mapped = [];
for i = 1:length(full_tags)
if traj_map(cur, i) ~= 0
% do we have a corresponding class in the segments?
t = tag_map{i};
if t(1) == -1
% nop
sign = 'NA';
else
pos = cumpart(cur) + 1;
tot = 0;
for j = 1:length(t)
tot = tot + sum(class_idx(pos:(pos + partitions(cur))) == t(j));
mapped = [mapped, t(j)];
end
if tot > 0
sign = sprintf('OK, %.1f%%', tot/(sum(class_idx(pos:(pos + partitions(cur))) ~= 0))*100.);
else
sign = 'EE';
end
end
str = strcat(str, sprintf(' %s (%s)', full_tags(i).abbreviation, sign));
end
end
% look for unmapped classes
first = 1;
for i = 1:length(tags)
if isempty(find(mapped == i))
tot = sum(class_idx(pos:(pos + partitions(cur))) == i);
if tot > 0
tmp = sprintf(' %s (%.1f%%)', tags(i).abbreviation, tot/(sum(class_idx(pos:(pos + partitions(cur))) ~= 0))*100.);
if first
first = 0;
str = sprintf('%s\nOthers:%s', str, tmp);
else
str = strcat(str, tmp);
end
end
end
end
set(hs(1), 'String', str);
update_status;
end
function update_status
str = sprintf('Set %d / day %d / track %d [%d/%d]', traj.items(cur).set, ...
traj.items(cur).session, traj.items(cur).track, cur, traj.count);
set(hpos, 'String', str);
end
function previous_callback(source, eventdata)
if cur > 1
cur = cur - 1;
show_segments;
end
end
function next_callback(source, eventdata)
if cur < traj.count
cur = cur + 1;
show_segments;
end
end
function previous2_callback(source, eventdata)
cur = cur - floor(0.04*traj.count);
if cur < 1
cur = 1;
end
show_segments;
end
function next2_callback(source, eventdata)
cur = cur + floor(0.04*traj.count);
if cur > traj.count
cur = traj.count;
end
show_segments;
end
end