Exemple #1
0
class SessionManager(object):
    sessionmgr_version = Ver('0.0.1')
    name = ''

    def __init__(self, **kwargs):
        if not kwargs:
            pass
        elif 'data' in kwargs:
            self = self.load_from_dict(kwargs['data]'])
        else:
            pass

    def load_from_dict(self, data):
        self.sessionmgr_version = Ver(data['sessionmgr_version'])
        self.name = data['name']

    def save_to_dict(self):
        data = dict()
        data['sessionmgr_version'] = self.sessionmgr_version.__str__()
        data['name'] = self.name
        return data

    def __repr__(self):
        return "SessionManager object with name:%s" % (self.name)

    def check_schedule(self):
        return False
Exemple #2
0
class NoTimeOff(SessionManager):
    notimeoff_version = Ver('0.0.1')

    def __init__(self, **kwargs):
        super(NoTimeOff, self).__init__(**kwargs)
        if not kwargs:
            pass
        elif 'data' in kwargs:
            self = self.load_from_dict(kwargs['data]'])
        else:
            pass

    def load_from_dict(self, data):
        self.notimeoff_version = Ver(data['notimeoff_version'])

    def save_to_dict(self):
        data = super(NoTimeOff, self).save_to_dict()
        data['notimeoff_version'] = self.notimeoff_version.__str__()
        return data

    def __repr__(self):
        return "NoTimeOff object"

    def check_schedule(self, **kwargs):
        # Returns keep_doing_trials, secs_remaining_until_state_flip
        keep_doing_trials = True
        secs_remaining_until_state_flip = 0
        return keep_doing_trials, secs_remaining_until_state_flip
Exemple #3
0
class TimeRange(SessionManager):
    timerange_version = Ver('0.0.1')
    time_start = None
    time_stop = None

    def __init__(self, **kwargs):
        super(TimeRange, self).__init__(**kwargs)
        if not kwargs:
            pass
        elif 'data' in kwargs:
            self = self.load_from_dict(kwargs['data]'])
        else:
            pass

    def load_from_dict(self, data):
        self.timerange_version = Ver(data['timerange_version'])
        self.time_start = data['time_start']
        self.time_stop = data['time_stop']

    def save_to_dict(self):
        data = super(TimeRange, self).save_to_dict()
        data['timerange_version'] = self.timerange_version.__str__()
        data['time_start'] = self.time_start
        data['time_stop'] = self.time_stop
        return data

    def __repr__(self):
        return "TimeRange object"

    def check_schedule(self):
        return NotImplementedError()
Exemple #4
0
 def __init__(self):
     self.ver = Ver('0.0.1')  # Feb 28 2014
     name = "DemoGratingsProtocol"
     training_steps = [
         TrainingStep(
             name="DemoGratingStepNum1",
             trial_manager=gratings.GratingsAFC(
                 name='DemoAFCGratingsTrialManager',
                 deg_per_cycs={
                     'L': [0.20],
                     'R': [0.20]
                 },
                 durations={
                     'L': [1.],
                     'R': [1.]
                 },
                 reinforcement_manager=reinfmgr.ConstantReinforcement()),
             # trial_manager=Gratings(name='DemoAFCGratingsTrialManager',
             # deg_per_cycs=[0.1], #degrees
             # orientations=[45,-45,], #degrees
             # contrasts=[1],
             # durations=[1], #seconds
             # radii=[400], #degrees
             # iti=1, #seconds
             # itl=0., #inter trial luminance,
             # ),
             session_manager=sessmgr.NoTimeOff(),
             criterion=crit.RepeatIndefinitely())
     ]
     super(DemoAFCGratingsProtocol, self).__init__(training_steps,
                                                   name=name)
Exemple #5
0
class MinutesPerSession(SessionManager):
    minutespersession_version = Ver('0.0.1')
    minutes = None
    hours_between_sessions = None

    def __init__(self, **kwargs):
        super(MinutesPerSession, self).__init__(**kwargs)
        if not kwargs:
            pass
        elif 'data' in kwargs:
            self = self.load_from_dict(kwargs['data]'])
        else:
            pass

    def load_from_dict(self, data):
        self.minutespersession_version = Ver(data['minutespersession_version'])
        self.minutes = data['minutes']
        self.hours_between_sessions = data['hours_between_sessions']

    def save_to_dict(self):
        data = super(MinutesPerSession, self).save_to_dict()
        data[
            'minutespersession_version'] = self.minutespersession_version.__str__(
            )
        data['minutes'] = self.minutes
        data['hours_between_sessions'] = self.hours_between_sessions
        return data

    def __repr__(self):
        return "MinutesPerSession object, %s minutes with %s hrs between sessions" % (
            self.minutes, self.hours_between_sessions)

    def check_schedule(self):
        return NotImplementedError()
Exemple #6
0
 def __init__(self,
              trials_per_minute=10,
              consecutive_minutes=5,
              name='Unknown'):
     super(PerformanceCriterion, self).__init__(name)
     self.ver = Ver('0.0.1')
     self.trials_per_minute = trials_per_minute
     self.consecutive_minutes = consecutive_minutes
Exemple #7
0
 def __init__(self,
              num_trials=100,
              num_trials_mode='global',
              name='Unknown'):
     super(NumTrialsDoneCriterion, self).__init__(name)
     self.ver = Ver('0.0.1')
     self.num_trials = num_trials
     self.num_trials_mode = num_trials_mode
Exemple #8
0
 def load_from_dict(self, data):
     self.svbstation_version = Ver(data['svbstation_version'])
     self.sound_on = data['sound_on']
     self.io_type = data['io_type']
     self.parallel_port = data['parallel_port']
     self.parallel_port_address = data['parallel_port_address']
     self.display_name = data['display_name']
     self.display_type = data['display_type']
     return self
