def test_c_volume_out_of_range(config_fs, sound_mocker):
    with open(TEST_CONFIG_FN, 'r') as f:
        config = yaml.load(f, Loader=yaml.Loader)

    config['c_volume'] = 1.1

    n_config_fn = '_' + TEST_CONFIG_FN
    config_fs.create_file(n_config_fn,
                          contents=yaml.dump(config, Dumper=yaml.Dumper))

    try:
        config = cfg.ExperimentRunConfig(n_config_fn, STIM_LIST_FN, OUTDIR_FN)
        pytest.fail()
    except cfg.InvalidVolumeValue:
        pass

    with open(TEST_CONFIG_FN, 'r') as f:
        config = yaml.load(f, Loader=yaml.Loader)

    config['c_volume'] = -0.1

    n2_config_fn = '2_' + TEST_CONFIG_FN
    config_fs.create_file(n2_config_fn,
                          contents=yaml.dump(config, Dumper=yaml.Dumper))

    try:
        config = cfg.ExperimentRunConfig(n2_config_fn, STIM_LIST_FN, OUTDIR_FN)
        pytest.fail()
    except cfg.InvalidVolumeValue:
        pass
def test_randomized_trials(config_fs, sound_mocker):
    shuffle = sound_mocker.patch('random.shuffle')

    with open(TEST_CONFIG_FN, 'r') as f:
        config = yaml.load(f, Loader=yaml.Loader)

    config['randomize'] = False

    n_config_fn = '_' + TEST_CONFIG_FN
    config_fs.create_file(n_config_fn,
                          contents=yaml.dump(config, Dumper=yaml.Dumper))

    config = cfg.ExperimentRunConfig(n_config_fn, STIM_LIST_FN, OUTDIR_FN)
    shuffle.assert_not_called()
    assert config.stimuli_list == STIM_LIST

    with open(TEST_CONFIG_FN, 'r') as f:
        config = yaml.load(f, Loader=yaml.Loader)

    config['randomize'] = True

    n2_config_fn = '2_' + TEST_CONFIG_FN
    config_fs.create_file(n2_config_fn,
                          contents=yaml.dump(config, Dumper=yaml.Dumper))

    config = cfg.ExperimentRunConfig(n2_config_fn, STIM_LIST_FN, OUTDIR_FN)
    shuffle.assert_called_once()
    assert set(config.stimuli_list) == set(STIM_LIST)
def test_wrong_type(config_fs, sound_mocker):
    with open(TEST_CONFIG_FN, 'r') as f:
        config = yaml.load(f, Loader=yaml.Loader)

    n_config_fn = '_' + TEST_CONFIG_FN

    # Not int
    n_config = config.copy()
    n_config['black_duration'] = 'not int'
    config_fs.create_file(n_config_fn,
                          contents=yaml.dump(n_config, Dumper=yaml.Dumper))
    try:
        cfg.ExperimentRunConfig(n_config_fn, STIM_LIST_FN, OUTDIR_FN)
        pytest.fail()
    except cfg.InvalidConfigType as e:
        assert e.key == 'black_duration'
        assert e.type == typing.Union[typing.Tuple[int, int], int]
    os.remove(n_config_fn)

    # Not str
    n_config = config.copy()
    n_config['c1_color'] = 0
    config_fs.create_file(n_config_fn,
                          contents=yaml.dump(n_config, Dumper=yaml.Dumper))
    try:
        cfg.ExperimentRunConfig(n_config_fn, STIM_LIST_FN, OUTDIR_FN)
        pytest.fail()
    except cfg.InvalidConfigType as e:
        assert e.key == 'c1_color'
        assert e.type == str
    os.remove(n_config_fn)

    # Not dur
    n_config = config.copy()
    n_config['c1_duration'] = 'not dur'
    config_fs.create_file(n_config_fn,
                          contents=yaml.dump(n_config, Dumper=yaml.Dumper))
    try:
        cfg.ExperimentRunConfig(n_config_fn, STIM_LIST_FN, OUTDIR_FN)
        pytest.fail()
    except cfg.InvalidConfigType as e:
        assert e.key == 'c1_duration'
        assert e.type == typing.Union[int, typing.Tuple[int, int]]
    os.remove(n_config_fn)

    # Not float
    n_config = config.copy()
    n_config['c_volume'] = 'not float'
    config_fs.create_file(n_config_fn,
                          contents=yaml.dump(n_config, Dumper=yaml.Dumper))
    try:
        cfg.ExperimentRunConfig(n_config_fn, STIM_LIST_FN, OUTDIR_FN)
        pytest.fail()
    except cfg.InvalidConfigType as e:
        assert e.key == 'c_volume'
        assert e.type == typing.Union[float, int]
    os.remove(n_config_fn)
def test_nonempty_existing_output_dir(config_fs, sound_mocker):
    config_fs.create_dir(OUTDIR_FN)
    config_fs.create_file(os.path.join(OUTDIR_FN, 'out'))

    try:
        cfg.ExperimentRunConfig(TEST_CONFIG_FN, STIM_LIST_FN, OUTDIR_FN)
        pytest.fail()
    except cfg.IllegalOutputDirectory as iod:
        pass
