def __init__(self, value, shape=None, dtype=None): if isinstance(value, str): errmsg = "Value should be a string expressing a function of d. " try: value = eval("lambda d: %s" % value) except SyntaxError: raise errors.InvalidParameterValueError(errmsg + "Incorrect syntax.") try: value(0.0) except NameError as err: raise errors.InvalidParameterValueError(errmsg + str(err)) super(LazyArray, self).__init__(value, shape, dtype)
def _set_spike_times(self, spike_times): # spike_times should be a Sequence object try: self._spike_times = h.Vector(spike_times.value) except (RuntimeError, AttributeError): raise errors.InvalidParameterValueError( "spike_times must be an array of floats") if numpy.any(spike_times.value[:-1] > spike_times.value[1:]): raise errors.InvalidParameterValueError( "Spike times given to SpikeSourceArray must be in increasing order" ) self.play(self._spike_times)
def _set_spike_times(self, spike_times): try: self._spike_times = h.Vector(spike_times) except RuntimeError: raise errors.InvalidParameterValueError( "spike_times must be an array of floats") self.play(self._spike_times)
def _set_spike_times(self, spike_times): # spike_times should be a Sequence object try: self._spike_times = h.Vector(spike_times.value) except (RuntimeError, AttributeError): raise errors.InvalidParameterValueError("spike_times must be an array of floats") self.play(self._spike_times)
def _check_spike_times(self, spike_times): for seq in spike_times: seq = np.asarray(seq) if np.any(seq[:-1] > seq[1:]): raise errors.InvalidParameterValueError( "Spike times given to SpikeSourceArray must be in increasing order" )
def evaluate(self, mask=None, simplify=False): """ Evaluate all lazy arrays contained in the parameter space, using the given mask. """ if self._shape is None: raise Exception( "Must set shape of parameter space before evaluating") if mask is None: for name, value in self._parameters.items(): self._parameters[name] = value.evaluate(simplify=simplify) self._evaluated_shape = self._shape else: for name, value in self._parameters.items(): try: if isinstance(value.base_value, RandomDistribution ) and value.base_value.rng.parallel_safe: value = value.evaluate( ) # can't partially evaluate if using parallel safe self._parameters[name] = value[mask] except ValueError: raise errors.InvalidParameterValueError( f"{name} should not be of type {type(value)}") self._evaluated_shape = partial_shape(mask, self._shape) self._evaluated = True
def _create_cells(self): """ Create cells in NEST using the celltype of the current Population. """ # this method should never be called more than once # perhaps should check for that nest_model = self.celltype.nest_name[simulator.state.spike_precision] if isinstance(self.celltype, StandardCellType): self.celltype.parameter_space.shape = ( self.size, ) # should perhaps do this on a copy? params = _build_params( self.celltype.native_parameters, None, size=self.size, extra_parameters=self.celltype.extra_parameters) else: params = _build_params(self.celltype.parameter_space, None, size=self.size) try: self.node_collection = nest.Create(nest_model, self.size, params=params) except nest.NESTError as err: if "UnknownModelName" in err.args[0] and "cond" in err.args[0]: raise errors.InvalidModelError( "%s Have you compiled NEST with the GSL (Gnu Scientific Library)?" % err) if "Spike times must be sorted in non-descending order" in err.args[ 0]: raise errors.InvalidParameterValueError( "Spike times given to SpikeSourceArray must be in increasing order" ) raise # errors.InvalidModelError(err) # create parrot neurons if necessary if hasattr(self.celltype, "uses_parrot") and self.celltype.uses_parrot: self.node_collection_source = self.node_collection # we put the parrots into all_cells, since this will parrot_model = simulator.state.spike_precision == "off_grid" and "parrot_neuron_ps" or "parrot_neuron" self.node_collection = nest.Create( parrot_model, self.size ) # be used for connections and recording. all_cells_source # should be used for setting parameters self._deferred_parrot_connections = True # connecting up the parrot neurons is deferred until we know the value of min_delay # which could be 'auto' at this point. if self.node_collection.local is True: self._mask_local = np.array([True]) else: self._mask_local = np.array(self.node_collection.local) self.all_cells = np.array( [simulator.ID(gid) for gid in self.node_collection.tolist()], simulator.ID) for gid in self.all_cells: gid.parent = self gid.node_collection = nest.NodeCollection([int(gid)]) if hasattr(self.celltype, "uses_parrot") and self.celltype.uses_parrot: for gid, source in zip(self.all_cells, self.node_collection_source.tolist()): gid.source = source
def translate(cls, parameters): if 'spike_times' in parameters: try: parameters['spike_times'] = numpy.array( parameters['spike_times'], float) except ValueError: raise errors.InvalidParameterValueError( "spike times must be floats") return super(SpikeSourceArray, cls).translate(parameters)
def _set_parameters(self, parameter_space): """parameter_space should contain native parameters""" for name, value in parameter_space.items(): try: self.parent._parameters[name][self.mask] = value.evaluate( simplify=True) except ValueError as err: raise errors.InvalidParameterValueError( f"{name} should not be of type {type(value)}")
def check_parameters(cls, supplied_parameters, with_defaults=False): """ Returns a parameter dictionary, checking that each supplied_parameter is in the default_parameters and converts to the type of the latter. If with_defaults==True, parameters not in supplied_parameters are in the returned dictionary as in default_parameters. """ default_parameters = cls.default_parameters if with_defaults: parameters = copy.copy(default_parameters) else: parameters = {} if supplied_parameters: for k in supplied_parameters.keys(): if k in default_parameters.keys(): err_msg = "For %s in %s, expected %s, got %s (%s)" % \ (k, cls.__name__, type(default_parameters[k]), type(supplied_parameters[k]), supplied_parameters[k]) # same type if type(supplied_parameters[k]) == type( default_parameters[k]): parameters[k] = supplied_parameters[k] # float and something that can be converted to a float elif isinstance(default_parameters[k], float): try: parameters[k] = float(supplied_parameters[k]) except (ValueError, TypeError): raise errors.InvalidParameterValueError(err_msg) # list and something that can be transformed to a list elif isinstance(default_parameters[k], list): try: parameters[k] = list(supplied_parameters[k]) except TypeError: raise errors.InvalidParameterValueError(err_msg) else: raise errors.InvalidParameterValueError(err_msg) else: raise errors.NonExistentParameterError( k, cls, cls.default_parameters.keys()) return parameters
def sanitize_spike_times(spike_times): """ PCSIM has a bug that the SpikingInputNeuron sometimes stops emitting spikes I think this happens when two spikes fall in the same time step. This workaround removes any spikes after the first within a given time step. """ time_step = common.get_time_step() try: spike_times = numpy.array(spike_times, float) except ValueError, e: raise errors.InvalidParameterValueError("Spike times must be floats. %s")
def update(self, **parameters): """ Update the contents of the parameter space according to the `(key, value)` pairs in ``**parameters``. All values will be turned into lazy arrays. If the :class:`ParameterSpace` has a schema, the keys and the data types of the values will be checked against the schema. """ if self.schema: for name, value in parameters.items(): try: expected_dtype = self.schema[name] except KeyError: if self.component: model_name = self.component.__name__ else: model_name = 'unknown' raise errors.NonExistentParameterError( name, model_name, valid_parameter_names=self.schema.keys()) if issubclass(expected_dtype, ArrayParameter) and isinstance( value, collections.Sized): if len(value) == 0: value = ArrayParameter([]) elif not isinstance( value[0], ArrayParameter ): # may be a more generic way to do it, but for now this special-casing seems like the most robust approach if isinstance( value[0], collections.Sized): # e.g. list of tuples value = type(value)( [ArrayParameter(x) for x in value]) else: value = ArrayParameter(value) try: self._parameters[name] = LazyArray(value, shape=self._shape, dtype=expected_dtype) except (TypeError, errors.InvalidParameterValueError): raise errors.InvalidParameterValueError( "For parameter %s expected %s, got %s" % (name, expected_dtype, type(value))) except ValueError as err: raise errors.InvalidDimensionsError( err ) # maybe put the more specific error classes into lazyarray else: for name, value in parameters.items(): self._parameters[name] = LazyArray(value, shape=self._shape)
def set_native_parameters(self, parameters): """Set parameters of the NEST cell model from a dictionary.""" if hasattr(self, "source"): # self is a parrot_neuron gid = self.source else: gid = self try: nest.SetStatus([gid], [parameters]) except: # I can't seem to catch the NESTError that is raised, hence this roundabout way of doing it. exc_type, exc_value, traceback = sys.exc_info() if exc_type == 'NESTError' and "Unsupported Numpy array type" in exc_value: raise errors.InvalidParameterValueError() else: raise
def sanitize_spike_times(spike_times): """ PCSIM has a bug that the SpikingInputNeuron sometimes stops emitting spikes I think this happens when two spikes fall in the same time step. This workaround removes any spikes after the first within a given time step. """ time_step = common.get_time_step() try: spike_times = numpy.array(spike_times, float) except ValueError as e: raise errors.InvalidParameterValueError( "Spike times must be floats. %s") bins = (spike_times / time_step).astype('int') mask = numpy.concatenate((numpy.array([True]), bins[1:] != bins[:-1])) if mask.sum() < len(bins): logger.warn( "Spikes have been thrown away because they were too close together." ) logger.debug(spike_times[(1 - mask).astype('bool')]) if len(spike_times) > 0: return spike_times[mask] else: return spike_times