Ejemplo n.º 1
0
 def connect_nest_nodes(self):
     # Define a function for the exact synthesis of source and target populations
     population = lambda node, populations: \
         flatten_tuple([node[pop] for pop in ensure_list(populations)])
     # For every different type of connections between distinct NEST nodes' populations
     for i_conn, conn in enumerate(ensure_list(self.nodes_connections)):
         model = property_to_fun(conn["model"])
         weight = property_to_fun(conn["weight"])
         delay = property_to_fun(conn["delay"])
         receptor_type = property_to_fun(conn["receptor_type"])
         conn_spec = property_to_fun(conn['conn_spec'])
         # ...and form the connection for every distinct pair of NEST nodes
         for source_index in conn["source_nodes"]:
             i_source_node = np.where(
                 self.nest_nodes_ids == source_index)[0][0]
             for target_index in conn["target_nodes"]:
                 if source_index != target_index:  # TODO! Confirm that no self connections are allowed here!
                     i_target_node = np.where(
                         self.nest_nodes_ids == target_index)[0][0]
                     if self.tvb_weights[source_index, target_index] > 0:
                         self._connect_two_populations_between_nodes(
                             population(self.nodes[i_source_node],
                                        conn["source"]),
                             population(self.nodes[i_target_node],
                                        conn["target"]), i_source_node,
                             i_target_node,
                             conn_spec(source_index, target_index),
                             model(source_index, target_index),
                             weight(source_index, target_index),
                             delay(source_index, target_index),
                             receptor_type(source_index, target_index))
Ejemplo n.º 2
0
 def _configure_populations(self):
     # Every population must have his own model model,
     # scale of spiking neurons' number, and model specific parameters
     models = []
     for i_pop, population in enumerate(self.populations):
         temp_population = dict(self.default_population)
         temp_population.update(population)
         self.populations[i_pop] = temp_population
         if len(self.populations[i_pop].get("label", "")) == 0:
             self.populations[i_pop]["label"] = "Pop%d" % i_pop
         if self.populations[i_pop]["nodes"] is None:
             self.populations[i_pop]["nodes"] = self.nest_nodes_ids
         if hasattr(self.populations[i_pop]["model"], "__call__"):
             for node_id in self.populations[i_pop]["nodes"]:
                 models.append(self.populations[i_pop]["model"](node_id))
         else:
             models.append(self.populations[i_pop]["model"])
             self.populations[i_pop]["model"] = property_to_fun(
                 self.populations[i_pop]["model"])
         self.populations[i_pop]["scale"] = property_to_fun(
             self.populations[i_pop]["scale"])
         self.populations[i_pop]["params"] = property_to_fun(
             self.populations[i_pop]["params"])
     models = np.unique(models)
     self._confirm_compile_install_nest_models(models)
Ejemplo n.º 3
0
 def _configure_populations(self):
     # Every population must have its own model model, label.
     # scale of spiking neurons' number, and model specific parameters,
     # and a list of spiking region nodes where it is going to be placed
     # "scale" and "parameters" can be given as functions.
     # This configuration will make confirm user inputs
     # and set the two properties above as functions of node index
     self.models = []
     self.populations_labels = []
     _populations = []
     for i_pop, population in enumerate(self.populations):
         _populations.append(dict(self.default_population))
         _populations[-1].update(population)
         if len(_populations[-1].get("label", "")) == 0:
             _populations[-1]["label"] = "Pop%d" % i_pop
         self.populations_labels.append(_populations[-1]["label"])
         if _populations[-1]["nodes"] is None:
             _populations[-1]["nodes"] = self.spiking_nodes_ids
         self.models.append(_populations[-1]["model"])
         _populations[-1]["scale"] = property_to_fun(
             _populations[-1]["scale"])
         _populations[-1]["params"] = property_to_fun(
             _populations[-1]["params"])
     self.populations_labels = np.unique(self.populations_labels).tolist()
     self.models = np.unique(self.models).tolist()
     self._populations = _populations
     return self._populations
