コード例 #1
0
ファイル: run.py プロジェクト: lupyanlab/motivated-arrows
    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'))
コード例 #2
0
    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'))
コード例 #3
0
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
コード例 #4
0
ファイル: run.py プロジェクト: lupyanlab/dual-verification
    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'))
コード例 #5
0
    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'))