예제 #1
0
    def _config_write_analog(self,
                             channel,
                             analog_event_handler=None,
                             min_val=-10.0,
                             max_val=10.0,
                             **kwargs):
        """ Configure a channel or group of channels as an analog output

        Parameters))
        ----------
        channel: string
            a channel or group of channels that will all be written to at the same
        analog_event_handler: instance of events.EventDToAHandler
            an event handler for sending event information down an analog channel. Should have a channel attribute.
        min_val: float
            the minimum voltage that can be read
        max_val: float
            the maximum voltage that can be read

        Returns
        -------
        True if configuration succeeded
        """

        logger.debug("Configuring analog output on channel(s) %s" %
                     str(channel))
        task = nidaqmx.AnalogOutputTask()
        if self._analog_event_handler is None and \
            analog_event_handler is not None:
            if not hasattr(analog_event_handler, "channel"):
                raise AttributeError(
                    "analog_event_handler must have a channel attribute")
            channel = nidaqmx.libnidaqmx.make_pattern(
                [channel, analog_event_handler.channel])
            logger.debug("Configuring digital to analog output as well.")
            self._analog_event_handler = analog_event_handler

        task.create_voltage_channel(channel, min_val=min_val, max_val=max_val)
        task.configure_timing_sample_clock(source=self.clock_channel,
                                           rate=self.samplerate,
                                           sample_mode="finite")
        self.tasks[channel] = task
예제 #2
0
# while simultaneously outputing a 1ms digital pulse every 5 ms (duty cycle 20%)
# using correlated digital output based off the analog sample clock

# need to start the dio task first!

from __future__ import print_function
from six.moves import input

import numpy as np
import nidaqmx
nsamples = 1000
samplerate = 1000

adata = 9.95*np.sin(np.arange(nsamples,dtype=np.float64)*2*np.pi/nsamples)

atask = nidaqmx.AnalogOutputTask()
atask.create_voltage_channel('Dev1/ao0', min_val=-10.0,max_val=10.0)
atask.configure_timing_sample_clock(rate=samplerate,sample_mode='finite', samples_per_channel=1000)
atask.write(adata, auto_start=False)
# ok that's tee'd up

ddata = np.zeros(nsamples, dtype=np.uint8)
ddata[0:nsamples:5]=1

dotask = nidaqmx.DigitalOutputTask()
dotask.create_channel('Dev1/port0/line0', name='line0')
#print("dotask info:", dotask.get_info_str(True))
print("atask info:", atask.get_info_str())
# note must use r'ao/SampleClock' (can't prefix with /Dev1/
dotask.configure_timing_sample_clock(source=r'ao/SampleClock',rate=1000,sample_mode='finite',samples_per_channel=1000)
dotask.write(ddata, auto_start=False)
예제 #3
0
    def __init__(self, config=None):

        # Load config
        # this sets self.config (the config attribute of our experiment class) to a dictionary containing all the values
        # in our config file. The keys of this dictionary correspond to the section headings in the config file, and
        # each value is another dictionary with keys that refer to the subheadings in the config file. This means you can
        # reference things in the dictionary by e.g. self.config['heading']['subheading']

        with open(config) as f:
            self.config = yaml.load(f)

        self.quest_settings = self.config['quest_settings']
        self.quest = None

        # Check quest numbers of trials
        if self.quest_settings['n_trials'] <= self.quest_settings['n_ignored']:
            raise ValueError(
                "Number of QUEST trials must be greater than the number of ignored trials"
            )

        # ------------------------------------#
        # Subject/task information and saving #
        # ------------------------------------#

        # Enter subject ID and other information
        dialogue = gui.Dlg()
        dialogue.addText("Subject info")
        dialogue.addField('Subject ID')
        dialogue.addText("Task settings")
        dialogue.addField('Run QUEST', initial=True)
        dialogue.show()

        # check that values are OK and assign them to variables
        if dialogue.OK:
            self.subject_id = dialogue.data[0]
            self.run_quest = dialogue.data[1]
        else:
            core.quit()

        # Recode blank subject ID to zero - useful for testing
        if self.subject_id == '':
            self.subject_id = '0'

        # Folder for saving data
        self.save_folder = self.config['directories']['saved_data']
        if not os.path.isdir(self.save_folder):
            os.makedirs(self.save_folder)

        self.save_path = '{0}/Subject{1}_data.csv'.format(
            self.save_folder, self.subject_id, data.getDateStr())

        # Data to be saved
        self.data = dict(
            trial_number=[],  # Trial number
            stimulation_level=[],  # Detection probability
            voltage=[],  # Actual voltage
            response=[],  # Subject's response
            confidence=[],  # Confidence rating
            detected=[],  # Whether or not they detected the stimulus
            session=[],  # Session number
            block=[],  # Block number
            catch=[])  # Whether this was a catch trial

        # -----------------------#
        # Monitor & window setup #
        # -----------------------#

        monitor = monitors.Monitor('monitor', width=40.92, distance=74)
        monitor.setSizePix((1024, 768))
        self.win = visual.Window(
            monitor=monitor,
            size=(1024, 768),
            fullscr=self.config['task_settings']['fullscreen'],
            allowGUI=False,
            color=rgb_convert((-1, -1, -1)),
            units='deg',
            colorSpace='rgb')
        self.win.mouseVisible = False  # make the mouse invisible
        self.frame_rate = 60

        # DAQ
        try:
            device = nidaqmx.libnidaqmx.Device(
                self.config['stimulation']['device'])
            device.reset()

            self.analogOutputTask = nidaqmx.AnalogOutputTask()
            self.analogOutputTask.create_voltage_channel('Dev1/ao0',
                                                         min_val=-10.0,
                                                         max_val=10.0)
        except:
            self.analogOutputTask = fakeAnalogOutputTask()

        # Keys used for making moves
        # self.response_keys = self.config['response keys']['response_keys']
        # self.response_phases = self.config['response keys']['response_phases']  # levels of the tree

        io = launchHubServer()
        self.keyboard = io.devices.keyboard

        self.pain_key = self.config['response_keys']['pain_key']
        self.no_pain_key = self.config['response_keys']['no_pain_key']

        # Clock
        self.clock = core.Clock()

        # --------#
        # Stimuli #
        # --------#

        # Fixation cross
        self.fixation = visual.TextStim(
            win=self.win,
            height=self.config['stimuli']['fixation_size'],
            color='white',
            text="+")

        # Question mark for catch trials
        self.question_mark = visual.TextStim(
            win=self.win,
            height=self.config['stimuli']['question_mark_size'],
            color='white',
            text="?")

        self.instruction_text = visual.TextStim(
            win=self.win,
            height=self.config['stimuli']['text_size'],
            color='white',
            wrapWidth=30)
        self.instruction_text.fontFiles = [self.config['fonts']['font_path']
                                           ]  # Arial is horrible
        self.instruction_text.font = self.config['fonts']['font_name']

        self.confidence_scale = ConfidenceScale(self.win,
                                                ymin=-5,
                                                ymax=5,
                                                width=8)

        # ---------------------- #
        # Stimulation parameters #
        # ---------------------- #

        # Default levels - used if calibration isn't performed
        self.detection_levels = [
            self.quest_settings['default_p0'],
            self.quest_settings['default_p25'],
            self.quest_settings['default_p50'],
            self.quest_settings['default_p75']
        ]

        # Voltage for practice
        self.practice_levels = [
            self.config['task_settings']['low'],
            self.config['task_settings']['high']
        ]

        # Voltage that shouldn't be exceeded
        self.abs_max_voltage = self.config['stimulation'][
            'absolute_maximum_voltage']