Exemple #9
0
 def __init__(self, draw_stim_onset_rect=False, iti=1.0, itl=(0., 0., 0.)):
     self.ver = Ver('0.0.2')
     self.draw_stim_onset_rect = draw_stim_onset_rect
     self.iti = iti
     if np.isscalar(itl):
         self.itl = itl * np.asarray(
             [1, 1, 1])  # inter trial luminance as gray scale
     else:
         self.itl = np.asarray(itl)  #itl as color
Exemple #10
0
 def __init__(self,
              pct_correct=0.8,
              num_trials=200,
              num_trials_mode='global',
              name='Unknown'):
     super(PerformanceCriterion, self).__init__(name)
     self.ver = Ver('0.0.1')
     self.pct_correct = pct_correct
     self.num_trials = num_trials
     self.num_trials_mode = num_trials_mode
Exemple #11
0
 def load_from_dict(self, data):
     self.version = Ver(data['version'])  # needed
     self.server_id = data['server_id']  # needed
     self.server_data_path = data['server_data_path']  # needed
     self.creation_time = datetime.datetime.strptime(
         data['creation_time'],
         DATETIME_TO_STR)  # Month-dd-YYYY::Hr:Min:Sec
     for sub in data['subjects']:
         self.subjects.append(Subject.load_from_dict(sub))
     for stn in data['stations']:
         self.stations.append(Station.load_from_dict(stn))
     self.assignments = data['assignemnts']
     return self
Exemple #12
0
    def load_from_dict(self, data):
        self.station_version = Ver(data['station_version'])
        self.creation_time = datetime.datetime.strptime(
            data['creation_time'], DATETIME_TO_STR)
        self.station_id = data['station_id']
        self.station_name = data['station_name']
        self.station_path = os.path.join(get_base_path(), 'BCoreData',
                                         'StationData', str(self.station_id))
        self.station_location = data['station_location']

        self.mac_address = get_mac_address()
        self.ip_address = get_ip_addr()
        self.port = get_port()
        return self
Exemple #13
0
    def __init__(
            self,
            name,
            reinforcement_manager=reinfmgr.ConstantReinforcement(),
            min_run_speed=50,  # sets_trigger on arduino
            run_duration_distribution=2.,  # seconds
            iti=1.,
            itl=(
                0.,
                0.,
                0.,
            ),
            **kwargs):
        super(RunForReward, self).__init__(iti=iti, itl=itl)
        self.ver = Ver('0.0.1')
        self.reinforcement_manager = reinforcement_manager
        self.name = name
        self.run_speed = run_speed
        self.run_duration_distribution = delay_distribution

        self._verify_params_ok()
Exemple #14
0
    def __init__(self,
                 name='DefaultCC_ConstantDelay_1s',
                 delay_distribution=('Constant', 1.),
                 go_signal=None,
                 response_duration=2.,
                 iti=1.,
                 itl=(
                     0.,
                     0.,
                     0.,
                 ),
                 **kwargs):

        super(ClassicalConditioning, self).__init__(iti=iti, itl=itl)
        self.ver = Ver('0.0.2')
        self.reinforcement_manager = reinforcement_manager
        self.name = name
        self.delay_distribution = delay_distribution
        self.go_signal = go_signal
        self.response_duration = response_duration

        # check if values are ok
        self._verify_params_ok()
Exemple #15
0
    def __init__(self,
                 name='DefaultAuditory_Go_ConstantDelay_2s',
                 reinforcement_manager=reinfmgr.ConstantReinforcement(),
                 delay_distribution=('Constant', 2.),
                 go_signal=None,
                 response_duration=2.,
                 iti=1.,
                 itl=(
                     0.,
                     0.,
                     0.,
                 ),
                 **kwargs):
        super(AuditoryGoOnly, self).__init__(iti=iti, itl=itl)
        self.ver = Ver('0.0.1')
        self.reinforcement_manager = reinforcement_manager
        self.name = name
        self.delay_distribution = delay_distribution
        self.go_signal = go_signal
        self.response_duration = response_duration

        # check if values are ok
        self._verify_params_ok()
