Home > database > ensemble_session_trial_info_v2.m

ensemble_session_trial_info_v2

PURPOSE ^

sessData = ensemble_session_trial_info_without_trial_id(indata,params)

SYNOPSIS ^

function sessData = ensemble_session_trial_info_v2(indata,params)

DESCRIPTION ^

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

 This version merges the functionality of ensemble_session_trial_info and
 ensemble_session_trial_info_v2, each of which contained functionality limited
 to certain kinds of data. Most noteably:
       - Ensemble trial IDs are not needed 
       - Allows removal of practice trials not recorded in audio but that
       are present in response_table
       - One can parse either data from a MIDI instrument (e.g., Handsonic pad) or 
       continuous MIDI parameter modulation data (e.g., the slider).

 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.)
       - if parsing MIDI, assumes you are parsing MIDI instrument data
       - if parsing continuous MIDI parameter modulation (e.g., the
       slider), set params.parse_midi_resps.slider = 1 in params file
 

 handles only single stimulus trials for now

 

 Feb 20 2012 - BH

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

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

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