class GUI(object):
    """
    simple gui to demostrate live inejction of the spike io script.
    """

    def __init__(self, n_neurons):
        """
        creates the gui
        :return:
        """
        self._started = False
        # Set up the live connection for sending and receiving spikes
        self.live_spikes_connection = SpynnakerLiveSpikesConnection(
            receive_labels=None, local_port=19996,
            send_labels=["spike_injector_forward", "spike_injector_backward"])

        # Set up callbacks to occur at the start of simulation
        self.live_spikes_connection.add_start_callback(
            "spike_injector_forward", self.send_input_forward)
        root = tk.Tk()
        root.title("Injecting Spikes GUI")
        label = tk.Label(root, fg="dark green")
        label.pack()
        neuron_id_value = tk.IntVar()
        self.neuron_id = tk.Spinbox(
            root, from_=0, to=n_neurons - 1, textvariable=neuron_id_value)
        self.neuron_id.pack()
        pop_label_value = tk.StringVar()
        self.pop_label = tk.Spinbox(
            root, textvariable=pop_label_value,
            values=("spike_injector_forward", "spike_injector_backward"))
        self.pop_label.pack()
        button = tk.Button(root, text='Inject', width=25,
                           command=self.inject_spike)
        button.pack()
        root.mainloop()

    # Create a sender of packets for the forward population
    def send_input_forward(self, pop_label, _):
        """
        records that stuff has started on the spinnaker machine
        :param pop_label: label
        :param _: dont care
        :return:
        """
        self._started = True

    # add a gui with a button and scroll list
    def inject_spike(self):
        """
        is set off when inject is pressed, takes the vlaues from the spin
        boxes and fires a spike in.
        :return:
        """
        print "injecting with neuron_id {} to pop {}".format(
            self.neuron_id.get(), self.pop_label.get())
        if self._started:
            self.live_spikes_connection.send_spike(str(self.pop_label.get()),
                                                   int(self.neuron_id.get()))
Пример #2
0
 def setupSpikeReceiver(self, network=None):
     print "\tSetting up Spike Receiver..."
     networkLabels = []
     for pop in network:
         ExternalDevices.activate_live_output_for(pop[1], database_notify_host="localhost", database_notify_port_num=19996)
         networkLabels.append(pop[1].label)
        
     liveConnection = SpynnakerLiveSpikesConnection(receive_labels=networkLabels, local_port=19996, send_labels=None)   
     
     for label in networkLabels:
         liveConnection.add_receive_callback(label, self.plotReceivedSpike)    
Пример #3
0
    def __init__(self, pop_labels):
        self._length_sender = SpynnakerLiveSpikesConnection(
            receive_labels=None, local_port=19999, send_labels=pop_labels)
        self._len = 0.95
        self._dlen = 0.0
        self._go_on = True

        for label in pop_labels:
            self._length_sender.add_start_callback(label,
                                                   self.send_input_spindle)

        self._count = 0
Пример #4
0
def setupSpikeInjectors(retinaLeft=None, retinaRight=None):
    print "Setting up Spike Injectors for Retina Left and Retina Right..."
    retinaLabels = []
    for popL, popR in zip(retinaLeft, retinaRight):
        retinaLabels.append(popL.label)
        retinaLabels.append(popR.label)
    
    liveConnection = SpynnakerLiveSpikesConnection(receive_labels=None, local_port=19999, send_labels=retinaLabels)
    
    from retinaSpikeInjector import startInjecting
    liveConnection.add_start_callback(retinaLabels[0], startInjecting)
    return liveConnection 
Пример #5
0
def setupSpikeReceiver(network=None):
    print "Setting up Spike Receiver..."
    networkLabels = []
    for pop in network:
        ExternalDevices.activate_live_output_for(pop[1], database_notify_host="localhost", database_notify_port_num=19996, board_address='10.162.177.122')
        networkLabels.append(pop[1].label)
        
    if not useCVisualiser:
        liveConnection = SpynnakerLiveSpikesConnection(receive_labels=networkLabels, local_port=19996, send_labels=None)   
    
    for label in networkLabels:
        liveConnection.add_receive_callback(label, receiveSpike)    
    return liveConnection       
class GUI(object):
    """ Simple gui to demostrate live inejction of the spike io script.
    """

    def __init__(self, n_neurons, ready):
        self._n_neurons = n_neurons

        # Set up the live connection for sending and receiving spikes
        self._live_spikes_connection = SpynnakerLiveSpikesConnection(
            receive_labels=None, local_port=19996,
            send_labels=["spike_injector_forward",
                         "spike_injector_backward"])

        # Set up callbacks to occur at the start of simulation
        self._live_spikes_connection.add_start_callback(
            "spike_injector_forward", self.start)

        self._root = tk.Tk()
        self._root.title("Injecting Spikes GUI")
        label = tk.Label(self._root, fg="dark green")
        label.pack()
        neuron_id_value = tk.IntVar()
        self._neuron_id = tk.Spinbox(
            self._root, from_=0, to=self._n_neurons - 1,
            textvariable=neuron_id_value)
        self._neuron_id.pack()
        pop_label_value = tk.StringVar()
        self._pop_label = tk.Spinbox(
            self._root, textvariable=pop_label_value,
            values=("spike_injector_forward", "spike_injector_backward"))
        self._pop_label.pack()
        self._button = tk.Button(
            self._root, text='Inject', width=25, command=self.inject_spike,
            state="disabled")
        self._button.pack()

        ready.set()

        self._root.mainloop()

    def start(self, pop_label, connection):
        self._button["state"] = "normal"

    def inject_spike(self):
        neuron_id = int(self._neuron_id.get())
        label = str(self._pop_label.get())
        print "injecting with neuron_id {} to pop {}".format(neuron_id, label)
        self._live_spikes_connection.send_spike(label, neuron_id)
    def __init__(self, n_neurons):
        """
        creates the gui
        :return:
        """
        self._started = False
        # Set up the live connection for sending and receiving spikes
        self.live_spikes_connection = SpynnakerLiveSpikesConnection(
            receive_labels=None, local_port=19996,
            send_labels=["spike_injector_forward", "spike_injector_backward"])

        # Set up callbacks to occur at the start of simulation
        self.live_spikes_connection.add_start_callback(
            "spike_injector_forward", self.send_input_forward)
        root = tk.Tk()
        root.title("Injecting Spikes GUI")
        label = tk.Label(root, fg="dark green")
        label.pack()
        neuron_id_value = tk.IntVar()
        self.neuron_id = tk.Spinbox(
            root, from_=0, to=n_neurons - 1, textvariable=neuron_id_value)
        self.neuron_id.pack()
        pop_label_value = tk.StringVar()
        self.pop_label = tk.Spinbox(
            root, textvariable=pop_label_value,
            values=("spike_injector_forward", "spike_injector_backward"))
        self.pop_label.pack()
        button = tk.Button(root, text='Inject', width=25,
                           command=self.inject_spike)
        button.pack()
        root.mainloop()
    def __init__(self, n_neurons, ready):
        self._n_neurons = n_neurons

        # Set up the live connection for sending and receiving spikes
        self._live_spikes_connection = SpynnakerLiveSpikesConnection(
            receive_labels=None, local_port=19996,
            send_labels=["spike_injector_forward",
                         "spike_injector_backward"])

        # Set up callbacks to occur at the start of simulation
        self._live_spikes_connection.add_start_callback(
            "spike_injector_forward", self.start)

        self._root = tk.Tk()
        self._root.title("Injecting Spikes GUI")
        label = tk.Label(self._root, fg="dark green")
        label.pack()
        neuron_id_value = tk.IntVar()
        self._neuron_id = tk.Spinbox(
            self._root, from_=0, to=self._n_neurons - 1,
            textvariable=neuron_id_value)
        self._neuron_id.pack()
        pop_label_value = tk.StringVar()
        self._pop_label = tk.Spinbox(
            self._root, textvariable=pop_label_value,
            values=("spike_injector_forward", "spike_injector_backward"))
        self._pop_label.pack()
        self._button = tk.Button(
            self._root, text='Inject', width=25, command=self.inject_spike,
            state="disabled")
        self._button.pack()

        ready.set()

        self._root.mainloop()
Пример #9
0
class SpindleLengthSender(object):
    def __init__(self, pop_labels):
        self._length_sender = SpynnakerLiveSpikesConnection(
            receive_labels=None, local_port=19999, send_labels=pop_labels)
        self._len = 0.95
        self._dlen = 0.0
        self._go_on = True

        for label in pop_labels:
            self._length_sender.add_start_callback(label,
                                                   self.send_input_spindle)

        self._count = 0

    def len_to_intlist(self):
        l = list()
        l.append(int(math.trunc(self._len)))
        l.append(int((self._len - math.trunc(self._len)) * 1000))
        l.append(int(math.trunc(self._dlen)))
        l.append(int((self._dlen - math.trunc(self._dlen)) * 1000))
        return l

    def stop(self):
        self._go_on = False

    def generate_new_length(self):
        if self._count < 110:
            self._len = 0.95
            self._dlen = 0.0
        elif self._count < 220:
            self._len += (1.08 - 0.95) / 110
            self._dlen = (1.08 - 0.95) / 1.1
        else:
            self._len = 1.08
            self._dlen = 0.0
        self._count += 1

    def send_input_spindle(self, label, sender):
        while self._go_on:
            self.generate_new_length()
            sender.send_spikes(label, self.len_to_intlist())
            time.sleep(0.01)
    def __init__(self, n_neurons):
        """
        creates the gui
        :return:
        """
        self._started = False
        # Set up the live connection for sending and receiving spikes
        self.live_spikes_connection = SpynnakerLiveSpikesConnection(
            receive_labels=None,
            local_port=19996,
            send_labels=["spike_injector_forward", "spike_injector_backward"])

        # Set up callbacks to occur at the start of simulation
        self.live_spikes_connection.add_start_callback(
            "spike_injector_forward", self.send_input_forward)
        root = tk.Tk()
        root.title("Injecting Spikes GUI")
        label = tk.Label(root, fg="dark green")
        label.pack()
        neuron_id_value = tk.IntVar()
        self.neuron_id = tk.Spinbox(root,
                                    from_=0,
                                    to=n_neurons - 1,
                                    textvariable=neuron_id_value)
        self.neuron_id.pack()
        pop_label_value = tk.StringVar()
        self.pop_label = tk.Spinbox(root,
                                    textvariable=pop_label_value,
                                    values=("spike_injector_forward",
                                            "spike_injector_backward"))
        self.pop_label.pack()
        button = tk.Button(root,
                           text='Inject',
                           width=25,
                           command=self.inject_spike)
        button.pack()
        root.mainloop()
Пример #11
0
def setupVisualiser(network=None, retinaLeft=None, retinaRight=None):
    
    
    print "Setting up Visualiser..."
    global retinaThreads, disparityThread, logFile
    
    logFile = open("dipsarities.txt", 'w')
    
    print "\tSetting up Spike Receiver..."
    networkLabels = []
    for pop in network:
        ExternalDevices.activate_live_output_for(pop[1], database_notify_host="localhost", database_notify_port_num=19996)
        networkLabels.append(pop[1].label)
    
    liveConnection_receiver = SpynnakerLiveSpikesConnection(receive_labels=networkLabels, local_port=19996, send_labels=None) 
    
    disparityThread = spike_plotter()
    
    for label in networkLabels:
        liveConnection_receiver.add_receive_callback(label, disparityThread.plotReceivedSpike)
    
    disparityThread.start()
    
    print "\tSetting up Spike Injectors for Retina Left and Retina Right..."            
    retinaLabels = []
    for popL, popR in zip(retinaLeft, retinaRight):
        retinaLabels.append(popL[1].label)
        retinaLabels.append(popR[1].label)
      
    liveConnection_sender = SpynnakerLiveSpikesConnection(receive_labels=None, local_port=19999, send_labels=retinaLabels)
    bg_col=pygame.Color(230,230,230,0)
    on_col=pygame.Color(10,220,10,0)
    off_col=pygame.Color(220,10,10,0)
    retinaThreads[ports[0]] = dvs_reader(port=ports[0], colors = {"bg": bg_col, "on": on_col, "off": off_col}, label="RetL", liveConnection=liveConnection_sender)
    retinaThreads[ports[1]] = dvs_reader(port=ports[1], colors = {"bg": bg_col, "on": on_col, "off": off_col}, label="RetR", liveConnection=liveConnection_sender)
     
    liveConnection_sender.add_start_callback(retinaLabels[0], startInjecting)
    
    panelsDrawer = Thread(target=setupPanels)
    panelsDrawer.start()
# Activate the sending of live spikes
ExternalDevices.activate_live_output_for(pop_forward,
                                         database_notify_host="localhost",
                                         database_notify_port_num=19996)


# Create a sender of packets for the forward population
def send_input_forward(label, sender):
    print "Sending forward spike for neuron 0"
    sender.send_spike(label, 0)


# if not using the c visualiser, then a new spynnaker live spikes connection
# is created to define that there are python code which receives the
# outputted spikes.
live_spikes_connection = SpynnakerLiveSpikesConnection(
    local_port=19996, send_labels=["spike_injector_forward"])
# Set up callbacks to occur at the start of simulation
live_spikes_connection.add_start_callback("spike_injector_forward",
                                          send_input_forward)
# Run the simulation on spiNNaker
Frontend.run(run_time)
# Retrieve spikes from the synfire chain population
spikes_forward = pop_forward.getSpikes()
# If there are spikes, plot using matplotlib
if len(spikes_forward) != 0:
    pylab.figure()
    if len(spikes_forward) != 0:
        pylab.plot([i[1] for i in spikes_forward],
                   [i[0] for i in spikes_forward], "b.")
    pylab.ylabel('neuron id')
    pylab.xlabel('Time/ms')
    def __init__(self):

        # initial call to set up the front end (pynn requirement)
        Frontend.setup(timestep=1.0, min_delay=1.0, max_delay=144.0)

        use_c_visualiser = True
        use_spike_injector = True

        # neurons per population and the length of runtime in ms for the
        # simulation, as well as the expected weight each spike will contain
        self.n_neurons = 100

        # set up gui
        p = None
        if use_spike_injector:
            from multiprocessing import Process
            from multiprocessing import Event
            ready = Event()
            p = Process(target=GUI, args=[self.n_neurons, ready])
            p.start()
            ready.wait()

        # different runtimes for demostration purposes
        run_time = None
        if not use_c_visualiser and not use_spike_injector:
            run_time = 1000
        elif use_c_visualiser and not use_spike_injector:
            run_time = 10000
        elif use_c_visualiser and use_spike_injector:
            run_time = 100000
        elif not use_c_visualiser and use_spike_injector:
            run_time = 10000

        weight_to_spike = 2.0

        # neural parameters of the IF_curr model used to respond to injected
        # spikes.
        # (cell params for a synfire chain)
        cell_params_lif = {'cm': 0.25,
                           'i_offset': 0.0,
                           'tau_m': 20.0,
                           'tau_refrac': 2.0,
                           'tau_syn_E': 5.0,
                           'tau_syn_I': 5.0,
                           'v_reset': -70.0,
                           'v_rest': -65.0,
                           'v_thresh': -50.0
                           }

        ##################################
        # Parameters for the injector population.  This is the minimal set of
        # parameters required, which is for a set of spikes where the key is
        # not important.  Note that a virtual key *will* be assigned to the
        # population, and that spikes sent which do not match this virtual key
        # will be dropped; however, if spikes are sent using 16-bit keys, they
        # will automatically be made to match the virtual key.  The virtual
        # key assigned can be obtained from the database.
        ##################################
        cell_params_spike_injector = {

            # The port on which the spiNNaker machine should listen for
            # packets. Packets to be injected should be sent to this port on
            # the spiNNaker machine
            'port': 12345
        }

        ##################################
        # Parameters for the injector population.  Note that each injector
        # needs to be given a different port.  The virtual key is assigned
        # here, rather than being allocated later.  As with the above, spikes
        # injected need to match this key, and this will be done automatically
        # with 16-bit keys.
        ##################################
        cell_params_spike_injector_with_key = {

            # The port on which the spiNNaker machine should listen for
            # packets. Packets to be injected should be sent to this port on
            # the spiNNaker machine
            'port': 12346,

            # This is the base key to be used for the injection, which is used
            # to allow the keys to be routed around the spiNNaker machine.
            # This assignment means that 32-bit keys must have the high-order
            # 16-bit set to 0x7; This will automatically be prepended to
            # 16-bit keys.
            'virtual_key': 0x70000
        }

        # create synfire populations (if cur exp)
        pop_forward = Frontend.Population(
            self.n_neurons, Frontend.IF_curr_exp,
            cell_params_lif, label='pop_forward')
        pop_backward = Frontend.Population(
            self.n_neurons, Frontend.IF_curr_exp,
            cell_params_lif, label='pop_backward')

        # Create injection populations
        injector_forward = None
        injector_backward = None
        if use_spike_injector:
            injector_forward = Frontend.Population(
                self.n_neurons, ExternalDevices.SpikeInjector,
                cell_params_spike_injector_with_key,
                label='spike_injector_forward')
            injector_backward = Frontend.Population(
                self.n_neurons, ExternalDevices.SpikeInjector,
                cell_params_spike_injector, label='spike_injector_backward')
        else:
            spike_times = []
            for _ in range(0, self.n_neurons):
                spike_times.append([])
            spike_times[0] = [0]
            spike_times[20] = [(run_time / 100) * 20]
            spike_times[40] = [(run_time / 100) * 40]
            spike_times[60] = [(run_time / 100) * 60]
            spike_times[80] = [(run_time / 100) * 80]
            cell_params_forward = {'spike_times': spike_times}
            spike_times_backwards = []
            for _ in range(0, self.n_neurons):
                spike_times_backwards.append([])
            spike_times_backwards[0] = [(run_time / 100) * 80]
            spike_times_backwards[20] = [(run_time / 100) * 60]
            spike_times_backwards[40] = [(run_time / 100) * 40]
            spike_times_backwards[60] = [(run_time / 100) * 20]
            spike_times_backwards[80] = [0]
            cell_params_backward = {'spike_times': spike_times_backwards}
            injector_forward = Frontend.Population(
                self.n_neurons, Frontend.SpikeSourceArray,
                cell_params_forward,
                label='spike_injector_forward')
            injector_backward = Frontend.Population(
                self.n_neurons, Frontend.SpikeSourceArray,
                cell_params_backward, label='spike_injector_backward')

        # Create a connection from the injector into the populations
        Frontend.Projection(
            injector_forward, pop_forward,
            Frontend.OneToOneConnector(weights=weight_to_spike))
        Frontend.Projection(
            injector_backward, pop_backward,
            Frontend.OneToOneConnector(weights=weight_to_spike))

        # Synfire chain connections where each neuron is connected to its next
        # neuron
        # NOTE: there is no recurrent connection so that each chain stops once
        # it reaches the end
        loop_forward = list()
        loop_backward = list()
        for i in range(0, self.n_neurons - 1):
            loop_forward.append((i, (i + 1) %
                                 self.n_neurons, weight_to_spike, 3))
            loop_backward.append(((i + 1) %
                                  self.n_neurons, i, weight_to_spike, 3))
        Frontend.Projection(pop_forward, pop_forward,
                            Frontend.FromListConnector(loop_forward))
        Frontend.Projection(pop_backward, pop_backward,
                            Frontend.FromListConnector(loop_backward))

        # record spikes from the synfire chains so that we can read off valid
        # results in a safe way afterwards, and verify the behavior
        pop_forward.record()
        pop_backward.record()

        # Activate the sending of live spikes
        ExternalDevices.activate_live_output_for(
            pop_forward, database_notify_host="localhost",
            database_notify_port_num=19996)
        ExternalDevices.activate_live_output_for(
            pop_backward, database_notify_host="localhost",
            database_notify_port_num=19996)

        if not use_c_visualiser:
            # if not using the c visualiser, then a new spynnaker live spikes
            # connection is created to define that there are python code which
            # receives the outputted spikes.
            live_spikes_connection_receive = SpynnakerLiveSpikesConnection(
                receive_labels=["pop_forward", "pop_backward"],
                local_port=19999, send_labels=None)

            # Set up callbacks to occur when spikes are received
            live_spikes_connection_receive.add_receive_callback(
                "pop_forward", receive_spikes)
            live_spikes_connection_receive.add_receive_callback(
                "pop_backward", receive_spikes)
        # Run the simulation on spiNNaker
        Frontend.run(run_time)

        # Retrieve spikes from the synfire chain population
        spikes_forward = pop_forward.getSpikes()
        spikes_backward = pop_backward.getSpikes()

        # If there are spikes, plot using matplotlib
        if len(spikes_forward) != 0 or len(spikes_backward) != 0:
            pylab.figure()
            if len(spikes_forward) != 0:
                pylab.plot([i[1] for i in spikes_forward],
                           [i[0] for i in spikes_forward], "b.")
            if len(spikes_backward) != 0:
                pylab.plot([i[1] for i in spikes_backward],
                           [i[0] for i in spikes_backward], "r.")
            pylab.ylabel('neuron id')
            pylab.xlabel('Time/ms')
            pylab.title('spikes')
            pylab.show()
        else:
            print "No spikes received"

        # Clear data structures on spiNNaker to leave the machine in a clean
        # state for future executions
        Frontend.end()
        if use_spike_injector:
            p.join()