Exemple #16
0
class BServer(object):
    """
        BSERVER  keeps track of all the stations that it commands,
        which subjects are allowed in which station and data storage locations.
            version             : string identifier
            server_id           : string Identifier
            server_data_path    : allowed data storage location
            server_ip           : IPV4 value
            creation_time       : time.time()
            stations            : list of stations
            subjects            : list of subjects
            assignments         : dictionary with keys being subjectID
                                  and values being list of stationIDs
    """
    version = Ver('0.0.1')  # Feb 5, 2014
    server_id = ''
    server_ip = ''
    server_data_path = ''
    creation_time = None
    stations = []
    subjects = []
    assignments = dict()
    server_connection = []
    station_connections = []

    def __init__(self, **kwargs):
        if not kwargs:
            self.creation_time = datetime.datetime.now()
        elif 'data' in kwargs:
            self = self.load_from_dict(kwargs['data'], convert=False)
        else:
            pass

    def load_from_dict(self, data):
        self.version = Ver(data['version'])  # needed
        self.server_id = data['server_id']  # needed
        self.server_data_path = data['server_data_path']  # needed
        self.creation_time = datetime.datetime.strptime(
            data['creation_time'],
            DATETIME_TO_STR)  # Month-dd-YYYY::Hr:Min:Sec
        for sub in data['subjects']:
            self.subjects.append(Subject.load_from_dict(sub))
        for stn in data['stations']:
            self.stations.append(Station.load_from_dict(stn))
        self.assignments = data['assignemnts']
        return self

    def save_to_dict(self):
        data = dict()
        data['version'] = self.version.__str__()
        data['server_id'] = self.server_id
        data['server_data_path'] = self.server_data_path
        data['creation_time'] = datetime.datetime.strftime(
            self.creation_time, DATETIME_TO_STR)

        subjects = []
        for sub in self.subjects:
            subjects.append(sub.save_to_dict())
        data['subjects'] = subjects

        stations = []
        for stn in self.stations:
            stations.append(stn.save_to_dict())
        data['stations'] = stations

        data['assignments'] = self.assignments

    def __repr__(self):
        return "BServer with id:%s, name:%s, created on:%s)" % (
            self.server_id, self.server_name,
            time.strftime("%b-%d-%Y", self.creation_time))

    def run(server, **kwargs):
        # should expose the ZMQ context. and allow connections
        raise NotImplementedError()

    @staticmethod
    def load():
        """
            Alias for server.loadServer
        """
        return BServer.load_server()

    @staticmethod
    def load_server():
        # use standard location for path,
        # make sure to never modify server here:
        dbLoc = os.path.join(get_base_path(), 'BCoreData', 'ServerData',
                             'db.BServer')
        if os.path.isfile(dbLoc):
            with open(dbLoc, 'rb') as f:
                server = json.load(f)
            print('BServer loaded')
        else:
            raise RuntimeError(
                'db.Server not found. Ensure it exists before calling loadServer'
            )
        return server

    def save(self):
        """
            Alias for server.saveServer
        """
        self.save_server()

    def save_server(self):
        srcDir = os.path.join(get_base_path(), 'BCoreData', 'ServerData')
        desDir = os.path.join(get_base_path(), 'BCoreData', 'ServerData',
                              'backupDBs')

        if not os.path.isdir(self.server_data_path):
            # assume that these are never made alone...
            self._setup_paths()

        if os.path.isfile(os.path.join(srcDir, 'db.BServer')):  # old db exists
            print(('Old db.Bserver found. moving to backup'))
            old = BServer()  # standardLoad to old
            des_name = 'db_' + get_time_stamp(old.creation_time) + '.BServer'
            shutil.copyfile(os.path.join(srcDir, 'db.BServer'),
                            os.path.join(desDir, des_name))
            print(('Moved to backup... deleting old copy'))
            os.remove(os.path.join(srcDir, 'db.BServer'))

        # there might be some attributes that need to be deleted
        # delete them here before continuing
        print(('Cleaning and pickling object'))
        cleanedBServer = copy.deepcopy(self)
        cleanedBServer.station_connections = {}
        with open(os.path.join(srcDir, 'db.BServer'), 'wb') as f:
            pickle.dump(cleanedBServer, f)

    def load_backup(self):
        """
            Use this only if you specifically require the deletion of current
            db.BServer and replacement with an older backup. Only the latest
            back up is used.
        """
        desDir = os.path.join(get_base_path(), 'BCoreData', 'ServerData')
        srcDir = os.path.join(get_base_path(), 'BCoreData', 'ServerData',
                              'backupDBs')
        # delete the original database
        os.remove(os.path.join(desDir, 'db.BServer'))
        # find the latest file in the backupDBs
        newestBkup = max(os.listdir(srcDir), key=os.path.getctime)
        shutil.copyfile(
            os.path.join(srcDir, newestBkup),  # source
            os.path.join(desDir, 'db.BServer')  # destination
        )
        # delete the newest backup
        os.remove(os.path.join(srcDir, newestBkup))

    def _setup_paths(server):
        # create 'BServerData'
        os.mkdir(os.path.join(get_base_path(), 'BCoreData'))
        # create 'ServerData','Stations','PermanentTrialRecordStore' in
        # BServerData
        os.mkdir(os.path.join(get_base_path(), 'BCoreData', 'ServerData'))
        os.mkdir(os.path.join(get_base_path(), 'BCoreData', 'StationData'))
        os.mkdir(os.path.join(get_base_path(), 'BCoreData', 'SubjectData'))
        os.mkdir(os.path.join(get_base_path(), 'BCoreData', 'ChangeParams'))
        # create 'replacedDBs' in 'ServerData'
        os.mkdir(
            os.path.join(get_base_path(), 'BCoreData', 'ServerData',
                         'backupDBs'))
        # create 'Full' and 'Compiled' in 'SubjectData'
        os.mkdir(
            os.path.join(get_base_path(), 'BCoreData', 'SubjectData',
                         'SessionRecords'))
        os.mkdir(
            os.path.join(get_base_path(), 'BCoreData', 'SubjectData',
                         'CompiledTrialRecords'))

    def add_station(self, new_station):
        if (new_station.station_id in self.get_station_ids()
                or new_station.station_name in self.get_station_names()):
            raise ValueError('Station IDs and Station Names have to be unique')
        self.stations.append(new_station)
        # now enable station specific data
        self.save()

    def add_subject(self, new_subject):
        if new_subject in self.subjects:
            raise ValueError('Cannot add replica of subjects to BServer')
        self.subjects.append(new_subject)
        self.save()

    def change_assignment(self, subject, new_assignment):
        if subject not in self.subjects:
            raise ValueError('Cannot change assignment on a subject \
            that is not on Bserver')
        if not (any(new_assignment in self.get_station_ids())):
            raise ValueError('Cannot assign subject to non existent stations')
        self.assignments[subject.subject_id] = new_assignment
        self.save()

    def get_station_ids(self):
        station_ids = []
        for station in self.stations:
            station_ids.append(station.station_id)
        return station_ids

    def get_station_names(self):
        station_names = []
        for station in self.stations:
            station_names.append(station.station_name)
        return station_names

    def get_subject_ids(self):
        subject_ids = []
        for subject in self.subjects:
            subject_ids.append(subject.subject_id)
        return subject_ids