Ejemplo n.º 4
0
 def build_interface(self, interface):
     # One NEST output device for every combination of NEST node
     # and TVB state variable/parameter to be transmitted
     # from NEST to TVB
     nest_to_tvb_interface = Series()
     nest_nodes = interface.get(
         "nodes",
         self.nest_nodes_ids)  # Indices corresponding to NEST nodes
     if nest_nodes is None:
         nest_nodes = self.nest_nodes_ids
     nest_nodes = list(nest_nodes)
     if self.exclusive_nodes:
         # TODO: decide about the following: can a TVB node be updated from a NEST node via a NEST -> TVB interface,
         # get simulated in TVB and again update NEST via a TVB -> NEST interface?
         # Will it depend on whether there is also a directly coupling of that NEST node with other NEST nodes?
         assert np.all(nest_node not in self.tvb_nodes_ids
                       for nest_node in nest_nodes)
     # We prefer to multiply interface_weights outside NEST:
     interface_weights = np.ones((len(nest_nodes), )).astype("f")
     interface_weight = property_to_fun(
         interface.pop("interface_weights", 1.0))
     delays = np.ones((len(nest_nodes), )).astype("f")
     delay = property_to_fun(interface.pop("delays", 0.0))
     for i_w, nest_node in enumerate(nest_nodes):
         interface_weights[i_w] = interface_weight(nest_node)
         delays[i_w] = delay(nest_node)
     # Delays should be set to the device
     interface["delays"] = delays  # Per node
     # Convert TVB node index to interface NEST node index:
     nest_nodes_ids = [
         np.where(self.nest_nodes_ids == nest_node)[0][0]
         for nest_node in nest_nodes
     ]
     interface["nodes"] = nest_nodes_ids
     devices = build_and_connect_output_devices(self.nest_instance,
                                                [interface],
                                                self.nest_nodes)
     for name, device_set in devices.items():
         try:
             tvb_sv_id = self.tvb_model.state_variables.index(name)
         except:
             tvb_sv_id = None  # it might be a TVB parameter, not a state variable
         nest_to_tvb_interface[name] = \
             NESTtoTVBinterface(nodes_ids=nest_nodes,
                                scale=interface_weights).from_device_set(device_set, tvb_sv_id, name)
     return nest_to_tvb_interface
Ejemplo n.º 5
0
 def build_interface(self, interface):
     # One SpikeNet output device for every combination of SpikeNet node
     # and TVB state variable/parameter to be transmitted
     # from SpikeNet to TVB
     spikeNet_to_tvb_interface = Series()
     spiking_nodes = interface.get(
         "nodes",
         self.spiking_nodes_ids)  # Indices corresponding to NEST nodes
     if spiking_nodes is None:
         spiking_nodes = self.spiking_nodes_ids
     spiking_nodes = list(spiking_nodes)
     if self.exclusive_nodes:
         # TODO: decide about the following: can a TVB node be updated from a NEST node via a NEST -> TVB interface,
         # get simulated in TVB and again update SpikeNet via a TVB -> SpikeNet interface?
         # Will it depend on whether there is also a directly coupling of that NEST node with other NEST nodes?
         assert np.all(spiking_node not in self.tvb_nodes_ids
                       for spiking_node in spiking_nodes)
     interface_weights = np.ones((len(spiking_nodes), )).astype("f")
     interface_weight_fun = property_to_fun(
         interface.pop("interface_weights", 1.0))
     delays = np.ones((len(spiking_nodes), )).astype("f")
     delay_fun = property_to_fun(interface.pop("delays", 0.0))
     for i_w, spiking_node in enumerate(spiking_nodes):
         interface_weights[i_w] = interface_weight_fun(spiking_node)
         delays[i_w] = delay_fun(spiking_node)
     # Delays should be set to the device
     interface["delays"] = delays  # Per node
     # Convert TVB node index to interface SpikeNet node index:
     spiking_nodes_ids = [
         np.where(self.spiking_nodes_ids == spiking_node)[0][0]
         for spiking_node in spiking_nodes
     ]
     interface["nodes"] = spiking_nodes_ids
     devices = self.build_and_connect_devices([interface],
                                              self.spiking_nodes)
     for name, device_set in devices.items():
         try:
             # The index of the TVB state variable that is targeted
             tvb_sv_id = self.tvb_model.state_variables.index(name)
         except:
             tvb_sv_id = None  # it might be a TVB parameter, not a state variable
         spikeNet_to_tvb_interface[name] = \
             self._build_target_class(self.spiking_network, nodes_ids=spiking_nodes,
                                      scale=interface_weights).from_device_set(device_set, tvb_sv_id, name)
     return spikeNet_to_tvb_interface
