def make(cls, **kwargs): seed = kwargs.get('seed') prng = random.RandomState(seed) ratio_cue_valid = kwargs.get('ratio_cue_valid', 0.67) trials = pandas.DataFrame({'cue_type': ['arrow', 'word']}) trials = expand(trials, 'cue_validity', values=['valid', 'invalid'], ratio=ratio_cue_valid, seed=seed) trials = extend(trials, max_length=320) trials['target_loc'] = prng.choice(['left', 'right'], len(trials)) trials['correct_response'] = trials['target_loc'] reverser = dict(left='right', right='left') def pick_cue_dir(trial): cue_validity = trial['cue_validity'] target_loc = trial['target_loc'] if cue_validity == 'valid': return target_loc elif cue_validity == 'invalid': return reverser[target_loc] else: raise NotImplementedError('cue_validity: %s' % cue_validity) trials['cue_dir'] = trials.apply(pick_cue_dir, axis=1) # Determine cue pos and target pos trials['cue_pos_dy'] = 0. trials['target_pos_dy'] = 0. trials[['cue_pos_dy', 'target_pos_dy']] = prng.multivariate_normal( mean=[0, 0], cov=[[1, 0], [0, 1]], size=len(trials) ) # Actual units (pixels) are determined at runtime. for x in ['target_pos_x', 'target_pos_y', 'cue_pos_y']: trials[x] = '' trials = add_block(trials, size=60, start=1, seed=seed) trials['block_type'] = 'test' # Add practice trials num_practice = 8 practice_ix = prng.choice(trials.index, num_practice) practice_trials = trials.ix[practice_ix, ] trials.drop(practice_ix, inplace=True) practice_trials['block'] = 0 practice_trials['block_type'] = 'practice' trials = pandas.concat([practice_trials, trials]) trials['trial'] = range(len(trials)) # Add blank columns for response variables for x in ['response', 'rt', 'is_correct']: trials[x] = '' 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. """ # 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 spatial_cueing_trial_list(cue_type, mask_type, **participant_kwargs): trials = counterbalance({ 'target_loc': ['left', 'right'], 'cue_type': cue_type, 'mask_type': mask_type, }) seed = participant_kwargs.get('seed') random.seed(seed) # Determine cue validity, starting with the smallest group # 66.6% valid, 25% invalid, 8.3% neutral trials = expand(trials, 'cue_validity', values=['invalid', 'neutral'], ratio=0.75, seed=seed) trials = expand(trials, 'tmp_cue_valid', values=[1, 0], ratio=0.7, seed=seed) trials.loc[trials.tmp_cue_valid == 1, 'cue_validity'] = 'valid' del trials['tmp_cue_valid'] # Take anything given by the participant and put it in the trial list for col_name, subj_info in participant_kwargs.items(): trials[col_name] = subj_info # Target was determined, now determine cue dir based on cue validity direction_reverser = {'left': 'right', 'right': 'left'} def determine_cue_dir(trial): target_loc = trial['target_loc'] if trial['cue_validity'] in 'valid': return target_loc elif trial['cue_validity'] == 'invalid': return direction_reverser[target_loc] elif trial['cue_validity'] == 'neutral': return 'neutral' else: msg = 'cue validity %s not implemented' % trial['cue_validity'] raise NotImplementedError(msg) trials['cue_dir'] = trials.apply(determine_cue_dir, axis=1) # Save a copy of the practice trials practice_trials = trials.copy() practice_trials['block'] = 0 # Ensure that there are some up/down targets in the practice trials practice_trial_invalid_ix = practice_trials.ix[ practice_trials.cue_validity == 'invalid', ].index practice_trial_target_loc = [ random.choice(['up', 'down']) for _ in practice_trial_invalid_ix ] practice_trials.ix[practice_trial_invalid_ix, 'target_loc'] = \ practice_trial_target_loc # Select a subset of trials for practice num_practice_trials = 15 sampled_trials = random.sample(practice_trials.index, num_practice_trials) practice_trials = practice_trials.ix[sampled_trials] practice_trials.reset_index(drop=True) # Duplicate unique trials evenly to reach max # 320 trials ~ 20 trials in each within subject cell trials = extend(trials, max_length=320) # Set target location for catch trials invalid_trial_ix = trials.ix[trials.cue_validity == 'invalid', ].index catch_trial_ix = random.sample(invalid_trial_ix, len(invalid_trial_ix) / 2) catch_trial_target_loc = [ random.choice(['up', 'down']) for _ in catch_trial_ix ] trials.ix[catch_trial_ix, 'target_loc'] = catch_trial_target_loc # Assign block randomly block_size = 80 trials = add_block(trials, size=block_size, id_col='cue_validity', start_at=1, seed=seed) # Join the practice trials trials = pandas.concat([practice_trials, trials]) # Shuffle by block trials = simple_shuffle(trials, block='block', seed=seed) trials = trials.reset_index(drop=True) # Label trial number trials.insert(0, 'trial', range(len(trials))) # Rearrange columns participant_keys = [ 'subj_id', 'seed', 'sona_experiment_code', 'experimenter', 'cue_contrast', ] for p in participant_keys: if p not in trials.columns: trials[p] = '' col_order = participant_keys + [ 'block', 'trial', 'mask_type', 'cue_type', 'cue_validity', 'cue_dir', 'target_loc', ] assert all([c in trials.columns for c in col_order]) trials = trials[col_order] # Fill columns decided at runtime trials['soa'] = '' trials['target_loc_x'] = '' trials['target_loc_y'] = '' # Fill response columns trials['rt'] = '' trials['response_type'] = '' trials['is_correct'] = '' return trials
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'))