Exemple #17
0
 def __init__(self):
     self.ver = Ver('0.0.1')
     name = 'DemoNoStimulusProtocol'
Exemple #18
0
class StandardKeyboardStation(StandardVisionBehaviorStation):
    """
        STANDARDKEYBOARDSTATION(SKBS) defines a subclass of
        STANDARDVISIONBEHAVIORSTATION(SVBS).
        It defines a station with a standard display, sounds settings
        which can only be turned on or off, three sensor pins
        [connected to the keyboard]. Only allows stand alone running
        Attributes allowed are:
            station_id       : numeric ID to be sent to STATION
            station_path     : DO NOT SEND - STATION WILL SET IT
            display          : dictionary containing details about the
                               display unit
            soundOn          : True/False

        For the StandardKeyboardStation:
            K+1              :            Left Sensor
            K+2              :            Center Sensor
            K+3              :            Right Sensor
            K+Q              :            Quit

    """

    skstation_version = Ver('0.0.1')

    def __init__(self, **kwargs):
        super(StandardKeyboardStation, self).__init__(**kwargs)
        if not kwargs:
            pass
        elif 'data' in kwargs:
            self = self.load_from_dict(kwargs['data]'])
        else:
            pass

    def load_from_dict(self, data):
        self.skstation_version = Ver(data['skstation_version'])
        return self

    def save_to_dict(self):
        data = super(StandardKeyboardStation, self).save_to_dict()
        data['skstation_version'] = self.skstation_version
        return data

    def __repr__(self):
        return "StandardKeyboardStation object with id:%s, location:%s and ip:%s" % (
            self.station_id, self.station_location, self.ip_address)

    @property
    def num_ports(self):
        return 3

    def read_ports(self):
        key = psychopy.event.getKeys(keyList=['1', '2', '3', 'k'])
        ports = np.asarray([False, False, False])
        if key:
            if not key[0] in self._key_pressed:
                self._key_pressed.append(key[0])
        if 'k' in self._key_pressed and '1' in self._key_pressed:
            ports = np.bitwise_or(ports, [True, False, False])
            psychopy.event.clearEvents()
            print(self._key_pressed)
            self._key_pressed.remove('k')
            self._key_pressed.remove('1')
        if 'k' in self._key_pressed and '2' in self._key_pressed:
            ports = np.bitwise_or(ports, [False, True, False])
            psychopy.event.clearEvents()
            print(self._key_pressed)
            self._key_pressed.remove('k')
            self._key_pressed.remove('2')
        if 'k' in self._key_pressed and '3' in self._key_pressed:
            ports = np.bitwise_or(ports, [False, False, True])
            psychopy.event.clearEvents()
            print(self._key_pressed)
            self._key_pressed.remove('k')
            self._key_pressed.remove('3')

        return self.get_ports()[ports]

    def open_valve(self, valve):
        print('Opening valve', valve)

    def close_valve(self, valve):
        print('Closing valve', valve)

    def flush_valves(self, dur=1):
        pass

    def close_all_valves(self):
        print('Closing all valves')

    def initialize(self):
        self.initialize_display(display=self.display)
        self.initialize_sounds()
        self.close_all_valves()
Exemple #19
0
 def load_from_dict(self, data):
     self.notimeoff_version = Ver(data['notimeoff_version'])
Exemple #20
0
 def __init__(self, name='DefaultProtocol'):
     self.ver = Ver('0.0.1')  # Feb 28 2014
     self.name = name
Exemple #21
0
 def load_from_dict(self, data):
     self.sessionmgr_version = Ver(data['sessionmgr_version'])
     self.name = data['name']
Exemple #22
0
 def load_from_dict(self, data):
     self.timerange_version = Ver(data['timerange_version'])
     self.time_start = data['time_start']
     self.time_stop = data['time_stop']