Ejemplo n.º 6
0
 def connect_within_node_nest_populations(self):
     # For every different type of connections between distinct NEST nodes' populations
     for i_conn, conn in enumerate(ensure_list(
             self.populations_connections)):
         model = property_to_fun(conn["model"])
         weight = property_to_fun(conn["weight"])
         delay = property_to_fun(conn["delay"])
         receptor_type = property_to_fun(conn["receptor_type"])
         conn_spec = property_to_fun(conn['conn_spec'])
         # ...and form the connection within each NEST node
         for node_index in conn["nodes"]:
             i_node = np.where(self.nest_nodes_ids == node_index)[0][0]
             self._connect_two_populations_within_node(
                 self._get_node_populations_neurons(self.nodes[i_node],
                                                    conn["source"]),
                 self._get_node_populations_neurons(self.nodes[i_node],
                                                    conn["target"]),
                 conn_spec(node_index), model(node_index),
                 weight(node_index), delay(node_index),
                 receptor_type(node_index))
Ejemplo n.º 7
0
 def _configure_devices(self, devices):
     # Configure devices by the variable model they measure or stimulate (Series),
     # population (Series),
     # and target node (Series) for faster reading
     # "weight", "delay" and "receptor_type" are set as functions, following user input
     _devices = list()
     for device in devices:
         _devices.append(dict(device))
         spiking_nodes = device.get("nodes", self.spiking_nodes_ids)
         if spiking_nodes is None:
             spiking_nodes = self.spiking_nodes_ids
         # User inputs
         # ..set/converted to functions
         weights_fun = property_to_fun(device.get("weights", 1.0))
         delays_fun = property_to_fun(device.get("delays", 0.0))
         receptor_types_fun = property_to_fun(
             device.get("receptor_types", 0))
         # Defaults in arrays:
         shape = (len(spiking_nodes), )
         receptor_types = np.zeros(shape).astype("i")
         # weights and delays might be dictionaries for distributions:
         weights = np.tile([1.0], shape).astype("object")
         delays = np.tile([0.0], shape).astype("object")
         target_spiking_nodes_ids = \
             [np.where(self.spiking_nodes_ids == trg_node)[0][0] for trg_node in spiking_nodes]
         # Set now the properties using the above defined functions:
         for trg_node, i_trg in zip(spiking_nodes,
                                    target_spiking_nodes_ids):
             weights[i_trg] = weights_fun(
                 trg_node)  # a function also of self.tvb_weights
             delays[i_trg] = delays_fun(
                 trg_node)  # a function also of self.tvb_delays
             receptor_types[i_trg] = receptor_types_fun(trg_node)
         _devices[-1]["nodes"] = target_spiking_nodes_ids
         _devices[-1]["weights"] = weights
         _devices[-1]["delays"] = delays
         _devices[-1]["receptor_types"] = receptor_types
         _devices[-1]["params"] = device.get("params", {})
     return _devices
Ejemplo n.º 8
0
 def _configure_connections(self, connections, default_connection):
     # This method sets "weight", "delay" and "receptor_type" synapse properties
     # as functions of the node where the populations are placed
     _connections = []
     for i_con, connection in enumerate(connections):
         self._assert_connection_populations(connection)
         temp_conn = dict(default_connection)
         temp_conn.update(connection)
         _connections.append(temp_conn)
         for prop in ["weight", "delay", "receptor_type"]:
             _connections[i_con][prop] = property_to_fun(
                 _connections[i_con][prop])
     return _connections
