Home > database > ensemble_session_trial_info_without_trial_id.m

ensemble_session_trial_info_without_trial_id

PURPOSE ^

sessData = ensemble_session_trial_info_without_trial_id(indata,params)

SYNOPSIS ^

function sessData = ensemble_session_trial_info_without_trial_id(indata,params)

DESCRIPTION ^

 sessData = ensemble_session_trial_info_without_trial_id(indata,params)
 
 Extracts the response_order and stimulus IDs for each given session.

 Adapted from ensemble_session_trial_info to accomodate data from
 experiments for which trial IDs were not created

 indata is a cell array of two data structures (response_data and
 session_info), as returned from ensemble_load_expinfo
 
 This function looks at the response table (from ensemble_load_expinfo)
 of an experiment to extract the response_order and stimulus IDs for each 
 session, in the order that they were presented. This info is stored 
 in a 'trial info' structure that is tagged to the end of each session 
 in the session structure (also retrieved from ensemble_load_expinfo). 

 Optionally,the audio corresponding to each trial can be parsed from a session recording
 (e.g. from digital performer). The time offsets of each trial relative to
 the beginning of the recording are then recorded. This information is then
 used to parse a continuously recorded MIDI time course into individual responses
 corresponding to each trial (if MIDI data was recorded along-side the audio 
 recording.)
 

 handles only single stimulus trials for now


 main differences from ensemble_session_trial_info:
   - accomodates data with no trial_id values in response table
   - calls parse_midi_slider_response, which resamples midi responses into time courses of evenly spaced points
   - allows removal of practice trials not recorded in audio but recorded in response_table 
  


 29 June 2011 - BH
 06Sep2013 PJ - added parfor to session loop

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function sessData = ensemble_session_trial_info_without_trial_id(indata,params)
0002 % sessData = ensemble_session_trial_info_without_trial_id(indata,params)
0003 %
0004 % Extracts the response_order and stimulus IDs for each given session.
0005 %
0006 % Adapted from ensemble_session_trial_info to accomodate data from
0007 % experiments for which trial IDs were not created
0008 %
0009 % indata is a cell array of two data structures (response_data and
0010 % session_info), as returned from ensemble_load_expinfo
0011 %
0012 % This function looks at the response table (from ensemble_load_expinfo)
0013 % of an experiment to extract the response_order and stimulus IDs for each
0014 % session, in the order that they were presented. This info is stored
0015 % in a 'trial info' structure that is tagged to the end of each session
0016 % in the session structure (also retrieved from ensemble_load_expinfo).
0017 %
0018 % Optionally,the audio corresponding to each trial can be parsed from a session recording
0019 % (e.g. from digital performer). The time offsets of each trial relative to
0020 % the beginning of the recording are then recorded. This information is then
0021 % used to parse a continuously recorded MIDI time course into individual responses
0022 % corresponding to each trial (if MIDI data was recorded along-side the audio
0023 % recording.)
0024 %
0025 %
0026 % handles only single stimulus trials for now
0027 %
0028 %
0029 % main differences from ensemble_session_trial_info:
0030 %   - accomodates data with no trial_id values in response table
0031 %   - calls parse_midi_slider_response, which resamples midi responses into time courses of evenly spaced points
0032 %   - allows removal of practice trials not recorded in audio but recorded in response_table
0033 %
0034 %
0035 %
0036 % 29 June 2011 - BH
0037 % 06Sep2013 PJ - added parfor to session loop
0038 
0039 if ~isfield(params,'verbose'), params.verbose=0; end
0040 
0041 % params.numPracticeTrials parameter is used for removing practice trials from the
0042 % parsed audio/ensemble response set. This is useful if practice
0043 % trials were recorded, but are not desired in the results. Note that this
0044 % should be used only if practice trials recorded in audio file.
0045 if(isfield(params,'numPracticeTrials')) %fix to handle scenario where practice trials not recorded in DP but exist in response table
0046   practiceTrialIdxs = 1:params.numPracticeTrials;
0047 else
0048   practiceTrialIdxs = [];    
0049 end
0050 
0051 % params.num_practice_trials_database_only paramter is used to remove
0052 % practice trials from ensemble response set only, and not audio. This is an
0053 % alternative to numPractice Trials and is usefule if practice trials were not
0054 % recorded in the audio files but exist in the response table
0055 if(isfield(params,'num_practice_trials_database_only'))
0056     databasePracticeTrialIdxs = 1:params.num_practice_trials_database_only;
0057 else
0058     databasePracticeTrialIdxs = [];
0059 end
0060 
0061 dataStructCrit.name = 'session_info';
0062 sessIdx = ensemble_find_analysis_struct(indata,dataStructCrit);
0063 sessData = indata{sessIdx};
0064 sessData.name = 'session_x_trial_info';
0065 sessData.type = 'session_x_trial_info';
0066 sessData.vars{end+1} = 'trial_info';
0067 sessCols = set_var_col_const(sessData.vars);
0068 
0069 dataStructCrit.name = 'response_data';
0070 respIdx = ensemble_find_analysis_struct(indata,dataStructCrit);
0071 respData = indata{respIdx};
0072 respCols = set_var_col_const(respData.vars);
0073 
0074 
0075 sessionIDs = sessData.data{sessCols.session_id};
0076 subjectIDs = sessData.data{sessCols.subject_id};
0077 
0078 sessData.data{sessCols.trial_info} = cell(length(sessionIDs),1);
0079 tinfoStack = cell(length(sessionIDs),1);
0080 for sessIdx = 1:length(sessionIDs)
0081 
0082   session_id = sessionIDs(sessIdx);
0083   subject_id  = subjectIDs{sessIdx};
0084  
0085   message(['Sorting trial info for session # ' num2str(sessIdx) ...
0086        ', ID ' subject_id ...
0087        ', Ensemble session # ' num2str(session_id)],...
0088        params.verbose);
0089   
0090   cfilt = [];
0091   cfilt.include.all.session_id = session_id;
0092   respThisSess = ensemble_filter(respData,cfilt);
0093   
0094   trialInfoStruct = ensemble_init_data_struct;
0095   trialInfoStruct.name='trial info';
0096   trialInfoStruct.type='trial info';
0097   trialInfoStruct.vars={'response_order' 'stimulus_id'};
0098 
0099    
0100   % get rid of repeated response order values and stimulus ids
0101   % this is done by taking the diff of the response order
0102   % and zeroing out all the indices where the diff == 0
0103   % also, getting rid of NaNs in the and stim id list
0104   trialInfoVector = [respThisSess.data{respCols.response_order}  ...
0105       respThisSess.data{respCols.stimulus_id}];
0106   
0107   trialdiffIdx = [ 1 diff(trialInfoVector(:,1))'];
0108   trialInfoVector(trialdiffIdx == 0,:) = [];
0109   trialInfoVector( isnan(trialInfoVector(:,2)),: ) = [];
0110   
0111   % if databasePracticeTrialIdxs set remove those trials
0112   if ~isempty(databasePracticeTrialIdxs)
0113       trialInfoVector(databasePracticeTrialIdxs,:) = [];
0114   end
0115   
0116   trialInfoCols = set_var_col_const(trialInfoStruct.vars);
0117   trialInfoStruct.data{trialInfoCols.response_order}=trialInfoVector(:,1);
0118   trialInfoStruct.data{trialInfoCols.stimulus_id}=trialInfoVector(:,2);
0119   
0120   %if params.parse_audio was set, then audio parsing will be
0121   %performed. params.parse_audio serves as the param struct for the
0122   %audio parser
0123   if isfield(params,'parse_audio_stims') && ~isempty(params.parse_audio_stims)
0124   
0125       parseAudioParams = params.parse_audio_stims;
0126       parseAudioParams.mysql = params.mysql;
0127       parseAudioParams.filename = ...
0128           replaceFilenameTags(parseAudioParams.filename,struct('subject_id',subject_id,'session_id',session_id));
0129 
0130 
0131       %if the recorded responses in Ensemble or audio recordings
0132       %don't match, these parameters will ignore either Ensemble
0133       %session info (ignoreMatchedEventForSub) or audio info
0134       %(ignoreParsedStimAudioForSub)during matching
0135       if(isfield(params,'ignoreMatchedEventForSub'))
0136           
0137           [hasEventExclusions,ignoreCellIdx] = ismember(subject_id,params.ignoreMatchedEventForSub{1});
0138           if(ignoreCellIdx ~= 0)
0139               parseAudioParams.ignoreEventIdxs = ...
0140                   params.ignoreMatchedEventForSub{2}{ignoreCellIdx};
0141 
0142 
0143               %if ensemble practice sessions are missing from database,
0144               %then we might need to revise which practice trials to
0145               %throw out.
0146               usePracticeTrialIdxs = setdiff(practiceTrialIdxs,parseAudioParams.ignoreEventIdxs);
0147 
0148           end
0149       end
0150         
0151       if(isfield(params,'ignoreParsedStimAudioForSub'))
0152           [hasStimAudioExclusions,ignoreCellIdx] = ...
0153           ismember(subject_id,params.ignoreParsedStimAudioForSub{1});
0154           
0155           if(ignoreCellIdx ~= 0)
0156               parseAudioParams.ignoreParsedAudioIdxs = params.ignoreParsedStimAudioForSub{2}{ignoreCellIdx};
0157           end
0158       end
0159       
0160       trialInfoStruct = parse_audio_clips(trialInfoStruct,parseAudioParams);
0161       if isempty(trialInfoStruct)
0162           warning('no audio data for %s',subject_id);
0163           continue
0164       end
0165   end %parse audio
0166   
0167   if isfield(params,'parse_midi_resps') && ~isempty(params.parse_midi_resps)
0168     
0169     parseMidiRespsParams = params.parse_midi_resps;
0170     parseMidiRespsParams.filename = replaceFilenameTags(parseMidiRespsParams.filename,struct('subject_id',subject_id,'session_id',session_id));
0171     trialInfoStruct = parse_midi_slider_response(trialInfoStruct,parseMidiRespsParams);
0172    
0173   end %parse MIDI
0174   
0175   %throw out the practice trials if this was set
0176   allTrialIdxs = 1:length(trialInfoStruct.data{1});
0177   trialIdxsToKeep = setdiff(allTrialIdxs,practiceTrialIdxs);
0178   for iCol = 1:length(trialInfoStruct.data)
0179     trialInfoStruct.data{iCol} = trialInfoStruct.data{iCol}(trialIdxsToKeep);
0180   end
0181   
0182   tinfoStack{sessIdx} = trialInfoStruct;
0183   
0184 end %sessIdx
0185 sessData.data{sessCols.trial_info} = tinfoStack;
0186 
0187 function message(messageString,verbose)
0188 
0189 if(verbose > 0)
0190   disp(sprintf(messageString));
0191 end
0192 
0193 return
0194 
0195 
0196 function filename = replaceFilenameTags(filename,replaceStrings)
0197 
0198 filename = strrep(filename,'<subject_id>',replaceStrings.subject_id);
0199 filename = strrep(filename,'<session_id>',num2str(replaceStrings.session_id));
0200 
0201 return

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