Exemple #23
0
class Station(object):
    """
        STATION contains all the relevant details and interfaces to run
        trials from a particular station. This is an abstract class.
        Do not instantiate.
        stationID       : numeric ID
        stationPath     : string path to data storage location
        MACAddress      : unique mac address for the processor/ethernet
                          card. string identifier
    """
    _subject = None
    _key_pressed = []
    _sounds = {}
    _stims = {}
    _clocks = {}
    _parallel_port_conn = None
    creation_time = ''
    station_version = Ver('0.0.1')
    station_id = None
    station_name = ''
    station_path = ''
    station_location = None

    def __init__(self, **kwargs):
        if not kwargs:
            pass
        elif 'data' in kwargs:
            self = self.load_from_dict(kwargs['data'])
        else:
            pass

    def load_from_dict(self, data):
        self.station_version = Ver(data['station_version'])
        self.creation_time = datetime.datetime.strptime(
            data['creation_time'], DATETIME_TO_STR)
        self.station_id = data['station_id']
        self.station_name = data['station_name']
        self.station_path = os.path.join(get_base_path(), 'BCoreData',
                                         'StationData', str(self.station_id))
        self.station_location = data['station_location']

        self.mac_address = get_mac_address()
        self.ip_address = get_ip_addr()
        self.port = get_port()
        return self

    def save_to_dict(self):
        data = dict()
        data['station_version'] = self.station_version.__str__()
        data['station_id'] = self.station_id
        data['station_name'] = self.station_name
        data['station_location'] = self.station_location
        data['creation_time'] = datetime.datetime.strftime(
            self.creation_time, DATETIME_TO_STR)
        return data

    def __repr__(self):
        return "Station object with id:%s, location:%s and ip:%s" % (
            self.station_id, self.station_location, self.ip_address)

    def register(self):
        #
        pass

    def _setup_paths(self):
        if not os.path.isdir(self.station_path):
            os.makedirs(self.station_path)

    def do_trials(self, **kwargs):
        raise NotImplementedError('Run doTrials() on a subclass')

    def initialize_sounds(self):
        self._sounds['trial_start_sound'] = psychopy.sound.Sound(440,
                                                                 stereo=0,
                                                                 secs=1.,
                                                                 hamming=True)

        self._sounds['request_sound'] = psychopy.sound.Sound(493.88,
                                                             stereo=0,
                                                             secs=1.,
                                                             hamming=True)
        self._sounds['stim_start_sound'] = psychopy.sound.Sound(493.88,
                                                                stereo=0,
                                                                secs=1.,
                                                                hamming=True)
        self._sounds['go_sound'] = psychopy.sound.Sound(493.88,
                                                        stereo=0,
                                                        secs=1.,
                                                        hamming=True)
        self._sounds['keep_going_sound'] = psychopy.sound.Sound(493.88,
                                                                stereo=0,
                                                                secs=1.,
                                                                hamming=True)
        self._sounds['request_sound'] = psychopy.sound.Sound(493.88,
                                                             stereo=0,
                                                             secs=1.,
                                                             hamming=True)

        self._sounds['correct_sound'] = psychopy.sound.Sound(523.25,
                                                             stereo=0,
                                                             secs=1.,
                                                             hamming=True)
        self._sounds['reward_sound'] = psychopy.sound.Sound(523.25,
                                                            stereo=0,
                                                            secs=1.,
                                                            hamming=True)
        self._sounds['trial_end_sound'] = psychopy.sound.Sound(523.25,
                                                               stereo=0,
                                                               secs=1.,
                                                               hamming=True)

        sampleRate, secs, f_punishment = (44100, 2, [370, 440])
        nSamples = int(secs * sampleRate)
        phase = 2 * np.pi * np.linspace(0.0, 1.0, nSamples)
        val = np.full_like(phase, 0.)
        for f in f_punishment:
            val += np.sin(f * phase)
        val = np.matlib.repmat(val, 2, 1)
        self._sounds['punishment_sound'] = psychopy.sound.Sound(val.T,
                                                                hamming=True)

        val = 0.5 * np.random.randn(1, nSamples)
        val = np.matlib.repmat(val, 2, 1)
        self._sounds['try_something_else'] = psychopy.sound.Sound(val.T,
                                                                  hamming=True)

        self._sounds['trial_end_sound'] = psychopy.sound.Sound(587.33,
                                                               stereo=0,
                                                               secs=1.,
                                                               hamming=True)

    def _rewind_sounds(self, time=0.):
        for sound in self._sounds:
            self._sounds[sound].seek(time)

    def decache(self):
        """
            Remove session specific details. ideal for pickling
        """
        self._key_pressed = None
        self._sounds = None
        self._stims = None
        self._clocks = None
Exemple #24
0
 def load_from_dict(self, data):
     self.minutespersession_version = Ver(data['minutespersession_version'])
     self.minutes = data['minutes']
     self.hours_between_sessions = data['hours_between_sessions']
