Home > database > check_completion_v2.m

check_completion_v2

PURPOSE ^

provides details on subjects who have started and who have completed a given experiment

SYNOPSIS ^

function outData = check_completion_v2(varargin)

DESCRIPTION ^

 provides details on subjects who have started and who have completed a given experiment

 adapted from anps_collect_check_completion.m written by Fred Barrett

 REQUIRED PARAMS
 Either 
    params.resptbl_name              - The name of the response table for the experiment
 or 
    params.ensemble.experiment_title - The title of the experiment

 OPTIONAL PARAMS
 params.terminal_form             - The form ID to check against for
                                    completion of experiment
 params.terminal_question         - The question ID to check against for
                                    completion
 params.filt                      - Filter params to filter out unwanted subjects
 params.ensemble.conn_id          - Connection ID to use for database 
                                    if no live connection, a new connection is established
 params.ensemble.host             - hostname of database
 params.ensemble.database         - database name
 params.report_after              - any sessions before this date will be
                                    ignored in the report (if not specified,
                                    all sessions will display)
 params.check_completion_v2.report.incomplete_details - more detailed
                                    information about incomplete sessions

 OUTPUTS

 Returns a list of subjects who completed the experiment

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function outData = check_completion_v2(varargin)
0002 % provides details on subjects who have started and who have completed a given experiment
0003 %
0004 % adapted from anps_collect_check_completion.m written by Fred Barrett
0005 %
0006 % REQUIRED PARAMS
0007 % Either
0008 %    params.resptbl_name              - The name of the response table for the experiment
0009 % or
0010 %    params.ensemble.experiment_title - The title of the experiment
0011 %
0012 % OPTIONAL PARAMS
0013 % params.terminal_form             - The form ID to check against for
0014 %                                    completion of experiment
0015 % params.terminal_question         - The question ID to check against for
0016 %                                    completion
0017 % params.filt                      - Filter params to filter out unwanted subjects
0018 % params.ensemble.conn_id          - Connection ID to use for database
0019 %                                    if no live connection, a new connection is established
0020 % params.ensemble.host             - hostname of database
0021 % params.ensemble.database         - database name
0022 % params.report_after              - any sessions before this date will be
0023 %                                    ignored in the report (if not specified,
0024 %                                    all sessions will display)
0025 % params.check_completion_v2.report.incomplete_details - more detailed
0026 %                                    information about incomplete sessions
0027 %
0028 % OUTPUTS
0029 %
0030 % Returns a list of subjects who completed the experiment
0031 
0032 % Author(s)
0033 % 2/21/2009 Fred Barrett - Original Author
0034 % 4/7/2009 Stefan Tomic - adapted script into a more general purpose function for all experiments
0035 % 06/15/2010 PJ - eliminated ensemble_globals, and forced new
0036 %                 msyql_make_conn scheme.
0037 % 13Mar2012 PJ - Fixed handling of database connectivity, giving precedence to
0038 %                mysql. Added reporting of subject names and start and stop
0039 %                times
0040 % 03Nov2013 PJ - Added optional reporting of more details for incomplete sessions
0041 % 03May2016 PJ - fixed minor bug to handle situation where no response data
0042 %                are present for a session
0043 
0044 outData = [];
0045 
0046 if nargin == 1
0047   params = varargin{1};
0048 elseif nargin == 2
0049   params = varargin{2};
0050 else
0051   fprintf('%s: Wrong number of arguments: %d\n', mfilename, nargin);
0052 end
0053 
0054 if isfield(params,'mysql')
0055     db_params_struct = 'mysql';
0056 elseif isfield(params, 'ensemble')
0057     db_params_struct = 'ensemble';
0058 else
0059     error('Do not have a mysql structure with db parameter info');
0060 end
0061 
0062 try
0063   conn_id = params.mysql.conn_id;
0064 catch
0065     try 
0066         conn_id = params.ensemble.conn_id;
0067     catch
0068         conn_id = 7;
0069         params.mysql.conn_id = conn_id;
0070     end
0071 end
0072 
0073 try
0074   params.filt;
0075 catch
0076   params.filt = {};handling
0077 end
0078 
0079 if(mysql(conn_id,'status') ~= 0)
0080   mysql_make_conn(params.(db_params_struct));
0081 end
0082 
0083 try tbl_name = params.resptbl_name; catch tbl_name = ''; end
0084 
0085 if isempty(tbl_name) && isfield(params.ensemble, 'experiment_title')
0086   mysql_str = sprintf('SELECT response_table, experiment_id FROM experiment WHERE experiment_title="%s"', params.ensemble.experiment_title);
0087   [tbl_name, exp_id] = mysql(conn_id, mysql_str);
0088   tbl_name = tbl_name{1};
0089   if ~isfield(params.ensemble, 'response_table')
0090     params.ensemble.response_table = tbl_name;
0091   end
0092 end
0093 
0094 try form_id = params.terminal_form; catch form_id = []; end;
0095 
0096 % If form_id is unspecified, get it from the experiment_x_form table
0097 if isempty(form_id)
0098   mysql_str = sprintf('SELECT form_id, form_order FROM experiment_x_form WHERE experiment_id=%d;', exp_id);
0099   [ids,order] = mysql(conn_id, mysql_str);
0100   % Get next to last form, as last form is an end_session form that doesn't
0101   % leave its mark on the response table
0102   form_id = ids(order==(max(order)-1));
0103 end
0104 
0105 try question_id = params.terminal_question; catch question_id = []; end
0106 if isempty(question_id)
0107   mysql_str = sprintf('SELECT question_id, form_question_num FROM form_x_question WHERE form_id=%d;', form_id);
0108   [qids, order] = mysql(conn_id,mysql_str);
0109   question_id = qids(order==max(order));
0110 end
0111 
0112 try PRINT_TO_FILE = params.report.write2file; catch PRINT_TO_FILE=0; end
0113 
0114 % % % REPORT AFTER THIS DATE
0115 try
0116   report_after = datenum(params.report_after);
0117 catch
0118   %if report_after wasn't specied, report all sessions
0119   report_after = 0;
0120 end
0121 
0122 %% Consult the session table to get list of completed subs, sessions, and time stamps
0123 vars = {'session_id','date_time','end_datetime','subject_id','ticket_id'};
0124 mysql_str = sprintf('SELECT %s FROM session WHERE experiment_id =%d;', cell2str(vars,','), exp_id);
0125 data = cell(1,length(vars));
0126 [data{:}] = mysql(conn_id,mysql_str);
0127 completedData = ensemble_init_data_struct;
0128 completedData.type = 'session_info';
0129 completedData.vars = vars;
0130 completedData.data = data;
0131 cdCols = set_var_col_const(vars);
0132 
0133 % Get the ticket codes
0134 
0135 %% Filter completion data if desired
0136 completedData = ensemble_filter(completedData,params.filt);
0137 
0138 % open logfile
0139 if exist('PRINT_TO_FILE','var') && PRINT_TO_FILE
0140   logfname = fullfile(params.paths.logpath,'completion_info.txt');
0141   fid = fopen(logfname,'wt');
0142   fprintf(fid,'Completion information for experiment: %s\n', params.ensemble.experiment_title);
0143   fprintf(fid,'Generated: %s\n\n\n', datestr(now));
0144 else
0145   fid = 1; % stdout
0146 end
0147 params.report.fid = fid;
0148 
0149 % Get subject information
0150 subInfo = mysql_get_subinfo('subject_id', completedData.data{cdCols.subject_id}, ...
0151   'mysql', params.(db_params_struct));
0152 siCols = set_var_col_const(subInfo.vars);
0153 
0154 nsess = length(completedData.data{cdCols.session_id});
0155 fprintf(fid,'%d initiated sessions\n', nsess);
0156 
0157 completed_mask = ~isnan(completedData.data{cdCols.end_datetime});
0158 completed_idxs = find(completed_mask);
0159 fprintf(fid,'%d completed sessions\n', sum(completed_mask));
0160 
0161 % Add the completion mask to the completedData structure
0162 completedData.vars{end+1} = 'completed';
0163 completedData.data{end+1} = completed_mask;
0164 cdCols = set_var_col_const(completedData.vars);
0165 
0166 for itype = 1:2
0167   if itype == 1
0168     idx_list = completed_idxs;
0169     type_str = 'COMPLETED';
0170   else
0171     idx_list = find(~completed_mask);
0172     type_str = 'INCOMPLETE';
0173   end
0174   
0175   fprintf(fid,'\n%s: %d sessions\n', type_str, length(idx_list));
0176   fprintf(fid,'Session\tSubject\tFirstName\tLastName\tStartTime\tEndTime\tTicketID\tTicketCode\n');
0177   for isess = 1:length(idx_list)
0178     curr_idx = idx_list(isess);
0179     
0180     curr_tick_id = completedData.data{cdCols.ticket_id}(curr_idx);
0181     mysql_str = sprintf('SELECT ticket_code FROM ticket WHERE ticket_id = %d;', curr_tick_id);
0182     ticket_code = mysql(conn_id, mysql_str);
0183     
0184         start_str = datestr(completedData.data{cdCols.date_time}(curr_idx));
0185         if strcmp(type_str,'INCOMPLETE')
0186             stop_str = '';
0187         else
0188             stop_str = datestr(completedData.data{cdCols.end_datetime}(curr_idx));
0189         end
0190         
0191         first_name = subInfo.data{siCols.name_first}{strcmp(subInfo.data{siCols.subject_id},completedData.data{cdCols.subject_id}{curr_idx})};
0192         last_name = subInfo.data{siCols.name_last}{strcmp(subInfo.data{siCols.subject_id},completedData.data{cdCols.subject_id}{curr_idx})};
0193             
0194     fprintf(fid, '%d\t%s\t%s\t%s\t%s\t%s\t%d\t%s\n', ...
0195       completedData.data{cdCols.session_id}(curr_idx), ...
0196       completedData.data{cdCols.subject_id}{curr_idx}, ...
0197             first_name, last_name, ...
0198       start_str, stop_str, ...
0199       curr_tick_id, ticket_code{1});
0200   end % for isess
0201 end % for itype (COMPLETED, INCOMPLETE)
0202 
0203 %
0204 % Check to see if there is any further reporting to be done
0205 %
0206 if isfield(params, mfilename) && isfield(params.(mfilename), 'report')
0207   report_types = fieldnames(params.(mfilename).report);
0208   nreports = length(report_types);
0209   for ireport = 1:nreports
0210     currReport = report_types{ireport};
0211     fprintf('\n\nRunning report %d/%d: %s\n', ireport, nreports, currReport);
0212     
0213     % Get a handle to the sub-function we want to run
0214     fh = str2func(currReport);
0215     result = fh({completedData, subInfo}, params);
0216   end
0217 end % if isfield(params, mfilename) && isfield(params.(mfilename), 'report')
0218 
0219 return
0220 end
0221 
0222 function result = incomplete_details(data_st, params)
0223   st = dbstack;
0224   funcname = st(1).name; % get current function name
0225   
0226   % Get the parameters that specifically control this function
0227   fparams = params.(mfilename).report.(funcname);
0228   if isnumeric(fparams) && ~fparams
0229     result = [];
0230     return
0231   end
0232   
0233   if isstruct(fparams)
0234     if isfield(fparams, 'fname')
0235       fid = ensemble_init_fid(fparams);
0236     end
0237   else
0238     fid = 1;
0239   end
0240   
0241   % Parse out the incoming data structures
0242   an_idx = ensemble_find_analysis_struct(data_st,struct('type','session_info'));
0243   sess_st = data_st{an_idx};
0244   sessCols = set_var_col_const(sess_st.vars);
0245   
0246   an_idx = ensemble_find_analysis_struct(data_st,struct('type','subject_info'));
0247   sub_st = data_st{an_idx};
0248   subCols = set_var_col_const(sub_st.vars);
0249   
0250   % Filter out the completed sessions
0251   cfilt.exclude.all.completed = 1;
0252   sess_st = ensemble_filter(sess_st, cfilt);
0253   sessIDs = sess_st.data{sessCols.session_id};
0254   nsess = length(sessIDs);
0255   
0256   % Get the response table data for the incomplete sessions
0257   respdata = ensemble_init_data_struct;
0258   [respdata.data, respdata.vars] = mysql_extract_data(...
0259     'table', params.ensemble.response_table, ...
0260     'conn_id', params.mysql.conn_id, ...
0261     'session_id', sess_st.data{sessCols.session_id});
0262   respCols = set_var_col_const(respdata.vars);
0263   
0264   % Loop over sessions
0265   lastStim = nan(nsess,1);
0266   for isess = 1:nsess
0267     currSessID = sessIDs(isess); 
0268     currSubID = sess_st.data{sessCols.subject_id}{isess};
0269     
0270     % Get mask into subject info structure
0271     submask = strcmp(sub_st.data{subCols.subject_id},currSubID);
0272     
0273     % Filter the response table data to extract the current session
0274     cfilt = [];
0275     cfilt.include.all.session_id = currSessID;
0276     currData = ensemble_filter(respdata,cfilt);
0277     
0278     % Get the last entry that was made for this subject
0279     lastTimeStamp = max(currData.data{respCols.date_time});
0280     lastEntryMask = currData.data{respCols.date_time} == lastTimeStamp;
0281     
0282     % Print out diagnostic information
0283     fprintf(fid,'\nSession ID: %d, Subject ID: %s, Name: %s, Started: %s\n', ...
0284       currSessID, ...
0285       currSubID, ...
0286       sprintf('%s %s', sub_st.data{subCols.name_first}{submask}, sub_st.data{subCols.name_last}{submask}), ...
0287       datestr(sess_st.data{sessCols.date_time}(isess)));
0288     
0289     % Check to see whether there is any response data for this session ID
0290     if isempty(lastTimeStamp)
0291       continue
0292     end
0293     
0294     % Provide information about last form submitted
0295     formID = currData.data{respCols.form_id}(lastEntryMask);
0296     if any(diff(formID))
0297       error('Multiple formIDs associated with single timestamp: %s', sprintf('\t%d', unique(formID)))
0298     else
0299       formID = formID(1);
0300     end
0301     
0302     mysql_str = sprintf('SELECT form_name FROM form WHERE form_id = %d;', formID);
0303     formName = mysql(params.mysql.conn_id, mysql_str);
0304     formName = formName{1};
0305     
0306     fprintf(fid,'\tLast submitted form: ID=%d, %s, %s\n', formID, formName, datestr(lastTimeStamp));
0307     
0308     % Provide number and list of stimuli encountered
0309     stimIDs = unique(currData.data{respCols.stimulus_id}, 'stable');
0310     stimIDs(isnan(stimIDs)) = [];  % eliminate entries for which there were no stimulus IDs
0311     fprintf(fid,'\t%d stimuli:%s\n', length(stimIDs), sprintf('\t%d', stimIDs));
0312     
0313     % Track last stimulus encountered across sessions
0314     if ~isempty(stimIDs)
0315       lastStim(isess) = stimIDs(end);
0316     end
0317     
0318   end % for isess
0319   result = 0;
0320 end % incomplete_details
0321

Generated on Wed 20-Sep-2023 04:00:50 by m2html © 2003