def test_non_existing_stim_error(config_fs, sound_mocker):
    config_fs.create_file('stim2.txt', contents='\n'.join(list('abdc')))

    try:
        config = cfg.ExperimentRunConfig(TEST_CONFIG_FN, 'stim2.txt',
                                         OUTDIR_FN)
        pytest.fail()
    except cfg.MissingStimuliFiles as msf:
        pass
def test_config_read(config_fs, sound_mocker):
    config = cfg.ExperimentRunConfig(TEST_CONFIG_FN, STIM_LIST_FN, OUTDIR_FN)
    assert config.black_duration == 600
    assert config.c1_duration == 300
    assert config.c1_color == "#afd444"
    assert config.c2_duration == 000
    assert config.c2_color == "#afd444"
    assert config.randomize == False
    assert config.sound_device == "USB Device"
    assert config.silence_duration == 1500
    assert config.c_volume == 1
    assert config.output_dir == OUTDIR_FN
    assert config.stimuli_list == list('abc')
def test_missing_sound_device(config_fs, mocker):
    mocker.patch('sounddevice.query_devices',
                 return_value=[{
                     'name': 'Intel'
                 }, {
                     'name': 'Default'
                 }])

    try:
        cfg.ExperimentRunConfig(TEST_CONFIG_FN, STIM_LIST_FN, OUTDIR_FN)
        pytest.fail()
    except cfg.NoMatchingDeviceFound as nmdf:
        pass
Exemple #8
0
def run_experiment(args):
    '''
    Executes the trial configuration.

    Args:
        * args.trial_config: open file for the trial config yaml
        * args.stimuli_list: open file for the stimuli list
        * args.output_dir: str indicating directory where output 
            should be saved
    '''
    import m2.runAudioExperiment.experiment_config as ec
    import m2.runAudioExperiment.trial_data as td
    import m2.runAudioExperiment.env as environment
    import random

    logger.info('Loading config from {}.'.format(args.trial_config))
    # Load and verify experiment config
    try:
        exp_config = ec.ExperimentRunConfig(args.trial_config,
                                            args.stimuli_list, args.output_dir,
                                            args.debug_durations)
    except ec.ExperimentConfigError as ece:
        print(ece)
        sys.exit()

    logger.info('Preparing environment.')
    # Prepare environment (Psychopy, Sounddevice)
    env = environment.Environment(exp_config)

    logger.info('Creating trials data.')
    # Instance trials data
    trials_data = td.TrialsData(exp_config)

    # Prepare trials
    for trial in trials_data:
        logger.debug('Preparing trial with stimulus {}.'.format(
            trial.stimulus_path))
        trial.prepare(env)

    # Run trials
    for idx, trial in enumerate(trials_data):
        logger.debug('Starting trial #{} with stimulus {}.'.format(
            idx, trial.stimulus_path))
        trial.execute(env)

    # Save data
    exp_config.save()
    trials_data.save()
def test_config_read_interval(config_fs, sound_mocker):
    with open(TEST_CONFIG_FN, 'r') as f:
        config = yaml.load(f, Loader=yaml.Loader)

    config['c1_duration'] = (300, 500)

    n_config_fn = '_' + TEST_CONFIG_FN
    config_fs.create_file(n_config_fn,
                          contents=yaml.dump(config, Dumper=yaml.Dumper))

    config = cfg.ExperimentRunConfig(n_config_fn, STIM_LIST_FN, OUTDIR_FN)
    assert config.black_duration == 600
    assert config.c1_duration == (300, 500)
    assert config.c1_color == "#afd444"
    assert config.c2_duration == 000
    assert config.c2_color == "#afd444"
    assert config.randomize == False
    assert config.sound_device == "USB Device"
    assert config.silence_duration == 1500
def test_missing_keys(config_fs, skips_n, sound_mocker):
    skips = random.choices(list(cfg.ExperimentRunConfig.config_keys_set),
                           k=skips_n)
    with open(TEST_CONFIG_FN, 'r') as f:
        config = yaml.load(f, Loader=yaml.Loader)
    n_config = {k: v for k, v in config.items() if k not in skips}

    n_config_path = '_' + TEST_CONFIG_FN
    config_fs.create_file(n_config_path,
                          contents=yaml.dump(n_config, Dumper=yaml.Dumper))

    try:
        cfg.ExperimentRunConfig(n_config_path, STIM_LIST_FN, OUTDIR_FN)
        pytest.fail()
    except cfg.IncompleteExperimentConfig as e:
        assert e.filename == n_config_path
        assert e.missing_keys == set(skips)
        return

    pytest.fail()
def test_existing_output_dir(config_fs, sound_mocker):
    config_fs.create_dir(OUTDIR_FN)

    cfg.ExperimentRunConfig(TEST_CONFIG_FN, STIM_LIST_FN, OUTDIR_FN)