Exemple #25
0
class StandardVisionBehaviorStation(Station):
    """
        STANDARDVISIONBEHAVIORSTATION(SVBS) defines a subclass of STATION.
        It defines a station with a standard display, a parallel port for i/o
        with standard pin-out settings, sounds settings which can only be
        turned on or off, three valve pins, three sensor pins. Only allows
        stand alone running
        Attributes allowed are:
            station_id       : numeric ID to be sent to STATION
            station_path     : DO NOT SEND - STATION WILL SET IT
            display          : dictionary containing details about the
                               display unit
            soundOn          : True/False
            parallelPort     : dictionary containing details about the parallel
                               port

        For the StandardVisualBehaviorStation, with Rev 2/3 breakout boards
        ("The Bomb"), only certain ports are used and for specific purposes:
            Pin 2            :            Right Reward Valve
            Pin 3            :            Center Reward Valve
            Pin 4            :            Left Reward Valve
            Pin 5            :            LED1
            Pin 6            :            eyePuff
            Pin 7            :            LED2
            Pin 8            :            indexPulse
            Pin 9            :            framePulse
            Pin 10           :            Center Response Sensor
            Pin 12           :            Right Response Sensor
            Pin 13           :            Left Response Sensor
        While, these values are not hard coded here, use these values if you
        want your system to work :)

        Use these defaults unless you know what you are doing
        parallel_port = {}
        parallel_port['right_valve'] = 2
        parallel_port['center_valve'] = 3
        parallel_port['left_valve'] = 4
        parallel_port['valve_pins'] = (2, 3, 4)
        parallel_port['center_port'] = 10
        parallel_port['right_port'] = 12
        parallel_port['left_port'] = 13
        parallel_port['port_pins'] = (12, 10, 13)
        parallel_port['index_pin'] = 8
        parallel_port['frame_pin'] = 9
        parallel_port['led_0'] = 5
        parallel_port['led_1'] = 7
    """
    _window = None
    _session = None
    _server_conn = None

    svbstation_version = Ver('0.0.1')
    sound_on = False
    io_type = ''
    parallel_port = None
    parallel_port_address = ''
    display_name = ''
    display_type = ''
    display = None

    def __init__(self, **kwargs):
        super(StandardVisionBehaviorStation, self).__init__(**kwargs)
        if not kwargs:
            pass
        elif 'data' in kwargs:
            self = self.load_from_dict(kwargs['data]'])
        else:
            pass
        self.display = self.get_display()
        self.parallel_port = self.get_parport_mappings()

    def load_from_dict(self, data):
        self.svbstation_version = Ver(data['svbstation_version'])
        self.sound_on = data['sound_on']
        self.io_type = data['io_type']
        self.parallel_port = data['parallel_port']
        self.parallel_port_address = data['parallel_port_address']
        self.display_name = data['display_name']
        self.display_type = data['display_type']
        return self

    def save_to_dict(self):
        data = super(StandardVisionBehaviorStation, self).save_to_dict()
        data['svbstation_version'] = self.svbstation_version
        data['sound_on'] = self.sound_on
        data['io_type'] = self.io_type
        data['parallel_port'] = self.parallel_port
        data['parallel_port_address'] = self.parallel_port_address
        data['display_name'] = self.display_name
        data['display_type'] = self.display_type
        return data

    def __repr__(self):
        return "StandardVisionBehaviorStation object with id:%s, location:%s and ip:%s" % (
            self.station_id, self.station_location, self.ip_address)

    def get_display(self):
        return displays.StandardDisplay()

    def get_parport_mappings(self):
        if self.parallel_port == 'standardVisionBehaviorDefault':
            print(
                'STANDARDVISIONBEHAVIORSTATION:INITIALIZE_PARALLEL_PORT::setting parallelport to standardVisionBehaviorDefault'
            )
            pPort = {}
            pPort['right_valve'] = 2
            pPort['center_valve'] = 3
            pPort['left_valve'] = 4
            pPort['valve_pins'] = [2, 3, 4]
            pPort['center_port'] = 10
            pPort['right_port'] = 12
            pPort['left_port'] = 13
            pPort['port_pins'] = [13, 10, 12]
            pPort['index_pin'] = 8
            pPort['frame_pin'] = 9
            pPort['trial_pin'] = 6
            pPort['led_0'] = 5
            pPort['led_1'] = 7
            return pPort
        elif self.parallel_port == 'standardHeadfixBehaviorDefault':
            print(
                'STANDARDVISIONBEHAVIORSTATION:INITIALIZE_PARALLEL_PORT::setting parallelport to standardVisionHeadfixDefault'
            )
            pPort = {}
            pPort['reward_valve'] = 3
            pPort['valve_pins'] = [
                3,
            ]
            pPort['response_port'] = 10
            pPort['running_port'] = 13
            pPort['port_pins'] = [
                10,
            ]
            pPort['index_pin'] = 8
            pPort['frame_pin'] = 9
            pPort['trial_pin'] = 6
            pPort['led_0'] = 5
            pPort['led_1'] = 7
            return pPort
        else:
            return None  # need to write code that checks if allowable

    def initialize(self):
        self.initialize_display(display=self.display)
        self.initialize_sounds()
        self.initialize_parallel_port()
        self.close_all_valves()

    def run(self):
        self.connect_to_server()
        run_trials = False
        while True:
            # look for data from server
            msg = self.get_server_msg()
            quit = False
            if run_trials and ~quit:
                # get info anout session
                self.get_session()

                sub = self._session['subject']
                tR = self._session['trial_record']
                cR = self._session['compiled_record']
                prot = self._session['protocol']
                trial_num = self._session['trial_num']

    def initialize_display(self, display=displays.StandardDisplay()):
        self._window = psychopy.visual.Window(color=(0., 0., 0.),
                                              fullscr=True,
                                              winType='pyglet',
                                              allowGUI=False,
                                              units='deg',
                                              screen=0,
                                              viewScale=None,
                                              waitBlanking=True,
                                              allowStencil=True,
                                              monitor=display)
        self._window.flip()

    def initialize_parallel_port(self):
        self._parallel_port_conn = psychopy.parallel.ParallelPort(
            address=self.parallel_port_address)
        self.close_all_valves()

    def connect_to_server(self):
        """
            This is a somewhat complicated handshake. Initially, the
            station acts as a server exposing its IP::port to the server.
            Since the server knows this IP::port it can create a client
            connection easily. Upon connection, BServer(currently client)
            sends a connection info for a separate connection(BServer will
            reserve the space for this connection) to the station and the
            station will connect to the BServer now as a client. This way
            new stations can be added to the server without any
            station-side code modification. BServer can dynamically manage
            its resources. Along with threaded TCP server connections on
            the server side, this should provide scalable, TCP communications
            with the server
        """
        self._server_conn = TCPServerConnection(ipaddr=self.ip_address,
                                                port=self.port)
        self._server_conn.start()
        server_connection_details = self._server_conn.recvData()
        # use server_connection_details to connect to the BServer as a client
        print(
            'STANDARDVISIONBEHAVIORSTATION:CONNECT_TO_SERVER::Closing connection as server...'
        )
        self._server_conn.stop()
        self._server_conn = BehaviorClientConnection(
            ipaddr=server_connection_details['ipaddr'],
            port=server_connection_details['port'])
        print(
            'STANDARDVISIONBEHAVIORSTATION:CONNECT_TO_SERVER::Starting connection as client...'
        )
        self._server_conn.start()

    @property
    def subject(self):
        return self._subject

    @subject.setter
    def subject(self, value):
        self._subject = value

    @property
    def session(self):
        return self._session

    @session.setter
    def session(self, value):
        self._session = value

    def get_ports(self):
        return np.asarray(['left_port', 'center_port', 'right_port'])

    @property
    def num_ports(self):
        if self.parallel_port:
            return len(self.parallel_port['port_pins'])
        else:
            return 0

    def add_subject(self, sub):
        self.subject = sub
        #if sub.subject_id in self.get_subjects():
        #    RuntimeError("STATION:STANDARDVISIONBEHAVIORSTATION:ADD_SUBJECT:Subject "+ sub.subject_id + " already in station. Cannot add twice")
        #
        #print("STATION:STANDARDVISIONBEHAVIORSTATION:ADD_SUBJECT: Adding subject_id " + sub.subject_id +" to station_id " + str(self.station_id))
        #self.subjects.append(sub)

    def remove_subject(self, sub):
        self.subject = None
        #if sub.subject_id not in self.get_subjects():
        #    RuntimeError("STATION:STANDARDVISIONBEHAVIORSTATION:ADD_SUBJECT:Subject "+ sub.subject_id + " not in station. Cannot remove.")
        #print("STATION:STANDARDVISIONBEHAVIORSTATION:REMOVE_SUBJECT: Removing subject_id " + sub.subject_id +" from station_id " + str(self.station_id))
        #idx = [i for (i,x) in enumerate(self.get_subjects()) if x==sub.subject_id]
        #self.subjects = self.subjects[:idx[0]]+self.subjects[idx[0]+1:]

    def close_all_valves(self):
        val = list('{0:08b}'.format(self._parallel_port_conn.readData()))
        for valve in self.parallel_port['valve_pins']:
            val[1 - valve] = '0'
        self._parallel_port_conn.setData(int(''.join(val), 2))

    def read_ports(self):
        out = [False, False, False]
        port_names = ['left_port', 'center_port', 'right_port']
        for i, port in enumerate(self.parallel_port['port_pins']):
            out[i] = self._parallel_port_conn.readPin(port)
        active_ports = [x for x, y in zip(port_names, out) if not y]
        return active_ports

    def open_valve(self, valve):
        valve_pin = self.parallel_port[valve]
        self.set_pin_on(valve_pin)

    def close_valve(self, valve):
        valve_pin = self.parallel_port[valve]
        self.set_pin_off(valve_pin)

    def flush_valves(self, dur=1):
        val = list('{0:08b}'.format(self._parallel_port_conn.readData()))
        for valve in self.parallel_port['valve_pins']:
            val[1 - valve] = '1'
        self._parallel_port_conn.setData(int(''.join(val), 2))

        time.sleep(dur)

        for valve in self.parallel_port['valve_pins']:
            val[1 - valve] = '0'
        self._parallel_port_conn.setData(int(''.join(val), 2))

    def set_index_pin_on(self):
        index_pin = self.parallel_port['index_pin']
        self.set_pin_on(index_pin)

    def set_index_pin_off(self):
        index_pin = self.parallel_port['index_pin']
        self.set_pin_off(index_pin)

    def set_frame_pin_on(self):
        frame_pin = self.parallel_port['frame_pin']
        self.set_pin_on(frame_pin)

    def set_frame_pin_off(self):
        frame_pin = self.parallel_port['frame_pin']
        self.set_pin_off(frame_pin)

    def set_trial_pin_on(self):
        trial_pin = self.parallel_port['trial_pin']
        self.set_pin_on(trial_pin)

    def set_trial_pin_off(self):
        trial_pin = self.parallel_port['trial_pin']
        self.set_pin_off(trial_pin)

    def set_pin_on(self, pin):
        if pin < 2 or pin > 9:
            ValueError('Cannot deal with this')
        val = list('{0:08b}'.format(self._parallel_port_conn.readData()))
        val[1 - pin] = '1'
        self._parallel_port_conn.setData(int(''.join(val), 2))

    def set_pin_off(self, pin):
        if pin < 2 or pin > 9:
            ValueError('Cannot deal with this')
        val = list('{0:08b}'.format(self._parallel_port_conn.readData()))
        val[1 - pin] = '0'
        self._parallel_port_conn.setData(int(''.join(val), 2))

    def get_display_size(self):
        pass

    def get_session(self):
        """
            Connect to BServer and request session details to be loaded
        """
        self._session = self._server_conn.client_to_server(
            self._server_conn.SESSION_REQUESTED)

    def decache(self):
        """
            Remove session specific details. ideal for pickling
        """
        self._window = None
        self._session = None
        self._server_conn = None
        self._parallel_port_conn = None
        self._clocks = None

    def do_trials(self, **kwargs):
        # first step in the running of trials. called directly by station
        # or through the BServer
        if __debug__:
            pass
        self.initialize()
        # get the compiled_records for the animal. Compiled records will contain all the information that will be used in
        # the course of running the experiment. If some stimulus parameter for a given trial is dependent on something in
        # the previous trial, please add it to compiled records
        compiled_record = self.subject.load_compiled_records()
        quit = False

        # session starts here
        session_record = []  # just a list of tRs
        session_number = compiled_record["session_number"][-1] + 1

        # setup the clocks
        self._clocks['session_clock'] = psychopy.core.MonotonicClock()
        self._clocks['trial_clock'] = psychopy.core.Clock()
        session_start_time = psychopy.core.getAbsTime()

        while not quit:
            # it loops in here every trial
            trial_record = {}
            # just assign relevant details here
            trial_record["session_start_time"] = session_start_time
            trial_record[
                "trial_number"] = compiled_record["trial_number"][-1] + 1
            trial_record["session_number"] = session_number
            trial_record["station_id"] = self.station_id
            trial_record["station_version_number"] = self.ver.__str__()
            trial_record["station_name"] = self.station_name
            trial_record["num_ports_in_station"] = self.num_ports
            trial_record["trial_start_time"] = self._clocks[
                'session_clock'].getTime()
            # doTrial - only trial_record will be returned as its type will be changed
            trial_record, quit = self.subject.do_trial(
                station=self,
                trial_record=trial_record,
                compiled_record=compiled_record,
                quit=quit)

            trial_record["trial_stop_time"] = self._clocks[
                'session_clock'].getTime()
            # update sessionRecord and compiledRecord
            compiled_record = compile_records(compiled_record, trial_record)
            session_record.append(trial_record)

        # save session records
        self.subject.save_session_records(session_record)
        # save compiled records
        self.subject.save_compiled_records(compiled_record)

        self.decache()

    def close_session(self, **kwargs):
        print("STANDARDVISIONBEHAVIORSTATION:CLOSE_SESSION::Closing Session")

    def close_window(self):
        self._window.close()

    def check_manual_quit(self):
        key = psychopy.event.getKeys(keyList=['k', 'q'])
        if key:
            if not key[0] in self._key_pressed:
                self._key_pressed.append(key[0])
        if 'k' in self._key_pressed and 'q' in self._key_pressed:
            psychopy.event.clearEvents()
            return True
        else:
            return False

    def read_kb(self):
        key, modifier = event.getKeys(keyList=['1', '2', '3', 'k'],
                                      modifier=True)
        ports = np.asarray([False, False, False])
        if key:
            if not key[0] in self._key_pressed:
                self._key_pressed.append(key[0])
        if 'k' in self._key_pressed and '1' in self._key_pressed:
            self._key_pressed.remove('k')
            self._key_pressed.remove('1')
        if 'k' in self._key_pressed and '2' in self._key_pressed:
            ports = np.bitwise_or(ports, [False, True, False])
            psychopy.event.clearEvents()
            print(self._key_pressed)
            self._key_pressed.remove('k')
            self._key_pressed.remove('2')
        if 'k' in self._key_pressed and '3' in self._key_pressed:
            ports = np.bitwise_or(ports, [False, False, True])
            psychopy.event.clearEvents()
            print(self._key_pressed)
            self._key_pressed.remove('k')
            self._key_pressed.remove('3')

        return self.get_ports()[ports]