Ejemplo n.º 9
0
 def build_and_connect_nest_stimulation_devices(self):
     # Build devices by the variable model they stimulate (Series),
     # population (Series),
     # and target node (Series) for faster reading
     stimulation_devices = Series()
     for devices in self.stimulation_devices:
         target_nest_nodes = devices.pop("nodes", self.nest_nodes_ids)
         n_target_nest_nodes = len(target_nest_nodes)
         if target_nest_nodes is None:
             target_nest_nodes = self.nest_nodes_ids
         param = property_to_fun(devices.pop("params", {}))
         weight = property_to_fun(devices.pop("weights", 1.0))
         delay = property_to_fun(devices.pop("delays", 0.0))
         receptor_type = property_to_fun(devices.pop("receptor_types", 0))
         receptor_types = np.zeros(n_target_nest_nodes, ).astype("i")
         params = np.array([{}] * n_target_nest_nodes)
         weights = 1.0 + receptor_types
         delays = self.nest_instance.GetKernelStatus(
             "resolution") + receptor_types
         target_nest_nodes_ids = [
             np.where(self.nest_nodes_ids == trg_node)[0][0]
             for trg_node in target_nest_nodes
         ]
         devices["nodes"] = target_nest_nodes_ids
         for trg_node, i_trg in zip(target_nest_nodes,
                                    target_nest_nodes_ids):
             params[i_trg] = param(trg_node)
             weights[i_trg] = weight(trg_node)
             delays[i_trg] = delay(trg_node)
             receptor_types[i_trg] = receptor_type(trg_node)
         devices["weights"] = weights
         devices["delays"] = delays
         devices["receptor_types"] = receptor_types
         devices["params"] = params
         stimulation_devices = \
             stimulation_devices.append(
                 build_and_connect_input_devices(self.nest_instance, devices, self.nodes))
     return stimulation_devices
 def build_interface(self, interface):
     # One interface for every combination of Spiking node
     # and TVB state variable to be transmitted
     # from TVB to Spiking Network
     connections = interface["connections"]
     if isinstance(connections, string_types):
         connections = {
             connections: slice(None)
         }  # return all population types
     default_parameter = self._build_target_class._available_input_parameters[
         interface["model"]]
     spiking_nodes_ids = interface.get("nodes", self.spiking_nodes_ids)
     if spiking_nodes_ids is None:
         spiking_nodes_ids = self.spiking_nodes_ids
     spiking_nodes_ids = list(spiking_nodes_ids)
     if self.exclusive_nodes:
         assert np.all(spiking_node not in self.tvb_nodes_ids
                       for spiking_node in spiking_nodes_ids)
     interface_weights = 1.0 * np.ones(
         (len(spiking_nodes_ids), )).astype("f")
     interface_weight_fun = property_to_fun(
         interface.get("interface_weights", 1.0))
     for i_w, spiking_node_id in enumerate(spiking_nodes_ids):
         interface_weights[i_w] = interface_weight_fun(spiking_node_id)
     tvb_to_spikeNet_interfaces = Series()
     for name, populations in connections.items():
         try:
             tvb_coupling_id = self.tvb_model.cvar.tolist().index(
                 self.tvb_model.state_variables.index(name))
         except:
             raise_value_error(
                 "Failed to compute the coupling index of TVB state variable %s!"
                 % name)
         tvb_to_spikeNet_interfaces[name] = \
             self._build_target_class(self.spiking_network, name, interface["model"],
                                      interface.get("parameter", default_parameter),
                                      tvb_coupling_id, spiking_nodes_ids, interface_weights)
         for node in self.spiking_nodes:
             tvb_to_spikeNet_interfaces[name][
                 node.label] = node[populations]
         return tvb_to_spikeNet_interfaces
