def make(cls, **kwargs): """Create a list of trials. Each trial is a dict with values for all keys in self.COLUMNS. """ # make convenience copies of class defaults stim_dir = cls.STIM_DIR columns = cls.COLUMNS settings = kwargs.copy() seed = settings.get('seed') try: seed = int(seed) except (TypeError, ValueError): logging.info('seed was None or couldn\'t be converted to int') seed = None prng = random.RandomState(seed) # Read in the trials (same for all participants) trials = pd.read_csv(Path(stim_dir, 'propositions.csv')) # Randomly assign mask trials trials['mask_type'] = prng.choice(['mask', 'nomask'], size=len(trials)) # Choose a version of each cue at random all_cues = Path(stim_dir, 'cues').listdir('*.wav', names_only=True) def pick_cue_file(cue): options = [c for c in all_cues if c.find(cue) == 0] return prng.choice(options) trials['cue_file'] = trials.cue.apply(pick_cue_file) # Add columns for response variables for col in ['response', 'rt', 'is_correct']: trials[col] = '' # Add practice trials num_practice = 6 practice_ix = prng.choice(trials.index, num_practice, replace=False) practice_trials = trials.ix[practice_ix, ] practice_trials['block'] = 0 practice_trials['block_type'] = 'practice' trials.drop(practice_ix, inplace=True) # Finishing touches: block trials and shuffle num_blocks = 4 trials_per_block = (len(trials)/num_blocks) + 1 trials = add_block(trials, trials_per_block, name='block', start=1, groupby='cue', seed=seed) trials = smart_shuffle(trials, col='cue', block='block', seed=seed) trials['block_type'] = 'test' # Merge practice trials trials = pd.concat([practice_trials, trials], ignore_index=True) # Label trial trials['trial'] = range(1, len(trials)+1) # Reorder columns trials = trials[columns] return cls(trials.to_dict('record'))
def make(cls, **kwargs): """ Create a list of trials. Each trial is a dict with values for all keys in self.COLUMNS. """ stim_dir = unipath.Path(cls.STIM_DIR) # default settings settings = dict(ratio_prompt_trials=0.75, ratio_yes_correct_responses=0.75) settings.update(kwargs) seed = kwargs.get('seed', '') try: seed = int(seed) except ValueError: seed = random.randint(100) print 'no seed given, using', seed prng = random.RandomState(seed) # Balance within subject variables trials = counterbalance({ 'feat_type': ['visual', 'nonvisual'], 'mask_type': ['mask', 'nomask'] }) trials = expand(trials, name='correct_response', values=['yes', 'no'], ratio=settings['ratio_yes_correct_responses'], seed=seed) trials = expand(trials, name='response_type', values=['prompt', 'word'], ratio=settings['ratio_prompt_trials'], seed=seed) # Extend the trials to final length trials = extend(trials, reps=4) # Read proposition info propositions_csv = unipath.Path(stim_dir, 'propositions.csv') propositions = pandas.read_csv(propositions_csv) # Add cue categories = propositions.cue.unique() trials['cue'] = prng.choice(categories, len(trials), replace=True) cue_info_csv = unipath.Path(stim_dir, 'cues', '_cue_info.csv') cues = pandas.read_csv(cue_info_csv) def determine_cue_file(row): options = cues.ix[cues.cue == row['cue'], 'cue_file'].tolist() return prng.choice(options) trials['cue_file'] = trials.apply(determine_cue_file, axis=1) # copy propositions to prevent duplicate questions _propositions = propositions.copy() def determine_question(row): is_cue = (_propositions.cue == row['cue']) is_feat_type = (_propositions.feat_type == row['feat_type']) is_correct_response = ( _propositions.correct_response == row['correct_response']) valid_propositions = (is_cue & is_feat_type & is_correct_response) if valid_propositions.sum() == 0: # no more propositions for this cue! # switch to a different cue and try again # row.name is the index for this row trials.loc[row.name, 'cue'] = prng.choice(categories) trials.loc[row.name, 'cue_file'] = determine_cue_file( trials.ix[row.name]) return determine_question(trials.ix[row.name, ]) options = _propositions.ix[valid_propositions, ] selected_ix = prng.choice(options.index) selected_proposition_id = options.ix[selected_ix, 'proposition_id'] _propositions.drop(selected_ix, inplace=True) return selected_proposition_id trials['proposition_id'] = trials.apply(determine_question, axis=1) # Merge in question trials = trials.merge(propositions) # Replace proposition on word trials trials.loc[trials.response_type == 'word', 'question'] = '----------' for prop_col in ['question_slug', 'feat_type', 'proposition_id']: trials.loc[trials.response_type == 'word', prop_col] = '' # Add in word def determine_word(row): if row['response_type'] != 'word': return '' elif row['correct_response'] == 'yes': return row['cue'] else: distractors = list(categories) distractors.remove(row['cue']) return prng.choice(distractors) trials['word'] = trials.apply(determine_word, axis=1) # for V2, the word is now auditory, so a file must be selected def determine_word_file(row): if row['response_type'] == 'prompt': return '' options = cues.ix[cues.cue == row['word'], 'cue_file'].tolist() if row['cue_file'] in options: options.remove(row['cue_file']) return prng.choice(options) trials['word_file'] = trials.apply(determine_word_file, axis=1) # Add columns for response variables for col in ['response', 'rt', 'is_correct']: trials[col] = '' # Add practice trials num_practice = 8 practice_ix = prng.choice(trials.index, num_practice) practice_trials = trials.ix[practice_ix, ] practice_trials['block'] = 0 practice_trials['block_type'] = 'practice' trials.drop(practice_ix, inplace=True) # Separate response type by block # HARDCODED!!! prompt_blocks = [1, 3, 5] word_blocks = [2, 4] def assign_block(row): response_type = row['response_type'] if response_type == 'prompt': return prng.choice(prompt_blocks) elif response_type == 'word': return prng.choice(word_blocks) else: raise NotImplementedError('response type %s' % response_type) trials['block'] = trials.apply(assign_block, axis=1) trials.sort('block', inplace=True) # Finishing touches trials = smart_shuffle(trials, col='cue', block='block', seed=seed) trials['block_type'] = 'test' # Merge practice trials trials = pandas.concat([practice_trials, trials]) # Label trial trials['trial'] = range(len(trials)) # Reorcder columns trials = trials[cls.COLUMNS] return cls(trials.to_dict('record'))
def make(cls, **kwargs): """ Create a list of trials. Each trial is a dict with values for all keys in self.COLUMNS. """ settings = dict(cls.DEFAULTS) settings.update(kwargs) seed = settings.get('seed') prng = pd.np.random.RandomState(seed) # Balance within subject variables trials = counterbalance({'feat_type': ['visual', 'nonvisual'], 'mask_type': ['mask', 'nomask']}) trials = expand(trials, name='correct_response', values=['yes', 'no'], ratio=settings['ratio_yes_correct_responses'], seed=seed) trials = expand(trials, name='response_type', values=['prompt', 'pic'], ratio=settings['ratio_prompt_response_type'], seed=seed) # Extend the trials to final length trials = extend(trials, reps=4) # Read proposition info propositions_csv = Path(cls.STIM_DIR, 'propositions.csv') propositions = pd.read_csv(propositions_csv) # Add cue categories = propositions.cue.unique() trials['cue'] = prng.choice(categories, len(trials), replace=True) _propositions = propositions.copy() def determine_question(row): is_cue = (_propositions.cue == row['cue']) is_feat_type = (_propositions.feat_type == row['feat_type']) is_correct_response = (_propositions.correct_response == row['correct_response']) valid_propositions = (is_cue & is_feat_type & is_correct_response) if valid_propositions.sum() == 0: trials.ix[row.name, 'cue'] = prng.choice(categories) return determine_question(trials.ix[row.name, ]) options = _propositions.ix[valid_propositions, ] selected_ix = prng.choice(options.index) selected_proposition_id = options.ix[selected_ix, 'proposition_id'] _propositions.drop(selected_ix, inplace=True) return selected_proposition_id trials['proposition_id'] = trials.apply(determine_question, axis=1) # Merge in question trials = trials.merge(propositions) # Add in picture def determine_pic(row): if row['response_type'] != 'pic': return '' elif row['correct_response'] == 'yes': return row['cue'] else: distractors = list(categories) distractors.remove(row['cue']) return prng.choice(distractors) trials['pic'] = trials.apply(determine_pic, axis=1) # Add columns for response variables for col in ['response', 'rt', 'is_correct']: trials[col] = '' # Add practice trials num_practice = 8 practice_ix = prng.choice(trials.index, num_practice) practice_trials = trials.ix[practice_ix, ] practice_trials['block'] = 0 practice_trials['block_type'] = 'practice' trials.drop(practice_ix, inplace=True) # Finishing touches trials = add_block(trials, 50, name='block', start=1, groupby='cue', seed=seed) trials = smart_shuffle(trials, col='cue', block='block', seed=seed) trials['block_type'] = 'test' # Merge practice trials trials = pd.concat([practice_trials, trials]) # Label trial trials['trial'] = range(len(trials)) # Reorcder columns trials = trials[cls.COLUMNS] return cls(trials.to_dict('record'))
def make(cls, **kwargs): """ Create a list of trials. Each trial is a dict with values for all keys in self.COLUMNS. """ settings = dict(cls.DEFAULTS) settings.update(kwargs) seed = settings.get('seed') prng = pd.np.random.RandomState(seed) # Balance within subject variables trials = counterbalance({ 'feat_type': ['visual', 'nonvisual'], 'mask_type': ['mask', 'nomask'] }) trials = expand(trials, name='correct_response', values=['yes', 'no'], ratio=settings['ratio_yes_correct_responses'], seed=seed) trials = expand(trials, name='response_type', values=['prompt', 'pic'], ratio=settings['ratio_prompt_response_type'], seed=seed) # Extend the trials to final length trials = extend(trials, reps=4) # Read proposition info propositions_csv = Path(cls.STIM_DIR, 'propositions.csv') propositions = pd.read_csv(propositions_csv) # Add cue categories = propositions.cue.unique() trials['cue'] = prng.choice(categories, len(trials), replace=True) _propositions = propositions.copy() def determine_question(row): is_cue = (_propositions.cue == row['cue']) is_feat_type = (_propositions.feat_type == row['feat_type']) is_correct_response = ( _propositions.correct_response == row['correct_response']) valid_propositions = (is_cue & is_feat_type & is_correct_response) if valid_propositions.sum() == 0: trials.ix[row.name, 'cue'] = prng.choice(categories) return determine_question(trials.ix[row.name, ]) options = _propositions.ix[valid_propositions, ] selected_ix = prng.choice(options.index) selected_proposition_id = options.ix[selected_ix, 'proposition_id'] _propositions.drop(selected_ix, inplace=True) return selected_proposition_id trials['proposition_id'] = trials.apply(determine_question, axis=1) # Merge in question trials = trials.merge(propositions) # Add in picture def determine_pic(row): if row['response_type'] != 'pic': return '' elif row['correct_response'] == 'yes': return row['cue'] else: distractors = list(categories) distractors.remove(row['cue']) return prng.choice(distractors) trials['pic'] = trials.apply(determine_pic, axis=1) # Add columns for response variables for col in ['response', 'rt', 'is_correct']: trials[col] = '' # Add practice trials num_practice = 8 practice_ix = prng.choice(trials.index, num_practice) practice_trials = trials.ix[practice_ix, ] practice_trials['block'] = 0 practice_trials['block_type'] = 'practice' trials.drop(practice_ix, inplace=True) # Finishing touches trials = add_block(trials, 50, name='block', start=1, groupby='cue', seed=seed) trials = smart_shuffle(trials, col='cue', block='block', seed=seed) trials['block_type'] = 'test' # Merge practice trials trials = pd.concat([practice_trials, trials]) # Label trial trials['trial'] = range(len(trials)) # Reorcder columns trials = trials[cls.COLUMNS] return cls(trials.to_dict('record'))