ECG-Kit 1.0
(12,087 bytes)
%% (Internal) A progress bar class for showing evolution of a process to users
%
% Description:
% A progress-bar object to show the progress of a process. If the process
% is a loop, and the iteration number is known a priori, the object can inform
% the remaining time to finish the loop. If the iteration number is
% unknown, the object informs the mean duration of a loop.
% If the process is linear, the object can indicate the advance in the
% execution. The interface is very simple, and this example show the way of
% using it.
%
% Example:
%
% %% start of algorithm
% clear
%
% pb = progress_bar('Progress bar demo', 'Start of algorithm');
%
% pause(2)
%
% %% initialization code
%
% pb.checkpoint('Initialization');
%
% pause(4)
%
% %% some iteration known a priori
%
% pb.Loops2Do = 10;
% pb.Title = 'Iterations known a priori';
%
% for ii = 1:10
%
% pb.start_loop();
%
% pause(3+randn(1))
%
% pb.checkpoint('Step 1');
%
% pause(3+randn(1))
%
% pb.checkpoint('Step 2');
%
% pause(3+randn(1))
%
% pb.checkpoint('Step 3');
%
% pause(3+randn(1))
%
% pb.end_loop();
%
% end
%
% %% some iteration unknown a priori
%
% pb.reset();
% pb.Title = 'Iterations Unknown a priori';
%
% for ii = 1:round(8+2*rand(1))
%
% pb.start_loop();
%
% pause(3+randn(1))
%
% pb.checkpoint('Step 1');
%
% pause(3+randn(1))
%
% pb.checkpoint('Step 2');
%
% pause(3+randn(1))
%
% pb.checkpoint('Step 3');
%
% pause(3+randn(1))
%
% pb.end_loop();
%
% end
%
% %this clear and close all.
% clear pb
%
% Author: Mariano Llamedo Soria (llamedom at {electron.frba.utn.edu.ar; unizar.es}
% Version: 0.1 beta
% Birthdate : 23/8/2011
% Last update: 24/3/2014
% Copyright 2008-2015
%
classdef progress_bar < handle
properties(GetAccess = private, Constant)
%constant for the waitbar
bar_position = [0.05 0.3 0.9 0.25];
default_evolution = 0.1;
long_loop_in_sec = 10; % seconds
update_msg_time = 10; % seconds
loops2weight = 20; % last 20 loops
end
properties ( Access = private )
bUIpresent = usejava('desktop');
wb_handle = [];
wb_axes_hdl = [];
LoopTimes = [];
counter = 0;
obj_tic = [];
Cleanup_hdl = [];
bPBcreated = false;
childs
parent
update_counter
time_elapsed
time_weighting
end
properties(SetAccess = private, GetAccess = public)
LoopMeanTime = [];
end
properties
Message = '';
Title = '';
Loops2Do = [];
LoopsDone = 0;
end
methods
function obj = progress_bar(Title, Message, wb_handle)
if( nargin > 0 && ischar(Title) )
obj.Title = Title;
end
if( nargin > 1 && ischar(Message) )
obj.Message = Message;
end
if( obj.bUIpresent )
% log to a waitbar
obj.update_counter = 0;
obj.time_elapsed = 0;
if( nargin < 3 || ~ishandle(wb_handle) )
obj.wb_handle = waitbar(0, obj.Message, 'name', obj.Title );
else
obj.wb_handle = wb_handle;
end
set(obj.wb_handle, 'Tag', 'progress_bar_class');
obj.wb_axes_hdl = findobj(obj.wb_handle,'Type','Axes');
set(obj.wb_axes_hdl, 'units','normalized' );
set(obj.wb_axes_hdl, 'position', obj.bar_position);
else
% TODO:log to stdout
end
obj.time_weighting = linspace(1,0.1,obj.loops2weight);
obj.time_weighting = obj.time_weighting / sum(obj.time_weighting);
%to clean and delete the waitbar.
% obj.Cleanup_hdl = onCleanup(@()DoPBHouseKeeping(, obj.wb_handle));
obj.bPBcreated = true;
end
function hide(obj)
set(obj.wb_handle, 'Visible', 'off');
end
function show(obj)
set(obj.wb_handle, 'Visible', 'on');
end
function checkpoint(obj, Message )
if( ischar(Message) )
obj.Message = Message;
end
if( isempty(obj.LoopMeanTime) )
%first loop, learning times. Just to show time evolution.
obj.counter = obj.counter + obj.default_evolution;
currTime = 0;
else
%estimate progress
currTime = toc(obj.obj_tic);
if( isempty(obj.parent) )
aux_mean_time = obj.LoopMeanTime;
aux_LoopsDone = obj.LoopsDone;
aux_Loop2do = obj.Loops2Do;
else
aux_mean_time = obj.parent.LoopMeanTime + obj.LoopMeanTime;
aux_LoopsDone = obj.parent.LoopsDone * obj.Loops2Do + obj.LoopsDone;
aux_Loop2do = obj.parent.Loops2Do * obj.Loops2Do ;
end
if( ~isempty(aux_Loop2do) && aux_Loop2do > 0 )
obj.counter = aux_LoopsDone/aux_Loop2do;
else
obj.counter = currTime/aux_mean_time;
end
end
% take care always a waitbar to draw.
if( obj.bUIpresent && ~ishandle(obj.wb_handle) )
obj.wb_handle = waitbar(0);
set(obj.wb_handle, 'Tag', 'progress_bar');
obj.wb_axes_hdl = findobj(obj.wb_handle,'Type','Axes');
set(obj.wb_axes_hdl, 'units','normalized' );
set(obj.wb_axes_hdl, 'position', obj.bar_position );
end
if( obj.bUIpresent )
waitbar( obj.counter - fix(obj.counter), obj.wb_handle, obj.Message );
end
if( isempty(obj.parent) )
aux_LoopMeanTime = obj.LoopMeanTime;
else
aux_LoopMeanTime = obj.parent.LoopMeanTime;
end
if( isempty(aux_LoopMeanTime) )
if( obj.bUIpresent && ~isempty(obj.obj_tic) )
%Learning phase
set(obj.wb_handle, 'Name', [ obj.Title '. Learning loop time ...' ]);
end
else
if( isempty(obj.parent) )
aux_Time2Finish = (obj.Loops2Do-obj.LoopsDone) * obj.LoopMeanTime;
else
aux_Time2Finish = (obj.parent.Loops2Do - obj.parent.LoopsDone) * obj.parent.LoopMeanTime + (obj.Loops2Do-obj.LoopsDone) * obj.LoopMeanTime;
end
if( obj.bUIpresent )
obj.update_counter = obj.update_counter + obj.LoopMeanTime;
if( obj.update_counter > obj.update_msg_time )
obj.update_counter = 0;
if( isempty(obj.Loops2Do) )
set(obj.wb_handle, 'Name', [ adjust_string(obj.Title, 30) ' - [' Seconds2HMS( aux_LoopMeanTime ) ' s/loop]']);
else
set(obj.wb_handle, 'Name', [ adjust_string(obj.Title, 30) ' - Finishing in ' Seconds2HMS(aux_Time2Finish) ]);
end
end
end
end
end
function start_loop(obj)
%start of loop. Reset timers
obj.obj_tic = tic;
if( isempty(obj.parent) )
aux_mean_time = obj.LoopMeanTime;
else
aux_mean_time = obj.parent.LoopMeanTime + obj.LoopMeanTime;
end
if( obj.bUIpresent && ~isempty(aux_mean_time) && aux_mean_time > obj.long_loop_in_sec )
% long process: progress within a loop.
waitbar( 0, obj.wb_handle, 'Start of loop.' );
% else
% short process: total progress
end
end
function end_loop(obj)
%end of loop. Calculate averages.
obj.LoopTimes = [obj.LoopTimes; toc(obj.obj_tic)];
obj.LoopsDone = obj.LoopsDone + 1;
if( length(obj.loops2weight) >= obj.loops2weight )
% last loop is the most weighted
obj.LoopMeanTime = mean([ (rowvec(obj.LoopTimes((end-obj.loops2weight+1):end))*flipud(colvec(obj.time_weighting))) (obj.time_elapsed / obj.LoopsDone) ]);
else
obj.LoopMeanTime = mean(obj.LoopTimes);
end
obj.time_elapsed = obj.time_elapsed + obj.LoopTimes(end);
if( obj.bUIpresent )
if( obj.LoopMeanTime > obj.long_loop_in_sec )
% long process: progress within a loop.
waitbar( 1, obj.wb_handle, 'End of loop.' );
% else
% short process: total progress
end
end
end
function pb_inner = AddInerLoop(obj, strMessage)
pb_inner = progress_bar(obj.Title, strMessage, obj.wb_handle);
pb_inner.parent = obj;
obj.childs = [ obj.childs; pb_inner ];
end
function reset(obj)
obj.LoopTimes = [];
obj.LoopMeanTime = [];
obj.counter = 0;
obj.LoopsDone = 0;
obj.Loops2Do = [];
obj.obj_tic = [];
obj.Message = '';
obj.update_counter = 0;
obj.time_elapsed = 0;
if( obj.bUIpresent )
waitbar( 0, obj.wb_handle, obj.Message );
set(obj.wb_handle, 'Name', obj.Title);
end
end
function set.Message(obj,value)
if( ischar(value) )
obj.Message = value;
if( obj.bUIpresent && obj.bPBcreated )
waitbar( obj.counter - fix(obj.counter), obj.wb_handle, obj.Message );
end
else
warning('progress_bar:BadArg', 'Message must be a string.');
end
end
function set.Title(obj,value)
if( ischar(value) )
obj.Title = value;
if( obj.bUIpresent && obj.bPBcreated )
set(obj.wb_handle, 'Name', obj.Title);
end
else
warning('progress_bar:BadArg', 'Title must be a string.');
end
end
function set.Loops2Do(obj,value)
if( isempty(value) || (isnumeric(value) && value > 0 ) )
obj.Loops2Do = value;
else
warning('progress_bar:BadArg', 'Loops2Do must be a number > 1.');
end
end
function delete(obj)
if( obj.bUIpresent )
if( ishandle(obj.wb_handle) )
% waitbar close
delete(obj.wb_handle)
end
else
end
end
end
end