Ejemplo n.º 11
0
 def build_interface(self, interface):
     # One interface for every combination NEST node
     # and TVB state variable to be transmitted
     # from TVB to NEST
     connections = interface["connections"]
     if isinstance(connections, string_types):
         connections = {
             connections: slice(None)
         }  # return all population types
     default_parameter = NEST_INPUT_PARAMETERS[interface["model"]]
     nest_nodes_ids = interface.get("nodes", self.nest_nodes_ids)
     if nest_nodes_ids is None:
         nest_nodes_ids = self.nest_nodes_ids
     nest_nodes_ids = list(nest_nodes_ids)
     if self.exclusive_nodes:
         assert np.all(nest_node not in self.tvb_nodes_ids
                       for nest_node in nest_nodes_ids)
     interface_weights = 1.0 * np.ones((len(nest_nodes_ids), )).astype("f")
     interface_weight = property_to_fun(
         interface.get("interface_weights", 1.0))
     for i_w, nest_node_id in enumerate(nest_nodes_ids):
         interface_weights[i_w] = interface_weight(nest_node_id)
     tvb_to_nest_interfaces = Series()
     for name, populations in connections.items():
         try:
             tvb_coupling_id = self.tvb_model.cvar.tolist().index(
                 self.tvb_model.state_variables.index(name))
         except:
             raise ValueError(
                 "Failed to compute the coupling index of TVB state variable %s!"
                 % name)
         tvb_to_nest_interfaces[name] = TVBNESTParameterInterface(
             self.nest_instance, name, interface["model"],
             interface.get("parameter", default_parameter), tvb_coupling_id,
             nest_nodes_ids, interface_weights)
         for node in self.nest_nodes:
             tvb_to_nest_interfaces[name][node.label] = node[populations]
         return tvb_to_nest_interfaces
 def build_interface(self, interface):
     # One NEST stimulation device for every combination of
     # TVB node and state variable to be transmitted from TVB to NEST
     source_tvb_nodes = interface.pop("source_nodes", self.tvb_nodes_ids)
     if source_tvb_nodes is None:
         source_tvb_nodes = self.tvb_nodes_ids
     source_tvb_nodes = list(source_tvb_nodes)
     target_nest_nodes = interface.pop("target_nodes", self.nest_nodes_ids)
     if target_nest_nodes is None:
         target_nest_nodes = self.nest_nodes_ids
     target_nest_nodes = list(target_nest_nodes)
     if self.exclusive_nodes:
         # TODO: decide about the following: can a TVB node be updated from a NEST node via a NEST -> TVB interface,
         # get simulated in TVB and again update NEST via a TVB -> NEST interface?
         # Will it depend on whether there is also a directly coupling of that NEST node with other NEST nodes?
         assert np.all(node not in self.tvb_nodes_ids
                       for node in target_nest_nodes)
         assert np.all(node not in self.nest_nodes_ids
                       for node in source_tvb_nodes)
     interface_weight = property_to_fun(
         interface.pop("interface_weights", 1.0))
     interface_weights = np.ones((len(source_tvb_nodes), )).astype("f")
     weight = property_to_fun(interface.pop("weights", 1.0))
     delay = property_to_fun(interface.pop("delays", 0.0))
     receptor_type = property_to_fun(interface.pop("receptor_types", 0))
     # TODO: Find a way to change self directed weights in cases of non exclusive TVB and NEST nodes!
     weights = self.tvb_weights[source_tvb_nodes][:, target_nest_nodes]
     delays = self.tvb_delays[source_tvb_nodes][:, target_nest_nodes]
     receptor_types = np.zeros(delays.shape).astype("i")
     target_nest_nodes_ids = [
         np.where(self.nest_nodes_ids == trg_node)[0][0]
         for trg_node in target_nest_nodes
     ]
     interface["nodes"] = target_nest_nodes_ids
     device_names = []
     for src_node in source_tvb_nodes:
         i_src = np.where(self.tvb_nodes_ids == src_node)[0][0]
         interface_weights[i_src] = interface_weight(src_node)
         device_names.append(self.node_labels[src_node])
         for trg_node, i_trg in zip(target_nest_nodes,
                                    target_nest_nodes_ids):
             weights[i_src, i_trg] *= weight(src_node, trg_node)
             delays[i_src, i_trg] += delay(src_node, trg_node)
             receptor_types[i_src,
                            i_trg] = receptor_type(src_node, trg_node)
     interface["weights"] = weights
     interface["delays"] = delays
     interface["receptor_types"] = receptor_types
     interface["names"] = device_names
     devices = build_and_connect_output_devices(self.nest_instance,
                                                [interface],
                                                self.nest_nodes)
     tvb_to_nest_interface = Series()
     for name, device in devices.items():
         try:
             tvb_sv_id = self.tvb_model.state_variables.index(name)
         except:
             raise_value_error(
                 "Interface with %s doesn't correspond to a TVB state variable!"
             )
         try:
             interface_builder = INPUT_INTERFACES_DICT[device.model]
         except:
             raise_value_error("Interface model %s is not supported yet!" %
                               device.model)
         tvb_to_nest_interface[name] = \
             interface_builder(self.nest_instance,
                               nodes_ids=source_tvb_nodes,
                               target_nodes=target_nest_nodes,
                               scale=interface_weights,
                               dt=self.tvb_dt).from_device_set(device, tvb_sv_id, name)
         if len(source_tvb_nodes) * len(target_nest_nodes) > 0:
             assert np.abs(
                 np.max(tvb_to_nest_interface[name].weights -
                        weights)) < 0.001
             assert np.abs(
                 np.max(tvb_to_nest_interface[name].delays -
                        delays)) < 1.0  # ms
             assert np.abs(
                 np.max(tvb_to_nest_interface[name].receptors -
                        receptor_types)) < 1  # integers
     return tvb_to_nest_interface