# !/usr/bin/python3
# -*- coding: utf-8 -*-
import logging
from pybpodapi.bpod.hardware.channels import Channels
logger = logging.getLogger(__name__)
[docs]class Hardware(object):
"""
Represents an hardware description based on information received from the current connected Bpod deviced.
"""
DEFAULT_FREQUENCY_DIVIDER = 1000000
def __init__(self):
self.inputs = None
self.outputs = None
self.channels = None
self.max_states = None
self.max_serial_events = None
self.inputs_enabled = None
self.cycle_period = None
self.n_global_timers = None
self.n_global_counters = None
self.n_conditions = None
self.n_uart_channels = None
self.firmware_version = None
self.machine_type = None
self.live_timestamps = True # The state machine will end timestamps during the execution
self.pos_global_timer_trig = 0
##################################################
#################### METHODS #####################
##################################################
[docs] def setup(self, modules):
"""
Set up hardware based on hardware description obtained from Bpod device
:param HardwareInfoContainer hw_info_container: hardware parameters received from Bpod
"""
self.outputs = self.outputs # + ['G', 'G', 'G']
self.n_uart_channels = len([idx for idx in self.inputs if idx == 'U'])
# set up channels
self.channels = Channels() # type: Channels
self.channels.setup_input_channels(self, modules)
self.channels.setup_output_channels(self.outputs, self)
logger.debug(self.channels)
logger.debug(str(self))
def __str__(self):
return "Hardware Configuration\n" \
"Max states: {max_states}\n" \
"Cycle period: {cycle_period}\n" \
"Cycle frequency: {cycle_frequency}\n" \
"Number of events per serial channel: {max_serial_events}\n" \
"Number of global timers: {n_global_timers}\n" \
"Number of global counters: {n_global_counters}\n" \
"Number of conditions: {n_conditions}\n" \
"Inputs ({n_inputs}): {inputs}\n" \
"Outputs ({n_outputs}): {outputs}\n" \
"Enabled inputs ({n_inputs_enabled}): {inputs_enabled}\n" \
"".format(max_states=self.max_states,
cycle_period=self.cycle_period,
cycle_frequency=self.cycle_frequency,
max_serial_events=self.max_serial_events,
n_global_timers=self.n_global_timers,
n_global_counters=self.n_global_counters,
n_conditions=self.n_conditions,
inputs=self.inputs,
n_inputs=len(self.inputs),
outputs=self.outputs,
n_outputs=len(self.outputs),
inputs_enabled=self.inputs_enabled,
n_inputs_enabled=len([idx for idx in self.inputs_enabled if idx == 1]))
##################################################
#################### PROPERTIES ##################
##################################################
@property
def cycle_frequency(self):
return int(self.DEFAULT_FREQUENCY_DIVIDER / self.cycle_period)
@property
def times_scale_factor(self):
return float(self.cycle_period) / float(self.DEFAULT_FREQUENCY_DIVIDER)
@property
def bnc_inputports_indexes(self):
return [i for i, input_type in enumerate(self.inputs) if input_type == 'B']
@property
def wired_inputports_indexes(self): return [i for i, input_type in enumerate(self.inputs) if input_type == 'W']
@property
def behavior_inputports_indexes(self): return [i for i, input_type in enumerate(self.inputs) if input_type == 'P']
@property
def bnc_inputports_names(self): return ['BNC{0}'.format(i) for i, input_type in enumerate(self.inputs) if input_type == 'B']
@property
def wired_inputports_names(self): return ['Wire{0}'.format(i) for i, input_type in enumerate(self.inputs) if input_type == 'W']
@property
def behavior_inputports_names(self): return ['Port{0}'.format(i) for i, input_type in enumerate(self.inputs) if input_type == 'P']