Пример #14
0
class ExternalDvsEmulatorDevice(ReverseIpTagMultiCastSource,
                    AbstractProvidesOutgoingConstraints,
                    ):

    MODE_128 = "128"
    MODE_64 = "64"
    MODE_32 = "32"
    MODE_16 = "16"

    UP_POLARITY = "UP"
    DOWN_POLARITY = "DOWN"
    MERGED_POLARITY = "MERGED"
    RECTIFIED_POLARITY = "RECTIFIED_POLARITY"
    POLARITY_DICT = {UP_POLARITY: uint8(0),
                     DOWN_POLARITY: uint8(1),
                     MERGED_POLARITY: uint8(2),
                     RECTIFIED_POLARITY: uint8(3),
                     0: UP_POLARITY,
                     1: DOWN_POLARITY,
                     2: MERGED_POLARITY,
                     3: RECTIFIED_POLARITY}

    OUTPUT_RATE = "RATE"
    OUTPUT_TIME = "TIME"
    OUTPUT_TIME_BIN = "TIME_BIN"
    OUTPUT_TIME_BIN_THR = "TIME_BIN_THR"

    def __init__(self, n_neurons, machine_time_step, timescale_factor,
                 database_socket,
                 label, port=12345, virtual_key=None,
                 spikes_per_second=0, ring_buffer_sigma=None,
                 device_id=0, fps=60, mode="128", scale_img=True, polarity="MERGED",
                 inhibition = False, inh_area_width = 2,
                 threshold=12, adaptive_threshold = False,
                 min_threshold=6, max_threshold=168,
                 threshold_delta_down = 2, threshold_delta_up = 12,
                 output_type="TIME", num_bits_per_spike=4,
                 history_weight=0.99, save_spikes=None, run_time_ms=None,
                 local_port=19876):
        """
        :param device_id: int for webcam modes, or string for video file
        :param mode: The retina "mode"
        :param retina_key: The value of the top 16-bits of the key
        :param polarity: The "polarity" of the retina data
        :param machine_time_step: The time step of the simulation
        :param timescale_factor: The timescale factor of the simulation
        :param label: The label for the population
        :param n_neurons: The number of neurons in the population

        """
        fixed_n_neurons = n_neurons

        if mode == ExternalDvsEmulatorDevice.MODE_128 or \
           mode == ExternalDvsEmulatorDevice.MODE_64  or \
           mode == ExternalDvsEmulatorDevice.MODE_32  or \
           mode == ExternalDvsEmulatorDevice.MODE_16:
            self._out_res = int(mode)
            self._res_2x = self._out_res*2

        else:
            raise exceptions.SpynnakerException("the model does not "
                                                "recongise this mode")

        if (polarity == ExternalDvsEmulatorDevice.UP_POLARITY or
            polarity == ExternalDvsEmulatorDevice.DOWN_POLARITY or
            polarity == ExternalDvsEmulatorDevice.RECTIFIED_POLARITY):
            fixed_n_neurons = self._out_res**2
        else:
            fixed_n_neurons = 2*(self._out_res**2)

        if fixed_n_neurons != n_neurons and n_neurons is not None:
            logger.warn("The specified number of neurons for the DVS emulator"
                        " device has been ignored {} will be used instead"
                        .format(fixed_n_neurons))

        self._video_source = None
        self._device_id = device_id
        self._is_virtual_cam = False
        self._polarity = polarity
        self._polarity_n = ExternalDvsEmulatorDevice.POLARITY_DICT[polarity]
        self._global_max = int16(0)
        self._output_type = output_type

        self._raw_frame = None
        self._gray_frame = None
        self._tmp_frame = None

        self._ref_frame = 128*np.ones((self._out_res, self._out_res), dtype=int16)

        self._curr_frame = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._spikes_frame = np.zeros((self._out_res, self._out_res, 3), dtype=uint8)

        self._diff = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._abs_diff = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._spikes = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._adaptive_threshold = adaptive_threshold
        self._thresh_matrix = None
        if adaptive_threshold:
          self._thresh_matrix = np.zeros((self._out_res, self._out_res),
                                             dtype=int16)

        self._threshold_delta_down = int16(threshold_delta_down)
        self._threshold_delta_up = int16(threshold_delta_up)
        self._max_threshold = int16(max_threshold)
        self._min_threshold = int16(min_threshold)

        self._up_spikes = None
        self._down_spikes = None
        self._spikes_lists = None

        self._threshold = int16(threshold)

        self._data_shift = uint8(np.log2(self._out_res))
        self._up_down_shift = uint8(2*self._data_shift)
        self._data_mask = uint8(self._out_res - 1)


        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:
            self._num_bins = 8 #8-bit images don't need more
        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._num_bins = 6 #should be enough?
        else:
            self._num_bins = int(1000./fps)

        self._num_bits_per_spike = min(num_bits_per_spike, self._num_bins)

        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN or \
           self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._log2_table = gs.generate_log2_table(self._num_bits_per_spike, self._num_bins)
        else:
            self._log2_table = gs.generate_log2_table(self._num_bits_per_spike, 8) #stupid hack, compatibility issues


        self._scale_img = scale_img
        self._img_height = 0
        self._img_height_crop_u = 0
        self._img_height_crop_b = 0
        self._img_width = 0
        self._img_width_crop_l = 0
        self._img_width_crop_r = 0
        self._img_ratio = 0.
        self._img_scaled_width = 0
        self._scaled_width = 0
        self._fps = fps
        self._max_time_ms = 0
        self._time_per_frame = 0.

        self._time_per_spike_pack_ms = 0

        self._get_sizes = True
        self._scale_changed = False

        self._running = True

        self._label = label
        self._n_neurons = fixed_n_neurons
        self._local_port = local_port

        self._inh_area_width = inh_area_width
        self._inhibition = inhibition
        self._inh_coords = gs.generate_inh_coords(self._out_res,
                                               self._out_res,
                                               inh_area_width)

        self._history_weight = history_weight

        self._run_time_ms = run_time_ms
        ################################################################

        if spinn_version == "2015.005":
            ReverseIpTagMultiCastSource.__init__(self,
                n_neurons=self._n_neurons,
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                port=self._local_port,
                label=self._label,
                virtual_key=virtual_key)
        else:
            ReverseIpTagMultiCastSource.__init__(self,
                n_keys=self._n_neurons,
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                label=self._label,
                receive_port=self._local_port,
                virtual_key=virtual_key)

        AbstractProvidesOutgoingConstraints.__init__(self)

        print("number of neurons for webcam = %d"%self._n_neurons)

        self._live_conn = SpynnakerLiveSpikesConnection(send_labels = [self._label, ],
                                                        local_port = self._local_port)
        def init(label, n_neurons, run_time_ms, machine_timestep_ms):
            print("Sending %d neuron sources from %s"%(n_neurons, label))

        self._live_conn.add_init_callback(self._label, init)
        self._live_conn.add_start_callback(self._label, self.run)
        self._sender = None

        self._save_spikes = save_spikes


    def get_outgoing_edge_constraints(self, partitioned_edge, graph_mapper):
        constraints = ReverseIpTagMultiCastSource\
            .get_outgoing_edge_constraints(
                self, partitioned_edge, graph_mapper)
        constraints.append(KeyAllocatorContiguousRangeContraint())
        return constraints


    def get_number_of_mallocs_used_by_dsg(self, vertex_slice, in_edges):
        mallocs = \
            ReverseIpTagMultiCastSource.get_number_of_mallocs_used_by_dsg(
                self, vertex_slice, in_edges)
        if config.getboolean("SpecExecution", "specExecOnHost"):
            return 1
        else:
            return mallocs


    def __del__(self):

        self._running = False


    def stop(self):
        self.__del__()


    def run(self, label, sender):

        self._label = label
        self._sender = sender


        if self._run_time_ms is None:
            max_run_time_s = self.no_machine_time_steps/float(self.machine_time_step) - 0.5
        else:
            max_run_time_s = self._run_time_ms/1000.


        self.acquire_device()

        spike_queue = Queue()
        spike_emmision_proc = Process(target=self.send_spikes, args=(spike_queue,))
        spike_emmision_proc.start()

        img_queue = Queue()
        #~ spike_gen_proc = Process(target=self.process_frame, args=(img_queue,))
        spike_gen_proc = Process(target=self.process_frame, args=(img_queue, spike_queue))
        spike_gen_proc.start()

        grab_times = []
        start_time = 0.
        app_start_time = time.time()
        app_curr_time = time.time()
        first_frame = True
        frame_time = 0.
        while self._running:

            start_time = time.time()
            valid_frame = self.grab_frame()
            grab_times.append(time.time() - start_time)

            if not valid_frame:
                self._running = False

            # send the minimum difference value once to synchronize time-based
            # decoding on the receiver end
            if self._output_type != ExternalDvsEmulatorDevice.OUTPUT_RATE and \
               first_frame == True:

                first_frame = False
                self._curr_frame[:] = 128 + self._threshold + 1 #half range of vals + thresh + 1


            img_queue.put(self._curr_frame)

            app_curr_time = time.time()
            if app_curr_time - app_start_time > max_run_time_s:
              self._running = False
            frame_time = time.time() - start_time
            if frame_time < self._time_per_frame:
              time.sleep(self._time_per_frame - frame_time)

        print("webcam runtime ", app_curr_time - app_start_time)
        img_queue.put(None)
        spike_gen_proc.join()

        spike_queue.put(None)
        spike_emmision_proc.join()

        if self._video_source is not None:
            self._video_source.release()
            cv2.destroyAllWindows()


    def process_frame(self, img_queue, spike_queue):

        label = self._label
        spikes_frame = self._spikes_frame
        
        cv2.namedWindow (label)
        cv2.startWindowThread()
        
        res2x = self._res_2x
        spike_list = []
        # gen_times = []
        # compose_times = []
        # transform_times = []
        # ref_up_times = []
        lists = None
        while True:
            image = img_queue.get()

            if image is None or not self._running:
                break

            # start_time = time.time()
            self.generate_spikes(image)
            # gen_times.append(time.time()-start_time)

            # start_time = time.time()
            self.update_reference()
            # ref_up_times.append(time.time()-start_time)

            # start_time = time.time()
            lists = self.transform_spikes()
            # transform_times.append(time.time() - start_time)

            spike_queue.put(lists)

            if self._save_spikes is not None:
                spike_list.append(lists)

            # start_time = time.time()
            self.compose_output_frame()
            # compose_times.append(time.time()-start_time)


            cv2.imshow( label, cv2.resize(spikes_frame, (res2x, res2x)) )

            if cv2.waitKey(1) & 0xFF == ord('q'):#\
              #or not sender.isAlive():
              self._running = False
              break

            #continue

        # print("gen times")
        # print(np.array(gen_times).mean())
        # print("update ref times")
        # print(np.array(ref_up_times).mean())
        # print("transform times")
        # print(np.array(transform_times).mean())
        # print("compose times")
        # print(np.array(compose_times).mean())

        cv2.destroyAllWindows()
        cv2.waitKey(1)

        if self._save_spikes is not None:
            #print spike_list
            print("attempting to save spike_list")
            pickle.dump( spike_list, open(self._save_spikes, "wb") )


    def send_spikes(self, spike_queue):
        sender = self._sender
        while True:
            spikes = spike_queue.get()

            if spikes is None or not self._running:
                break

            self.emit_spikes(sender, spikes)




    def acquire_device(self):
        if isinstance(self._device_id, VirtualCam):
            self._video_source = self._device_id
            self._is_virtual_cam = True
        else:
            self._video_source = cv2.VideoCapture(self._device_id)

        if not self._video_source.isOpened():
            self._video_source.open()

        try:
            self._video_source.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
            self._video_source.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
        except:
            pass

        try:
            self._video_source.set(cv2.CAP_PROP_FPS, self._fps)
        except:
            self._fps = self._video_source.get(cv2.CAP_PROP_FPS)

        self._max_time_ms = int16((1./self._fps)*1000)
        self._time_per_frame = 1./self._fps

        self._time_per_spike_pack_ms = self.calculate_time_per_pack()




    def grab_frame(self):
        #~ start_time = time.time()
        if self._is_virtual_cam:
            valid_frame, self._curr_frame[:] = self._video_source.read(self._ref_frame)
            return True

        else:
            if self._raw_frame is None or self._scale_changed:
                valid_frame, self._raw_frame = self._video_source.read()
            else:
                valid_frame, self._raw_frame[:] = self._video_source.read()

            #~ end_time = time.time()
            #~ print("Time to capture frame = ", end_time - start_time)

            if not valid_frame:
              return False

            #~ start_time = time.time()
            if self._gray_frame is None or self._scale_changed:
                self._gray_frame = cv2.convertColor(self._raw_frame, cv2.COLOR_BGR2GRAY).astype(int16)
            else:
                self._gray_frame[:] = cv2.convertColor(self._raw_frame, cv2.COLOR_BGR2GRAY)
            #~ end_time = time.time()
            #~ print("Time to convert to grayscale = ", end_time - start_time)

            #~ start_time = time.time()
            if self._get_sizes or self._scale_changed:
                self._get_sizes = False
                self._scale_changed = False
                self._img_height, self._img_width = self._gray_frame.shape

                self._img_ratio = float(self._img_width)/float(self._img_height)
                self._img_scaled_width = int(float(self._out_res)*self._img_ratio)

                if self._scale_img:
                    diff = self._img_scaled_width - self._out_res
                    self._img_width_crop_l = diff//2
                    self._img_width_crop_r = self._img_width_crop_l + self._out_res
                else:
                    diff = self._img_width - self._out_res
                    self._img_width_crop_l = diff//2
                    self._img_width_crop_r = self._img_width_crop_l + self._out_res
                    diff = self._img_height - self._out_res
                    self._img_height_crop_u = diff//2
                    self._img_height_crop_b = self._img_height_crop_u + self._out_res

                self._tmp_frame = np.zeros((self._out_res, self._img_scaled_width))


            #~ end_time = time.time()
            #~ print("Time to calculate sizes = ", end_time - start_time)

            #~ start_time = time.time()
            if self._scale_img:
                self._tmp_frame[:] = cv2.resize(self._gray_frame, (self._img_scaled_width, self._out_res),
                                             interpolation=cv2.INTER_NN)

                self._curr_frame[:] = self._tmp_frame[:, self._img_width_crop_l: self._img_width_crop_r]
            else:
                self._curr_frame[:] = self._gray_frame[self._img_height_crop_u: self._img_height_crop_b,
                                                    self._img_width_crop_l:  self._img_width_crop_r]
            #~ end_time = time.time()
            #~ print("Time to scale frame = ", end_time - start_time)


        return True






    def emit_spikes(self, sender, lists):
        lbl     = self._label
        max_time_s = self._time_per_spike_pack_ms/1000.
        #~ lists   = self._spikes_lists
        send_spikes = sender.send_spikes

        #from generate_spikes.pyx (cython)
        if lists is not None:
          for spike_pack in lists:
            start_time = time.time()
            send_spikes(lbl, spike_pack, send_full_keys=False)
            elapsed_time = time.time() - start_time
            if elapsed_time < max_time_s:
              time.sleep(max_time_s - elapsed_time)



    def generate_spikes(self, image):
        self._curr_frame = image
        curr_frame = self._curr_frame

        #~ curr_frame = image
        ref_frame = self._ref_frame
        diff = self._diff
        abs_diff = self._abs_diff
        spikes = self._spikes
        img_w = self._out_res
        inh_w = self._inh_area_width
        inhibition = self._inhibition
        inh_coords = self._inh_coords
        threshold = self._threshold

        if self._adaptive_threshold:
            thresh_mat = self._thresh_matrix


            #all from generate_spikes.pyx (cython)
            diff[:], abs_diff[:], spikes[:] = gs.thresholded_difference_adpt(curr_frame, ref_frame,
                                                                          thresh_mat)
        else:
            #all from generate_spikes.pyx (cython)
            diff[:], abs_diff[:], spikes[:] = gs.thresholded_difference(curr_frame, ref_frame,
                                                                     threshold)

        if inhibition:
            spikes[:] = gs.local_inhibition(spikes, abs_diff, inh_coords, img_w, img_w, inh_w)




    def update_reference(self):
        abs_diff = self._abs_diff
        spikes = self._spikes
        ref_frame = self._ref_frame
        min_thresh = self._min_threshold
        max_thresh = self._max_threshold
        threshold  = self._threshold
        max_time_ms = self._max_time_ms
        history_weight = self._history_weight
        num_bits = self._num_bits_per_spike
        log2_table = self._log2_table[num_bits-1] #no values for 0-bit encoding

        if self._adaptive_threshold:
            thresh_mat = self._thresh_matrix
            thresh_delta_down = self._threshold_delta_down
            thresh_delta_up   = self._threshold_delta_up
            ref_frame[:], thresh_mat[:] = gs.update_reference_rate_adpt(abs_diff, spikes,
                                                                     ref_frame, thresh_mat,
                                                                     min_thresh, max_thresh,
                                                                     thresh_delta_down,
                                                                     thresh_delta_up,
                                                                     max_time_ms,
                                                                     history_weight)

        else:
            if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_RATE:

                ref_frame[:] = gs.update_reference_rate(abs_diff, spikes, ref_frame,
                                                     threshold, max_time_ms, history_weight)

            elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME:

                ref_frame[:] = gs.update_reference_time_thresh(abs_diff, spikes, ref_frame,
                                                            threshold, max_time_ms,
                                                            history_weight)

            elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:

                ref_frame[:] = gs.update_reference_time_binary_raw(abs_diff, spikes, ref_frame,
                                                                threshold, max_time_ms,
                                                                num_bits,
                                                                history_weight,
                                                                log2_table)

            elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:

                ref_frame[:] = gs.update_reference_time_binary_thresh(abs_diff, spikes, ref_frame,
                                                                   threshold, max_time_ms,
                                                                   num_bits,
                                                                   history_weight,
                                                                   log2_table)

    def transform_spikes(self):
        data_shift = self._data_shift
        up_down_shift = self._up_down_shift
        data_mask = self._data_mask
        polarity = self._polarity_n
        spikes = self._spikes
        threshold = self._threshold
        max_thresh = self._max_threshold
        #~ lists = self._spikes_lists
        max_time_ms = self._max_time_ms
        abs_diff = self._abs_diff
        num_bins = self._num_bins
        num_bits = self._num_bits_per_spike
        log2_table = self._log2_table[num_bits - 1]

        dn_spks, up_spks, g_max = gs.split_spikes(spikes, abs_diff, polarity)
        lists = None
        #from generate_spikes.pyx (cython)
        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_RATE:
          lists = gs.make_spike_lists_rate(up_spks, dn_spks,
                                        g_max, threshold,
                                        up_down_shift, data_shift, data_mask,
                                        max_time_ms)

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME:
          lists = gs.make_spike_lists_time(up_spks, dn_spks,
                                        g_max,
                                        up_down_shift, data_shift, data_mask,
                                        num_bins,
                                        max_time_ms,
                                        threshold, max_thresh)

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:
          lists = gs.make_spike_lists_time_bin(up_spks, dn_spks,
                                            g_max,
                                            up_down_shift, data_shift, data_mask,
                                            max_time_ms,
                                            threshold, max_thresh,
                                            num_bins,
                                            log2_table)

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
          lists = gs.make_spike_lists_time_bin_thr(up_spks, dn_spks,
                                                  g_max,
                                                  up_down_shift, data_shift, data_mask,
                                                  max_time_ms,
                                                  threshold, max_thresh,
                                                  num_bins,
                                                  log2_table)
        return lists


    def compose_output_frame(self):
        curr_frame = self._curr_frame
        spikes_frame = self._spikes_frame
        spikes = self._spikes
        width = self._out_res
        height = self._out_res
        polarity = self._polarity_n

        #from generate_spikes.pyx (cython)
        spikes_frame[:] = gs.render_frame(spikes=spikes, curr_frame=curr_frame,
                                          width=width, height=height,
                                          polarity=polarity)


    def calculate_time_per_pack(self):
        time_per_pack = 0
        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_RATE:
            time_per_pack = 1

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME:
            time_per_pack = (self._max_time_ms)// \
                            (min(self._max_time_ms,
                                 self._max_threshold//self._min_threshold + 1))

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:
            time_per_pack = (self._max_time_ms)//(8) #raw difference value could be 8-bit
        else:
            time_per_pack = (self._max_time_ms)//(self._num_bits_per_spike + 1)

        return time_per_pack
Пример #15
0
# Activate the sending of live spikes
ExternalDevices.activate_live_output_for(pop_forward,
                                         database_notify_host="localhost",
                                         database_notify_port_num=19996)


# Create a receiver of live spikes
def receive_spikes(label, time, neuron_ids):
    for neuron_id in neuron_ids:
        print "Received spike at time", time, "from", label, "-", neuron_id


# if not using the c visualiser, then a new spynnaker live spikes connection
# is created to define that there are python code which receives the
# outputted spikes.
live_spikes_connection = SpynnakerLiveSpikesConnection(
    receive_labels=["pop_forward"], local_port=19996, send_labels=None)
# Set up callbacks to occur when spikes are received
live_spikes_connection.add_receive_callback("pop_forward", receive_spikes)
# Run the simulation on spiNNaker
Frontend.run(run_time)
# Retrieve spikes from the synfire chain population
spikes_forward = pop_forward.getSpikes()
# If there are spikes, plot using matplotlib
if len(spikes_forward) != 0:
    pylab.figure()
    if len(spikes_forward) != 0:
        pylab.plot([i[1] for i in spikes_forward],
                   [i[0] for i in spikes_forward], "b.")
    pylab.ylabel('neuron id')
    pylab.xlabel('Time/ms')
    pylab.title('spikes')
Пример #16
0
}


pop_forward = Frontend.Population(n_neurons, Frontend.IF_curr_exp, cell_params_lif, label="pop_forward")
pop_forward.record()


injector_forward = Frontend.Population(
    n_neurons, ExternalDevices.SpikeInjector, cell_params_spike_injector, label="spike_injector_forward"
)


Frontend.Projection(injector_forward, pop_forward, Frontend.OneToOneConnector(weights=weight_to_spike))

live_spikes_connection_send = SpynnakerLiveSpikesConnection(
    receive_labels=None, local_port=board_port, send_labels=["spike_injector_forward"]
)

live_spikes_connection_send.add_init_callback("spike_injector_forward", init_pop)

live_spikes_connection_send.add_start_callback("spike_injector_forward", send_input_forward)

Frontend.run(run_time)

spikes_forward = pop_forward.getSpikes()

sorted_spikes = sorted(spikes_forward, key=lambda x: x[1])
for i in range(len(sorted_spikes) - 1):
    print sorted_spikes[i][1], ", ", sorted_spikes[i][0], ", ", sorted_spikes[i + 1][1] - sorted_spikes[i][1]

Пример #17
0
        tNext = retinasSpikes[index+1][0]  
        if r == 1:  
            send_spike_retina("ret_right", liveConnectionRetina)
        else:
            send_spike_retina("ret_left", liveConnectionRetina)  
        time.sleep((tNext - t)/1000.0)
         
def init_thread(label, sender):
    if label == "ret_left":
        sender_thread = Thread(target=threadLeft_run, args=(sender,))
        sender_thread.start()
    else:
        sender_thread = Thread(target=threadRight_run, args=(sender,))
        sender_thread.start()  
     
live_spikes_connection_receiver = SpynnakerLiveSpikesConnection(receive_labels=["collector", "inh_left", "inh_right"], local_port=19996, send_labels=None)
live_spikes_connection_receiver.add_receive_callback("collector", receive_spike_cell)
live_spikes_connection_receiver.add_receive_callback("inh_left", receive_spike_cell)
live_spikes_connection_receiver.add_receive_callback("inh_right", receive_spike_cell)
 
live_spikes_connection_sender = SpynnakerLiveSpikesConnection(receive_labels=None, local_port=19999, send_labels=["ret_right", "ret_left"])
# Set up callbacks to occur at the start of simulation
# live_spikes_connection_sender.add_start_callback("ret_left", init_thread)
live_spikes_connection_sender.add_start_callback("ret_right", init_thread)
 
# Run the simulation on spiNNaker
 
Frontend.run(run_time)
# Retrieve spikes from the synfire chain population
spikes_collector = collector.getSpikes()
print "Spikes count collector: ", len(spikes_collector)
class ExternalDvsEmulatorDevice(
        ReverseIpTagMultiCastSource,
        AbstractProvidesOutgoingConstraints,
):

    MODE_128 = "128"
    MODE_64 = "64"
    MODE_32 = "32"
    MODE_16 = "16"

    UP_POLARITY = "UP"
    DOWN_POLARITY = "DOWN"
    MERGED_POLARITY = "MERGED"
    RECTIFIED_POLARITY = "RECTIFIED_POLARITY"
    POLARITY_DICT = {
        UP_POLARITY: uint8(0),
        DOWN_POLARITY: uint8(1),
        MERGED_POLARITY: uint8(2),
        RECTIFIED_POLARITY: uint8(3),
        0: UP_POLARITY,
        1: DOWN_POLARITY,
        2: MERGED_POLARITY,
        3: RECTIFIED_POLARITY
    }

    OUTPUT_RATE = "RATE"
    OUTPUT_TIME = "TIME"
    OUTPUT_TIME_BIN = "TIME_BIN"
    OUTPUT_TIME_BIN_THR = "TIME_BIN_THR"

    def __init__(self,
                 n_neurons,
                 machine_time_step,
                 timescale_factor,
                 database_socket,
                 label,
                 port=12345,
                 virtual_key=None,
                 spikes_per_second=0,
                 ring_buffer_sigma=None,
                 device_id=0,
                 fps=60,
                 mode="128",
                 scale_img=True,
                 polarity="MERGED",
                 inhibition=False,
                 inh_area_width=2,
                 threshold=12,
                 adaptive_threshold=False,
                 min_threshold=6,
                 max_threshold=168,
                 threshold_delta_down=2,
                 threshold_delta_up=12,
                 output_type="TIME",
                 num_bits_per_spike=4,
                 history_weight=0.99,
                 save_spikes=None,
                 run_time_ms=None,
                 local_port=19876):
        """
        :param device_id: int for webcam modes, or string for video file
        :param mode: The retina "mode"
        :param retina_key: The value of the top 16-bits of the key
        :param polarity: The "polarity" of the retina data
        :param machine_time_step: The time step of the simulation
        :param timescale_factor: The timescale factor of the simulation
        :param label: The label for the population
        :param n_neurons: The number of neurons in the population

        """
        fixed_n_neurons = n_neurons

        if mode == ExternalDvsEmulatorDevice.MODE_128 or \
           mode == ExternalDvsEmulatorDevice.MODE_64  or \
           mode == ExternalDvsEmulatorDevice.MODE_32  or \
           mode == ExternalDvsEmulatorDevice.MODE_16:
            self._out_res = int(mode)
            self._res_2x = self._out_res * 2

        else:
            raise exceptions.SpynnakerException("the model does not "
                                                "recongise this mode")

        if (polarity == ExternalDvsEmulatorDevice.UP_POLARITY
                or polarity == ExternalDvsEmulatorDevice.DOWN_POLARITY
                or polarity == ExternalDvsEmulatorDevice.RECTIFIED_POLARITY):
            fixed_n_neurons = self._out_res**2
        else:
            fixed_n_neurons = 2 * (self._out_res**2)

        if fixed_n_neurons != n_neurons and n_neurons is not None:
            logger.warn(
                "The specified number of neurons for the DVS emulator"
                " device has been ignored {} will be used instead".format(
                    fixed_n_neurons))

        self._video_source = None
        self._device_id = device_id
        self._is_virtual_cam = False
        self._polarity = polarity
        self._polarity_n = ExternalDvsEmulatorDevice.POLARITY_DICT[polarity]
        self._global_max = int16(0)
        self._output_type = output_type

        self._raw_frame = None
        self._gray_frame = None
        self._tmp_frame = None

        self._ref_frame = 128 * np.ones(
            (self._out_res, self._out_res), dtype=int16)

        self._curr_frame = np.zeros((self._out_res, self._out_res),
                                    dtype=int16)

        self._spikes_frame = np.zeros((self._out_res, self._out_res, 3),
                                      dtype=uint8)

        self._diff = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._abs_diff = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._spikes = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._adaptive_threshold = adaptive_threshold
        self._thresh_matrix = None
        if adaptive_threshold:
            self._thresh_matrix = np.zeros((self._out_res, self._out_res),
                                           dtype=int16)

        self._threshold_delta_down = int16(threshold_delta_down)
        self._threshold_delta_up = int16(threshold_delta_up)
        self._max_threshold = int16(max_threshold)
        self._min_threshold = int16(min_threshold)

        self._up_spikes = None
        self._down_spikes = None
        self._spikes_lists = None

        self._threshold = int16(threshold)

        self._data_shift = uint8(np.log2(self._out_res))
        self._up_down_shift = uint8(2 * self._data_shift)
        self._data_mask = uint8(self._out_res - 1)

        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:
            self._num_bins = 8  #8-bit images don't need more
        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._num_bins = 6  #should be enough?
        else:
            self._num_bins = int(1000. / fps)

        self._num_bits_per_spike = min(num_bits_per_spike, self._num_bins)

        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN or \
           self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._log2_table = gs.generate_log2_table(self._num_bits_per_spike,
                                                      self._num_bins)
        else:
            self._log2_table = gs.generate_log2_table(
                self._num_bits_per_spike,
                8)  #stupid hack, compatibility issues

        self._scale_img = scale_img
        self._img_height = 0
        self._img_height_crop_u = 0
        self._img_height_crop_b = 0
        self._img_width = 0
        self._img_width_crop_l = 0
        self._img_width_crop_r = 0
        self._img_ratio = 0.
        self._img_scaled_width = 0
        self._scaled_width = 0
        self._fps = fps
        self._max_time_ms = 0
        self._time_per_frame = 0.

        self._time_per_spike_pack_ms = 0

        self._get_sizes = True
        self._scale_changed = False

        self._running = True

        self._label = label
        self._n_neurons = fixed_n_neurons
        self._local_port = local_port

        self._inh_area_width = inh_area_width
        self._inhibition = inhibition
        self._inh_coords = gs.generate_inh_coords(self._out_res, self._out_res,
                                                  inh_area_width)

        self._history_weight = history_weight

        self._run_time_ms = run_time_ms
        ################################################################

        if spinn_version == "2015.005":
            ReverseIpTagMultiCastSource.__init__(
                self,
                n_neurons=self._n_neurons,
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                port=self._local_port,
                label=self._label,
                virtual_key=virtual_key)
        else:
            ReverseIpTagMultiCastSource.__init__(
                self,
                n_keys=self._n_neurons,
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                label=self._label,
                receive_port=self._local_port,
                virtual_key=virtual_key)

        AbstractProvidesOutgoingConstraints.__init__(self)

        print("number of neurons for webcam = %d" % self._n_neurons)

        self._live_conn = SpynnakerLiveSpikesConnection(
            send_labels=[
                self._label,
            ], local_port=self._local_port)

        def init(label, n_neurons, run_time_ms, machine_timestep_ms):
            print("Sending %d neuron sources from %s" % (n_neurons, label))

        self._live_conn.add_init_callback(self._label, init)
        self._live_conn.add_start_callback(self._label, self.run)
        self._sender = None

        self._save_spikes = save_spikes

    def get_outgoing_edge_constraints(self, partitioned_edge, graph_mapper):
        constraints = ReverseIpTagMultiCastSource\
            .get_outgoing_edge_constraints(
                self, partitioned_edge, graph_mapper)
        constraints.append(KeyAllocatorContiguousRangeContraint())
        return constraints

    def get_number_of_mallocs_used_by_dsg(self, vertex_slice, in_edges):
        mallocs = \
            ReverseIpTagMultiCastSource.get_number_of_mallocs_used_by_dsg(
                self, vertex_slice, in_edges)
        if config.getboolean("SpecExecution", "specExecOnHost"):
            return 1
        else:
            return mallocs

    def __del__(self):

        self._running = False

    def stop(self):
        self.__del__()

    def run(self, label, sender):

        self._label = label
        self._sender = sender

        if self._run_time_ms is None:
            max_run_time_s = self.no_machine_time_steps / float(
                self.machine_time_step) - 0.5
        else:
            max_run_time_s = self._run_time_ms / 1000.

        self.acquire_device()

        spike_queue = Queue()
        spike_emmision_proc = Process(target=self.send_spikes,
                                      args=(spike_queue, ))
        spike_emmision_proc.start()

        img_queue = Queue()
        #~ spike_gen_proc = Process(target=self.process_frame, args=(img_queue,))
        spike_gen_proc = Process(target=self.process_frame,
                                 args=(img_queue, spike_queue))
        spike_gen_proc.start()

        grab_times = []
        start_time = 0.
        app_start_time = time.time()
        app_curr_time = time.time()
        first_frame = True
        frame_time = 0.
        while self._running:

            start_time = time.time()
            valid_frame = self.grab_frame()
            grab_times.append(time.time() - start_time)

            if not valid_frame:
                self._running = False

            # send the minimum difference value once to synchronize time-based
            # decoding on the receiver end
            if self._output_type != ExternalDvsEmulatorDevice.OUTPUT_RATE and \
               first_frame == True:

                first_frame = False
                self._curr_frame[:] = 128 + self._threshold + 1  #half range of vals + thresh + 1

            img_queue.put(self._curr_frame)

            app_curr_time = time.time()
            if app_curr_time - app_start_time > max_run_time_s:
                self._running = False
            frame_time = time.time() - start_time
            if frame_time < self._time_per_frame:
                time.sleep(self._time_per_frame - frame_time)

        print("webcam runtime ", app_curr_time - app_start_time)
        img_queue.put(None)
        spike_gen_proc.join()

        spike_queue.put(None)
        spike_emmision_proc.join()

        if self._video_source is not None:
            self._video_source.release()
            cv2.destroyAllWindows()

    def process_frame(self, img_queue, spike_queue):

        label = self._label
        spikes_frame = self._spikes_frame

        cv2.namedWindow(label)
        cv2.startWindowThread()

        res2x = self._res_2x
        spike_list = []
        # gen_times = []
        # compose_times = []
        # transform_times = []
        # ref_up_times = []
        lists = None
        while True:
            image = img_queue.get()

            if image is None or not self._running:
                break

            # start_time = time.time()
            self.generate_spikes(image)
            # gen_times.append(time.time()-start_time)

            # start_time = time.time()
            self.update_reference()
            # ref_up_times.append(time.time()-start_time)

            # start_time = time.time()
            lists = self.transform_spikes()
            # transform_times.append(time.time() - start_time)

            spike_queue.put(lists)

            if self._save_spikes is not None:
                spike_list.append(lists)

            # start_time = time.time()
            self.compose_output_frame()
            # compose_times.append(time.time()-start_time)

            cv2.imshow(label, cv2.resize(spikes_frame, (res2x, res2x)))

            if cv2.waitKey(1) & 0xFF == ord('q'):  #\
                #or not sender.isAlive():
                self._running = False
                break

            #continue

        # print("gen times")
        # print(np.array(gen_times).mean())
        # print("update ref times")
        # print(np.array(ref_up_times).mean())
        # print("transform times")
        # print(np.array(transform_times).mean())
        # print("compose times")
        # print(np.array(compose_times).mean())

        cv2.destroyAllWindows()
        cv2.waitKey(1)

        if self._save_spikes is not None:
            #print spike_list
            print("attempting to save spike_list")
            pickle.dump(spike_list, open(self._save_spikes, "wb"))

    def send_spikes(self, spike_queue):
        sender = self._sender
        while True:
            spikes = spike_queue.get()

            if spikes is None or not self._running:
                break

            self.emit_spikes(sender, spikes)

    def acquire_device(self):
        if isinstance(self._device_id, VirtualCam):
            self._video_source = self._device_id
            self._is_virtual_cam = True
        else:
            self._video_source = cv2.VideoCapture(self._device_id)

        if not self._video_source.isOpened():
            self._video_source.open()

        try:
            self._video_source.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
            self._video_source.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
        except:
            pass

        try:
            self._video_source.set(cv2.CAP_PROP_FPS, self._fps)
        except:
            self._fps = self._video_source.get(cv2.CAP_PROP_FPS)

        self._max_time_ms = int16((1. / self._fps) * 1000)
        self._time_per_frame = 1. / self._fps

        self._time_per_spike_pack_ms = self.calculate_time_per_pack()

    def grab_frame(self):
        #~ start_time = time.time()
        if self._is_virtual_cam:
            valid_frame, self._curr_frame[:] = self._video_source.read(
                self._ref_frame)
            return True

        else:
            if self._raw_frame is None or self._scale_changed:
                valid_frame, self._raw_frame = self._video_source.read()
            else:
                valid_frame, self._raw_frame[:] = self._video_source.read()

            #~ end_time = time.time()
            #~ print("Time to capture frame = ", end_time - start_time)

            if not valid_frame:
                return False

            #~ start_time = time.time()
            if self._gray_frame is None or self._scale_changed:
                self._gray_frame = cv2.convertColor(
                    self._raw_frame, cv2.COLOR_BGR2GRAY).astype(int16)
            else:
                self._gray_frame[:] = cv2.convertColor(self._raw_frame,
                                                       cv2.COLOR_BGR2GRAY)
            #~ end_time = time.time()
            #~ print("Time to convert to grayscale = ", end_time - start_time)

            #~ start_time = time.time()
            if self._get_sizes or self._scale_changed:
                self._get_sizes = False
                self._scale_changed = False
                self._img_height, self._img_width = self._gray_frame.shape

                self._img_ratio = float(self._img_width) / float(
                    self._img_height)
                self._img_scaled_width = int(
                    float(self._out_res) * self._img_ratio)

                if self._scale_img:
                    diff = self._img_scaled_width - self._out_res
                    self._img_width_crop_l = diff // 2
                    self._img_width_crop_r = self._img_width_crop_l + self._out_res
                else:
                    diff = self._img_width - self._out_res
                    self._img_width_crop_l = diff // 2
                    self._img_width_crop_r = self._img_width_crop_l + self._out_res
                    diff = self._img_height - self._out_res
                    self._img_height_crop_u = diff // 2
                    self._img_height_crop_b = self._img_height_crop_u + self._out_res

                self._tmp_frame = np.zeros(
                    (self._out_res, self._img_scaled_width))

            #~ end_time = time.time()
            #~ print("Time to calculate sizes = ", end_time - start_time)

            #~ start_time = time.time()
            if self._scale_img:
                self._tmp_frame[:] = cv2.resize(
                    self._gray_frame, (self._img_scaled_width, self._out_res),
                    interpolation=cv2.INTER_NN)

                self._curr_frame[:] = self._tmp_frame[:,
                                                      self._img_width_crop_l:
                                                      self._img_width_crop_r]
            else:
                self._curr_frame[:] = self._gray_frame[
                    self._img_height_crop_u:self._img_height_crop_b,
                    self._img_width_crop_l:self._img_width_crop_r]
            #~ end_time = time.time()
            #~ print("Time to scale frame = ", end_time - start_time)

        return True

    def emit_spikes(self, sender, lists):
        lbl = self._label
        max_time_s = self._time_per_spike_pack_ms / 1000.
        #~ lists   = self._spikes_lists
        send_spikes = sender.send_spikes

        #from generate_spikes.pyx (cython)
        if lists is not None:
            for spike_pack in lists:
                start_time = time.time()
                send_spikes(lbl, spike_pack, send_full_keys=False)
                elapsed_time = time.time() - start_time
                if elapsed_time < max_time_s:
                    time.sleep(max_time_s - elapsed_time)

    def generate_spikes(self, image):
        self._curr_frame = image
        curr_frame = self._curr_frame

        #~ curr_frame = image
        ref_frame = self._ref_frame
        diff = self._diff
        abs_diff = self._abs_diff
        spikes = self._spikes
        img_w = self._out_res
        inh_w = self._inh_area_width
        inhibition = self._inhibition
        inh_coords = self._inh_coords
        threshold = self._threshold

        if self._adaptive_threshold:
            thresh_mat = self._thresh_matrix

            #all from generate_spikes.pyx (cython)
            diff[:], abs_diff[:], spikes[:] = gs.thresholded_difference_adpt(
                curr_frame, ref_frame, thresh_mat)
        else:
            #all from generate_spikes.pyx (cython)
            diff[:], abs_diff[:], spikes[:] = gs.thresholded_difference(
                curr_frame, ref_frame, threshold)

        if inhibition:
            spikes[:] = gs.local_inhibition(spikes, abs_diff, inh_coords,
                                            img_w, img_w, inh_w)

    def update_reference(self):
        abs_diff = self._abs_diff
        spikes = self._spikes
        ref_frame = self._ref_frame
        min_thresh = self._min_threshold
        max_thresh = self._max_threshold
        threshold = self._threshold
        max_time_ms = self._max_time_ms
        history_weight = self._history_weight
        num_bits = self._num_bits_per_spike
        log2_table = self._log2_table[num_bits -
                                      1]  #no values for 0-bit encoding

        if self._adaptive_threshold:
            thresh_mat = self._thresh_matrix
            thresh_delta_down = self._threshold_delta_down
            thresh_delta_up = self._threshold_delta_up
            ref_frame[:], thresh_mat[:] = gs.update_reference_rate_adpt(
                abs_diff, spikes, ref_frame, thresh_mat, min_thresh,
                max_thresh, thresh_delta_down, thresh_delta_up, max_time_ms,
                history_weight)

        else:
            if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_RATE:

                ref_frame[:] = gs.update_reference_rate(
                    abs_diff, spikes, ref_frame, threshold, max_time_ms,
                    history_weight)

            elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME:

                ref_frame[:] = gs.update_reference_time_thresh(
                    abs_diff, spikes, ref_frame, threshold, max_time_ms,
                    history_weight)

            elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:

                ref_frame[:] = gs.update_reference_time_binary_raw(
                    abs_diff, spikes, ref_frame, threshold, max_time_ms,
                    num_bits, history_weight, log2_table)

            elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:

                ref_frame[:] = gs.update_reference_time_binary_thresh(
                    abs_diff, spikes, ref_frame, threshold, max_time_ms,
                    num_bits, history_weight, log2_table)

    def transform_spikes(self):
        data_shift = self._data_shift
        up_down_shift = self._up_down_shift
        data_mask = self._data_mask
        polarity = self._polarity_n
        spikes = self._spikes
        threshold = self._threshold
        max_thresh = self._max_threshold
        #~ lists = self._spikes_lists
        max_time_ms = self._max_time_ms
        abs_diff = self._abs_diff
        num_bins = self._num_bins
        num_bits = self._num_bits_per_spike
        log2_table = self._log2_table[num_bits - 1]

        dn_spks, up_spks, g_max = gs.split_spikes(spikes, abs_diff, polarity)
        lists = None
        #from generate_spikes.pyx (cython)
        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_RATE:
            lists = gs.make_spike_lists_rate(up_spks, dn_spks, g_max,
                                             threshold, up_down_shift,
                                             data_shift, data_mask,
                                             max_time_ms)

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME:
            lists = gs.make_spike_lists_time(up_spks, dn_spks, g_max,
                                             up_down_shift, data_shift,
                                             data_mask, num_bins, max_time_ms,
                                             threshold, max_thresh)

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:
            lists = gs.make_spike_lists_time_bin(up_spks, dn_spks, g_max,
                                                 up_down_shift, data_shift,
                                                 data_mask, max_time_ms,
                                                 threshold, max_thresh,
                                                 num_bins, log2_table)

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            lists = gs.make_spike_lists_time_bin_thr(up_spks, dn_spks, g_max,
                                                     up_down_shift, data_shift,
                                                     data_mask, max_time_ms,
                                                     threshold, max_thresh,
                                                     num_bins, log2_table)
        return lists

    def compose_output_frame(self):
        curr_frame = self._curr_frame
        spikes_frame = self._spikes_frame
        spikes = self._spikes
        width = self._out_res
        height = self._out_res
        polarity = self._polarity_n

        #from generate_spikes.pyx (cython)
        spikes_frame[:] = gs.render_frame(spikes=spikes,
                                          curr_frame=curr_frame,
                                          width=width,
                                          height=height,
                                          polarity=polarity)

    def calculate_time_per_pack(self):
        time_per_pack = 0
        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_RATE:
            time_per_pack = 1

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME:
            time_per_pack = (self._max_time_ms)// \
                            (min(self._max_time_ms,
                                 self._max_threshold//self._min_threshold + 1))

        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:
            time_per_pack = (self._max_time_ms) // (
                8)  #raw difference value could be 8-bit
        else:
            time_per_pack = (self._max_time_ms) // (self._num_bits_per_spike +
                                                    1)

        return time_per_pack
    print_condition.acquire()
    print "Sending forward spike for neuron 0"
    print_condition.release()
    sender.send_spike(label, 0)
# Create a receiver of live spikes
def receive_spikes(label, time, neuron_ids):
    for neuron_id in neuron_ids:
        print_condition.acquire()
        print "Received spike at time", time, "from", label, "-", neuron_id
        print_condition.release()
        if neuron_id == 0 and label== "pop_backward_parrot":
            live_spikes_connection.send_spike("spike_injector_forward", 0)
        elif neuron_id == 99 and label== "pop_forward_parrot":
            live_spikes_connection.send_spike("spike_injector_forward", 1)
# Set up the live connection for sending spikes
live_spikes_connection = SpynnakerLiveSpikesConnection(
    local_port=19996, send_labels=["spike_injector_forward"])
# Set up the live connection for sending spikes to closed loop
live_spikes_connection_receiver = SpynnakerLiveSpikesConnection(
    receive_labels=["pop_forward_parrot", "pop_backward_parrot"],
    local_port=19995)
# Set up callbacks to occur at the start of simulation
live_spikes_connection.add_start_callback("spike_injector_forward",
                                          send_input_forward)
# Set up callbacks to occur when spikes are received
live_spikes_connection_receiver.add_receive_callback("pop_forward_parrot", receive_spikes)
live_spikes_connection_receiver.add_receive_callback("pop_backward_parrot", receive_spikes)
# Run the simulation on spiNNaker
Frontend.run(run_time)

# Retrieve spikes from the synfire chain population
spikes_forward = pop_forward.getSpikes()
# record spikes from the synfire chains so that we can read off valid results
# in a safe way afterwards, and verify the behavior
pop_forward.record()
# Activate the sending of live spikes
ExternalDevices.activate_live_output_for(
    pop_forward, database_notify_host="localhost",
    database_notify_port_num=19996)
# Create a receiver of live spikes
def receive_spikes(label, time, neuron_ids):
    for neuron_id in neuron_ids:
        print "Received spike at time", time, "from", label, "-", neuron_id
# if not using the c visualiser, then a new spynnaker live spikes connection
# is created to define that there are python code which receives the
# outputted spikes.
live_spikes_connection = SpynnakerLiveSpikesConnection(
    receive_labels=["pop_forward"],
    local_port=19996, send_labels=None)
# Set up callbacks to occur when spikes are received
live_spikes_connection.add_receive_callback("pop_forward", receive_spikes)
# Run the simulation on spiNNaker
Frontend.run(run_time)
# Retrieve spikes from the synfire chain population
spikes_forward = pop_forward.getSpikes()
# If there are spikes, plot using matplotlib
if len(spikes_forward) != 0:
    pylab.figure()
    if len(spikes_forward) != 0:
        pylab.plot([i[1] for i in spikes_forward],
                   [i[0] for i in spikes_forward], "b.")
    pylab.ylabel('neuron id')
    pylab.xlabel('Time/ms')
Пример #21
0
  add_spikes(full_input_spikes, input_spikes[n][in_id], silence=period_length*2)


input_layer = {}
#~ for i in xrange(len(input_spikes)):
  #~ input_layer[i] = sim.Population(img_neurons, sim.SpikeSourceArray, 
                                  #~ {"spike_times": input_spikes[i]}, 
                                  #~ structure=grid) 


input_layer[in_id] = sim.Population(img_neurons, inj_cell_type,
                                    inj_cell_params, 
                                    label="spike_injector")

live_spikes_connection_send = SpynnakerLiveSpikesConnection(
                                  receive_labels=None, local_port=19999,
                                  send_labels=["spike_injector"])

live_spikes_connection_send.add_start_callback("spike_injector", send_input)



#~ input_layer[in_id] = sim.Population(img_neurons, sim.SpikeSourceArray, 
                                    #~ {"spike_times": input_spikes[in_id]}
                                   #~ ) 
learn_layer = {}

learn_layer['exc'] = sim.Population(num_exc+1, neuron_model, cell_params_izk_exc, 
                                    label="Learn layer - exc")
learn_layer['inh'] = sim.Population(num_inh+1, neuron_model, cell_params_izk_inh, 
                                    label="Learn layer - inh")
    def _connect_spike_sources(self, retinae=None, verbose=False):

        if verbose:
            print "INFO: Connecting Spike Sources to Network."

        global _retina_proj_l, _retina_proj_r

        # left is 0--dimensionRetinaY-1; right is dimensionRetinaY--dimensionRetinaY*2-1
        connListRetLBlockerL = []
        connListRetLBlockerR = []
        connListRetRBlockerL = []
        connListRetRBlockerR = []
        for y in range(0, self.dim_y):
            connListRetLBlockerL.append(
                (y, y, self.cell_params['synaptic']['wSaB'],
                 self.cell_params['synaptic']['dSaB']))
            connListRetLBlockerR.append(
                (y, y + self.dim_y, self.cell_params['synaptic']['wSzB'],
                 self.cell_params['synaptic']['dSzB']))
            connListRetRBlockerL.append(
                (y, y, self.cell_params['synaptic']['wSzB'],
                 self.cell_params['synaptic']['dSzB']))
            connListRetRBlockerR.append(
                (y, y + self.dim_y, self.cell_params['synaptic']['wSaB'],
                 self.cell_params['synaptic']['dSaB']))

        retinaLeft = retinae['left'].pixel_columns
        retinaRight = retinae['right'].pixel_columns
        pixel = 0
        for row in _retina_proj_l:
            for pop in row:
                ps.Projection(retinaLeft[pixel],
                              self.network[pop][1],
                              ps.OneToOneConnector(
                                  weights=self.cell_params['synaptic']['wSC'],
                                  delays=self.cell_params['synaptic']['dSC']),
                              target='excitatory')
                ps.Projection(retinaLeft[pixel],
                              self.network[pop][0],
                              ps.FromListConnector(connListRetLBlockerL),
                              target='excitatory')
                ps.Projection(retinaLeft[pixel],
                              self.network[pop][0],
                              ps.FromListConnector(connListRetLBlockerR),
                              target='inhibitory')
            pixel += 1

        pixel = 0
        for col in _retina_proj_r:
            for pop in col:
                ps.Projection(retinaRight[pixel],
                              self.network[pop][1],
                              ps.OneToOneConnector(
                                  weights=self.cell_params['synaptic']['wSC'],
                                  delays=self.cell_params['synaptic']['dSC']),
                              target='excitatory')
                ps.Projection(retinaRight[pixel],
                              self.network[pop][0],
                              ps.FromListConnector(connListRetRBlockerR),
                              target='excitatory')
                ps.Projection(retinaRight[pixel],
                              self.network[pop][0],
                              ps.FromListConnector(connListRetRBlockerL),
                              target='inhibitory')
            pixel += 1

        # configure for the live input streaming if desired
        if not (retinae['left'].use_prerecorded_input
                and retinae['right'].use_prerecorded_input):
            from spynnaker_external_devices_plugin.pyNN.connections.spynnaker_live_spikes_connection import \
                SpynnakerLiveSpikesConnection

            all_retina_labels = retinaLeft.labels + retinaRight.labels
            self.live_connection_sender = SpynnakerLiveSpikesConnection(
                receive_labels=None,
                local_port=19999,
                send_labels=all_retina_labels)

            # this callback will be executed right after simulation.run() has been called. If simply a while True
            # is put there, the main thread will stuck there and will not complete the simulation.
            # One solution might be to start a thread/process which runs a "while is_running:" loop unless the main thread
            # sets the "is_running" to False.
            self.live_connection_sender.add_start_callback(
                all_retina_labels[0], self.start_injecting)

            import DVSReader as dvs
            # the port numbers might well be wrong
            self.dvs_stream_left = dvs.DVSReader(
                port=0,
                label=retinaLeft.label,
                live_connection=self.live_connection_sender)
            self.dvs_stream_right = dvs.DVSReader(
                port=1,
                label=retinaRight.label,
                live_connection=self.live_connection_sender)

            # start the threads, i.e. start reading from the DVS. However, nothing will be sent to the SNN.
            # See start_injecting
            self.dvs_stream_left.start()
            self.dvs_stream_right.start()
class GUI(object):
    """
    simple gui to demostrate live inejction of the spike io script.
    """
    def __init__(self, n_neurons):
        """
        creates the gui
        :return:
        """
        self._started = False
        # Set up the live connection for sending and receiving spikes
        self.live_spikes_connection = SpynnakerLiveSpikesConnection(
            receive_labels=None,
            local_port=19996,
            send_labels=["spike_injector_forward", "spike_injector_backward"])

        # Set up callbacks to occur at the start of simulation
        self.live_spikes_connection.add_start_callback(
            "spike_injector_forward", self.send_input_forward)
        root = tk.Tk()
        root.title("Injecting Spikes GUI")
        label = tk.Label(root, fg="dark green")
        label.pack()
        neuron_id_value = tk.IntVar()
        self.neuron_id = tk.Spinbox(root,
                                    from_=0,
                                    to=n_neurons - 1,
                                    textvariable=neuron_id_value)
        self.neuron_id.pack()
        pop_label_value = tk.StringVar()
        self.pop_label = tk.Spinbox(root,
                                    textvariable=pop_label_value,
                                    values=("spike_injector_forward",
                                            "spike_injector_backward"))
        self.pop_label.pack()
        button = tk.Button(root,
                           text='Inject',
                           width=25,
                           command=self.inject_spike)
        button.pack()
        root.mainloop()

    # Create a sender of packets for the forward population
    def send_input_forward(self, pop_label, _):
        """
        records that stuff has started on the spinnaker machine
        :param pop_label: label
        :param _: dont care
        :return:
        """
        self._started = True

    # add a gui with a button and scroll list
    def inject_spike(self):
        """
        is set off when inject is pressed, takes the vlaues from the spin
        boxes and fires a spike in.
        :return:
        """
        print "injecting with neuron_id {} to pop {}".format(
            self.neuron_id.get(), self.pop_label.get())
        if self._started:
            self.live_spikes_connection.send_spike(str(self.pop_label.get()),
                                                   int(self.neuron_id.get()))
Пример #24
0
# Create a connection from the injector into the populations
Frontend.Projection(injector, pop,
		    Frontend.OneToOneConnector(weights=weight_to_spike))



# Activate the sending of live spikes
ExternalDevices.activate_live_output_for(
    pop, database_notify_host="localhost",
    database_notify_port_num=19996)



# Set up the live connection for sending spikes
live_spikes_connection_send = SpynnakerLiveSpikesConnection(
    receive_labels=None, local_port=19999,
    send_labels=["spike_injector"])



# Set up callbacks to occur at initialisation
live_spikes_connection_send.add_init_callback(
    "spike_injector", init_pop)



live_spikes_connection_receive = SpynnakerLiveSpikesConnection(
	receive_labels=["pop"],
	local_port=19996, send_labels=None)

    def __init__(self,
            n_neurons_source=None,
            Spike_Source_Class=None,
            Spike_Sink_Class=None,
            output_population=None,
            ros_topic_send='to_spinnaker',
            ros_topic_recv='from_spinnaker',
            clk_rate=1000,
            ros_output_rate=10,
            benchmark=False):

        # Members
        self.n_neurons = n_neurons_source if n_neurons_source is not None else 1
        self._Spike_Source_Class = Spike_Source_Class
        self._Spike_Sink_Class = Spike_Sink_Class

        self.interface_id = self._instance_counter.next()

        self._output_population = output_population


        self.send_topic = ros_topic_send
        self.recv_topic = ros_topic_recv
        self._clk_rate = clk_rate  # in Hz
        self._ros_output_rate = ros_output_rate  # Hz
        self._benchmark = benchmark

        

        self._injector_label = 'injector{}'.format(self.interface_id)
        spike_injector_port = 12345 + self.interface_id
        local_port = 19999 + self.interface_id
        local_recv_port = 17895
        self._database_notify_port = local_port

        self._queue_ros_spinnaker = Queue()
        self._queue_spinnaker_ros = Queue()

        # My own "population" data structures to send and receive spikes, initialized later.
        self._spike_source = None
        self._spike_sink = None

        send_labels = [self._injector_label]
        rcv_labels = None

        self.sender_active = n_neurons_source is not None and self._Spike_Source_Class is not None
        self.receiver_active = self._output_population is not None and self._Spike_Sink_Class is not None

        if self.receiver_active:
            rcv_labels = [self._output_population.label]

        self._spike_injector_population = pynn.Population(size=self.n_neurons,
                                                          cellclass=ExternalDevices.SpikeInjector,
                                                          cellparams={'port': spike_injector_port,
                                                                      'database_notify_port_num':local_port},
                                                          label=self._injector_label)

        self._spinnaker_connection = LiveSpikesConnection(receive_labels=rcv_labels,
                                                          local_port=local_port,
                                                          send_labels=send_labels)

        self._spinnaker_connection.add_start_callback(self._injector_label, self._init_ros_node)  # spinnaker thread!

        if self.receiver_active:
            self._spinnaker_connection.add_receive_callback(self._output_population.label, self._incoming_spike_callback)

            ExternalDevices.activate_live_output_for(self._output_population,
                                                     port=local_recv_port+self.interface_id,
                                                     database_notify_port_num=self._database_notify_port)
Пример #26
0
        print "Sending backward spike", real_id
        print_condition.release()
        sender.send_spike(label, real_id)


# Create a receiver of live spikes
def receive_spikes(label, time, neuron_ids):
    for neuron_id in neuron_ids:
        print_condition.acquire()
        print "Received spike at time", time, "from", label, "-", neuron_id
        print_condition.release()


# Set up the live connection for sending spikes
live_spikes_connection_send = SpynnakerLiveSpikesConnection(
    receive_labels=None,
    local_port=19999,
    send_labels=["spike_injector_forward", "spike_injector_backward"])

# Set up callbacks to occur at the start of simulation
live_spikes_connection_send.add_start_callback("spike_injector_forward",
                                               send_input_forward)
live_spikes_connection_send.add_start_callback("spike_injector_backward",
                                               send_input_backward)

if not using_c_vis:
    # if not using the c visualiser, then a new spynnaker live spikes connection
    # is created to define that there are python code which receives the
    # outputted spikes.
    live_spikes_connection_receive = SpynnakerLiveSpikesConnection(
        receive_labels=["pop_forward", "pop_backward"],
        local_port=19996,
    def __init__(self, n_neurons, machine_time_step, timescale_factor,
                 label, images=None, 
                 port=12345, virtual_key=None,
                 spikes_per_second=0, ring_buffer_sigma=None, 
                 database_socket=None, 
                 behaviour="SACCADE", max_saccade_distance=1,
                 frames_per_microsaccade = 1, frames_per_saccade = 29, #~30
                 total_on_time_ms = 1000, inter_off_time_ms = 100,
                 background_gray = 0,
                 fps=90, mode="128", scale_img=True, polarity="MERGED",
                 inhibition = False, inh_area_width = 2,
                 threshold=12, adaptive_threshold = False,
                 min_threshold=6, max_threshold=168,
                 threshold_delta_down = 2, threshold_delta_up = 12,
                 output_type="TIME", num_bits_per_spike=5, 
                 history_weight=0.99, save_spikes=None,
                 local_port=19876):
        """
        :param device_id: int for webcam modes, or string for video file
        :param mode: The retina "mode"
        :param retina_key: The value of the top 16-bits of the key
        :param polarity: The "polarity" of the retina data
        :param machine_time_step: The time step of the simulation
        :param timescale_factor: The timescale factor of the simulation
        :param label: The label for the population
        :param n_neurons: The number of neurons in the population
        
        """
        
        
        self._loaded_idx = 0
        self._total_images = 0
        self._image_list = self.get_images_paths(images)
        
        fixed_n_neurons = n_neurons

        if mode == ExternalImageDvsEmulatorDevice.MODE_128 or \
           mode == ExternalImageDvsEmulatorDevice.MODE_64  or \
           mode == ExternalImageDvsEmulatorDevice.MODE_32  or \
           mode == ExternalImageDvsEmulatorDevice.MODE_16:
            self._out_res = int(mode)

        else:
            raise exceptions.SpynnakerException("the model does not "
                                                "recongise this mode")

        if (polarity == ExternalImageDvsEmulatorDevice.UP_POLARITY or
            polarity == ExternalImageDvsEmulatorDevice.DOWN_POLARITY):
            fixed_n_neurons = self._out_res**2
        else:
            fixed_n_neurons = 2*(self._out_res**2)

        if fixed_n_neurons != n_neurons and n_neurons is not None:
            logger.warn("The specified number of neurons for the DVS emulator"
                        " device has been ignored {} will be used instead"
                        .format(fixed_n_neurons))

        self._center_x = 0
        self._center_y = 0
        
        self._max_saccade_distance = max_saccade_distance
        self._frames_per_microsaccade = frames_per_microsaccade
        self._frames_per_saccade = frames_per_saccade
        self._traverse_speed = (self._out_res*2.)/((total_on_time_ms/1000.)*fps)
        
        self._behaviour = behaviour
        self._total_on_time_ms = total_on_time_ms
        self._inter_off_time_ms = inter_off_time_ms
        self._background_gray = background_gray
        
        self._polarity = polarity
        self._polarity_n = ExternalImageDvsEmulatorDevice.POLARITY_DICT[polarity]
        self._global_max = int16(0)
        self._output_type = output_type
        
        self._raw_frame = None
        self._gray_frame = None
        self._tmp_frame = None
        
        self._ref_frame = 128*numpy.ones((self._out_res, self._out_res), dtype=int16) 
        
        self._curr_frame = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        self._moved_frame = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        self._silence_frame = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        
        self._spikes_frame = numpy.zeros((self._out_res, self._out_res, 3), dtype=uint8)
        
        self._diff = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        
        self._abs_diff = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        
        self._spikes = numpy.zeros((self._out_res, self._out_res), dtype=int16)

        self._adaptive_threshold = adaptive_threshold
        
        self._thresh_matrix = None
        if adaptive_threshold:
          self._thresh_matrix = numpy.zeros((self._out_res, self._out_res), 
                                             dtype=int16)

        self._threshold_delta_down = int16(threshold_delta_down)
        self._threshold_delta_up = int16(threshold_delta_up)
        self._max_threshold = int16(max_threshold)
        self._min_threshold = int16(min_threshold)
        
        self._up_spikes = None
        self._down_spikes = None
        self._spikes_lists = None
        
        self._threshold = int16(threshold)
        
        self._data_shift = uint8(numpy.log2(self._out_res))
        self._up_down_shift = uint8(2*self._data_shift)
        self._data_mask = uint8(self._out_res - 1)
        
        if self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN:
            self._num_bins = 8 #8-bit images don't need more
        elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._num_bins = 6 #should be enough?
        else:
            self._num_bins = int(1000./fps)

        self._num_bits_per_spike = min(num_bits_per_spike, self._num_bins)
        
        if self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN or \
           self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._log2_table = generate_log2_table(self._num_bits_per_spike, self._num_bins)
        else:
            self._log2_table = generate_log2_table(self._num_bits_per_spike, 8) #stupid hack, compatibility issues
            
        self._scale_img = scale_img
        self._img_height = 0
        self._img_height_crop_u = 0
        self._img_height_crop_b = 0
        self._img_width = 0
        self._img_width_crop_l = 0
        self._img_width_crop_r = 0
        self._img_ratio = 0.
        self._img_scaled_width = 0
        self._scaled_width = 0
        self._fps = fps
        self._half_frame = fps/2
        self._max_time_ms = int16((1./fps)*1000)
        
        self._time_per_spike_pack_ms = self.calculate_time_per_pack()
        
        self._get_sizes = True
        self._scale_changed = False
        
        self._running = True

        self._label = label
        self._n_neurons = fixed_n_neurons
        self._local_port = local_port
        
        self._inh_area_width = inh_area_width
        self._inhibition = inhibition
        
        self._history_weight = history_weight
        
        ################################################################

        if spinn_version == "2015.005":
            ReverseIpTagMultiCastSource.__init__(self, 
                n_neurons=self._n_neurons, 
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                port=self._local_port,
                label=self._label,
                virtual_key=virtual_key)
        else:
            ReverseIpTagMultiCastSource.__init__(self, 
                n_keys=self._n_neurons, 
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor, 
                label=self._label, 
                receive_port=self._local_port,
                virtual_key=virtual_key)
        
        AbstractProvidesOutgoingConstraints.__init__(self)

        print "number of neurons for webcam = %d"%self._n_neurons
        
        self._live_conn = SpynnakerLiveSpikesConnection(send_labels = [self._label, ],
                                                        local_port = self._local_port)
        def init(label, n_neurons, run_time_ms, machine_timestep_ms):
            print("Sending %d neuron sources from %s"%(n_neurons, label))
        
        self._live_conn.add_init_callback(self._label, init)
        self._live_conn.add_start_callback(self._label, self.run)
        self._sender = None

        self._save_spikes = save_spikes
        self._spike_list = []
    def __init__(self,
                 n_neurons,
                 machine_time_step,
                 timescale_factor,
                 database_socket,
                 label,
                 port=12345,
                 virtual_key=None,
                 spikes_per_second=0,
                 ring_buffer_sigma=None,
                 device_id=0,
                 fps=60,
                 mode="128",
                 scale_img=True,
                 polarity="MERGED",
                 inhibition=False,
                 inh_area_width=2,
                 threshold=12,
                 adaptive_threshold=False,
                 min_threshold=6,
                 max_threshold=168,
                 threshold_delta_down=2,
                 threshold_delta_up=12,
                 output_type="TIME",
                 num_bits_per_spike=4,
                 history_weight=0.99,
                 save_spikes=None,
                 run_time_ms=None,
                 local_port=19876):
        """
        :param device_id: int for webcam modes, or string for video file
        :param mode: The retina "mode"
        :param retina_key: The value of the top 16-bits of the key
        :param polarity: The "polarity" of the retina data
        :param machine_time_step: The time step of the simulation
        :param timescale_factor: The timescale factor of the simulation
        :param label: The label for the population
        :param n_neurons: The number of neurons in the population

        """
        fixed_n_neurons = n_neurons

        if mode == ExternalDvsEmulatorDevice.MODE_128 or \
           mode == ExternalDvsEmulatorDevice.MODE_64  or \
           mode == ExternalDvsEmulatorDevice.MODE_32  or \
           mode == ExternalDvsEmulatorDevice.MODE_16:
            self._out_res = int(mode)
            self._res_2x = self._out_res * 2

        else:
            raise exceptions.SpynnakerException("the model does not "
                                                "recongise this mode")

        if (polarity == ExternalDvsEmulatorDevice.UP_POLARITY
                or polarity == ExternalDvsEmulatorDevice.DOWN_POLARITY
                or polarity == ExternalDvsEmulatorDevice.RECTIFIED_POLARITY):
            fixed_n_neurons = self._out_res**2
        else:
            fixed_n_neurons = 2 * (self._out_res**2)

        if fixed_n_neurons != n_neurons and n_neurons is not None:
            logger.warn(
                "The specified number of neurons for the DVS emulator"
                " device has been ignored {} will be used instead".format(
                    fixed_n_neurons))

        self._video_source = None
        self._device_id = device_id
        self._is_virtual_cam = False
        self._polarity = polarity
        self._polarity_n = ExternalDvsEmulatorDevice.POLARITY_DICT[polarity]
        self._global_max = int16(0)
        self._output_type = output_type

        self._raw_frame = None
        self._gray_frame = None
        self._tmp_frame = None

        self._ref_frame = 128 * np.ones(
            (self._out_res, self._out_res), dtype=int16)

        self._curr_frame = np.zeros((self._out_res, self._out_res),
                                    dtype=int16)

        self._spikes_frame = np.zeros((self._out_res, self._out_res, 3),
                                      dtype=uint8)

        self._diff = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._abs_diff = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._spikes = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._adaptive_threshold = adaptive_threshold
        self._thresh_matrix = None
        if adaptive_threshold:
            self._thresh_matrix = np.zeros((self._out_res, self._out_res),
                                           dtype=int16)

        self._threshold_delta_down = int16(threshold_delta_down)
        self._threshold_delta_up = int16(threshold_delta_up)
        self._max_threshold = int16(max_threshold)
        self._min_threshold = int16(min_threshold)

        self._up_spikes = None
        self._down_spikes = None
        self._spikes_lists = None

        self._threshold = int16(threshold)

        self._data_shift = uint8(np.log2(self._out_res))
        self._up_down_shift = uint8(2 * self._data_shift)
        self._data_mask = uint8(self._out_res - 1)

        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:
            self._num_bins = 8  #8-bit images don't need more
        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._num_bins = 6  #should be enough?
        else:
            self._num_bins = int(1000. / fps)

        self._num_bits_per_spike = min(num_bits_per_spike, self._num_bins)

        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN or \
           self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._log2_table = gs.generate_log2_table(self._num_bits_per_spike,
                                                      self._num_bins)
        else:
            self._log2_table = gs.generate_log2_table(
                self._num_bits_per_spike,
                8)  #stupid hack, compatibility issues

        self._scale_img = scale_img
        self._img_height = 0
        self._img_height_crop_u = 0
        self._img_height_crop_b = 0
        self._img_width = 0
        self._img_width_crop_l = 0
        self._img_width_crop_r = 0
        self._img_ratio = 0.
        self._img_scaled_width = 0
        self._scaled_width = 0
        self._fps = fps
        self._max_time_ms = 0
        self._time_per_frame = 0.

        self._time_per_spike_pack_ms = 0

        self._get_sizes = True
        self._scale_changed = False

        self._running = True

        self._label = label
        self._n_neurons = fixed_n_neurons
        self._local_port = local_port

        self._inh_area_width = inh_area_width
        self._inhibition = inhibition
        self._inh_coords = gs.generate_inh_coords(self._out_res, self._out_res,
                                                  inh_area_width)

        self._history_weight = history_weight

        self._run_time_ms = run_time_ms
        ################################################################

        if spinn_version == "2015.005":
            ReverseIpTagMultiCastSource.__init__(
                self,
                n_neurons=self._n_neurons,
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                port=self._local_port,
                label=self._label,
                virtual_key=virtual_key)
        else:
            ReverseIpTagMultiCastSource.__init__(
                self,
                n_keys=self._n_neurons,
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                label=self._label,
                receive_port=self._local_port,
                virtual_key=virtual_key)

        AbstractProvidesOutgoingConstraints.__init__(self)

        print("number of neurons for webcam = %d" % self._n_neurons)

        self._live_conn = SpynnakerLiveSpikesConnection(
            send_labels=[
                self._label,
            ], local_port=self._local_port)

        def init(label, n_neurons, run_time_ms, machine_timestep_ms):
            print("Sending %d neuron sources from %s" % (n_neurons, label))

        self._live_conn.add_init_callback(self._label, init)
        self._live_conn.add_start_callback(self._label, self.run)
        self._sender = None

        self._save_spikes = save_spikes
Пример #29
0
        while n < neuronCount:
            sender.send_spike("med", n, send_full_keys=False)
            n += 1
        counter_sent += neuronCount
#             time.sleep(0.007)
    print time.time()
           

   
def init(label, sender):
    pass
    sender_thread = Thread(target=th_run, args=(sender,))
    sender_thread.start()  
     
ExternalDevices.activate_live_output_for(source, database_notify_host="localhost",database_notify_port_num=19996)
live_spikes_connection_receiver = SpynnakerLiveSpikesConnection(receive_labels=["src"], local_port=19996, send_labels=None)
live_spikes_connection_receiver.add_receive_callback("src", receive_spike_cell)

live_spikes_connection_sender = SpynnakerLiveSpikesConnection(receive_labels=None, local_port=19999, send_labels=["med"])
live_spikes_connection_sender.add_start_callback("med", init)

Frontend.run(run_time)
# Retrieve spikes from the synfire chain population

# print "Spikes count source:", len(source.getSpikes())
# print "Spikes count collector_ssa:", len(collector_ssa.getSpikes())
# print collector_ssa.getSpikes()[:20]
# print "Spikes count collector_inj:", len(collector_inj.getSpikes())

print counter_received, counter_sent
# print collector_inj.getSpikes()[:20]
        print_condition.acquire()
        print "Sending backward spike", real_id
        print_condition.release()
        sender.send_spike(label, real_id)


# Create a receiver of live spikes
def receive_spikes(label, time, neuron_ids):
    for neuron_id in neuron_ids:
        print_condition.acquire()
        print "Received spike at time", time, "from", label, "-", neuron_id
        print_condition.release()

# Set up the live connection for sending spikes
live_spikes_connection_send = SpynnakerLiveSpikesConnection(
    receive_labels=None, local_port=19999,
    send_labels=["spike_injector_forward", "spike_injector_backward"])

# Set up callbacks to occur at initialisation
live_spikes_connection_send.add_init_callback(
    "spike_injector_forward", init_pop)
live_spikes_connection_send.add_init_callback(
    "spike_injector_backward", init_pop)

# Set up callbacks to occur at the start of simulation
live_spikes_connection_send.add_start_callback(
    "spike_injector_forward", send_input_forward)
live_spikes_connection_send.add_start_callback(
    "spike_injector_backward", send_input_backward)

live_spikes_connection_receive = None
class CooperativeNetwork(object):
    def __init__(self,
                 retinae=None,
                 max_disparity=0,
                 cell_params=None,
                 record_spikes=True,
                 record_v=False,
                 experiment_name="Experiment",
                 verbose=True):
        # IMPORTANT NOTE: This implementation assumes min_disparity = 0

        assert retinae['left'] is not None and retinae['right'] is not None, \
            "ERROR: Retinas are not initialised! Creating Network Failed."

        dx = retinae['left'].dim_x
        assert dx > max_disparity >= 0, "ERROR: Maximum Disparity Constant is illegal!"
        self.max_disparity = max_disparity
        self.min_disparity = 0
        self.size = (2 * (dx - self.min_disparity) *
                     (self.max_disparity - self.min_disparity + 1) -
                     (self.max_disparity - self.min_disparity + 1)**2 +
                     self.max_disparity - self.min_disparity + 1) / 2
        self.dim_x = dx
        self.dim_y = retinae['left'].dim_y

        # check this assertion before the actual network generation, since the former
        # might take very long to complete.
        assert retinae['left'].dim_x == retinae['right'].dim_x and \
               retinae['left'].dim_y == retinae['right'].dim_y, \
            "ERROR: Left and Right retina dimensions are not matching. Connecting Spike Sources to Network Failed."

        # TODO: make parameter values dependent on the simulation time step
        # (for the case 0.1 it is not tested completely and should serve more like an example)

        # the notation for the synaptic parameters is as follows:
        # B blocker, C collector, S spike source, (2, 4)
        # w weight, d delay, (1)
        # a one's own, z other, (3)
        # i inhibition, e excitation  (5)
        # If B is before C than the connection is from B to C.
        # Example: dSaB would mean a dealy from a spike source to the one's own blocker neuron, and
        # wSzB would be the weight from a spike source to the heterolateral blocker neuron.
        params = {'neural': dict(), 'synaptic': dict(), 'topological': dict()}
        simulation_time_step = 0.2
        if simulation_time_step == 0.2:
            params['neural'] = {
                'tau_E': 2.0,
                'tau_I': 2.0,
                'tau_mem': 2.07,
                'v_reset_blocker': -84.0,
                'v_reset_collector': -90.0
            }  # why -90.0?
            w = 18.0
            params['synaptic'] = {
                'wBC':
                w,  # -20.5: negative won't work. However keep in mind that it is inhibitory!
                'dBC': simulation_time_step,
                'wSC': w,
                'dSC': 1.6,
                'wSaB': w,
                'dSaB': simulation_time_step,
                'wSzB': w,  # same story here
                'dSzB': simulation_time_step,
                'wCCi': w,  # and again
                'dCCi': simulation_time_step,
                'wCCo': w / 3,  # and again
                'dCCo': simulation_time_step,
                'wCCe': 1.8,
                'dCCe': simulation_time_step
            }
            params['topological'] = {
                'radius_e': 1,
                'radius_i': max(self.dim_x, self.dim_y)
            }
        elif simulation_time_step == 0.1:
            params['neural'] = {
                'tau_E': 1.0,
                'tau_I': 1.0,
                'tau_mem': 1.07,
                'v_reset_blocker': -92.0,
                'v_reset_collector': -102.0
            }
            params['synaptic'] = {
                'wBC':
                39.5,  #weight should be positive numbers, indicated as inhibitory synapses (if necessary)!
                'dBC': simulation_time_step,
                'wSC': 39.5,
                'dSC': 0.8,
                'wSaB': 49.5,
                'dSaB': simulation_time_step,
                'wSzB': 39.5,  # same here
                'dSzB': simulation_time_step,
                'wCCi': 50.0,  # and here
                'dCCi': simulation_time_step,
                'wCCe': 4.0,
                'dCCe': simulation_time_step
            }
            params['topological'] = {
                'radius_e': 1,
                'radius_i': max(self.dim_x, self.dim_y)
            }

        self.cell_params = params if cell_params is None else cell_params

        self.network = self._create_network(record_spikes=record_spikes,
                                            record_v=record_v,
                                            verbose=verbose)

        self._connect_spike_sources(retinae=retinae, verbose=verbose)

        self.experiment_name = experiment_name.replace(" ", "_")

    def _create_network(self,
                        record_spikes=False,
                        record_v=False,
                        verbose=False):

        print(
            "INFO: Creating Cooperative Network of size {0} (in microensembles)."
            .format(self.size))

        #        if record_spikes:
        #            from pyNN.spiNNaker import record

        network = []
        neural_params = self.cell_params['neural']
        for x in range(0, self.size):
            blocker_columns = ps.Population(
                self.dim_y * 2,
                ps.IF_curr_exp, {
                    'tau_syn_E': neural_params['tau_E'],
                    'tau_syn_I': neural_params['tau_I'],
                    'tau_m': neural_params['tau_mem'],
                    'v_reset': neural_params['v_reset_blocker']
                },
                label="Blocker {0}".format(x))

            collector_column = ps.Population(
                self.dim_y,
                ps.IF_curr_exp, {
                    'tau_syn_E': neural_params['tau_E'],
                    'tau_syn_I': neural_params['tau_I'],
                    'tau_m': neural_params['tau_mem'],
                    'v_reset': neural_params['v_reset_collector']
                },
                label="Collector {0}".format(x))

            if record_spikes:
                collector_column.record()  # records only the spikes
            if record_v:
                collector_column.record_v(
                )  # records the membrane potential -- very resource demanding!
                blocker_columns.record_v()

            network.append((blocker_columns, collector_column))

        self._interconnect_neurons(network, verbose=verbose)
        if self.dim_x > 1:
            self._interconnect_neurons_inhexc(network, verbose)
        else:
            global _retina_proj_l, _retina_proj_r, same_disparity_indices
            _retina_proj_l = [[0]]
            _retina_proj_r = [[0]]
            same_disparity_indices = [[0]]

        return network

    def _interconnect_neurons(self, network, verbose=False):

        assert network is not None, \
            "ERROR: Network is not initialised! Interconnecting failed."

        synaptic_params = self.cell_params['synaptic']

        # generate connectivity list: 0 untill dimensionRetinaY-1 for the left
        # and dimensionRetinaY till dimensionRetinaY*2 - 1 for the right
        connList = []
        for y in range(0, self.dim_y):
            connList.append(
                (y, y, synaptic_params['wBC'], synaptic_params['dBC']))
            connList.append((y + self.dim_y, y, synaptic_params['wBC'],
                             synaptic_params['dBC']))

        # connect the inhibitory neurons to the cell output neurons
        if verbose:
            print "INFO: Interconnecting Neurons. This may take a while."
        for ensemble in network:
            ps.Projection(ensemble[0],
                          ensemble[1],
                          ps.FromListConnector(connList),
                          target='inhibitory')

    def _interconnect_neurons_inhexc(self, network, verbose=False):

        assert network is not None, \
            "ERROR: Network is not initialised! Interconnecting for inhibitory and excitatory patterns failed."

        if verbose and self.cell_params['topological']['radius_i'] < self.dim_x:
            print "WARNING: Bad radius of inhibition. Uniquness constraint cannot be satisfied."
        if verbose and 0 <= self.cell_params['topological'][
                'radius_e'] > self.dim_x:
            print "WARNING: Bad radius of excitation. "

        # create lists with inhibitory along the Retina Right projective line
        nbhoodInhL = []
        nbhoodInhR = []
        nbhoodExcX = []
        nbhoodEcxY = []
        # used for the triangular form of the matrix in order to remain within the square
        if verbose:
            print "INFO: Generating inhibitory and excitatory connectivity patterns."
        # generate rows
        limiter = self.max_disparity - self.min_disparity + 1
        ensembleIndex = 0

        while ensembleIndex < len(network):
            if ensembleIndex / (self.max_disparity - self.min_disparity + 1) > \
                                    (self.dim_x - self.min_disparity) - (self.max_disparity - self.min_disparity) - 1:
                limiter -= 1
                if limiter == 0:
                    break
            nbhoodInhL.append(
                [ensembleIndex + disp for disp in range(0, limiter)])
            ensembleIndex += limiter

        ensembleIndex = len(network)

        # generate columns
        nbhoodInhR = [[x] for x in nbhoodInhL[0]]
        shiftGlob = 0
        for x in nbhoodInhL[1:]:
            shiftGlob += 1
            shift = 0

            for e in x:
                if (shift + 1) % (self.max_disparity - self.min_disparity +
                                  1) == 0:
                    nbhoodInhR.append([e])
                else:
                    nbhoodInhR[shift + shiftGlob].append(e)
                shift += 1

        # generate all diagonals
        for diag in map(None, *nbhoodInhL):
            sublist = []
            for elem in diag:
                if elem is not None:
                    sublist.append(elem)
            nbhoodExcX.append(sublist)

        # generate all y-axis excitation
        for x in range(0, self.dim_y):
            for e in range(1, self.cell_params['topological']['radius_e'] + 1):
                if x + e < self.dim_y:
                    nbhoodEcxY.append(
                        (x, x + e, self.cell_params['synaptic']['wCCe'],
                         self.cell_params['synaptic']['dCCe']))
                if x - e >= 0:
                    nbhoodEcxY.append(
                        (x, x - e, self.cell_params['synaptic']['wCCe'],
                         self.cell_params['synaptic']['dCCe']))

        # Store these lists as global parameters as they can be used to quickly match the spiking collector neuron
        # with the corresponding pixel xy coordinates (same_disparity_indices)
        # TODO: think of a better way to encode pixels: closed form formula would be perfect
        # These are also used when connecting the spike sources to the network! (retina_proj_l, retina_proj_r)

        global _retina_proj_l, _retina_proj_r, same_disparity_indices

        _retina_proj_l = nbhoodInhL
        _retina_proj_r = nbhoodInhR
        same_disparity_indices = nbhoodExcX

        if verbose:
            print "INFO: Connecting neurons for internal excitation and inhibition."

        for row in nbhoodInhL:
            for pop in row:
                for nb in row:
                    if nb != pop:
                        ps.Projection(
                            network[pop][1],
                            network[nb][1],
                            ps.OneToOneConnector(
                                weights=self.cell_params['synaptic']['wCCi'],
                                delays=self.cell_params['synaptic']['dCCi']),
                            target='inhibitory')
        for col in nbhoodInhR:
            for pop in col:
                for nb in col:
                    if nb != pop:
                        ps.Projection(
                            network[pop][1],
                            network[nb][1],
                            ps.OneToOneConnector(
                                weights=self.cell_params['synaptic']['wCCi'],
                                delays=self.cell_params['synaptic']['dCCi']),
                            target='inhibitory')

        for diag in nbhoodExcX:
            for pop in diag:
                for nb in range(
                        1, self.cell_params['topological']['radius_e'] + 1):
                    if diag.index(pop) + nb < len(diag):
                        ps.Projection(
                            network[pop][1],
                            network[diag[diag.index(pop) + nb]][1],
                            ps.OneToOneConnector(
                                weights=self.cell_params['synaptic']['wCCe'],
                                delays=self.cell_params['synaptic']['dCCe']),
                            target='excitatory')
                    if diag.index(pop) - nb >= 0:
                        ps.Projection(
                            network[pop][1],
                            network[diag[diag.index(pop) - nb]][1],
                            ps.OneToOneConnector(
                                weights=self.cell_params['synaptic']['wCCe'],
                                delays=self.cell_params['synaptic']['dCCe']),
                            target='excitatory')

        for ensemble in network:
            ps.Projection(ensemble[1],
                          ensemble[1],
                          ps.FromListConnector(nbhoodEcxY),
                          target='excitatory')

    def _connect_spike_sources(self, retinae=None, verbose=False):

        if verbose:
            print "INFO: Connecting Spike Sources to Network."

        global _retina_proj_l, _retina_proj_r

        # left is 0--dimensionRetinaY-1; right is dimensionRetinaY--dimensionRetinaY*2-1
        connListRetLBlockerL = []
        connListRetLBlockerR = []
        connListRetRBlockerL = []
        connListRetRBlockerR = []
        for y in range(0, self.dim_y):
            connListRetLBlockerL.append(
                (y, y, self.cell_params['synaptic']['wSaB'],
                 self.cell_params['synaptic']['dSaB']))
            connListRetLBlockerR.append(
                (y, y + self.dim_y, self.cell_params['synaptic']['wSzB'],
                 self.cell_params['synaptic']['dSzB']))
            connListRetRBlockerL.append(
                (y, y, self.cell_params['synaptic']['wSzB'],
                 self.cell_params['synaptic']['dSzB']))
            connListRetRBlockerR.append(
                (y, y + self.dim_y, self.cell_params['synaptic']['wSaB'],
                 self.cell_params['synaptic']['dSaB']))

        retinaLeft = retinae['left'].pixel_columns
        retinaRight = retinae['right'].pixel_columns
        pixel = 0
        for row in _retina_proj_l:
            for pop in row:
                ps.Projection(retinaLeft[pixel],
                              self.network[pop][1],
                              ps.OneToOneConnector(
                                  weights=self.cell_params['synaptic']['wSC'],
                                  delays=self.cell_params['synaptic']['dSC']),
                              target='excitatory')
                ps.Projection(retinaLeft[pixel],
                              self.network[pop][0],
                              ps.FromListConnector(connListRetLBlockerL),
                              target='excitatory')
                ps.Projection(retinaLeft[pixel],
                              self.network[pop][0],
                              ps.FromListConnector(connListRetLBlockerR),
                              target='inhibitory')
            pixel += 1

        pixel = 0
        for col in _retina_proj_r:
            for pop in col:
                ps.Projection(retinaRight[pixel],
                              self.network[pop][1],
                              ps.OneToOneConnector(
                                  weights=self.cell_params['synaptic']['wSC'],
                                  delays=self.cell_params['synaptic']['dSC']),
                              target='excitatory')
                ps.Projection(retinaRight[pixel],
                              self.network[pop][0],
                              ps.FromListConnector(connListRetRBlockerR),
                              target='excitatory')
                ps.Projection(retinaRight[pixel],
                              self.network[pop][0],
                              ps.FromListConnector(connListRetRBlockerL),
                              target='inhibitory')
            pixel += 1

        # configure for the live input streaming if desired
        if not (retinae['left'].use_prerecorded_input
                and retinae['right'].use_prerecorded_input):
            from spynnaker_external_devices_plugin.pyNN.connections.spynnaker_live_spikes_connection import \
                SpynnakerLiveSpikesConnection

            all_retina_labels = retinaLeft.labels + retinaRight.labels
            self.live_connection_sender = SpynnakerLiveSpikesConnection(
                receive_labels=None,
                local_port=19999,
                send_labels=all_retina_labels)

            # this callback will be executed right after simulation.run() has been called. If simply a while True
            # is put there, the main thread will stuck there and will not complete the simulation.
            # One solution might be to start a thread/process which runs a "while is_running:" loop unless the main thread
            # sets the "is_running" to False.
            self.live_connection_sender.add_start_callback(
                all_retina_labels[0], self.start_injecting)

            import DVSReader as dvs
            # the port numbers might well be wrong
            self.dvs_stream_left = dvs.DVSReader(
                port=0,
                label=retinaLeft.label,
                live_connection=self.live_connection_sender)
            self.dvs_stream_right = dvs.DVSReader(
                port=1,
                label=retinaRight.label,
                live_connection=self.live_connection_sender)

            # start the threads, i.e. start reading from the DVS. However, nothing will be sent to the SNN.
            # See start_injecting
            self.dvs_stream_left.start()
            self.dvs_stream_right.start()

    def start_injecting(self):
        # start injecting into the SNN
        self.dvs_stream_left.start_injecting = True
        self.dvs_stream_right.start_injecting = True

    def get_network_dimensions(self):
        parameters = {
            'size': self.size,
            'dim_x': self.dim_x,
            'dim_y': self.dim_y,
            'min_d': self.min_disparity,
            'max_d': self.max_disparity
        }
        return parameters

    """ this method returns (and saves) a full list of spike times
    with the corresponding pixel location and disparities."""

    def get_spikes(self, sort_by_time=True, save_spikes=True):
        global same_disparity_indices, _retina_proj_l
        spikes_per_population = [x[1].getSpikes() for x in self.network]
        spikes = list()
        # for each column population in the network, find the x,y coordinates corresponding to the neuron
        # and the disparity. Then write them in the list and sort it by the timestamp value.
        for col_index, col in enumerate(spikes_per_population,
                                        0):  # it is 0-indexed
            # find the disparity
            disp = self.min_disparity
            for d in range(0, self.max_disparity + 1):
                if col_index in same_disparity_indices[d]:
                    disp = d + self.min_disparity
                    break
            # for each spike in the population extract the timestamp and x,y coordinates
            for spike in col:
                x_coord = 0
                for p in range(0, self.dim_x):
                    if col_index in _retina_proj_l[p]:
                        x_coord = p
                        break
                y_coord = int(spike[0])
                spikes.append((round(spike[1], 1), x_coord + 1, y_coord + 1,
                               disp))  # pixel coordinates are 1-indexed
        if sort_by_time:
            spikes.sort(key=lambda x: x[0])
        if save_spikes:
            if not os.path.exists("./spikes"):
                os.makedirs("./spikes")
            i = 0
            while os.path.exists("./spikes/{0}_{1}_spikes.dat".format(
                    self.experiment_name, i)):
                i += 1
            with open(
                    './spikes/{0}_{1}_spikes.dat'.format(
                        self.experiment_name, i), 'w') as fs:
                self._write_preamble(fs)
                fs.write(
                    "### DATA FORMAT ###\n"
                    "# Description: All spikes from the Collector Neurons are recorded. The disparity is inferred "
                    "from the Neuron ID. The disparity is calculated with the left camera as reference."
                    "The timestamp is dependent on the simulation parameters (simulation timestep).\n"
                    "# Each row contains: "
                    "Time -- x-coordinate -- y-coordinate -- disparity\n"
                    "### DATA START ###\n")
                for s in spikes:
                    fs.write(
                        str(s[0]) + " " + str(s[1]) + " " + str(s[2]) + " " +
                        str(s[3]) + "\n")
                fs.write("### DATA END ###")
                fs.close()
        return spikes

    """ this method returns the accumulated spikes for each disparity as a list. It is not very useful except when
    the disparity sorting and formatting in the more general one get_spikes is not needed."""

    def get_accumulated_disparities(self,
                                    sort_by_disparity=True,
                                    save_spikes=True):
        if sort_by_disparity:
            global same_disparity_indices
            spikes_per_disparity_map = []
            for d in range(0, self.max_disparity - self.min_disparity + 1):
                collector_cells = [
                    self.network[x][1] for x in same_disparity_indices[d]
                ]
                spikes_per_disparity_map.append(
                    sum([
                        sum(x.get_spike_counts().values())
                        for x in collector_cells
                    ]))
                if save_spikes:
                    if not os.path.exists("./spikes"):
                        os.makedirs("./spikes")
                    i = 0
                    while os.path.exists("./spikes/{0}_{1}_disp.dat".format(
                            self.experiment_name, i)):
                        i += 1
                    with open(
                            './spikes/{0}_{1}_disp.dat'.format(
                                self.experiment_name, i), 'w') as fd:
                        self._write_preamble(fd)
                        for s in spikes_per_disparity_map:
                            fd.write(str(s) + "\n")
                        fd.close()
                return spikes_per_disparity_map
        else:
            # this is pretty useless. maybe it should be removed in the future
            all_spikes = sum(
                sum(x[1].get_spikes_count().values() for x in self.network))
            return all_spikes

    """ this method returns a list containing the membrane potential of all neural populations sorted by id."""

    def get_v(self, save_v=True):
        voltages = {
            "collector_v": [x[1].get_v() for x in self.network],
            "blockers_v": [x[0].get_v() for x in self.network]
        }
        if save_v:
            if not os.path.exists("./membrane_potentials"):
                os.makedirs("./membrane_potentials")
            i = 0
            while os.path.exists(
                    "./membrane_potentials/{0}_{1}_vmem.dat".format(
                        self.experiment_name, i)):
                i += 1
            with open(
                    './membrane_potentials/{0}_{1}_vmem.dat'.format(
                        self.experiment_name, i), 'w') as fv:
                self._write_preamble(fv)
                fv.write(
                    "### DATA FORMAT ###\n"
                    "# Description: First all Blocker Populations are being printed. "
                    "Then all Collector populations. Both are sorted by Population ID (i.e. order of creation). "
                    "Each Blocker/Collector Population lists all neurons, sorted by Neuron ID. "
                    "There are two times more Blocker than Collector Neurons.\n"
                    "# Each row contains: "
                    "Blocker/Collector tag (b/c) -- Population ID -- Neuron ID -- Time -- Membrane Potential\n"
                    "### DATA START ###\n")
                for pop_id, pop_v in enumerate(voltages["blockers_v"]):
                    for v in pop_v:
                        fv.write("b " + str(int(pop_id)) + " " +
                                 str(int(v[0])) + " " + str(v[1]) + " " +
                                 str(v[2]) + "\n")
                for pop_id, pop_v in enumerate(voltages["collector_v"]):
                    for v in pop_v:
                        fv.write("c " + str(int(pop_id)) + " " +
                                 str(int(v[0])) + " " + str(v[1]) + " " +
                                 str(v[2]) + "\n")
                fv.write("### DATA END ###")
                fv.close()
        return voltages

    def _write_preamble(self, opened_file_descriptor):
        if opened_file_descriptor is not None:
            f = opened_file_descriptor
            f.write("### PREAMBLE START ###\n")
            f.write("# Experiment name: \n\t{0}\n".format(
                self.experiment_name))
            f.write(
                "# Network parameters "
                "(size in ensembles, x-dimension, y-dimension, minimum disparity, maximum disparity, "
                "radius of excitation, radius of inhibition): "
                "\n\t{0} {1} {2} {3} {4} {5} {6}\n".format(
                    self.size, self.dim_x, self.dim_y, self.min_disparity,
                    self.max_disparity,
                    self.cell_params['topological']['radius_e'],
                    self.cell_params['topological']['radius_i']))
            f.write(
                "# Neural parameters "
                "(tau_excitation, tau_inhibition, tau_membrane, v_reset_blocker, v_reset_collector): "
                "\n\t{0} {1} {2} {3} {4}\n".format(
                    self.cell_params['neural']['tau_E'],
                    self.cell_params['neural']['tau_I'],
                    self.cell_params['neural']['tau_mem'],
                    self.cell_params['neural']['v_reset_blocker'],
                    self.cell_params['neural']['v_reset_collector']))
            f.write(
                '# Synaptic parameters '
                '(wBC, dBC, wSC, dSC, wSaB, dSaB, wSzB, dSzB, wCCi, dCCi, wCCe, dCCe): '
                '\n\t{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11}\n'.
                format(self.cell_params['synaptic']['wBC'],
                       self.cell_params['synaptic']['dBC'],
                       self.cell_params['synaptic']['wSC'],
                       self.cell_params['synaptic']['dSC'],
                       self.cell_params['synaptic']['wSaB'],
                       self.cell_params['synaptic']['dSaB'],
                       self.cell_params['synaptic']['wSzB'],
                       self.cell_params['synaptic']['dSzB'],
                       self.cell_params['synaptic']['wCCi'],
                       self.cell_params['synaptic']['dCCi'],
                       self.cell_params['synaptic']['wCCe'],
                       self.cell_params['synaptic']['dCCe']))
            f.write(
                '# Comments: Caution: The synaptic parameters may vary according with '
                'different simulation time steps. To understand the abbreviations for the '
                'synaptic parameters, see the code documentation.\n')
            f.write("### PREAMBLE END ###\n")
# in a safe way afterwards, and verify the behavior
pop_forward.record()
# Activate the sending of live spikes
ExternalDevices.activate_live_output_for(
    pop_forward, database_notify_host="localhost",
    database_notify_port_num=19996)
# Create a sender of packets for the forward population
def send_input_forward(label, sender):
    print "Sending forward spike for neuron 0"
    sender.send_spike(label, 0)
# Create a receiver of live spikes
def receive_spikes(label, time, neuron_ids):
    for neuron_id in neuron_ids:
        print "Received spike at time", time, "from", label, "-", neuron_id
# Set up the live connection for sending spikes
live_spikes_connection = SpynnakerLiveSpikesConnection(
    receive_labels=None, local_port=19999, send_labels=["spike_injector_forward"])
# Set up callbacks to occur at the start of simulation
live_spikes_connection.add_start_callback("spike_injector_forward", send_input_forward)
# if not using the c visualiser, then a new spynnaker live spikes connection
# is created to define that there are python code which receives the
# outputted spikes.
live_spikes_connection = SpynnakerLiveSpikesConnection(
    receive_labels=["pop_forward"], local_port=19996, send_labels=None)
# Set up callbacks to occur when spikes are received
live_spikes_connection.add_receive_callback("pop_forward", receive_spikes)
# Run the simulation on spiNNaker
Frontend.run(run_time)
# Retrieve spikes from the synfire chain population
spikes_forward = pop_forward.getSpikes()
# If there are spikes, plot using matplotlib
if len(spikes_forward) != 0:
Пример #33
0
for pop in range(0, populationCount):
    collector.append(Frontend.Population(neuronCount, Frontend.IF_curr_exp, cell_params_col, label='{0}'.format(pop)))
    source.append(Frontend.Population(neuronCount, Frontend.SpikeSourceArray, {'spike_times': spikeTimes} , label='s{0}'.format(pop)))
    Frontend.Projection(source[pop], collector[pop], Frontend.OneToOneConnector(weights=22, delays=0.2), target='excitatory') 
    collector[pop].record()
    counter_received_spikes.append(0)
    collector_labels.append('{0}'.format(pop))

def receive_spike_cell(label, time, neuron_ids):
    if time < 5050 :
        counter_received_spikes[int(label)] += len(neuron_ids) 

for col in collector:     
    ExternalDevices.activate_live_output_for(col, database_notify_host="localhost",database_notify_port_num=19996)
    
live_spikes_connection_receiver = SpynnakerLiveSpikesConnection(receive_labels=collector_labels, local_port=19996, send_labels=None)

for label in collector_labels:
    live_spikes_connection_receiver.add_receive_callback(label, receive_spike_cell)


Frontend.run(run_time)

total_spikes_count = 0
for col in collector:
    total_spikes_count += len(col.getSpikes())

print "Spikes count collector:", total_spikes_count
print "Spikes count received:", sum(counter_received_spikes)

Frontend.end()
class _ROS_Spinnaker_Interface(object):

    """
    Transform incoming ROS Messages into spikes and inject them into the Spinnaker Board and the other way round.

a
    Args:
b
    n_neurons_source (int):  The number of neurons of the Spike Source.

    transfer_function_send (function handle): A handle to the transfer function used to convert
        the ROS input data into spikes.
    
    transfer_function_recv (function handle): A handle to the transfer function used to convert
        the live spikes to a ROS value.
    
    output_population (pynn.Population): The pyNN.Population you want to get the live spikes from.
        Defaults to None, so the live output is disabled.

    ros_topic_send (str): The ROS Topic used for sending into spinnaker.
        Defaults to "to_spinnaker".

    ros_topic_recv (str): The ROS Topic used for sending into ROS.
        Defaults to "from_spinnaker".

    clk_rate (int): The frequency the ROS Node is running with in Hz.
        Defaults to 1000 Hz.
    
    ros_output_rate (int): The frequency with which ros messages are sent out.
        Defaults to 10 Hz.

    benchmark (bool): Receive a timing output at the end of the simulation.
        Defaults to False.


    Attributes:

    InjectorPopulation: The ExternalDevices.SpikeInjector instance which is used internally.


    Functions:
        
        is_roscore_running(): True if the ros core is runnig else False.

        activate_live_output_for(pynn.Population): Set the pynn population you want to get the live spikes from.

        add_simulation_start_callback(function): Register the function as callback at simulation start.


    Examples:
        Have a look at the ros_spinnaker_interface_example.py or other example scripts.

    Notes:
        This interface uses the Spinnaker LiveSpikesConnection internally with the local ports
        19999 and 17895 and the spinnaker port 12345. These ports are widely used for live spikes and
        therefore should'nt cause any problems, however you can also simply change them in the constructor if needed.
        For each parallel interface used, these port numbers are increased by one, so the second interface will use
        the local ports 20000 and 17896 and 12346 on spinnaker, etc.

        If you want to change or extend this interface, consider that there is a sub process started by the 
        interface itself, as well as a thread controlled by spinnaker. Make sure they terminate and communicate properly.

        Currently only the std_msgs.msg.Int64 type is supported for ROS Messages. If you want to use your own
        ros message types it is possible, but you need to change some code yourself:
            - in the _incoming_ros_package_callback unpack the ros message fields and decide what to do with it.
            - in run_ros_node adjust the Publisher and Subscriber message types and (if needed) the publisher callback.
    """


    _instance_counter = count(0)


    def __init__(self,
            n_neurons_source=None,
            Spike_Source_Class=None,
            Spike_Sink_Class=None,
            output_population=None,
            ros_topic_send='to_spinnaker',
            ros_topic_recv='from_spinnaker',
            clk_rate=1000,
            ros_output_rate=10,
            benchmark=False):

        # Members
        self.n_neurons = n_neurons_source if n_neurons_source is not None else 1
        self._Spike_Source_Class = Spike_Source_Class
        self._Spike_Sink_Class = Spike_Sink_Class

        self.interface_id = self._instance_counter.next()

        self._output_population = output_population


        self.send_topic = ros_topic_send
        self.recv_topic = ros_topic_recv
        self._clk_rate = clk_rate  # in Hz
        self._ros_output_rate = ros_output_rate  # Hz
        self._benchmark = benchmark

        

        self._injector_label = 'injector{}'.format(self.interface_id)
        spike_injector_port = 12345 + self.interface_id
        local_port = 19999 + self.interface_id
        local_recv_port = 17895
        self._database_notify_port = local_port

        self._queue_ros_spinnaker = Queue()
        self._queue_spinnaker_ros = Queue()

        # My own "population" data structures to send and receive spikes, initialized later.
        self._spike_source = None
        self._spike_sink = None

        send_labels = [self._injector_label]
        rcv_labels = None

        self.sender_active = n_neurons_source is not None and self._Spike_Source_Class is not None
        self.receiver_active = self._output_population is not None and self._Spike_Sink_Class is not None

        if self.receiver_active:
            rcv_labels = [self._output_population.label]

        self._spike_injector_population = pynn.Population(size=self.n_neurons,
                                                          cellclass=ExternalDevices.SpikeInjector,
                                                          cellparams={'port': spike_injector_port,
                                                                      'database_notify_port_num':local_port},
                                                          label=self._injector_label)

        self._spinnaker_connection = LiveSpikesConnection(receive_labels=rcv_labels,
                                                          local_port=local_port,
                                                          send_labels=send_labels)

        self._spinnaker_connection.add_start_callback(self._injector_label, self._init_ros_node)  # spinnaker thread!

        if self.receiver_active:
            self._spinnaker_connection.add_receive_callback(self._output_population.label, self._incoming_spike_callback)

            ExternalDevices.activate_live_output_for(self._output_population,
                                                     port=local_recv_port+self.interface_id,
                                                     database_notify_port_num=self._database_notify_port)

    def _init_ros_node(self, label, sender):
        """
        Initialize the spike source and start the ros node.
        
        This is started as thread from the spinnaker LiveSpikesConnection at the beginning of the simulation.
        """
        timestep = 1.0 / self._clk_rate * 1000

        #if the readout population consists of more than one neuron -> set the readout_pop flag
        if self._output_population.size > 1:
            self._readout_pop_flag = True
            print('**********readout_flag_activated*************'.format(self.interface_id))
        

        if self.sender_active:
            self._spike_source = self._Spike_Source_Class(self.n_neurons,
                                                          label,
                                                          sender,
                                                          self._queue_ros_spinnaker,
                                                          timestep)

        if self.receiver_active:
            self._spike_sink = self._Spike_Sink_Class(len(self._output_population),  # get number of neurons
                                                      self._queue_spinnaker_ros,
                                                      timestep)

        if not self.is_roscore_running():
            sys.exit(0)

        p = Process(target=self.run_ros_node)
        p.daemon = True
        print("Interface {} started".format(self.interface_id))
        p.start()

    def run_ros_node(self):
        """
        Initialize a ROS Node and subscribe and publish to the given ROS Topics.

        ROS requires this function to run in its own child process.

        The tick generator makes sure that it runs once per timestep.
        """
        rospy.init_node('spinnaker_ros_interface{}'.format(self.interface_id), anonymous=True)

        if self._readout_pop_flag:
            if self.receiver_active:
                publisher = rospy.Publisher(self.recv_topic, Pop_List, queue_size=10)
            if self.sender_active:
                rospy.Subscriber(self.send_topic, Int64, self._incoming_ros_package_callback)
        else:
            if self.receiver_active:
                publisher = rospy.Publisher(self.recv_topic, Int64, queue_size=10)
            if self.sender_active:
                rospy.Subscriber(self.send_topic, Int64, self._incoming_ros_package_callback)

        rospy.on_shutdown(self.on_ros_node_shutdown)

        def ros_publisher_callback(event):
            if not self.receiver_active:
                return
            try:
                publisher.publish(self._spike_sink._get_ros_value())
            except rospy.ROSException:
                return

        rospy.Timer(rospy.Duration(1.0 / self._ros_output_rate), ros_publisher_callback)  # 10 Hz default
        
        ros_timer = rospy.Rate(self._clk_rate)
        
        self.interface_start_time = time.time()

        if self._benchmark:
            last = time.clock()
            self._num_timer_warnings = 0
            self._num_ticks = 0
            self._mainloop_execution_times = []
        
        while not rospy.is_shutdown():
            if self.sender_active:
                self._spike_source._update()
            if self.receiver_active:
                self._spike_sink._update()
            
            # Count if the mainloop execution takes too long
            if self._benchmark:
                self._num_ticks += 1
                now = time.clock()
                self._mainloop_execution_times.append(now - last)
                if (now - last) > (1.0 / self._clk_rate):
                    self._num_timer_warnings += 1
                last = now

            ros_timer.sleep()
        
    def _incoming_ros_package_callback(self, ros_msg):
        """
        Callback for the incoming data. Forwards the data via UDP to the Spinnaker Board.
        """
        self._queue_ros_spinnaker.put(ros_msg.data)  # data is the name of the ros std_msgs data field.

    def _incoming_spike_callback(self, label, time, neuron_ids):
        """
        Call this callback to process incoming live spikes.
        """
        for neuron_id in neuron_ids:
            spike = (label, time, neuron_id)
            self._queue_spinnaker_ros.put(spike)

    def is_roscore_running(self):
        """
        Returns True if the ROS Core is running and False otherwise.
        """
        return True  # TODO
        try:
            _, _, ros_master_pid = rospy.get_master().getPid()
            return True

        except socket.error:
            print('\n\n[!] Cannot communicate with ROS Master. Please check if ROS Core is running.\n\n')
            return False
    
    @property
    def InjectorPopulation(self):
        """
        The handle to the ExternalDevices.SpikeInjector which is used internally.
        Can be used for pynn.Connectors
        """
        return self._spike_injector_population if self.sender_active else None

    def __str__(self):
        return 'ROS-Spinnaker-Interface'

    def __repr__(self):
        return self._spike_injector_population
    
    def on_ros_node_shutdown(self):
        # These do nothing on default. The plot functions need to be redefined in the SpikeSink/Source used to
        # actually do something.

        if self._benchmark:
            lock.acquire()
            print("Interface {} Benchmark".format(self.interface_id))
            # print("startet running on time {}".format(self.interface_start_time))
            # print("stopped runnning on time {}".format(time.time()))
            print("Number of times the mainloop took too long: {}".format(self._num_timer_warnings))
            print("Number of Mainloop Calls: {}".format(self._num_ticks))
            import numpy as np
            mean_execution_time = np.mean(self._mainloop_execution_times)
            print("Mean Mainloop Execution Time: {} ms, (max {} ms)".format(mean_execution_time, 1.0 / self._clk_rate))
            print("Highest possible interface clock rate: {} Hz\n".format(1.0 / mean_execution_time))
            lock.release()

        if self.sender_active:
            self._spike_source.plot()
        if self.receiver_active:
            self._spike_sink.plot()
    
    def add_simulation_start_callback(self, function):
        if self.sender_active:
            self._spinnaker_connection.add_start_callback(self._injector_label, function)
Пример #35
0
#~ cv2.imshow("new window", out)
#~ cv2.waitKey(1)

sim.setup(timestep=1.0, min_delay=1.0, max_delay=10.0)

# echo population ----------------------------------------------------------
target = sim.Population(num_neurons, model, cell_params, label="echo")

target.record()

ExternalDevices.activate_live_output_for(target, 
                                         database_notify_host="localhost",
                                         database_notify_port_num=live_out_port)

live_spikes_receive = SpynnakerLiveSpikesConnection(receive_labels=["echo",],
                                                    local_port=receive_port, 
                                                    send_labels=None)

live_spikes_receive.add_receive_callback("echo", receive_spikes)

# END: echo population ----------------------------------------------------------


# stim population ----------------------------------------------------------
stimulation = sim.Population(num_neurons, ImageDvsEmulatorDevice, cam_params,
                             label="Webcam population")

# END: stim population ----------------------------------------------------------


# connections ----------------------------------------------------------
class ExternalImageDvsEmulatorDevice(ReverseIpTagMultiCastSource,
                                     AbstractProvidesOutgoingConstraints,
                                     ):

    MODE_128 = "128"
    MODE_64  = "64"
    MODE_32  = "32"
    MODE_16  = "16"
    
    UP_POLARITY     = "UP"
    DOWN_POLARITY   = "DOWN"
    MERGED_POLARITY = "MERGED"
    POLARITY_DICT   = {UP_POLARITY: uint8(0), 
                     DOWN_POLARITY: uint8(1), 
                     MERGED_POLARITY: uint8(2),
                     0: UP_POLARITY,
                     1: DOWN_POLARITY,
                     2: MERGED_POLARITY}
    
    OUTPUT_RATE         = "RATE"
    OUTPUT_TIME         = "TIME"
    OUTPUT_TIME_BIN     = "TIME_BIN"
    OUTPUT_TIME_BIN_THR = "TIME_BIN_THR"
    
    BEHAVE_MICROSACCADE = "SACCADE"
    BEHAVE_ATTENTION    = "ATTENTION"
    BEHAVE_TRAVERSE     = "TRAVERSE"
    BEHAVE_FADE         = "FADE"
    
    IMAGE_TYPES = ["png", 'jpeg', 'jpg']
    MAX_LOADED_IMAGES = 100
    
    def __init__(self, n_neurons, machine_time_step, timescale_factor,
                 label, images=None, 
                 port=12345, virtual_key=None,
                 spikes_per_second=0, ring_buffer_sigma=None, 
                 database_socket=None, 
                 behaviour="SACCADE", max_saccade_distance=1,
                 frames_per_microsaccade = 1, frames_per_saccade = 29, #~30
                 total_on_time_ms = 1000, inter_off_time_ms = 100,
                 background_gray = 0,
                 fps=90, mode="128", scale_img=True, polarity="MERGED",
                 inhibition = False, inh_area_width = 2,
                 threshold=12, adaptive_threshold = False,
                 min_threshold=6, max_threshold=168,
                 threshold_delta_down = 2, threshold_delta_up = 12,
                 output_type="TIME", num_bits_per_spike=5, 
                 history_weight=0.99, save_spikes=None,
                 local_port=19876):
        """
        :param device_id: int for webcam modes, or string for video file
        :param mode: The retina "mode"
        :param retina_key: The value of the top 16-bits of the key
        :param polarity: The "polarity" of the retina data
        :param machine_time_step: The time step of the simulation
        :param timescale_factor: The timescale factor of the simulation
        :param label: The label for the population
        :param n_neurons: The number of neurons in the population
        
        """
        
        
        self._loaded_idx = 0
        self._total_images = 0
        self._image_list = self.get_images_paths(images)
        
        fixed_n_neurons = n_neurons

        if mode == ExternalImageDvsEmulatorDevice.MODE_128 or \
           mode == ExternalImageDvsEmulatorDevice.MODE_64  or \
           mode == ExternalImageDvsEmulatorDevice.MODE_32  or \
           mode == ExternalImageDvsEmulatorDevice.MODE_16:
            self._out_res = int(mode)

        else:
            raise exceptions.SpynnakerException("the model does not "
                                                "recongise this mode")

        if (polarity == ExternalImageDvsEmulatorDevice.UP_POLARITY or
            polarity == ExternalImageDvsEmulatorDevice.DOWN_POLARITY):
            fixed_n_neurons = self._out_res**2
        else:
            fixed_n_neurons = 2*(self._out_res**2)

        if fixed_n_neurons != n_neurons and n_neurons is not None:
            logger.warn("The specified number of neurons for the DVS emulator"
                        " device has been ignored {} will be used instead"
                        .format(fixed_n_neurons))

        self._center_x = 0
        self._center_y = 0
        
        self._max_saccade_distance = max_saccade_distance
        self._frames_per_microsaccade = frames_per_microsaccade
        self._frames_per_saccade = frames_per_saccade
        self._traverse_speed = (self._out_res*2.)/((total_on_time_ms/1000.)*fps)
        
        self._behaviour = behaviour
        self._total_on_time_ms = total_on_time_ms
        self._inter_off_time_ms = inter_off_time_ms
        self._background_gray = background_gray
        
        self._polarity = polarity
        self._polarity_n = ExternalImageDvsEmulatorDevice.POLARITY_DICT[polarity]
        self._global_max = int16(0)
        self._output_type = output_type
        
        self._raw_frame = None
        self._gray_frame = None
        self._tmp_frame = None
        
        self._ref_frame = 128*numpy.ones((self._out_res, self._out_res), dtype=int16) 
        
        self._curr_frame = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        self._moved_frame = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        self._silence_frame = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        
        self._spikes_frame = numpy.zeros((self._out_res, self._out_res, 3), dtype=uint8)
        
        self._diff = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        
        self._abs_diff = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        
        self._spikes = numpy.zeros((self._out_res, self._out_res), dtype=int16)

        self._adaptive_threshold = adaptive_threshold
        
        self._thresh_matrix = None
        if adaptive_threshold:
          self._thresh_matrix = numpy.zeros((self._out_res, self._out_res), 
                                             dtype=int16)

        self._threshold_delta_down = int16(threshold_delta_down)
        self._threshold_delta_up = int16(threshold_delta_up)
        self._max_threshold = int16(max_threshold)
        self._min_threshold = int16(min_threshold)
        
        self._up_spikes = None
        self._down_spikes = None
        self._spikes_lists = None
        
        self._threshold = int16(threshold)
        
        self._data_shift = uint8(numpy.log2(self._out_res))
        self._up_down_shift = uint8(2*self._data_shift)
        self._data_mask = uint8(self._out_res - 1)
        
        if self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN:
            self._num_bins = 8 #8-bit images don't need more
        elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._num_bins = 6 #should be enough?
        else:
            self._num_bins = int(1000./fps)

        self._num_bits_per_spike = min(num_bits_per_spike, self._num_bins)
        
        if self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN or \
           self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._log2_table = generate_log2_table(self._num_bits_per_spike, self._num_bins)
        else:
            self._log2_table = generate_log2_table(self._num_bits_per_spike, 8) #stupid hack, compatibility issues
            
        self._scale_img = scale_img
        self._img_height = 0
        self._img_height_crop_u = 0
        self._img_height_crop_b = 0
        self._img_width = 0
        self._img_width_crop_l = 0
        self._img_width_crop_r = 0
        self._img_ratio = 0.
        self._img_scaled_width = 0
        self._scaled_width = 0
        self._fps = fps
        self._half_frame = fps/2
        self._max_time_ms = int16((1./fps)*1000)
        
        self._time_per_spike_pack_ms = self.calculate_time_per_pack()
        
        self._get_sizes = True
        self._scale_changed = False
        
        self._running = True

        self._label = label
        self._n_neurons = fixed_n_neurons
        self._local_port = local_port
        
        self._inh_area_width = inh_area_width
        self._inhibition = inhibition
        
        self._history_weight = history_weight
        
        ################################################################

        if spinn_version == "2015.005":
            ReverseIpTagMultiCastSource.__init__(self, 
                n_neurons=self._n_neurons, 
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                port=self._local_port,
                label=self._label,
                virtual_key=virtual_key)
        else:
            ReverseIpTagMultiCastSource.__init__(self, 
                n_keys=self._n_neurons, 
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor, 
                label=self._label, 
                receive_port=self._local_port,
                virtual_key=virtual_key)
        
        AbstractProvidesOutgoingConstraints.__init__(self)

        print "number of neurons for webcam = %d"%self._n_neurons
        
        self._live_conn = SpynnakerLiveSpikesConnection(send_labels = [self._label, ],
                                                        local_port = self._local_port)
        def init(label, n_neurons, run_time_ms, machine_timestep_ms):
            print("Sending %d neuron sources from %s"%(n_neurons, label))
        
        self._live_conn.add_init_callback(self._label, init)
        self._live_conn.add_start_callback(self._label, self.run)
        self._sender = None

        self._save_spikes = save_spikes
        self._spike_list = []


    def get_outgoing_edge_constraints(self, partitioned_edge, graph_mapper):
        constraints = ReverseIpTagMultiCastSource\
            .get_outgoing_edge_constraints(
                self, partitioned_edge, graph_mapper)
        constraints.append(KeyAllocatorContiguousRangeContraint())
        return constraints


    def get_number_of_mallocs_used_by_dsg(self, vertex_slice, in_edges):
        mallocs = \
            ReverseIpTagMultiCastSource.get_number_of_mallocs_used_by_dsg(
                self, vertex_slice, in_edges)
        if config.getboolean("SpecExecution", "specExecOnHost"):
            return 1
        else:
            return mallocs


    def __del__(self):

        self._running = False

    
    def stop(self):
        self.__del__()
    
    
    def run(self, label, sender):
        
        self._label = label
        self._sender = sender
        #spike_list = self._spike_list
        
        max_run_time_s = self.no_machine_time_steps/float(self.machine_time_step) + 0.1
        time_per_frame_s = 1./self._fps
        time_per_image_s = self._total_on_time_ms/1000.
        time_off_s = self._inter_off_time_ms/1000.
        bg_gray = self._background_gray
        
        spike_queue = Queue()
        spike_emmision_proc = Process(target=self.send_spikes, args=(spike_queue,))
        spike_emmision_proc.start()
        
        img_queue = Queue()
        #~ spike_gen_proc = Process(target=self.process_frame, args=(img_queue,))
        spike_gen_proc = Process(target=self.process_frame, 
                                 args=(img_queue, spike_queue))
        spike_gen_proc.start()
        
        grab_times = []
        start_time = 0.
        app_start_time = time.time()
        app_curr_time = time.time()
        frame_start = 0.
        time_diff = 0.
        processed_images = 0
        buffer_idx = 0
        
        image_start_time = time.time()
        first_run = True
        silence_on = False
        frame_count = 1
        first_frame_time = True
        
        while self._running:
            
            frame_start = time.time()
            
            if  first_run or ( silence_on and \
               (frame_start - image_start_time) >= time_off_s ):
                # done waiting in silence, grab frame
                self.grab_frame(processed_images)
                self._moved_frame[:] = self._curr_frame
                silence_on = False
                first_run = False
                image_start_time = frame_start
                processed_images += 1
                silence_on = False
                frame_count = 1 
                self._center_x = 0
                self._center_y = 0
            elif not silence_on and \
                 (frame_start - image_start_time) >= time_per_image_s:
                # done showing current image, go to silence
                image_start_time = frame_start
                silence_on = True
                frame_count = 1 
            
            #reset count of images, run through them again
            if processed_images >= self._total_images:
                processed_images = 0

            
            # send the minimum difference value once to synchronize time-based
            # decoding on the receiver end
            if self._output_type != ExternalImageDvsEmulatorDevice.OUTPUT_RATE and \
               first_frame_time == True:
                
                first_frame_time = False
                self._silence_frame[:] = bg_gray + self._threshold + 1 
                
                img_queue.put(self._silence_frame)
                
            else:
                if silence_on:
                    self._moved_frame[:] = bg_gray
                else:
                    self._moved_frame[:] = self.move_image(frame_count)
            

                #"send" image to processing thread
                img_queue.put(self._moved_frame)
            
            # emulate frames per second
            time_diff = time.time() - frame_start
            if time_diff < time_per_frame_s:
                time.sleep(time_per_frame_s - time_diff*0.9)
            
            frame_count += 1
            
            # is application runtime done?
            app_curr_time = time.time()
            if app_curr_time - app_start_time > max_run_time_s:
                self._running = False

        print "imager runtime ", app_curr_time - app_start_time

        
        img_queue.put(None)
        spike_gen_proc.join()
        
        spike_queue.put(None)
        spike_emmision_proc.join()
        
        cv2.destroyAllWindows()
        
        




    def process_frame(self, img_queue, spike_queue):
        label = self._label
        sender = self._sender
        spikes_frame = self._spikes_frame
        spike_list = []
        move_times = []
        gen_times = []
        compose_times = []
        transform_times = []
        ref_up_times = []
        start_time = 0.
        end_time   = 0.
        lists = None
        while True:
            image = img_queue.get()

            if image is None or not self._running:  
                break
            
            start_time = time.time()
            self.generate_spikes(image)
            gen_times.append(time.time()-start_time)
            
            start_time = time.time()
            self.update_reference()
            ref_up_times.append(time.time()-start_time)
            
            start_time = time.time()
            lists = self.transform_spikes()
            transform_times.append(time.time() - start_time)
            
            spike_queue.put(lists)
            
            if self._save_spikes is not None:
                spike_list.append(lists)
              
            start_time = time.time()
            self.compose_output_frame()
            compose_times.append(time.time()-start_time)
            
            #show detected spikes
            cv2.imshow (label, spikes_frame)  
            
            if cv2.waitKey(1) & 0xFF == ord('q'):#\
               #or not sender.isAlive():
                self._running = False
                break
                
        
        #pipe_end.send(spike_list)
        
        print("gen times")
        print(numpy.array(gen_times).mean())
        print("update ref times")
        print(numpy.array(ref_up_times).mean())
        print("transform times")
        print(numpy.array(transform_times).mean())
        print("compose times")
        print(numpy.array(compose_times).mean())
        
        spike_queue.put(None)

        cv2.destroyAllWindows()
        
        if self._save_spikes is not None:
            #print spike_list
            print "attempting to save spike_list"
            pickle.dump( spike_list, open(self._save_spikes, "wb") )
            
        
        



    
    def send_spikes(self, spike_queue):
        
        sender = self._sender
        while True:
            spikes = spike_queue.get()
            
            if spikes is None or not self._running:  
                break
            
            self.emit_spikes(sender, spikes)
        
        cv2.destroyAllWindows()



    def move_image(self, frame_number):
        img = self._moved_frame
        fps = self._fps
        orig = self._curr_frame
        ref = self._ref_frame
        behaviour = self._behaviour
        half_frame = self._half_frame
        max_dist = self._max_saccade_distance
        speed = self._traverse_speed
        fp_uscd = self._frames_per_microsaccade
        fp_scd  = self._frames_per_saccade
        bg_gray = self._background_gray
        cx = self._center_x
        cy = self._center_y
        
        if behaviour == ExternalImageDvsEmulatorDevice.BEHAVE_TRAVERSE:
            img[:] = traverse_image(orig, frame_number, speed, bg_gray)
            
        elif behaviour == ExternalImageDvsEmulatorDevice.BEHAVE_FADE:
            img[:] = fade_image(orig, frame_number, half_frame, bg_gray)
            
        elif behaviour == ExternalImageDvsEmulatorDevice.BEHAVE_MICROSACCADE:
            img[:], cx, cy = usaccade_image(orig, frame_number, fp_uscd, 
                                            max_dist, cx, cy, bg_gray)

        else:
            img[:], cx, cy = attention_image(orig, img, ref, frame_number, 
                                             fp_uscd, fp_scd, 
                                             max_dist, cx, cy, bg_gray)
        
        self._center_x = cx
        self._center_y = cy
        return img


    def grab_frame(self, idx):

        self._gray_frame = cv2.imread(self._image_list[idx], CV_LOAD_IMAGE_GRAYSCALE)
        

        
        if self._gray_frame is None:
            print "could not read image %s"%self._image_list[idx]
            self._curr_frame[:] = 0
            return True
            
        #~ start_time = time.time()
        if self._get_sizes or self._scale_changed:
            self._get_sizes = False
            self._scale_changed = False
            self._img_height, self._img_width = self._gray_frame.shape
            

            if self._img_width <= self._out_res and self._img_height <= self._out_res:
                diff = self._out_res - self._img_width
                self._img_width_crop_l = diff//2
                self._img_width_crop_r = self._img_width_crop_l + self._img_width
                
                diff = self._out_res - self._img_height
                self._img_height_crop_u = diff//2
                self._img_height_crop_b = self._img_height_crop_u + self._img_height
                row_from = self._img_height_crop_u
                row_to = self._img_height_crop_b
                col_from = self._img_width_crop_l
                col_to = self._img_width_crop_r
                
                self._curr_frame[row_from:row_to, col_from:col_to] = self._gray_frame

                return True
                
            else:
                self._img_ratio = float(self._img_width)/float(self._img_height)
                self._img_scaled_width = int(float(self._out_res)*self._img_ratio)
                
                if self._scale_img:
                    diff = self._img_scaled_width - self._out_res
                    self._img_width_crop_l = diff//2
                    self._img_width_crop_r = self._img_width_crop_l + self._out_res
                else:
                    diff = self._img_width - self._out_res
                    self._img_width_crop_l = diff//2
                    self._img_width_crop_r = self._img_width_crop_l + self._out_res
                    diff = self._img_height - self._out_res
                    self._img_height_crop_u = diff//2
                    self._img_height_crop_b = self._img_height_crop_u + self._out_res
            
            self._tmp_frame = numpy.zeros((self._out_res, self._img_scaled_width))
            
            
        #~ end_time = time.time()
        #~ print("Time to calculate sizes = ", end_time - start_time)
        
        #~ start_time = time.time()
        if self._img_width <= self._out_res and self._img_height <= self._out_res:
            row_from = self._img_height_crop_u
            row_to = self._img_height_crop_b
            col_from = self._img_width_crop_l
            col_to = self._img_width_crop_r
            
            self._curr_frame[row_from:row_to, col_from:col_to] = self._gray_frame
            
        elif self._scale_img:
        
            self._tmp_frame[:] = cv2.resize(self._gray_frame, (self._img_scaled_width, self._out_res), 
                                         interpolation=CV_INTER_NN)
                             
            self._curr_frame[:] = self._tmp_frame[:, self._img_width_crop_l: self._img_width_crop_r]
        else:
        
            self._curr_frame[:] = self._gray_frame[self._img_height_crop_u: self._img_height_crop_b, 
                                                   self._img_width_crop_l:  self._img_width_crop_r]
        #~ end_time = time.time()
        #~ print("Time to scale frame = ", end_time - start_time)
        
        

        
        return True
            

    
    def emit_spikes(self, sender, lists):
        up_spks = self._up_spikes
        dn_spks = self._down_spikes
        lbl     = self._label
        max_time_s = self._time_per_spike_pack_ms/1000.
        #~ lists   = self._spikes_lists
        send_spikes = sender.send_spikes
        keys = []
        
        #from generate_spikes.pyx (cython)
        if lists is not None:
          for spike_pack in lists:
            start_time = time.time()
            send_spikes(lbl, spike_pack, send_full_keys=False)
            elapsed_time = time.time() - start_time
            if elapsed_time < max_time_s:
              time.sleep(max_time_s - elapsed_time)
    
    def generate_spikes(self, image):
        self._curr_frame = image
        curr_frame = self._curr_frame
        
        #~ curr_frame = image
        ref_frame = self._ref_frame
        diff = self._diff
        abs_diff = self._abs_diff
        spikes = self._spikes
        img_w = self._out_res
        inh_w = self._inh_area_width
        polarity = self._polarity_n
        inhibition = self._inhibition
        max_thresh = self._max_threshold
        min_thresh = self._min_threshold
        threshold = self._threshold
        
        if self._adaptive_threshold:
            thresh_mat = self._thresh_matrix
            thresh_delta_up   = self._threshold_delta_down
            thresh_delta_down = self._threshold_delta_up

            
            #all from generate_spikes.pyx (cython)
            diff[:], abs_diff[:], spikes[:] = thresholded_difference_adpt(curr_frame, ref_frame,
                                                                          thresh_mat)
        else:
            #all from generate_spikes.pyx (cython)
            diff[:], abs_diff[:], spikes[:] = thresholded_difference(curr_frame, ref_frame,
                                                                     threshold)

        if inhibition:
            spikes[:] = local_inhibition(spikes, abs_diff, img_w, img_w, inh_w)




    def update_reference(self):
        abs_diff = self._abs_diff
        spikes = self._spikes
        ref_frame = self._ref_frame
        min_thresh = self._min_threshold
        max_thresh = self._max_threshold
        threshold  = self._threshold
        max_time_ms = self._max_time_ms
        history_weight = self._history_weight
        num_bits = self._num_bits_per_spike
        log2_table = self._log2_table[num_bits-1] #no values for 0-bit encoding
        
        if self._adaptive_threshold:
            thresh_mat = self._thresh_matrix
            thresh_delta_down = self._threshold_delta_down
            thresh_delta_up   = self._threshold_delta_up
            ref_frame[:], thresh_mat[:] = update_reference_rate_adpt(abs_diff, spikes,
                                                                     ref_frame, thresh_mat,
                                                                     min_thresh, max_thresh,
                                                                     thresh_delta_down,
                                                                     thresh_delta_up,
                                                                     max_time_ms,
                                                                     history_weight)

        else:
            if self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_RATE: 
                
                ref_frame[:] = update_reference_rate(abs_diff, spikes, ref_frame, 
                                                     threshold, max_time_ms, history_weight)
                                      
            elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME:

                ref_frame[:] = update_reference_time_thresh(abs_diff, spikes, ref_frame,
                                                            threshold, max_time_ms,
                                                            history_weight)

            elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN:
              
                ref_frame[:] = update_reference_time_binary_raw(abs_diff, spikes, ref_frame,
                                                                threshold, max_time_ms,
                                                                num_bits,
                                                                history_weight,
                                                                log2_table)

            elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:

                ref_frame[:] = update_reference_time_binary_thresh(abs_diff, spikes, ref_frame,
                                                                   threshold, max_time_ms,
                                                                   num_bits,
                                                                   history_weight,
                                                                   log2_table)
                
    def transform_spikes(self):
        up_spks = self._up_spikes
        dn_spks = self._down_spikes
        g_max = self._global_max
        data_shift = self._data_shift
        up_down_shift = self._up_down_shift
        data_mask = self._data_mask
        polarity = self._polarity_n
        spikes = self._spikes
        max_thresh = self._max_threshold
        min_thresh = self._min_threshold
        #~ lists = self._spikes_lists
        max_time_ms = self._max_time_ms
        abs_diff = self._abs_diff
        num_bins = self._num_bins
        num_bits = self._num_bits_per_spike
        log2_table = self._log2_table[num_bits - 1]
        
        dn_spks, up_spks, g_max = split_spikes(spikes, abs_diff, polarity)
        lists = None
        #from generate_spikes.pyx (cython)
        if self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_RATE:
          lists = make_spike_lists_rate(up_spks, dn_spks,
                                        g_max,
                                        up_down_shift, data_shift, data_mask,
                                        max_time_ms)
        
        elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME:
          lists = make_spike_lists_time(up_spks, dn_spks,
                                        g_max,
                                        up_down_shift, data_shift, data_mask,
                                        num_bins,
                                        max_time_ms,
                                        min_thresh, max_thresh)
          
        elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN:
          lists = make_spike_lists_time_bin(up_spks, dn_spks,
                                            g_max,
                                            up_down_shift, data_shift, data_mask,
                                            max_time_ms,
                                            min_thresh, max_thresh,
                                            num_bins,
                                            log2_table)

        elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
          lists = make_spike_lists_time_bin_thr(up_spks, dn_spks,
                                                g_max,
                                                up_down_shift, data_shift, data_mask,
                                                max_time_ms,
                                                min_thresh, max_thresh,
                                                num_bins,
                                                log2_table)
        return lists
    
    
    def compose_output_frame(self):
        curr_frame = self._curr_frame
        spikes_frame = self._spikes_frame
        spikes = self._spikes
        width = self._out_res
        height = self._out_res
        polarity = self._polarity_n
        
        #from generate_spikes.pyx (cython)
        spikes_frame[:] = render_frame(spikes=spikes, curr_frame=curr_frame, 
                                       width=width, height=height,
                                       polarity=polarity)


    def calculate_time_per_pack(self):
        time_per_pack = 0
        if self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_RATE:
            time_per_pack = 1
            
        elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME:
            time_per_pack = (self._max_time_ms)/ \
                            (min(self._max_time_ms,
                                 self._max_threshold/self._min_threshold + 1))
                                 
        elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN:
            time_per_pack = (self._max_time_ms)/(8) #raw difference value could be 8-bit
        else:
            time_per_pack = (self._max_time_ms)/(self._num_bits_per_spike + 1)
        
        return time_per_pack



    def get_images_paths(self, images):

        imgs = []
        self._total_images = 0
        if type(images) == type(list()): #if we've got a list of image paths
            for img in images:
                if os.path.isfile(img): #check if the image file exists
                    imgs.append(img)
                    self._total_images += 1

        elif type(images) == type(str()): # if we get a string
            
            if os.path.isfile(images):  # is it a file?
                imgs.append(images)
                self._total_images += 1
                    
            elif os.path.isdir(images): # or a directory?
                for extension in ExternalImageDvsEmulatorDevice.IMAGE_TYPES:
                    for img in glob.glob(os.path.join(images, "*.%s"%extension)):
                        if os.path.isfile(img):
                            imgs.append(img)
                            self._total_images += 1

        if len(imgs) == 0:
            raise exceptions.SpynnakerException("No images loaded! ")
        
        return imgs
Пример #37
0
weight_to_spike = 2.
rate_weight = 1.5
delay = 1
rate_delay = 16
pool_size = 1

# Create breakout population and activate live output for it
breakout_pop = p.Population(1, spinn_breakout.Breakout, {}, label="breakout")
ex.activate_live_output_for(breakout_pop, host="0.0.0.0", port=UDP_PORT)

# Create spike injector to inject keyboard input into simulation
key_input = p.Population(2,
                         ex.SpikeInjector, {"port": 12367},
                         label="key_input")
key_input_connection = SpynnakerLiveSpikesConnection(send_labels=["key_input"])

# Connect key spike injector to breakout population
p.Projection(key_input, breakout_pop, p.OneToOneConnector(weights=2))

# Create visualiser
visualiser = spinn_breakout.Visualiser(UDP_PORT,
                                       key_input_connection,
                                       x_res=X_RESOLUTION,
                                       y_res=Y_RESOLUTION,
                                       x_bits=X_BITS,
                                       y_bits=Y_BITS)

direction_population = p.Population(3, p.IF_curr_exp, cell_params_lif)
p.Projection(
    direction_population, breakout_pop,