Exemple #26
0
 def __init__(self, name='Unknown'):
     self.name = name
     self.ver = Ver('0.0.1')
Exemple #27
0
class StandardVisionHeadfixStation(StandardVisionBehaviorStation):
    """
        STANDARDVISIONHEADFIXSTATION(SVHS) defines a subclass of SVBS.
        It defines a station with a standard display, a parallel port for i/o
        with standard pin-out settings, sounds settings which can only be
        turned on or off, one valve pins, one sensor pins. Only allows
        stand alone running
        Attributes allowed are:
            station_id       : numeric ID to be sent to STATION
            station_path     : DO NOT SEND - STATION WILL SET IT
            display          : dictionary containing details about the
                               display unit
            soundOn          : True/False
            parallelPort     : dictionary containing details about the parallel
                               port

        For the StandardVisualBehaviorStation, with Rev 2/3 breakout boards
        ("The Bomb"), only certain ports are used and for specific purposes:
            Pin 3            :            Center Reward Valve
            Pin 8            :            indexPulse
            Pin 9            :            framePulse
            Pin 10           :            Center Response Sensor
        While, these values are not hard coded here, use these values if you
        want your system to work :)

        Use these defaults unless you know what you are doing
        parallel_port = {}
        parallel_port['center_valve'] = 3
        parallel_port['valve_pins'] = (3)
        parallel_port['center_port'] = 10
        parallel_port['port_pins'] = (10)
        parallel_port['index_pin'] = 8
        parallel_port['frame_pin'] = 9
        parallel_port['led_0'] = 5
        parallel_port['led_1'] = 7
    """

    svhfstation_version = Ver('0.0.1')

    def __init__(self, **kwargs):
        super(StandardVisionHeadfixStation, self).__init__(**kwargs)
        if not kwargs:
            pass
        elif 'data' in kwargs:
            self = self.load_from_dict(kwargs['data]'])
        else:
            pass

    def load_from_dict(self, data):
        self.svhfstation_version = Ver(data['svhfstation_version'])
        return self

    def save_to_dict(self):
        data = super(StandardVisionHeadfixStation, self).save_to_dict()
        data['svhfstation_version'] = self.svhfstation_version
        return data

    def __repr__(self):
        return "StandardVisionHeadfixStation object with id:%s, location:%s and ip:%s" % (
            self.station_id, self.station_location, self.ip_address)

    def get_ports(self):
        return np.asarray(['response_port'])

    def read_ports(self):
        port_names = ['response_port']
        if self._parallel_port_conn.readPin(
                self.parallel_port['port_pins'][0]):
            return []  # when the lick port is high then it is empty.
        else:
            return ['response_port'
                    ]  # when the lick port is low, then there is licking

    def open_valve(self, valve):
        valve_pin = self.parallel_port[valve]
        self.set_pin_on(valve_pin)

    def close_valve(self, valve):
        valve_pin = self.parallel_port[valve]
        self.set_pin_off(valve_pin)

    def close_all_valves(self):
        self.close_valve('reward_valve')
Exemple #28
0
 def __init__(self, name='Unknown'):
     self.ver = Ver('0.0.1')
     super(RepeatIndefinitely, self).__init__(name)
Exemple #29
0
 def load_from_dict(self, data):
     self.skstation_version = Ver(data['skstation_version'])
     return self
Exemple #30
0
 def __init__(self, name, trial_manager, session_manager, criterion):
     self.ver = Ver('0.0.1')
     self.name = name
     self.trial_manager = trial_manager
     self.session_manager = session_manager
     self.criterion = criterion