function[studyinfo,study_status] = dsMonitorStudy(studyinfo,varargin)%MONITORSTUDY - display information on study progress.%% Usage:% [studyinfo,status]=dsMonitorStudy(studyinfo,key/value options)%% Inputs:% - studyinfo: DynaSim studyinfo structure, study directory, or studyinfo MAT filename% - options: TODO%% Outputs:% - studyinfo: DynaSim studyinfo structure% - status: numeric code% 0 (study in progress)% 1 (study finished)% 2 (error in study)% -1 (function failed)%% See also: dsSimulate, dsCreateBatch, dsCheckStudyinfo% % Author: Jason Sherfey, PhD <jssherfey@gmail.com>% Copyright (C) 2016 Jason Sherfey, Boston University, USA% Check inputs
options=dsCheckOptions(varargin,{...
'verbose_flag',1,{0,1},...
'process_id',[],[],... % process identifier for loading studyinfo if necessary
},false);
if isstruct(studyinfo) && isfield(studyinfo,'study_dir')
% retrieve most up-to-date studyinfo structure from studyinfo.mat file
studyinfo=dsCheckStudyinfo(studyinfo.study_dir,'process_id',options.process_id, varargin{:});
else% process the provided studyinfo structure
studyinfo=dsCheckStudyinfo(studyinfo,'process_id',options.process_id, varargin{:});
end% Check status of studyif all(strcmp('finished',{studyinfo.simulations.status}))
study_status=1; % study finishedelseif any(~cellfun(@isempty,{studyinfo.simulations.error_log}))
study_status=-1; % errors in studyelse
study_status=0; % study in progressendif options.verbose_flag==0return;
end
fprintf('-------------------------------------------------------------\n');
%% 1.0 Processing statistics by host (e.g., compute times)% get host for each simulation
running=find(~arrayfun(@(x)isempty(x.machine_info),studyinfo.simulations));
if any(running)
hosts=arrayfun(@(x)x.machine_info.host_name,studyinfo.simulations(running),'uni',0);
% make list of unique hosts
uniq_hosts=unique(hosts);
num_hosts=length(uniq_hosts);
% collect info for each host
num_simulations=zeros(1,num_hosts);
num_finished=zeros(1,num_hosts);
mean_duration=zeros(1,num_hosts);
num_running=zeros(1,num_hosts);
num_failed=zeros(1,num_hosts);
num_cores=zeros(1,num_hosts);
fori=1:num_hosts
% get list of simulations on this host
these_sims=running(strcmp(uniq_hosts{i},hosts));
% store the number of simulations processed on this host
num_simulations(i)=length(these_sims);
% get list of simulations that are running on this host
started=strcmp('started',{studyinfo.simulations(these_sims).status});
num_running(i)=length(find(started));
% get list of simulations that have finished
finished=strcmp('finished',{studyinfo.simulations(these_sims).status});
num_finished(i)=length(find(finished));
% get mean duration of simulations that have finishedif num_finished(i)>0
mean_duration(i)=mean([studyinfo.simulations(these_sims(finished)).duration]);
else
mean_duration(i)=nan;
end% get list of simulations that have failed
failed=strcmp('failed',{studyinfo.simulations(these_sims).status});
num_failed(i)=length(find(failed));
% tech infotry
num_cores(i)=studyinfo.simulations(these_sims(1)).machine_info.num_cores;
catch
num_cores(i)=nan;
end%total_memory=studyinfo.simulations(these_sims(1)).machine_info.total_memory; % stringend% sort hosts by mean_duration
[~,I]=sort(mean_duration,2,'descend');
% display info for each host
fprintf('Processing statistics (hosts sorted by mean compute time T):\n');
fori=1:num_hosts
index=I(i);
fprintf(' @%s (%g cores)\n',uniq_hosts{index},num_cores(index));%,num_finished(index),num_simulations(index),mean_duration(index),num_failed(index),num_running(index));
fprintf(' %g of %g sims finished (T: %gsec); %g failed; %g running.\n',num_finished(index),num_simulations(index),mean_duration(index),num_failed(index),num_running(index));
endend%% 2.0 Errors% get list of errors over all simulations
errors={studyinfo.simulations.error_log};
% collapse into list of unique errors
uniq_errors=unique(errors(cellfun(@ischar,errors)));
% number of unique errors
num_uniq_errors=length(uniq_errors);
% indices to simulations with errors
error_inds=find(~cellfun(@isempty,errors));
if options.verbose_flag
% Display errors for each simulationif any(error_inds) % some sims had errors
fprintf('Errors:\n');
fori=1:length(error_inds)
siminfo=studyinfo.simulations(error_inds(i));
if strcmp(siminfo.status,'finished')
fprintf(' Simulation %g (error corrected, now %s):\n',siminfo.sim_id,siminfo.status);
elseif ~strcmp(siminfo.status,'failed')
fprintf(' Simulation %g (now re-%s):\n',siminfo.sim_id,siminfo.status);
else
fprintf(' Simulation %g (%s):\n',siminfo.sim_id,siminfo.status);
endtry fprintf(' Host name: %s\n',siminfo.machine_info.host_name); end
fprintf(' Start time: %s\n',siminfo.start_time);
fprintf(' Error log: %s\n',siminfo.error_log);
endendelse% Display each unique error message only onceif any(error_inds) % some sims had errors
fprintf('Unique Errors:\n');
% display each unique error message once and list the simulation IDs with% matching errorsfori=1:num_uniq_errors
% do nothing if there is no error messageifisempty(uniq_errors{i})
continue;
end% get list of simulations with this error
matches=strcmp(uniq_errors{i},errors);
sim_ids=[studyinfo.simulations(matches).sim_id];
fprintf(' Simulation(s) %s:\n',num2str(sim_ids));
fprintf(' Error log: %s\n',uniq_errors{i});
endendend%% 3.0 Paths
fprintf('Paths:\n');
fprintf(' Study directory: %s\n',studyinfo.study_dir);
if ~isempty(studyinfo.paths)
if isfield(studyinfo.paths,'mechanisms') && iscell(studyinfo.paths.mechanisms)
iflength(studyinfo.paths.mechanisms)==1% print path on one line
fprintf(' Model files: %s\n',studyinfo.paths.mechanisms{1});
else% print each mech path on a separate line
fprintf(' Model files:\n');
fori=1:length(studyinfo.paths.mechanisms)
fprintf(' %s\n',studyinfo.paths.mechanisms{i});
endendendif isfield(studyinfo.paths,'dynasim_functions')
fprintf(' DynaSim functions: %s\n',studyinfo.paths.dynasim_functions);
endif isfield(studyinfo.paths,'batch_dir')
fprintf(' Batch directory: %s\n',studyinfo.paths.batch_dir);
endend%% 4.0 Status summary% get status for each simulation
status={studyinfo.simulations.status};
% make list of status types
uniq_status=unique(status);
% display counts for each status type
fprintf('Simulation status summary:\n');
fori=1:length(uniq_status)
count=length(find(strcmp(uniq_status{i},status)));
fprintf(' %g %s\n',count,uniq_status{i});
end%% notify about special casesif all(strcmp('finished',status))
fprintf('**** ALL SIMULATIONS HAVE FINISHED ****\n');
endif all(strcmp('initialized',status))
fprintf('**** NO SIMULATIONS HAVE STARTED ****\n');
endif all(strcmp('started',status))
fprintf('**** ALL SIMULATIONS ARE RUNNING ****\n');
endif all(strcmp('failed',status))
fprintf('**** ALL SIMULATIONS FAILED ****\n');
end
fprintf('-------------------------------------------------------------\n');