API Reference
This page collects the API that is not tied to a specific model: building and simulating a network, units and helper macros, saving and loading, spatial networks, perturbation experiments and spike-train analysis. The docstrings of the models themselves (neurons, synapses, connections, plasticity rules, stimuli) are in the model catalogue, next to the equations and parameter tables; recording and plotting have their own pages.
| Topic | Page |
|---|---|
| Integrate-and-fire neurons (IF, ExtendedIF, AdEx) | Integrate-and-fire models |
| Izhikevich, Hodgkin-Huxley, Morris-Lecar | Other neuron models |
| Rate and mean-field models | Rate models |
| Poisson and other spike sources | Sources |
| Tripod, BallAndStick, dendrites | Multicompartment models |
| Synapse and receptor models | Synapses and receptors |
| Connection types and connectivity rules | Connections |
| STDP, iSTDP, vSTDP, short-term plasticity | Plasticity rules |
| Normalization, scaling, turnover | Metaplasticity |
| Stimulus models | Stimuli |
| Models shipped with SNNUtils | SNNUtils models |
monitor!, record, getvariable, ... | Recordings |
| threads, flush-to-zero | Running simulations |
| SNNPlots functions | Visualization |
All symbols below are exported by SNNModels; with using SpikingNeuralNetworks they are available as SNN.<name> (most of them also unqualified).
Index
SNNModels.SNNModelsSNNPlots.SNNPlotsSNNUtils.SNNUtilsSpikingNeuralNetworks.SpikingNeuralNetworksSNNModels.EyalNMDASNNModels.NoSTDPSNNModels.SomaNMDASNNModels.SomaReceptorsSNNModels.SomaSynapseSNNModels.TripodDendSynapseSNNModels.TripodSomaSynapseSNNModels.all_lengthsSNNModels.human_dendSNNModels.mouse_dendSNNModels.proximalSNNModels.proximal_distalSNNModels.proximal_proximalSNNPlots.okabe_ito_10SpikingNeuralNetworks.DOCS_ASSETS_PATHSNNModels.AbstractComponentSNNModels.AbstractConnectionSNNModels.AbstractConnectionParameterSNNModels.AbstractConnectivitySNNModels.AbstractDendriteIFSNNModels.AbstractGeneralizedIFSNNModels.AbstractGeneralizedIFParameterSNNModels.AbstractGroupSNNModels.AbstractMarkramSTPParameterSNNModels.AbstractMetaPlasticitySNNModels.AbstractNormalizationSNNModels.AbstractParameterSNNModels.AbstractPerturbationStoreSNNModels.AbstractPopulationSNNModels.AbstractPopulationParameterSNNModels.AbstractSparseSynapseSNNModels.AbstractSpikeParameterSNNModels.AbstractSpikingSynapseSNNModels.AbstractSpikingSynapseParameterSNNModels.AbstractStimulusSNNModels.AbstractStimulusGroupSNNModels.AbstractStimulusParameterSNNModels.AbstractSynapseParameterSNNModels.AbstractSynapseVariableSNNModels.ActivityDependentTurnoverSNNModels.AdExSNNModels.AdExParameterSNNModels.AdditiveNormSNNModels.AggregateScalingSNNModels.AggregateScalingSNNModels.AggregateScalingParameterSNNModels.BalancedParameterSNNModels.BalancedStimulusSNNModels.BallAndStickSNNModels.ChunkPtrSNNModels.Confavreux2025SynapseSNNModels.Confavreux2025SynapseVarsSNNModels.CurrentNoiseSNNModels.CurrentParameterSNNModels.CurrentStimulusSNNModels.CurrentSynapseSNNModels.CurrentSynapseVarsSNNModels.DeltaSynapseSNNModels.DeltaSynapseVarsSNNModels.DendNeuronParameterSNNModels.DendriteSNNModels.DoubleExpCurrentSynapseSNNModels.DoubleExpCurrentSynapseVarsSNNModels.DoubleExpSynapseSNNModels.DoubleExpSynapseVarsSNNModels.EmptyParamSNNModels.EmptyStimulusSNNModels.EmptySynapseSNNModels.ExtendedIFSNNModels.ExtendedIFParameterSNNModels.FLSparseSynapseSNNModels.FLSparseSynapseParameterSNNModels.FLSynapseSNNModels.FLSynapseParameterSNNModels.GABAergicSNNModels.GlutamatergicSNNModels.HHSNNModels.HHParameterSNNModels.HetRecSNNModels.HetRecParameterSNNModels.IFSNNModels.IFParameterSNNModels.IZSNNModels.IZParameterSNNModels.IdentitySNNModels.IdentityParamSNNModels.InhomogeneousPoissonSNNModels.InhomogeneousPoissonParamSNNModels.KwStrSentinelSNNModels.LTPSNNModels.LTPParameterSNNModels.MarkramSTPParameterSNNModels.MarkramSTPParameterEventSNNModels.MarkramSTPParameterHetSNNModels.MarkramSTPParameterTimestepSNNModels.MarkramSTPVariablesSNNModels.MembraneParameterSNNModels.MetaPlasticityParameterSNNModels.MorrisLecarSNNModels.MorrisLecarParameterSNNModels.MultiReceptorSynapseSNNModels.MultiplicativeNormSNNModels.NMDAVoltageDependencySNNModels.NetworkModelSNNModels.NoLTPSNNModels.NoSTPSNNModels.NoVariablesSNNModels.NormParamSNNModels.PINningSparseSynapseSNNModels.PINningSparseSynapseParameterSNNModels.PINningSynapseSNNModels.PINningSynapseParameterSNNModels.PerturbationSpikeStoreSNNModels.PerturbationStoreSNNModels.PhysiologySNNModels.PlasticityParameterSNNModels.PlasticityVariablesSNNModels.PoissonSNNModels.PoissonFixedSNNModels.PoissonHetParameterSNNModels.PoissonHomoParameterSNNModels.PoissonIntervalSNNModels.PoissonLayerSNNModels.PoissonLayerHetSNNModels.PoissonLayerParameterSNNModels.PoissonParameterSNNModels.PoissonStimulusSNNModels.PoissonStimulusLayerSNNModels.PoissonStimulusParameterSNNModels.PoissonVariableSNNModels.PostSpikeSNNModels.RandomTurnoverSNNModels.RateSNNModels.RateParameterSNNModels.RateSynapseSNNModels.RateSynapseParameterSNNModels.ReceptorSNNModels.ReceptorArraySNNModels.ReceptorSynapseSNNModels.ReceptorSynapseVarsSNNModels.ReceptorVoltageSNNModels.STDPAntiSymmetricSNNModels.STDPConfavreux2025SNNModels.STDPGerstnerSNNModels.STDPMexicanHatSNNModels.STDPParameterSNNModels.STDPStructuredParameterSNNModels.STDPStructuredVariablesSNNModels.STDPSymmetricSNNModels.STDPTripletSNNModels.STDPTripletVariablesSNNModels.STDPVariablesSNNModels.STDPWeightDependentSNNModels.STPSNNModels.STPParameterSNNModels.SingleExpSynapseSNNModels.SingleExpSynapseVarsSNNModels.SpikeIndexSNNModels.SpikeRateSynapseSNNModels.SpikeTimeStimulusSNNModels.SpikeTimeStimulusParameterSNNModels.SpiketimesSNNModels.SpikingSynapseSNNModels.SpikingSynapseDelayParameterSNNModels.SpikingSynapseParameterSNNModels.StimulusGroupSNNModels.SynapseNormalizationSNNModels.SynapseNormalizationSNNModels.TimeSNNModels.TimeSNNModels.TouchListSNNModels.TripodSNNModels.TurnoverSNNModels.TurnoverParamSNNModels.VariablePoissonSNNModels.VariablePoissonParameterSNNModels.WCParameterSNNModels.WilsonCowanSNNModels.iSTDPParameterSNNModels.iSTDPPotentialSNNModels.iSTDPRateSNNModels.iSTDPVariablesSNNModels.vSTDPDenseParameterSNNModels.vSTDPDenseVariablesSNNModels.vSTDPParameterSNNModels.vSTDPVariablesSNNModels.BallAndStickParameterSNNModels.C_memSNNModels.FanoFactorSNNModels.G_axialSNNModels.G_memSNNModels.ISI_CVSNNModels.ISI_CV2SNNModels.MetaPlasticitySNNModels.MetaPlasticitySNNModels.MultiCompartmentStimulusGroupSNNModels.PopulationSNNModels.PopulationSNNModels.ReceptorsSNNModels.ReceptorsSNNModels.SNNfileSNNModels.SNNfolderSNNModels.SNNloadSNNModels.SNNpathSNNModels.SNNsaveSNNModels.STTCSNNModels.STTCSNNModels.SpikeTimeParameterSNNModels.SpikeTimeStimulusIdentitySNNModels.StimulusSNNModels.StimulusSNNModels.StimulusSNNModels.StimulusSNNModels.TripodParameterSNNModels._add_passes!SNNModels._allocate_records!SNNModels._ensure_fire_capacity!SNNModels._fire_mask!SNNModels._initial_clamp!SNNModels._post_spike_pass!SNNModels._pre_pass!SNNModels._pre_spike_pass!SNNModels._pre_spike_pass!SNNModels._spike_increment!SNNModels._stdp_passes!SNNModels._zt_poissonSNNModels.add_endtime!SNNModels.add_starttime!SNNModels.alpha_functionSNNModels.alpha_kernelSNNModels.asynchronous_stateSNNModels.attach_driver!SNNModels.average_conn_strengthSNNModels.average_firing_rateSNNModels.bin_spiketimesSNNModels.change_plasticitySNNModels.change_plasticity!SNNModels.check_loaded_modelSNNModels.chunk_ptr!SNNModels.chunk_rangeSNNModels.clear_monitor!SNNModels.clear_perturbation_monitor!SNNModels.clear_perturbation_records!SNNModels.clear_records!SNNModels.clear_records!SNNModels.clear_records!SNNModels.compact_perturbation_records!SNNModels.composeSNNModels.compute_connectionsSNNModels.compute_covariance_densitySNNModels.compute_cross_correlogramSNNModels.connect!SNNModels.convert_precisionSNNModels.create_dendriteSNNModels.current_valueSNNModels.current_weightsSNNModels.data2modelSNNModels.dsparseSNNModels.efficacySNNModels.ensure_transpose!SNNModels.exp256SNNModels.exp32SNNModels.exp64SNNModels.extract_itemsSNNModels.f2lSNNModels.fed_spike_indexSNNModels.filter_itemsSNNModels.find_interval_indicesSNNModels.firing_rateSNNModels.float_typeSNNModels.foreach_chunkSNNModels.foreach_chunk_cSNNModels.forward!SNNModels.forward!SNNModels.forward!SNNModels.forward!SNNModels.forward!SNNModels.forward!SNNModels.forward!SNNModels.forward!SNNModels.gaussian_kernelSNNModels.gaussian_kernel_estimateSNNModels.gaussian_smoothSNNModels.gaussian_weightSNNModels.get_dtSNNModels.get_git_commit_hashSNNModels.get_intervalSNNModels.get_maximaSNNModels.get_measure_intervalSNNModels.get_poisson_rateSNNModels.get_stepSNNModels.get_synapse_symbolSNNModels.get_timeSNNModels.get_timestampSNNModels.getrecordSNNModels.getvariableSNNModels.graphSNNModels.has_plasticitySNNModels.has_transposeSNNModels.indicesSNNModels.infer_receptorsSNNModels.infer_spikesSNNModels.infer_spiketimesSNNModels.integrate!SNNModels.integrate!SNNModels.integrate!SNNModels.integrate!SNNModels.integrate!SNNModels.integrate!SNNModels.interpolated_recordSNNModels.interval_standard_spikesSNNModels.interval_standard_spikes!SNNModels.is_attractor_stateSNNModels.is_unimodalSNNModels.isa_modelSNNModels.isiSNNModels.lazy_variablesSNNModels.linear_networkSNNModels.load_dataSNNModels.load_modelSNNModels.load_or_runSNNModels.make_heterogeneousSNNModels.matrixSNNModels.matrixSNNModels.matrix_recordSNNModels.max_neuronSNNModels.membrane_updateSNNModels.merge_modelsSNNModels.merge_spiketimesSNNModels.modelcopySNNModels.monitor!SNNModels.nameSNNModels.nchunksSNNModels.needs_transposeSNNModels.neuronsSNNModels.neuronsSNNModels.neurons_outside_areaSNNModels.neurons_per_threadSNNModels.neurons_within_circleSNNModels.next_neuronSNNModels.nmda_gatingSNNModels.norm_synapseSNNModels.norm_synapseSNNModels.periodic_distanceSNNModels.perturbation_recordSNNModels.perturbation_testSNNModels.perturbation_windowsSNNModels.place_populationsSNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity!SNNModels.plasticity_valueSNNModels.plasticityvariablesSNNModels.population_indicesSNNModels.postsynapticSNNModels.postsynaptic_idxsSNNModels.prepare_spikes!SNNModels.presynapticSNNModels.presynaptic_idxsSNNModels.presynaptic_spikesSNNModels.pretty_nt_printSNNModels.print_modelSNNModels.print_summarySNNModels.rand_valueSNNModels.read_folderSNNModels.read_folder!SNNModels.recordSNNModels.recordSNNModels.record!SNNModels.record_fire!SNNModels.record_fire_dense!SNNModels.record_sym!SNNModels.relative_time!SNNModels.release_input!SNNModels.remove_autapses!SNNModels.remove_elementSNNModels.resample_spikesSNNModels.reset_time!SNNModels.resolve_membraneSNNModels.sample_inputsSNNModels.sample_spikesSNNModels.save_configSNNModels.save_modelSNNModels.set_LTP!SNNModels.set_STP!SNNModels.set_active!SNNModels.set_active!SNNModels.set_intervals!SNNModels.set_intervals!SNNModels.set_optimal_neurons_per_thread!SNNModels.set_plasticity!SNNModels.set_plasticity!SNNModels.set_variable!SNNModels.set_variable!SNNModels.shift_spikes!SNNModels.shift_spikes!SNNModels.shift_spikes!SNNModels.shift_spikes!SNNModels.sim!SNNModels.snn_kw_finalizeSNNModels.snn_kw_get_concrete_typesSNNModels.snn_kw_str_fieldSNNModels.snn_kw_str_kwsSNNModels.snn_kw_str_kws_typesSNNModels.snn_kw_str_paramSNNModels.snn_kw_str_sentinel_checkSNNModels.snn_kw_str_sentinel_check_concreteSNNModels.snn_kw_str_sentinelsSNNModels.sorted_ntupleSNNModels.sparse_matrixSNNModels.sparse_matrixSNNModels.spatial_activitySNNModels.spike_indexSNNModels.spike_list!SNNModels.spikecountSNNModels.spikes_in_intervalSNNModels.spikes_in_intervalsSNNModels.spiketimesSNNModels.spiketimesSNNModels.spiketimes_splitSNNModels.st_orderSNNModels.stimulate!SNNModels.stimulate!SNNModels.stimulate!SNNModels.stimulate!SNNModels.stimulate!SNNModels.stimulate!SNNModels.stimulate!SNNModels.str_nameSNNModels.str_nameSNNModels.subpopulationsSNNModels.synaptic_current!SNNModels.synaptic_receptorsSNNModels.synaptic_targetSNNModels.synaptic_targetSNNModels.synaptic_turnover!SNNModels.synaptic_variablesSNNModels.sync_traces!SNNModels.sync_weights!SNNModels.target_neuronsSNNModels.tile_intervalSNNModels.trace_valuesSNNModels.train!SNNModels.update_neuron!SNNModels.update_plasticity!SNNModels.update_sparse_matrix!SNNModels.update_spikes!SNNModels.update_synapses!SNNModels.update_time!SNNModels.update_traces!SNNModels.update_weights!SNNModels.update_with_mergeSNNModels.validate_population_modelSNNModels.validate_stimulus_modelSNNModels.validate_synapse_modelSNNModels.with_flush_subnormalsSNNModels.with_membraneSNNModels.with_neurons_per_threadSNNModels.with_plasticitySNNModels.without_plasticitySNNModels.write_configSNNModels.write_valueSNNModels.α_synapseSNNPlots.makie_default!SNNPlots.plot_connection_distancesSNNPlots.plot_spatial_connectivitySNNPlots.rasterSNNPlots.raster!SNNPlots.stdp_kernelSNNPlots.stdp_kernel!SNNPlots.stdp_testSNNPlots.vecplotSNNPlots.vecplot!SNNUtils.LogRegtrainSNNUtils.MultinomialLogisticRegressionSNNUtils.SVCtrainSNNUtils.all_intervalsSNNUtils.all_windowsSNNUtils.average_weightSNNUtils.average_weight_dynamicsSNNUtils.bioseq_epochsSNNUtils.bioseq_lexiconSNNUtils.compute_keiSNNUtils.critical_windowSNNUtils.do_pcaSNNUtils.generate_balanced_sequenceSNNUtils.generate_lexiconSNNUtils.generate_sequenceSNNUtils.get_lexiconSNNUtils.get_modelSNNUtils.getdictionarySNNUtils.getdurationSNNUtils.getneuronsSNNUtils.getphonemesSNNUtils.getstimSNNUtils.getstimsymSNNUtils.import_bioseq_tasksSNNUtils.merge_intervalsSNNUtils.nmda_currSNNUtils.optimal_keiSNNUtils.residual_currentSNNUtils.root_pathSNNUtils.sample_stp_campagnolaSNNUtils.sample_stp_paramsSNNUtils.score_spikesSNNUtils.seq_bioseqSNNUtils.sequence_endSNNUtils.set_stimuli!SNNUtils.sign_intervalsSNNUtils.spikecount_featuresSNNUtils.standardizeSNNUtils.start_intervalSNNUtils.step_inputSNNUtils.stimuli_namesSNNUtils.store_activity_dataSNNUtils.store_experiment_dataSNNUtils.store_labelsSNNUtils.store_target_popsSNNUtils.sym_featuresSNNUtils.symbol_namesSNNUtils.symbols_to_intSNNUtils.time_in_intervalSNNUtils.trial_averageSNNUtils.trial_sortSNNUtils.update_stimuli!SNNUtils.word_phonemes_sequenceSNNModels.@chunksSNNModels.@load_unitsSNNModels.@snn_kwSNNModels.@symdictSNNModels.@updateSNNModels.@update!SNNPlots.@makie_default
Model composition and simulation
A network model is a NamedTuple (pop, syn, stim, name, time) built with compose. sim! integrates it without plasticity; train! runs the same loop and in addition calls update_traces! and plasticity! of every population and connection.
SNNModels.AbstractComponent — Type
AbstractComponentRoot of all network components: populations (AbstractPopulation), connections (AbstractConnection), stimuli (AbstractStimulus), groups of stimuli (AbstractGroup) and synapse models (AbstractSynapseParameter, AbstractSynapseVariable).
SNNModels.AbstractConnection — Type
AbstractConnection <: AbstractComponentAbstract type of connections between populations (synapses, metaplasticity operators). A concrete connection has at least the fields param (an AbstractConnectionParameter), id, name and records (checked by validate_synapse_model), and implements
forward!(c, param, dt::Float32, T::Time): propagate presynaptic activity to the postsynaptic target variable; called every step bysim!andtrain!, after all populations are integrated.- optionally
update_traces!(c, param, dt, T)andplasticity!(c, param, dt, T), called only bytrain!.
SNNModels.AbstractGroup — Type
AbstractGroup <: AbstractComponentAbstract type for containers of components that act as one unit (e.g. StimulusGroup).
SNNModels.AbstractParameter — Type
AbstractParameterRoot of all parameter types (population, connection and stimulus parameters).
Every model object stores its parameter struct in the field param; the simulation loop dispatches integrate!, forward! and stimulate! on typeof(obj.param). Direct subtypes are AbstractPopulationParameter, AbstractConnectionParameter and AbstractStimulusParameter.
SNNModels.AbstractPopulation — Type
AbstractPopulation <: AbstractComponentAbstract type of neuron populations. A concrete population has at least the fields N, param (an AbstractPopulationParameter), id, name and records (checked by validate_population_model), and implements
integrate!(p, param, dt::Float32): advance the state by one stepdt(called bysim!andtrain!).- optionally
update_traces!(p, param, dt, T)andplasticity!(p, param, dt, T), called only bytrain!(the defaults do nothing).
SNNModels.AbstractStimulus — Type
AbstractStimulus <: AbstractComponentAbstract type of external inputs. A concrete stimulus has at least the fields param (an AbstractStimulusParameter), id, name and records, and implements
stimulate!(s, param, T::Time, dt::Float32): called once per time step, before the populations are integrated, to write the input into the target population variable.
SNNModels.AbstractStimulusGroup — Type
AbstractStimulusGroup <: AbstractGroupAbstract type of groups of stimuli. When a model is simulated, the elements of a group are expanded and each element is stimulated as an individual AbstractStimulus (see sim!/train!).
SNNModels.EmptyParam — Type
EmptyParamA struct representing an empty parameter.
Fields
type::Symbol: The type of the parameter, default is:empty.
SNNModels.NetworkModel — Type
NetworkModelAlias of NamedTuple. A network model, as returned by compose, is a NamedTuple with fields pop, syn, stim (each a NamedTuple of components), time::Time and name::String.
SNNModels.Spiketimes — Type
SpiketimesType alias for Vector{Vector{Float32}}: one vector of spike times (ms) per neuron.
Example
using SpikingNeuralNetworks
st = SNN.Spiketimes([[1.0f0, 5.0f0], Float32[]]) # neuron 1 fires at 1 and 5 ms, neuron 2 neverSNNModels.Time — Type
Time(; t = [0.0f0], tt = Int32[0], dt = 0.125f0)
Time{FT}(; t = [zero(FT)], tt = Int32[0], dt = FT(0.125))Mutable simulation clock shared by all components of a model. Time() is a Time{Float32}; a model whose populations are Float64 (see float_type) gets a Time{Float64} from compose.
The values are stored in one-element vectors so that the clock can be shared and updated in place by update_time!. Use get_time, get_step, get_dt and reset_time! to read or reset it.
Fields
t::Vector{FT} = [0.0f0]: current time (ms),t[1].tt::Vector{Int32} = Int32[0]: number of integration steps performed,tt[1].dt::FT = 0.125f0: time step (ms) of the last update.
Example
using SpikingNeuralNetworks
T = SNN.Time()
SNN.get_time(T) # 0.0f0SNNModels.Time — Method
Time(time::Number; dt = 0.125f0)
Time{FT}(time::Number; dt = 0.125)Create a clock set at time (ms), with time step dt and step counter tt = round(time / dt) (Float32 unless FT is given).
Example
using SpikingNeuralNetworks
T = SNN.Time(100.0) # t = 100 ms, tt = 800SNNModels.float_type — Method
float_type(x)Floating-point element type (Float32 or Float64) of a model object or type. The precision is chosen on the populations (e.g. Identity(N = 10, VFT = Vector{Float64})); connections and stimuli take the type of the variable they write into, and plasticity state, delay buffers and the clock follow. For a type: its first type parameter that is a float or a vector of floats, else Float32. For a network built with compose: the promotion over its populations.
SNNModels.isa_model — Method
isa_model(model)Validate that a model has the required structure for a network model.
Arguments
model: The model to validate
Returns
trueif valid
Throws
- AssertionError if required fields (pop, syn, stim, time, name) are missing
- AssertionError if any component fails validation
Details
- Checks for presence of all required fields
- Validates each population, synapse, and stimulus
- Ensures time field is a Time struct
SNNModels.validate_population_model — Method
validate_population_model(model)Validate a population model structure.
Arguments
model: The population model to validate
Throws
- AssertionError if model doesn't inherit from AbstractPopulation
- AssertionError if param doesn't inherit from AbstractPopulationParameter
- AssertionError if required fields (N, param, id, name, records) are missing
SNNModels.validate_stimulus_model — Method
validate_stimulus_model(model)Validate a stimulus model structure.
Arguments
model: The stimulus model to validate
Throws
- AssertionError if model doesn't inherit from AbstractStimulus
- AssertionError if param doesn't inherit from AbstractStimulusParameter
- AssertionError if required fields (param, id, name, records) are missing
SNNModels.validate_synapse_model — Method
validate_synapse_model(model)Validate a synapse/connection model structure.
Arguments
model: The synapse model to validate
Throws
- AssertionError if model doesn't inherit from AbstractConnection
- AssertionError if param doesn't inherit from AbstractConnectionParameter
- AssertionError if required fields (param, id, name, records) are missing
SNNModels.change_plasticity — Method
change_plasticity(model, syn_name::Symbol; LTP = nothing, STP = nothing)A new model in which the synapse syn_name is replaced by with_plasticity(model.syn[syn_name]; LTP, STP) (see with_plasticity): a rule left to nothing is kept, NoLTP() / NoSTP() switch that part off. Everything else in the result is the same object as in model, which is not modified. The rule types are type parameters of the synapse, so there is no in-place model-level variant.
The new synapse shares W, the connectivity, the delay queue, the records and any kept rule state with the old one: simulate only the new model (or deepcopy(model) first). A SynapseNormalization or AggregateScaling in the model keeps acting on the old synapse.
Throws
ArgumentError if syn_name is not a synapse of the model; the message lists the available names.
Example
using SpikingNeuralNetworks
SNN.@load_units
E = SNN.IF(N = 100); E.I .= 300.0
EE = SNN.SpikingSynapse(E, E, :ge; conn = (p = 0.2, μ = 0.5))
model = SNN.compose(; E, EE, silent = true)
model_p = SNN.change_plasticity(model, :EE; LTP = SNN.STDPGerstner())
SNN.train!(; model = model_p, duration = 100ms)
model_f = SNN.change_plasticity(model_p, :EE; LTP = SNN.NoLTP(), STP = SNN.NoSTP()) # weights frozenSNNModels.compose — Method
compose(args...; name = randstring(10), silent = false, time = nothing, kwargs...)Assemble populations, connections and stimuli (or whole models) into one network model.
Returns the NamedTuple (pop = ..., syn = ..., stim = ..., name = name, time = time), where pop, syn and stim are NamedTuples of components. This is the object accepted by sim!, train!, monitor!, save_model, etc.
Arguments
args...: models or containers (NamedTuple/Dict) to merge. Their components keep their own keys.StringandTimepositional arguments are ignored.kwargs...: components or containers given by key. A component passed asE = popis stored under:E. A container passed asexc = (E = ..., EE = ...)is flattened with the key as prefix (:exc_E,:exc_EE). Inside containers, the keys:pop,:syn,:stimare descended into without prefixing and the key:nameis skipped.name: model name (default: random 10-character string).silent = false: iffalse, print the model summary withprint_model.time = nothing: the clock of the new model; by default a newTime{FT}()withFTthe promotion of thefloat_types of the populations. The clocks of merged models are not reused: passtime = model.timeto keep one.
Components are classified by type (AbstractPopulation, AbstractConnection, AbstractStimulus or AbstractStimulusGroup); a duplicated key is an AssertionError (to replace a synapse of an existing model use change_plasticity). pop and syn are sorted by key, stim by the stimuli name.
Example
using SpikingNeuralNetworks
@load_units
E = SNN.IF(N = 10, name = "E")
I = SNN.IF(N = 5, name = "I")
EI = SNN.SpikingSynapse(E, I, :ge, conn = (μ = 1.0, p = 0.2))
model = SNN.compose(; E, I, EI, name = "toy", silent = true)
model2 = SNN.compose(model, extra = (A = SNN.IF(N = 3, name = "A"),), silent = true)
keys(model2.pop) # (:E, :I, :extra_A)
sim!(model, 100ms)SNNModels.exp256 — Method
exp256(x::AbstractFloat)Fast approximation of exp(x) as $(1 + x/256)^{256}$, computed with eight squarings. Inputs below -10 are replaced by -256, so that the result is exactly 0.
Returns
- approximation of
exp(x)in the type ofx(Float32orFloat64).
SNNModels.exp32 — Method
exp32(x::R) where {R<:Real}Fast approximation of exp(x) as $(1 + x/32)^{32}$, computed with five squarings. Inputs below -10 are clamped to -10.
Returns
Float32approximation ofexp(x); accurate only for small|x|.
SNNModels.exp64 — Method
exp64(x::AbstractFloat)Fast approximation of exp(x) as $(1 + x/64)^{64}$, computed with six squarings. Inputs below -10 are replaced by -64, so that the result is exactly 0.
Returns
- approximation of
exp(x)in the type ofx(Float32for an integer argument); accurate only for small|x|.
Example
using SpikingNeuralNetworks
SNNModels.exp64(-1.0f0) # 0.3650, exp(-1) = 0.3679SNNModels.extract_items — Method
extract_items(root::Symbol, container; pop::Dict{Symbol,Any}, syn::Dict{Symbol,Any}, stim::Dict{Symbol,Any}, time::Time)Recursively collect the components found in container into pop, syn and stim (helper of compose). Keys of nested containers are prefixed with root (root_key) unless root is empty or one of :pop, :syn, :stim; :name entries and Time values are skipped.
Arguments
root::Symbol: The root symbol for the items being extracted.container: The container from which to extract items.pop::Dict{Symbol,Any}: The dictionary to store population items.syn::Dict{Symbol, Any}: The dictionary to store synapse items.stim::Dict{Symbol,Any}: The dictionary to store stimulus items.
Returns
true: Always returns true.
Details
- If the type of the item in the container is
AbstractPopulation, it is added to thepopdictionary. - If the type of the item in the container is
AbstractConnection, it is added to thesyndictionary. - If the type of the item in the container is
AbstractStimulus, it is added to thestimdictionary. - If the type of the item in the container is none of the above, the function is recursively called to extract items from the nested container.
SNNModels.f2l — Function
f2l(s, l=10)Format string to fixed length by padding or truncating.
Arguments
s: Input value to convert to stringl: Target length (default: 10)
Returns
- String of exactly length
l, padded with spaces or truncated
SNNModels.merge_models — Method
merge_models(args...; kwargs...)Deprecated alias of compose (emits a warning).
SNNModels.name — Function
name(pre, post, k=nothing)Generate a Symbol name for connections between populations.
Arguments
pre: Pre-synaptic population namepost: Post-synaptic population namek: Optional suffix for the name
Returns
- Symbol in format
:pre_to_postor:pre_to_post_kif k is provided
SNNModels.print_model — Function
print_model(model, get_keys = false)Log (with @info) a summary of a model built by compose: name, current time (s), and one line per population (name, type, N, parameter type), per synapse (name, pre/post populations, long-term plasticity type, metaplasticity, short-term plasticity type; AbstractMetaPlasticity connections are skipped in the list) and per stimulus (name, target, type). The connectivity is taken from graph(model). get_keys is accepted but does not change the output.
Arguments
model: The model containing populations, synapses, and stimuli to be printed.
Exception
Raises an assertion error if any component in the populations is not a subtype of AbstractPopulation, if any component in the synapses is not a subtype of AbstractConnection, or if any component in the stimuli is not a subtype of AbstractStimulus.
SNNModels.rand_value — Method
rand_value(N, p1, p2)Generate N random values (Float64) uniformly distributed between p1 and p2.
Arguments
N: Number of random values to generatep1: First boundary valuep2: Second boundary value
Returns
- Vector of N random values between min(p1,p2) and max(p1,p2)
SNNModels.remove_element — Method
remove_element(model, key)Remove an element (population, synapse, or stimulus) from a model by its key.
Arguments
model: The network modelkey: Symbol key of the element to remove
Returns
- New model with the element removed
Throws
- Nothing: if
keyis not found, an@infomessage is logged and the model is returned unchanged.
The new model is built with compose(; model..., silent = true), so it keeps the name and time of model. remove_element(model, keys::Vector) removes several elements.
SNNModels.sorted_ntuple — Method
sorted_ntuple(d::AbstractDict; by = identity)NamedTuple with the entries of d ordered by sort(keys; by); String keys become Symbols. Replaces DrWatson.dict2ntuple(sort(d; by)): OrderedCollections 2 removed sort(::Dict).
SNNModels.str_name — Function
str_name(pre, post, k=nothing)Generate a String name for connections between populations.
Arguments
pre: Pre-synaptic population name (String or Symbol)post: Post-synaptic population namek: Optional suffix for the name
Returns
- String in format "pretopost" or "pretopost_k" if k is provided
SNNModels.str_name — Function
str_name(pre::String, k=nothing)Generate a String name with optional suffix.
Arguments
pre::String: Base namek: Optional suffix
Returns
- String in format "pre" or "pre_k" if k is provided
SNNModels.sim! — Method
sim!(P::Vector{<:AbstractPopulation}, C::Vector{<:AbstractConnection} = [EmptySynapse()],
S::Vector{<:AbstractStimulus} = [EmptyStimulus()];
dt = 0.125f0, duration = 10.0f0, pbar = false, time = Time(), perturbation! = nothing)
sim!(; model, duration = 10ms, dt = 0.125ms, pbar = false, perturbation! = nothing)
sim!(model::NamedTuple, duration = 1s; kwargs...)
sim!(args...; model, kwargs...)Simulate a network without plasticity for duration (ms) with time step dt (ms).
Each step runs:
update_time!(the clock advances bydtfirst);- for every stimulus:
stimulate!(s, s.param, T, dt),record!; - for every population:
integrate!(p, p.param, dt),record!; - for every connection:
forward!(c, c.param, dt, T),record!.
The spike list of a population (spike_index) is built once per step and shared by its connections and recorder. A step that throws is a fatal error: discard the run.
No plasticity is applied: sim! never calls update_traces! or plasticity!, so weights and short-term plasticity variables stay constant even if a synapse carries an LTPParam or STPParam. Use train! for plastic networks.
Arguments
model: a NamedTuple built withcompose; its populations, connections and stimuli (stimulus groups are unpacked) are simulated andmodel.timeis advanced.args...: extra components (or vectors of them) added to those ofmodel.dt = 0.125ms: time step (converted to the float type oftime; each component gets it in its own precision).duration = 10ms (vector and keyword forms) or1s(positional model form): the loop runs over0:dt:(duration - dt).time = Time(): clock of the vector form.perturbation!: optional function called before every step asperturbation!(; P, C, S, t, dt, start_time).pbar = false: show a progress bar with the running firing rates of the populations that record:fire.neurons_per_thread = nothing: chunk size of the threaded updates for this run (nothingkeeps the current setting;0orInfturns threading off). Seeneurons_per_thread.flush_subnormals = true: run with subnormal results flushed to zero (on all threads, restored afterwards), which avoids slow subnormal arithmetic in decaying variables;falsekeeps IEEE gradual underflow. SeeSNNModels.with_flush_subnormals.
Recording buffers are sized before the loop (see monitor!). If the model time is 0, a first sample of every record is taken before the first step. Simulations can be continued by calling sim! again: time and recordings continue from where they stopped.
Returns
The Time object (vector form) or the model time in ms after the run (model forms).
Example
using SpikingNeuralNetworks
SNN.@load_units
E = SNN.IF(N = 100)
stim = SNN.Stimulus(SNN.PoissonFixed(rate = 2kHz), E, :ge)
model = SNN.compose(; E, stim)
SNN.monitor!(E, :fire)
SNN.sim!(; model, duration = 1s)
SNN.sim!(model, 500ms) # continue for 500 ms
SNN.get_time(model.time) # 1500.0SNNModels.train! — Method
train!(P::Vector{<:AbstractPopulation}, C::Vector{<:AbstractConnection} = [EmptySynapse()],
S::Vector{<:AbstractStimulus} = [EmptyStimulus()];
dt = 0.125ms, duration = 10ms, time = Time(), perturbation! = nothing, pbar = false)
train!(; model, duration = 10ms, dt = 0.125ms, pbar = false, perturbation! = nothing)
train!(model::NamedTuple, duration = 1s; kwargs...)
train!(args...; model, kwargs...)Simulate a network with plasticity for duration (ms) with time step dt (ms).
train! is the only entry point that applies plasticity. Each step runs:
update_time!(the clock advances bydtfirst);- for every stimulus:
stimulate!,record!; - for every population:
update_traces!,integrate!,plasticity!,record!; - for every connection:
update_traces!,forward!,plasticity!,record!.
The spike list of a population (spike_index) is built once per step and shared by its connections and recorder. A step that throws is a fatal error: discard the run.
sim! runs the same sequence without update_traces! and plasticity!, so weights and STP variables only change under train! (long-term STDP/iSTDP/vSTDP rules, short-term plasticity, metaplasticity components).
Arguments
model: a NamedTuple built withcompose; its populations, connections and stimuli (stimulus groups are unpacked) are simulated andmodel.timeis advanced.args...: extra components (or vectors of them) added to those ofmodel.dt = 0.125ms: time step (converted to the float type oftime; each component gets it in its own precision).duration = 10ms(vector and keyword forms) or1s(positional model form): simulated time; the loop runs over0:dt:(duration - dt), i.e.round(duration / dt)steps.time = Time(): clock of the vector form.perturbation!: optional function called before every step asperturbation!(; P, C, S, t, dt, start_time).pbar = false: show a progress bar with the running firing rates of the populations that record:fire.neurons_per_thread = nothing: chunk size of the threaded updates for this run (nothingkeeps the current setting;0orInfturns threading off). Seeneurons_per_thread.flush_subnormals = true: run with subnormal results flushed to zero (on all threads, restored afterwards), which avoids slow subnormal arithmetic in decaying variables;falsekeeps IEEE gradual underflow. SeeSNNModels.with_flush_subnormals.
Recording buffers are sized before the loop from duration (see monitor!). If the model time is 0, a first sample of every record is taken before the first step.
Returns
The Time object (vector form) or the model time in ms after the run (model forms).
Example
using SpikingNeuralNetworks
SNN.@load_units
E = SNN.IF(N = 100)
stim = SNN.Stimulus(SNN.PoissonFixed(rate = 2kHz), E, :ge)
EE = SNN.SpikingSynapse(E, E, :ge; conn = (p = 0.1, μ = 0.5), LTPParam = SNN.STDPGerstner())
model = SNN.compose(; E, EE, stim)
SNN.train!(; model, duration = 100ms)
SNN.get_time(model.time) # 100.0SNNModels.graph — Method
graph(model)Build a MetaGraphs.MetaDiGraph describing the connectivity of a model created by compose.
Vertices
One per population and one per stimulus, with properties :name (component name), :id (component id) and :key (key in model.pop or model.stim).
Edges
One edge per ordered pair of vertices; several connections between the same pair are stored as vectors in the same edge. Edge properties (vectors with one entry per connection): :type (syn.targets[:type], :fire_to_g for stimuli), :name (connection name), :pop ("pre -> post.sym"), :key, :id, :meta (key of the metaplasticity operator acting on the connection, or :none), :target (targets[:sym]) and :count; :multi is the number of connections on the edge.
- Connections are added from
syn.targets[:fire](presynaptic id) tosyn.targets[:post]. - Stimuli are drawn as an edge from the stimulus vertex to
stim.targets[:post]. AbstractMetaPlasticityconnections (normalization, scaling, turnover) add no edge; their key is written in the:metaproperty of the edges of the synapses listed intargets[:synapses].
Errors
Throws ArgumentError for a connection whose targets has no :type entry, and an error if a target population id is not in the model.
Example
using SpikingNeuralNetworks
@load_units
E = SNN.IF(N = 10, name = "E")
EE = SNN.SpikingSynapse(E, E, :ge, conn = (μ = 1.0, p = 0.2))
g = SNN.graph(SNN.compose(; E, EE, silent = true)) # 1 vertex, 1 self-loop edgeSNNModels.modelcopy — Method
modelcopy(x)Deep copy of a model (or of any object), adapted from Base.deepcopy, that does not copy recorded data.
The object graph is copied recursively as with deepcopy (shared references stay shared in the copy). The difference is in Dicts that hold a :data key, i.e. the records dictionaries filled by monitor!:
- the variables listed in
records[:data]are replaced by empty buffers (:fireby an empty spike-record dictionary with:time,:neurons,:times_buf,:neurons_buf; every other variable by an emptyVector{Float32}), so monitors stay configured but hold no data; :start_timeand:end_timeare replaced by empty dictionaries;:perturbationis replaced by an empty dictionary.
All other fields (state variables, weights, parameters, the Time clock) are copied. Used by perturbation_test to branch a model.
Specialised behaviour for a type T can be added by defining SNNModels.modelcopy_internal(x::T, dict::IdDict).
Example
using SpikingNeuralNetworks
@load_units
E = SNN.IF(N = 10, name = "E")
model = SNN.compose(; E, silent = true)
SNN.monitor!(E, [:v])
sim!(model, 10ms)
model2 = SNN.modelcopy(model)
isempty(model2.pop.E.records[:v]) # true: the copy has no recorded dataUnits and macros
SNNModels.@load_units — Macro
@load_unitsDefine the SNNModels unit constants as local variables in the calling scope.
SNNModels represents physical quantities as plain Float32 numbers in a fixed unit system; the constants convert a number to that system (e.g. 10ms == 10f0, 1s == 1000f0, 10Hz == 0.01f0). The base units are
| Quantity | Base unit | Value 1 equals |
|---|---|---|
| length | cm | 1 cm (metre = 100, um = 1e-4) |
| time | ms | 1 ms (s = second = 1000) |
| frequency | kHz | 1 kHz (Hz = 1e-3) |
| voltage | mV | 1 mV |
| current | pA | 1 pA |
| capacitance | pF | 1 pF |
| conductance | nS | 1 nS |
| resistance | GΩ | 1 GΩ (MΩ = 1e-3) |
| concentration | uM | 1 μM (M = 1e6, mM = 1e3) |
Constants defined by the macro: metre, meter, cm, mm, um, nm, cm2, m2, um2, nm2, second, s, ms, Hz, kHz, voltage, mV, ampere, mA, uA, μA, nA, pA, farad, uF, μF, nF, pF, ufarad, siemens, mS, msiemens, nS, nsiemens, Ω, MΩ, GΩ, M, mM, uM, nM. (mF exists in the module but is not defined by the macro.)
The default integration step of sim!/train! is 0.125ms.
Example
using SpikingNeuralNetworks
@load_units
duration = 2s # 2000.0f0
rate = 10Hz # 0.01f0 (per ms)SNNModels.KwStrSentinel — Type
KwStrSentinelSentinel type used internally by @snn_kw to track unassigned type parameters.
SNNModels.pretty_nt_print — Function
pretty_nt_print(value, indent = 0)Print a (nested) NamedTuple as an indented tree field := value, one field per line. Non-NamedTuple values are printed with println.
SNNModels.snn_kw_finalize — Method
snn_kw_finalize(T, fields::NamedTuple) -> NamedTupleHook called by the keyword constructor of @snn_kw with the struct type T (with its type parameters, e.g. HH{Vector{Float64},Vector{Bool}}) and the field values (in field order, before conversion) before the struct is built. The default returns fields. Specialise it to derive or validate interdependent fields (e.g. the membrane pair, see resolve_membrane, and the precision checks of the populations); keep the same keys in the same order.
SNNModels.snn_kw_get_concrete_types — Method
snn_kw_get_concrete_types(x)Infer concrete types for type parameters from field definitions.
Arguments
x: Vector of parsed field information
Returns
- Dictionary mapping type parameters to inferred concrete types
SNNModels.snn_kw_str_field — Method
snn_kw_str_field(x)Parse struct field expressions for the @snn_kw macro.
Arguments
x::Symbol: Simple field namex::Expr: Field expression with type annotation or default value
Returns
- Tuple containing parsed field information
SNNModels.snn_kw_str_kws — Method
snn_kw_str_kws(x::Tuple)Convert parsed field tuple to keyword argument expression.
Arguments
x::Tuple: Parsed field information (name, type, default)
Returns
- Expression for keyword argument in constructor
SNNModels.snn_kw_str_kws_types — Method
snn_kw_str_kws_types(x::Tuple)Convert parsed parameter tuple to typed keyword argument expression.
Arguments
x::Tuple: Parsed parameter information
Returns
- Expression for typed keyword argument
SNNModels.snn_kw_str_param — Method
snn_kw_str_param(x)Parse struct type parameter expressions for the @snn_kw macro.
Arguments
x::Symbol: Simple type parameterx::Expr: Type parameter expression with constraints or defaults
Returns
- Tuple containing parsed parameter information
SNNModels.snn_kw_str_sentinel_check — Method
snn_kw_str_sentinel_check(x)Generate code to check if type parameter was assigned or use default.
Arguments
x: Parsed parameter information
Returns
- Expression checking for sentinel value
SNNModels.snn_kw_str_sentinel_check_concrete — Method
snn_kw_str_sentinel_check_concrete(x; dict)Generate code to infer concrete type from field types if not explicitly provided.
Arguments
x: Parsed parameter informationdict: Dictionary mapping type parameters to inferred concrete types
Returns
- Expression checking for sentinel and inferring concrete type
SNNModels.snn_kw_str_sentinels — Method
snn_kw_str_sentinels(x)Add sentinel default values to type parameters for tracking assignment.
Arguments
x: Parsed parameter tuple
Returns
- Tuple with sentinel default value added
SNNModels.update_with_merge — Function
update_with_merge(base_config::NamedTuple, path::Vector{Symbol}, value, full_path = nothing)
update_with_merge(base_config, path::Vector{Symbol}, value, full_path = nothing)Return a copy of base_config with the nested field at path set to value (the function behind @update and @update!).
A missing final key is added with a warning; a missing intermediate key is created as an empty NamedTuple with a warning. If an element on the path is a struct with fields, it is converted to a NamedTuple, updated, and rebuilt with its keyword constructor T(; fields...). Any other type throws a TypeError.
Arguments
base_config::NamedTuple: The configuration to updatepath::Vector{Symbol}: Field path to update (e.g., [:a, :b, :c] for a.b.c)value: New value to assignfull_path: Full path for error messages (internal use)
Returns
- Updated NamedTuple with the field modified
SNNModels.@snn_kw — Macro
@snn_kw struct Name{T1 = Default1, T2 <: Bound, ...} <: Super
field::T1 = default
...
endVariant of Base.@kwdef that also accepts default values for the type parameters.
The macro defines the struct (with the defaults stripped) and one keyword constructor Name(; field1 = default1, ..., T1 = Default1, T2 = ...). Field defaults may refer to earlier fields and to the type parameters (which are the first keyword arguments, and may refer to earlier type parameters). Type parameters are keyword arguments of the constructor:
- a type parameter with a default (
FT = Float32) takes that default unless passed explicitly; - a type parameter without a default is inferred as
typeof(field)of the first field with a default value that is annotated with that parameter (internally tracked by the sentinelSNNModels.KwStrSentinel); every such parameter must be used by at least one field.
All population, synapse, stimulus and parameter types of SNNModels are defined with this macro.
The macro can be used in any module: nothing besides @snn_kw needs to be imported.
Example
using SpikingNeuralNetworks
using SNNModels: @snn_kw
@snn_kw struct MyStruct{FT = Float32}
x::FT = 1.0
y::FT = 2.0
end
MyStruct() # MyStruct{Float32}(1.0f0, 2.0f0)
MyStruct(FT = Float64) # MyStruct{Float64}(1.0, 2.0)
MyStruct(x = 3.0) # MyStruct{Float32}(3.0f0, 2.0f0)SNNModels.@symdict — Macro
@symdict(x...)Create a Dict{Symbol,Any} from variable names.
Arguments
x...: Variable names to include in the dictionary
Returns
- Dictionary mapping variable names (as symbols) to their values
Example
using SpikingNeuralNetworks
a = 1
b = 2
d = SNNModels.@symdict(a, b) # Dict{Symbol,Any}(:a => 1, :b => 2)SNNModels.@update! — Macro
@update! base begin
path.to.field = value
...
endIn-place counterpart of @update: computes the updated configuration and rebinds the variable base to it (base = update_with_merge(...)). The single-assignment form @update! base a.b = v also works (up to SNNModels 1.8.4 it did not escape base and failed with an UndefVarError).
Example
using SpikingNeuralNetworks
config = (a = 1, b = (c = 2, d = 3))
@update! config begin
b.c = 7
end
config.b.c # 7SNNModels.@update — Macro
@update base begin
path.to.field = value
...
endReturn a copy of the nested configuration base (a NamedTuple, possibly containing structs) with the listed fields replaced. base itself is not modified. Each assignment is applied with update_with_merge; missing intermediate keys are created (with a warning), structs on the path are rebuilt through their keyword constructor.
The single-assignment form @update base a.b = v is equivalent to a block with one line. (Up to SNNModels 1.8.4 it threw UndefVarError: current_config at macro expansion.)
Example
using SpikingNeuralNetworks
config = (a = 1, b = (c = 2, d = 3))
new_config = @update config begin
b.c = 5
b.d = 6
end
# new_config == (a = 1, b = (c = 5, d = 6)); config is unchangedSaving and loading
SNNModels.SNNfile — Function
SNNfile(type, count::Int, suffix = "")File name used by SNNsave/SNNload: "$(type)-$(count)-$(suffix).jld2" for count > 0, "$(type)-$(suffix).jld2" for count == 0 (e.g. "model-.jld2", "data-2-trial.jld2").
SNNModels.SNNfolder — Method
SNNfolder(path, name, info)Folder in which SNNsave stores a model: joinpath(path, savename(name, info, connector = "-")) (DrWatson savename, so the folder name encodes the info parameters).
Arguments
path: Base directory pathname: Model nameinfo: NamedTuple with model metadata
Returns
- String path to the model folder
SNNModels.SNNload — Method
SNNload(; path, name = "", info = nothing, count = 0, suffix = "", type = :model)
SNNload(path, name = "", info = nothing)Load a file written by SNNsave.
If path is a file, it is loaded directly. Otherwise the file joinpath(SNNfolder(path, name, info), SNNfile(type, count, suffix)) is loaded.
Arguments
path::String: file, or base directory used inSNNsave.name::String,info: model name and metadataNamedTuple(required ifpathis not a file).count::Int = 0: file counter.suffix = "": file suffix.type::Symbol = :model::model(records cleared) or:data(with records).
Returns
- The stored dictionary as a
NamedTuple((model = ..., config = ..., extra keys...)), ornothing(with an@errormessage) if the file does not exist.
Throws
ArgumentErrorifpathis not a file andnameorinfois missing.
Example
using SpikingNeuralNetworks
@load_units
E = SNN.IF(N = 10, name = "E")
model = SNN.compose(; E, silent = true)
dir = mktempdir()
SNN.save_model(; model, path = dir, name = "toy", info = (seed = 1,))
loaded = SNN.load_model(dir, "toy", (seed = 1,))
loaded.model.pop.E.N # 10SNNModels.SNNpath — Method
SNNpath(path, name, info, type, count)Full path joinpath(SNNfolder(path, name, info), SNNfile(type, count)) of a stored file (empty suffix).
Arguments
path: Base directory pathname: Model nameinfo: NamedTuple with model metadatatype: Type of file (:model, :data, etc.)count: File counter
Returns
- Complete file path string
SNNModels.SNNsave — Method
SNNsave(model; path, name, info, suffix = "", config = nothing, type = :all, count = 0, kwargs...)Save a model to SNNfolder(path, name, info) with JLD2 (through DrWatson.save).
Arguments
model: the model to save.path,name,info: base directory, model name and metadataNamedTuple; the folder name issavename(name, info, connector = "-").suffix = "",count = 0: file suffix and counter, seeSNNfile.config = nothing: configuration stored with the model and written inconfig.jl.type = :all::allwrites the:datafile (model with records) and the:modelfile (adeepcopywithclear_records!applied);:modelwrites only the:modelfile. Any other value logs an error and saves nothing.kwargs...: additional entries stored in the same file.
When count < 2, the folder also receives a human-readable config.jl written by write_config, with a timestamp and the git commit hash ("unknown" outside a git repository).
Returns
- The path of the
:modelfile.
SNNModels.check_loaded_model — Method
check_loaded_model(x; what = "file")Throw an ArgumentError if x (a loaded model, params or NamedTuple/Dict of them) contains a JLD2.ReconstructedMutable or JLD2.ReconstructedStatic placeholder, searching recursively through tuples, dictionaries, arrays of non-bits elements and struct fields. JLD2 builds such placeholders when the file holds a type whose layout no longer exists, e.g. a model saved with SNNModels <= 1.9.1; such a model loads without error and then fails later with an unrelated message. No migration is attempted. Returns x.
SNNModels.data2model — Method
data2model(; path, name=randstring(10), info=nothing, count = 0, suffix = "", kwargs...)Create the :model file (records cleared) from an existing :data file, using the layout of SNNsave: SNNfolder(path, name, info)/SNNfile(:data, count, suffix) and .../SNNfile(:model, count, suffix). (Up to SNNModels 1.8.4 it checked joinpath(path, savename(name, info, "data.jld2")), which SNNsave never writes.)
Arguments
path: Directory pathname: Model name (default: random string)info: Model metadata
Returns
trueif model file exists or was created,falseif data file doesn't exist
SNNModels.get_git_commit_hash — Method
get_git_commit_hash()Get current git commit hash of the repository containing the working directory.
Returns
- String containing the full commit hash, or
"unknown"when the working directory is not inside a git repository or git is not available (e.g. cluster jobs run from a copied directory).write_configrecords this string, so a missing repository no longer aborts the run.
Note
- Uses
gitfrom PATH; honoursGIT_DIR/GIT_WORK_TREEif set.
SNNModels.get_timestamp — Method
get_timestamp()Return the current date and time (Dates.now()).
SNNModels.load_data — Method
load_data(path, name, info; kwargs...)Load the :data file (model with its records) stored by SNNsave; same as SNNload(; path, name, info, kwargs..., type = :data).
Arguments
path::String: Directory pathname::String: Model nameinfo::NamedTuple: Model metadatakwargs...: Additional arguments passed to SNNload
Returns
- Loaded data as NamedTuple
SNNModels.load_model — Method
load_model(path, name, info; kwargs...)Load the :model file (records cleared) stored by SNNsave; same as SNNload(; path, name, info, kwargs..., type = :model). Returns nothing if the file is missing.
Arguments
path::String: Directory pathname::String: Model nameinfo::NamedTuple: Model metadatakwargs...: Additional arguments passed to SNNload
Returns
- Loaded model as NamedTuple
SNNModels.load_or_run — Method
load_or_run(f; path, name, info, exp_config...)Return load_model(path, name, info) if that file exists; otherwise call f(info), save the result with save_model and return it.
The model is saved in the folder that load_model(path, name, info) reads, so a second call loads it. (Up to SNNModels 1.8.4 name was replaced by savename(name, info) before saving, so the model was written to another folder and never found.)
Arguments
f::Function: Function to run if model doesn't exist (receivesinfoas argument)path: Directory pathname: Model nameinfo: Model metadataexp_config...: Configuration passed to save_model if running
Returns
- Loaded or newly generated model
SNNModels.print_summary — Method
print_summary(p)Print the type, parameter type, name, N and every parameter field of a population p.
SNNModels.read_folder — Function
read_folder(path, files=nothing; my_filter = <SNNfile names of `type`>, type=:model, name=nothing)List the files of the directory path for which my_filter(file, type) is true (logging each match) and append their full paths to files.
Arguments
path: Directory path to read fromfiles: Optional vector to append results to (default: creates new vector)my_filter: Filter function(file, type) -> Bool; the default matches the files written bySNNsave(SNNfilenames"$(type)-....jld2", e.g.model-.jld2,data-2-trial.jld2) and the older"...$(type).jld2"names. (Up to SNNModels 1.8.4 the default matched only names ending in"$(type).jld2", so it missed the files ofSNNsave.)type: File type to match (default: :model)name: accepted and ignored.
Returns
- Vector of file paths matching the filter
SNNModels.read_folder! — Method
read_folder!(df, path; type=:model, name=nothing)Same as read_folder(path, df; type, name): append the matching file paths to df.
Arguments
df: Vector to append results topath: Directory path to read fromtype: File type to match (default: :model)name: Optional name filter
Returns
- The modified df vector
SNNModels.save_config — Method
save_config(; path, name=randstring(10), config, info=nothing)Save config as joinpath(path, savename(name, info, "config.jld2", connector = "-")) (JLD2, key "config"), creating path if needed.
Arguments
path: Directory pathname: Config name (default: random string)config: Configuration data to saveinfo: Optional metadata
Returns
- Nothing
SNNModels.save_model — Method
save_model(; model, path, name, info, config = nothing, kwargs...)Save both the :data and the :model file, i.e. SNNsave(model; path, name, info, config, type = :all, kwargs...). See SNNsave for the file layout and load_model/load_data.
Arguments
model: The model to savepath: Directory pathname: Model nameinfo: Model metadataconfig: Optional configurationkwargs...: Additional data to save
Returns
- Path to the saved files
SNNModels.write_config — Method
write_config(path, info; config, name="", kwargs...)Write info (and config if not nothing) as Julia source to a text file, preceded by the generation timestamp and the git commit hash (get_git_commit_hash, "unknown" outside a git repository).
Arguments
path::String: file path; ifnameis given, the file isjoinpath(path, savename(name, info, "config", connector = "-"))instead.info:NamedTuplewritten asinfo = (...).config:NamedTuplewritten asconfig = (...), ornothing.kwargs...: accepted and ignored.
Returns
- The path of the written file.
Details
- Entries named
studyormodelsare skipped. (Up to SNNModels 1.8.4 onlymodelswas skipped, because of operator precedence.)
SNNModels.write_value — Function
write_value(file, key, value, indent="", equal_sign="=")Write key = value, to file as Julia source (helper of write_config).
Arguments
file: IO stream to write tokey: Key name (empty string for array elements)value: Value to write (supports Number, String, Symbol, Tuple, Array, Dict, NamedTuple, etc.)indent: Indentation string (default: "")equal_sign: Assignment operator (default: "=")
Details
- Recursively handles nested structures; other structs are written as
TypeName(field = ..., ...). - Formats different types appropriately (quoted strings, symbols with :, ranges as
a:s:b). - In a
Dict, non-numeric values are written as quoted strings.
Spatial networks
SNNModels.compute_connections — Method
compute_connections(pre::Symbol, post::Symbol, points; conn::NamedTuple, spatial::NamedTuple, dist::Sampleable)Draw a distance-dependent connectivity from the population pre to post on a 2D torus.
points is the output of place_populations; points.pre and points.post are used. Connection weights are drawn from the distribution dist. Periodic distances are computed with periodic_distance. spatial.grid_size must have length 2. Two rules are available, selected by spatial.type:
:critical_distance(fieldsdc,ϵ,grid_size,p_long): with $A = L_x L_y$, $p_l =$spatial.p_long[pre], $\gamma_s = A / (\pi d_c^2)$, $\gamma_l = A / (A - \pi d_c^2)$, a pair closer than $d_c$ is connected with probability $p_{short} = (1 - p_l)\,\gamma_s\,\epsilon\,p$ and a farther pair with $p_{long} = p_l\,\gamma_l\,\epsilon\,p$, where $p$ =conn.p. Autapses are excluded whenpre == post. The returnedPis all zeros.:gaussian(fieldsσs,grid_size,ϵ): $(\sigma_x, \sigma_y)$ =spatial.σs[pre]; the pair $(i, j)$ is connected with probability $P_{ij} = \gamma\,\epsilon\,p\,g_{ij}$, with $g_{ij}$ =gaussian_weight(pre_j, post_i)and $\gamma$ the inverse of the mean of the Gaussian profile over a 200x200 grid, so that the mean probability is $\epsilon p$. Pairs withi == jare excluded whenpre == post(up to SNNModels 1.8.4 also whenpre != post).
Any other spatial.type returns nothing.
Returns
L::BitMatrix(N_post x N_pre): connection mask.W::Matrix{Float32}: weights (rand(dist)whereLis true, 0 elsewhere).P::Matrix{Float32}: connection probabilities (:gaussianonly).
Example
using SpikingNeuralNetworks, Distributions
points = SNN.place_populations((E = 100,), [1.0f0, 1.0f0])
spatial = (type = :gaussian, σs = (E = (0.1f0, 0.1f0),), grid_size = [1.0f0, 1.0f0], ϵ = 1.0f0)
L, W, P = SNN.compute_connections(:E, :E, points; conn = (p = 0.1,), spatial, dist = Normal(1, 0.1))SNNModels.gaussian_weight — Function
gaussian_weight(pre::Vector{Float32}, post::Vector{Float32} = [0, 0]; σx, σy, grid_size::Vector{Float32})Gaussian profile $\exp(-(d_x/\sigma_x)^2 - (d_y/\sigma_y)^2)$ of the periodic distances $d_x, d_y$ between two 2D points (computed with exp64; note there is no factor 1/2 in the exponent).
Arguments
pre::Vector{Float32}: The coordinates of the pre-synaptic neuron.post::Vector{Float32}: The coordinates of the post-synaptic neuron.σx::Float32: The standard deviation of the Gaussian in the x-direction.σy::Float32: The standard deviation of the Gaussian in the y-direction.grid_size::Vector{Float32}: The size of the grid.
Returns
weight::Float32: The Gaussian weight between the pre- and post-synaptic neurons.
SNNModels.linear_network — Method
linear_network(N; σ_w = 0.38, w_max = 2.0, kwargs...)Weight matrix of a ring network: N neurons at angles $\theta_i = 2\pi i / N$ with
\[W_{ij} = w_0 + (w_{max} - w_0)\,\exp\!\left(-\frac{d(\theta_i, \theta_j)^2}{2\sigma_w^2}\right), \qquad d = \min(|\theta_i - \theta_j|,\ 2\pi - |\theta_i - \theta_j|),\]
where the baseline $w_0 = w_{max}\,\sigma_w\,(\mathrm{erf}(\pi/(\sqrt{2}\sigma_w)) - \sqrt{2\pi}) / (\sigma_w\,\mathrm{erf}(\pi/(\sqrt{2}\sigma_w)) - \sqrt{2\pi})$ is computed by the function. The diagonal is set to zero. kwargs are ignored.
Reference not given in the code.
Returns
W::Matrix{Float64}(N x N).
SNNModels.neurons_outside_area — Method
neurons_outside_area(points, center, distance, grid_size)Find the indices of neurons outside a specified area around a center point.
Arguments
points::Vector{Vector{Float32}}: The coordinates of the neurons.center::Vector{Float32}: The coordinates of the center point.distance: The minimum distance from the center point.grid_size: The size of the grid (scalar or vector, seeperiodic_distance).
Returns
Vector{Int}: indices of the neurons withperiodic_distance > distance.
SNNModels.neurons_within_circle — Method
neurons_within_circle(points, center, distance, grid_size)Boolean mask of the neurons whose periodic_distance from center is <= distance.
Arguments
points::Vector{Vector{Float32}}: The coordinates of the neurons.center::Vector{Float32}: The coordinates of the center point.distance: The maximum distance from the center point.grid_size: The size of the grid (scalar or vector, seeperiodic_distance).
Returns
Vector{Bool}with one entry per point (usefindallto get indices).
SNNModels.periodic_distance — Method
periodic_distance(x1::Float32, x2::Float32, grid_size::Float32)
periodic_distance(point1::Vector{Float32}, point2::Vector{Float32}, grid_size::Real)
periodic_distance(point1::Vector{Float32}, point2::Vector{Float32}, grid_size::Vector)Distance on a torus (periodic boundary conditions).
- Scalars: $d = \min(|x_1 - x_2|,\ L - |x_1 - x_2|)$.
- Points with a scalar
grid_size$L$ (same size in every dimension): Euclidean periodic distance $\sqrt{\sum_n d_n^2}$. - Points with a vector
grid_size$(L_1, L_2, \dots)$: Euclidean periodic distance $\sqrt{\sum_n d_n^2}$ with $d_n$ computed with $L_n$. (Up to SNNModels 1.8.4 this method computed $\sqrt{(\sum_n d_n)^2} = \sum_n d_n$, the L1 distance.)
Example
using SpikingNeuralNetworks
SNN.periodic_distance([0.05f0, 0.0f0], [0.95f0, 0.0f0], 1.0f0) # 0.1SNNModels.place_populations — Method
place_populations(Npop, grid_size)Place the neurons of each population uniformly at random in a box of size grid_size.
Arguments
Npop:NamedTuple(orDict) of population sizes; only entries of typeInt64are used, the others are skipped.grid_size: vector with the box size in each dimension (any number of dimensions).
Returns
NamedTuplewith, for each population, aVectorofNpoints, each point aVector{Float32}with coordinates in[0, grid_size[d]).
Example
using SpikingNeuralNetworks
points = SNN.place_populations((E = 80, I = 20), [1.0f0, 1.0f0])
length(points.E) # 80SNNModels.spatial_activity — Method
spatial_activity(points, activity; T, L = nothing, N = nothing, grid_size = (x = [0, 0.1], y = [0, 0.1]))Average activity over the cells of a regular 2D grid and over time windows.
Arguments
points: tuple(xs, ys)of the neuron coordinates.activity::Matrix:N_neurons x N_timepoints.T: time windows. A numberTgives the windows(1+(t-1)T):(tT)fort = 1:(N_timepoints ÷ T); a vector gives the windows explicitly (each element a range of column indices). (Up to SNNModels 1.8.4 the last column of each window was excluded.)LorN(exactly one must be given): cell side (number, or(x = Lx, y = Ly)), or number of cells per dimension (number, or(x = Nx, y = Ny)).grid_size = (x = [x0, x1], y = [y0, y1]): extent of the grid.
Returns
spatial_avg::Array{Any,3}:nx x ny x n_windows, mean activity of the neurons in each cell and window (0 for empty cells).x_range,y_range: ranges spanninggrid_size.xandgrid_size.ywithmax(nx, 2)andmax(ny, 2)points.
Example
using SpikingNeuralNetworks
xs = [0.05, 0.15, 0.25, 0.35]
ys = [0.05, 0.15, 0.25, 0.35]
activity = rand(4, 100) # 4 neurons, 100 time points
avg, xr, yr = SNN.spatial_activity((xs, ys), activity; T = 10, L = 0.1,
grid_size = (x = [0, 0.4], y = [0, 0.4]))
size(avg) # (4, 4, 10)Perturbation analysis
SNNModels.AbstractPerturbationStore — Type
AbstractPerturbationStoreSupertype of PerturbationStore and PerturbationSpikeStore: the ragged containers of the perturbation windows of one (variable, condition). They support length (number of windows), isempty, keys (the window numbers n), haskey(store, n) and store[n] (a legacy-style Dict("interval" => ..., "data" => ...), a copy).
SNNModels.PerturbationSpikeStore — Type
PerturbationSpikeStore(N)Spike windows (variable :fire) of one condition of an object with N neurons. Fields:
version::Int: layout version (1).N::Int: neurons.times::Vector{Float32},neuron::Vector{Int32}: all spikes of all windows, parallel arrays. Inside a window the spikes are sorted by neuron, then by time (the order ofspiketimes(pert_obj)flattened neuron by neuron).offsets::Vector{Int}:length(store) + 1entries,offsets[1] = 1; windowjis the spikesoffsets[j] : offsets[j+1]-1oftimes/neuron(an empty store hasoffsets == [1]).tstart,tend,ids,next_id: as inPerturbationStore.
SNNModels.PerturbationStore — Type
PerturbationStore(N)Dense perturbation windows of one (variable, condition) of an object with N rows (neurons or synapses). Built by perturbation_test(...; add_records = condition); fields:
version::Int: layout version (1); readers and writers throw anArgumentError("upgrade SNNModels") for any other number.N::Int: rows.data::Vector{Float32}: the windows concatenated along time, column-major. Viewed as anN x (sum of window lengths)matrix, windowjis the column blockoffsets[j] : offsets[j+1]-1, i.e.data[(offsets[j]-1)*N+1 : (offsets[j+1]-1)*N]. Nothing divides byN, so objects with 0 rows work.offsets::Vector{Int}:length(store) + 1entries,offsets[1] = 1; windowjis the columnsoffsets[j] : offsets[j+1]-1(zero columns allowed; an empty store hasoffsets == [1]).tstart::Vector{Float32},tend::Vector{Float32}: absolute simulation interval (ms) of each window.ids::Vector{Int}: window numbern(the argumentnofclear_perturbation_records!); increasing.next_id::Int: the number the next window gets (then incremented). Window numbers are never reused, not even after every window was deleted; the store is mutable for this counter.compact_perturbation_records!sets it tomaximum(legacy keys) + 1.
Windows may differ in length. Appending is amortised O(window size); deleting a window is O(store size) (its columns are removed from data and the later offsets shift down). The fields are plain arrays of bits types and integers: JLD2 stores them as they are.
SNNModels.clear_perturbation_monitor! — Method
clear_perturbation_monitor!(obj, variable)
clear_perturbation_monitor!(obj, variable, condition)
clear_perturbation_monitor!(obj, variable, condition; n)Remove perturbation records for a specific variable (required), optionally filtered by condition and n.
This is the targeted complement to clear_perturbation_records!:
| Call | Effect |
|---|---|
clear_perturbation_monitor!(obj, :v_s) | remove all conditions for :v_s |
clear_perturbation_monitor!(obj, :v_s, "silence") | remove all n under "silence" for :v_s |
clear_perturbation_monitor!(obj, :v_s, "silence"; n=2) | remove only the window with id 2 (ids are never reused) |
SNNModels.clear_perturbation_records! — Method
clear_perturbation_records!(obj)
clear_perturbation_records!(obj, condition)
clear_perturbation_records!(obj, condition; variable, n)Delete stored perturbation data from obj.
- No
condition: removes all perturbation data (all variables, all conditions);nis ignored. - With
condition: removes all entries for that condition across all variables. - With
variablekwarg: restricts deletion to that variable only. - With both
conditionandnkwarg: removes only the window numberednfor that condition (and variable if specified): its columns (dense) or spikes (:fire) are removed from the store and the later windows keep their numbers. Window numbers are theidsof the store (1, 2, ... in order of recording); they are never reused, also after the last window was deleted (the empty store stays and keeps counting). Deleting a window of a condition still in the pre-1.9.2 layout throws anArgumentError(convert withcompact_perturbation_records!first); deleting whole conditions, variables or everything works on any layout.
Accepts a single AbstractComponent, a NamedTuple of components (e.g. model.pop), or a full model NamedTuple.
SNNModels.compact_perturbation_records! — Method
compact_perturbation_records!(model_or_obj) -> Dict{Symbol,NamedTuple{(:windows,:bytes)}}The one-time migration of files written before SNNModels 1.9.2 / 2.0.2. Convert, in place, perturbation records written in the legacy layout (one Dict("interval", "data") per window, records[:perturbation][variable][condition][n]) into PerturbationStore / PerturbationSpikeStore. The legacy keys n (which may have gaps) become the window ids, next_id becomes maximum(n) + 1; the insertion order is the order of increasing n. Until a file is converted, every reader, flush and single-window deletion on its legacy records throws an ArgumentError naming the object, variable and condition (legacy and compact records never coexist in a working model); clearing a whole condition, variable or all records still works on legacy records. Save the model again after converting.
Accepts a single component, a NamedTuple of components, a model (pop, syn, stim) or the NamedTuple returned by load_data (its model). The conversion goes one object and one variable at a time: the new stores of a variable are built, checked, replace the dictionaries, and GC.gc() runs before the next variable, so two full copies of a variable are never held.
Safety: before the dictionaries of a (variable, condition) are dropped, the new store is compared with them bit by bit (interval, data, spike times, numbers n); on any difference an error is thrown and the legacy data of that condition stays as it was. A condition that cannot be stored (windows that are not Float32 matrices with the same number of rows, or spike windows with different neuron counts) throws an ArgumentError naming the object, variable, condition and n, without touching it. Conditions already compact are skipped, so running it twice is a no-op.
Returns, per variable, the number of windows converted and the legacy size in bytes (Base.summarysize), summed over the objects; empty when nothing needed conversion.
Run this once on each file written by an older version: it shrinks the file (save again afterwards) and cuts load time and memory. Files with compact records need SNNModels >= 1.9.2 / >= 2.0.2 in every process that reads them.
SNNModels.perturbation_record — Method
perturbation_record(obj, variable, condition, interval) -> (data, interval)Reconstruct a variable trace over interval by splicing stored perturbation windows into the baseline recording.
The baseline is retrieved from obj's normal records, aligned to interval via interpolation. Each stored entry for condition is then overlaid at its recorded [tstart, tend] window (in insertion order n, not sorted by time: overlapping windows overwrite earlier ones). The result is a continuous trace where perturbed segments replace the baseline.
Arguments
obj: anyAbstractPopulation,AbstractStimulus, orAbstractConnectionwith a:perturbationrecord populated byperturbation_test.variable:Symbolof a monitored field (e.g.:v_s,:fire,:ge).condition: theadd_recordsname string used inperturbation_test.interval:AbstractRangein ms, e.g.0:1ms:2s.
Returns
- Continuous variables:
(Matrix{Float32} of shape (N_neurons, T), interval).T = length(clipped interval)where the interval is clipped to the recorded baseline range. :fire:(Spiketimes, interval)— baseline spikes in each perturbation window removed and replaced by the recorded perturbed spike times.
Returns unmodified baseline when no perturbation data exists for the condition.
Interval alignment detail
interpolated_record(obj, variable) produces a ScaledInterpolation over the full baseline [start_time, end_time]. Evaluating it on eval_r (the requested interval clipped to the recorded range) yields an exactly time-aligned (N, T) Float32 matrix regardless of the original sampling rate. Each perturbation entry's [tstart, tend] is then mapped to column indices in this grid via searchsortedfirst/searchsortedlast on eval_r.
SNNModels.perturbation_test — Method
perturbation_test(model, simtime; trigger! = (m -> nothing), perturbation! = nothing,
from_state = nothing, add_records = nothing, train = true, kwargs...)Run a perturbed copy of model for simtime ms and return it, or archive its recordings in model.
The copy is created with modelcopy (deep copy with empty record buffers), trigger! is applied to it once, then the copy is simulated with train! or sim!. The original model is modified only when add_records is given (its records[:perturbation] entries are filled).
Arguments
model: source model.simtime: duration in ms, e.g.500ms.
Keyword arguments
trigger!(no-op):(pert_model) -> nothing, applied once to the copy before the run, e.g.m -> SNN.set_active!(m.stim.noise, false) # silence a stimulus m -> (m.pop.pv.I .= 200pA) # inject current m -> SNN.set_LTP!(m.syn.exc_exc, false) # freeze plasticityperturbation!(nothing): forwarded totrain!/sim!, which callperturbation!(; P, C, S, t, dt, start_time)at every time step.from_state(nothing): pre-built model to use instead ofmodelcopy(model). The caller is responsible for empty records and correct starting state.add_records(nothing): ifnothing, returns the perturbed model. If aString/Symbol, appends the recording window of every monitored variable of the perturbed model tomodel.<component>.records[:perturbation][variable][condition](see "Storage schema") and returnsnothing.train(true): iftruerunstrain!(plasticity active); iffalserunssim!.- Remaining
kwargsforwarded totrain!/sim!.
Storage schema (when add_records is set)
From SNNModels 1.9.2 / 2.0.2 the windows of one (variable, condition) are stored in one ragged store (append, delete by id):
obj.records[:perturbation][variable::Symbol][condition::String]
= PerturbationStore # dense variables: N x (sum of window lengths) Float32
| PerturbationSpikeStore # :fire: flat spike times + neuron indicesSee PerturbationStore and PerturbationSpikeStore for the layout, and perturbation_windows to read the windows one by one. Records written by earlier versions (one Dict("interval" => ..., "data" => ...) per window, under records[:perturbation][variable][condition][n]) are NOT read, appended to or edited window by window: the old and the new layout never coexist in a working model, and every flush or reader that meets a legacy store throws an ArgumentError naming object, variable and condition. Any other value (e.g. a NamedTuple) in place of a store is refused the same way, with its type. Convert such files once with compact_perturbation_records! and save them again. The old layout stored 17,160 small dictionaries per variable for 1,320 presentations x 13 conditions; the new one stores a handful of arrays. Only 2-D (N x T) dense windows can be stored; a flush of an N-dimensional window throws an ArgumentError. Files with compact records need SNNModels >= 1.9.2 / >= 2.0.2 in every process that reads them.
Retrieve with perturbation_record(obj, variable, condition, interval).
Example
using SpikingNeuralNetworks
@load_units
E = SNN.IF(N = 20, name = "E")
noise = SNN.CurrentStimulus(E, :I, param = SNN.CurrentNoise(E; I_base = 300pA))
model = SNN.compose(; E, noise, silent = true)
SNN.monitor!(E, [:v, :fire]; sr = 1kHz)
sim!(model, 100ms) # baseline
SNN.perturbation_test(model, 50ms; trigger! = m -> (m.pop.E.I .+= 100pA),
add_records = "kick", train = false)
v, r = SNN.perturbation_record(E, :v, "kick", 0:1ms:150ms)SNNModels.perturbation_windows — Method
perturbation_windows(obj, variable, condition)The perturbation windows stored in obj.records[:perturbation][variable][condition], in insertion order (the order of the window numbers n; not sorted by tstart), as a vector of (tstart, tend, data) named tuples. tstart and tend are Float32 absolute simulation times in ms. Returns an empty vector when nothing is stored. Throws an ArgumentError if the records are still in the pre-1.9.2 layout (one Dict per window): convert them once with compact_perturbation_records!.
data is
- dense variables: the
N x Twindow (areshape(view(...))of the store, no copy;Tcan differ between windows, and the samples span[tstart, tend]evenly); :fire:(neuron, times), two equally long views (Int32neuron indices,Float32spike times in ms): the spikes of the window sorted by neuron, then by time.times[neuron .== i]are the spike times of neuroni.
The views alias the store and are read-only; a later flush or clear_* invalidates them (their contents may change or be stale), so copy what you keep.
for (tstart, tend, v) in perturbation_windows(E, :v, "kick")
@show tstart, tend, size(v)
endSpike-train analysis
SNNModels.FanoFactor — Method
FanoFactor(spiketime::Vector{Float32}; interval::AbstractRange)
FanoFactor(spiketimes::Spiketimes; interval::AbstractRange)
FanoFactor(pop::AbstractPopulation; interval)Fano factor var(counts) / mean(counts) of the spike counts in the bins of interval (see bin_spiketimes; the bin width is step(interval)), 0 if undefined. The Spiketimes and population methods return one value per neuron.
interval is a required keyword (an AbstractRange). (Up to SNNModels 1.8.4 it defaulted to nothing, and the population method built a tuple, both rejected by bin_spiketimes.)
References
Softky, W. R., & Koch, C. (1993). The highly irregular firing of cortical cells is inconsistent with temporal integration of random EPSPs. Journal of Neuroscience, 13(1), 334–350. https://doi.org/10.1523/JNEUROSCI.13-01-00334.1993
Example
using SpikingNeuralNetworks
@load_units
st = SNN.Spiketimes([Float32.(sort(rand(50) .* 1000))])
SNN.FanoFactor(st; interval = 0:100ms:1s)SNNModels.ISI_CV — Method
ISI_CV(spiketime::Vector{Float32}; interval = nothing)
ISI_CV(spiketimes::Spiketimes; interval = nothing)Coefficient of variation of the inter-spike intervals, $CV = \sigma_{ISI} / \mu_{ISI}$ (0 if undefined). The Spiketimes method returns one value per neuron; interval is ignored.
Example
using SpikingNeuralNetworks
SNN.ISI_CV(Float32[0, 10, 20, 30]) # 0.0 (regular train)SNNModels.ISI_CV2 — Method
ISI_CV2(spiketime::Vector{Float32}; interval = nothing)
ISI_CV2(spiketimes::Spiketimes; interval = nothing)
ISI_CV2(pop::AbstractPopulation; interval = nothing)Local coefficient of variation of the inter-spike intervals,
\[CV_2 = \left\langle \frac{2\,|I_{i+1} - I_i|}{I_{i+1} + I_i} \right\rangle_i ,\]
averaged over consecutive ISI pairs of one train (0 if undefined, e.g. fewer than three spikes). The Spiketimes method returns one value per neuron; the population method first restricts the spikes to interval, the other methods ignore interval.
References
Holt, G. R., Softky, W. R., Koch, C., & Douglas, R. J. (1996). Comparison of discharge variability in vitro and in vivo in cat visual cortex neurons. Journal of Neurophysiology, 75(5), 1806–1814. https://doi.org/10.1152/jn.1996.75.5.1806
SNNModels.alpha_function — Method
alpha_function(t::Float32, τ::Float32)Alpha function $\alpha(t) = (t/\tau)\,e^{1 - t/\tau}$ for $t \ge 0$ and $0$ otherwise (peak value 1 at $t = \tau$). Used by alpha_kernel.
SNNModels.alpha_kernel — Method
alpha_kernel(; τ = 25ms, interval, kwargs...)Causal alpha-function kernel sampled with the step of interval on 0:step(interval):10τ, and normalised so that sum(kernel) * step(interval) == 1 (unit area, in 1/ms). Default kernel of firing_rate.
SNNModels.average_firing_rate — Method
average_firing_rate(spiketimes::Spiketimes; interval = [])
average_firing_rate(populations; interval)Spiketimes method: per-neuron time average of the convolved rate returned by firing_rate(spiketimes; interval, interpolate = false) (Hz).
The populations method (a population, a vector or a NamedTuple of populations) returns the histogram of all spike times over the bin edges interval and the left bin edges interval[1:end-1]. (Up to SNNModels 1.8.4 it failed with an UndefVarError: a local variable shadowed the function spiketimes.)
SNNModels.bin_spiketimes — Method
bin_spiketimes(spike_times::Vector{Float32}; interval::AbstractRange, do_sparse = true)
bin_spiketimes(spiketimes::Spiketimes; interval, do_sparse = true)
bin_spiketimes(p::Union{AbstractPopulation,AbstractStimulus}; kwargs...)
bin_spiketimes(P, interval::AbstractRange; kwargs...)
bin_spiketimes(populations::NamedTuple; interval = nothing, do_sparse = true)Count spikes in the bins of interval (bin width step(interval), one bin per element of interval; bin k covers [first(interval) + (k-1)Δ, first(interval) + kΔ)). Spikes at or before first(interval) are ignored.
Returns
- One train:
(counts, interval)withcountsaSparseVector(do_sparse = true) or a denseVector{Float64}of lengthlength(interval). Spiketimesor a population:(counts::Matrix{Float64}, interval)of size(N_neurons, length(interval)).NamedTupleof populations:(counts_per_population, interval, names), viaspiketimes_split.
Example
using SpikingNeuralNetworks
@load_units
st = SNN.Spiketimes([[1.5f0, 2.2f0, 7.0f0], Float32[3.0]])
counts, r = SNN.bin_spiketimes(st; interval = 0:1ms:10ms) # 2 x 11 matrixSNNModels.compute_covariance_density — Method
compute_covariance_density(spike_times1::Vector{Float32}, spike_times2::Vector{Float32};
bin_width = 1ms, max_lag = 200ms)Return (lags, C) with the covariance density $C(\tau) = \mathrm{xcorr}(\tau) - \lambda_x \lambda_y\,\Delta\,n_{bins}$ (cross-correlogram minus its value for independent trains with rates $\lambda_x, \lambda_y$; $\Delta$ = bin_width).
Both trains are binned on the same interval as in compute_cross_correlogram. (Up to SNNModels 1.8.4 the function always threw, see compute_cross_correlogram.)
SNNModels.compute_cross_correlogram — Function
compute_cross_correlogram(spike_times1::Vector{Float32}, spike_times2 = Float32[];
bin_width = 1ms, max_lag = 100.0, shift_predictor = false)Return (lags, corr): the cross-correlogram (DSP.xcorr) of the spike trains of two neurons binned with bin_width on the common interval 0:bin_width:(t_last + max_lag), or the autocorrelogram if spike_times2 is empty (with the zero-lag bin set to 0), for lags up to max_lag ms. corr[k] counts the pairs with t2 - t1 in the lag bin lags[k]. With shift_predictor = true the second train is shifted by 1000 ms.
(Up to SNNModels 1.8.4 the function always threw: bin_spiketimes was called without the required interval and the autocorrelation branch referred to an undefined auto_corr.)
SNNModels.find_interval_indices — Method
find_interval_indices(intervals::AbstractVector, interval::Vector)Index range x1:x2 of the vector of times intervals, with x1 (x2) the first index with value >= interval[1] (>= interval[2]).
SNNModels.firing_rate — Method
firing_rate(spiketimes::Spiketimes; interval, kwargs...) -> (rates, interval)
firing_rate(p::Union{AbstractPopulation,AbstractStimulus}; kwargs...)
firing_rate(P, interval::AbstractRange; kwargs...)
firing_rate(populations; mean_pop = false, kwargs...) -> (rates_per_pop, interval, names)Estimate per-neuron instantaneous firing rates (Hz) from a Spiketimes object by convolving each binned spike train (bin = step(interval)) with a kernel of unit area, then multiplying by 1s. Returns (rates, interval).
interval should be an AbstractRange in milliseconds (e.g. 0:1ms:500ms). It sets the time grid for binning and convolution. If it is omitted, it is built as tt0:sampling:ttf with the keyword arguments sampling = 20ms, tt0 = 0 and ttf = last spike time.
A population (or stimulus) is converted with spiketimes first. The method for a collection of populations (e.g. model.pop) applies spiketimes_split and returns one rate object per population with a :fire record (mean_pop = true averages each over its neurons).
Keyword arguments
interval: time grid in ms, e.g.0f0:1f0:1000f0.kernel: kernel function called askernel(; interval, kwargs...)returning aVectorof weights. Default:alpha_kernel(causal alpha function, controlled by theτkwarg, defaultτ=25ms).neurons: neuron subset.:ALL(default) processes every neuron; pass anIntorVector{Int}to select a subset. Indexing is intospiketimes.interpolate(true): whentrue, wraps the(N, T)rate matrix in aScaledInterpolationso rates can be evaluated at arbitrary(neuron, time)pairs viarates(n, t). Whenfalse, returns a plainMatrix{Float64}of shape(N_neurons, length(interval)).pop_average(false): iftrue, averages over neurons (dim 1) and returns a plainVectorof lengthlength(interval)regardless ofinterpolate.time_average(false): iftrue, skips convolution entirely and returns the mean firing rate per neuron (in Hz) overintervalas aVector{Float32}(spikes withfirst(interval) < t <= last(interval); theneuronsselection is not applied). Setting bothtime_averageandpop_averagecollapses to a single scalar.
Return types summary
interpolate | pop_average | time_average | return type of rates |
|---|---|---|---|
true | false | false | ScaledInterpolation — call as rates(n, t) |
false | false | false | Matrix{Float64} shape (N, T) |
| any | true | false | Vector of length T |
| any | false | true | Vector{Float32} of length N (Hz) |
| any | true | true | scalar Float32 (Hz) |
Example
using SpikingNeuralNetworks
@load_units
E = SNN.Poisson(N = 10, param = SNN.PoissonParameter(20Hz))
SNN.monitor!(E, [:fire])
sim!(SNN.compose(; E, silent = true), 2s)
st = SNN.spiketimes(E)
fr, r = SNN.firing_rate(st; interval = 0:1ms:2s, τ = 50ms)
fr(3, 500f0) # neuron 3 at t = 500 ms
fr_avg, r = SNN.firing_rate(st; interval = 0:1ms:2s, pop_average = true)
mean_rates, _ = SNN.firing_rate(E; interval = 0:1ms:2s, time_average = true)SNNModels.gaussian_smooth — Method
gaussian_smooth(xs, x, σ; skewed = :none) -> VectorApply a normalized Gaussian kernel to signal x sampled on grid xs. Kernel half-width is 3σ (truncated); boundary bins are renormalized by accumulated kernel weight so edge values are not biased toward zero.
Arguments
xs: sample-position grid (used only for its step sizexs[2]-xs[1])x: signal to smooth, lengthnsigma: Gaussian standard deviation in the same units asxsskewed::none(symmetric),:left(causal — uses only past samples),:right(anti-causal — uses only future samples)
Returns
- smoothed signal, same length as
x
SNNModels.infer_spikes — Method
infer_spikes(n_spikes::Vector{<:Integer}, interval::AbstractRange; dt = 0.125f0)Place exactly n_spikes[i] spikes, at distinct random sub-steps of size dt, inside the i-th bin of interval ((interval[i], interval[i] + step(interval)]). Returns a one-element Vector{Vector{Float32}}.
SNNModels.infer_spiketimes — Method
infer_spiketimes(rate::Matrix{<:Integer}, interval::AbstractRange; dt = 0.125f0, seed = nothing)Apply infer_spikes to each row of the spike-count matrix rate (rows = neurons, columns = bins of interval) and return one spike train per row. seed seeds the global RNG.
SNNModels.interval_standard_spikes! — Method
interval_standard_spikes!(spiketimes, interval::Vector; margin = [0, 0])
interval_standard_spikes!(spiketimes::Vector{Spiketimes}, intervals::Vector{Vector}; margin = [0, 0])In-place version of interval_standard_spikes: subtract interval[1] + margin[1] from every spike time; for a Vector{Spiketimes}, element i is shifted by intervals[i].
SNNModels.interval_standard_spikes — Method
interval_standard_spikes(spiketimes::Spiketimes, interval::Vector; margin = [0, 0])Express spike times relative to the interval start: subtract interval[1] + margin[1] from every spike. Works on a copy; see interval_standard_spikes! for the in-place version.
SNNModels.isi — Method
isi(spiketimes::Spiketimes) -> Vector{Vector{Float32}}
isi(spiketimes::Vector{Float32}) -> Vector{Float32}
isi(pop::AbstractPopulation; interval = nothing)Inter-spike intervals (ms), i.e. diff of each (sorted) spike train.
SNNModels.merge_spiketimes — Method
merge_spiketimes(spikes::Vector{Spiketimes}; start::Float32 = 0.0f0) -> Spiketimes
merge_spiketimes(spikes::Spiketimes) -> Vector{Float32}Merge the spike trains of several simulations of the same network, neuron by neuron.
With start > 0, the spikes of the k-th element are shifted by start * (k - 1) in place (the input is modified) before merging, so that consecutive simulations are placed one after the other. The result is sorted per neuron. The neurons are split over Threads.nthreads() tasks; the function is not meant to be called from several threads at once.
The Spiketimes method returns all spikes of all neurons in one sorted vector.
SNNModels.relative_time! — Method
relative_time!(spiketimes::Spiketimes, start_time)Subtract start_time from every spike time (the vectors are replaced in place) and return spiketimes.
SNNModels.resample_spikes — Method
resample_spikes(X, Y)If there are more than 200 000 points, return a random subsample (without replacement) of 200 000 pairs (X[i], Y[i]) and warn; otherwise return (X, Y). Used for raster plots.
SNNModels.sample_inputs — Method
sample_inputs(N, rate::Matrix{<:Integer}, interval; dt = 0.125f0, rate_factor = 1.0f0, seed = nothing)
sample_inputs(N, rate::Matrix{<:Real}, interval; dt = 0.125f0, rate_factor = 1.0f0, seed = nothing)
sample_inputs(N, spikes::BitMatrix, interval; rate_factor, dt = 0.125f0, seed = nothing)Build input spike trains from a matrix sampled on interval (columns = time bins):
- integer matrix: spike counts per bin, converted with
infer_spikes(one train per row;Nandrate_factorare ignored); - real matrix: rates in Hz, converted with
sample_spikes(N, row, interval)(Ntrains per row, concatenated); BitMatrix: spike indicators; each row gives the traininterval[findall(row)].
seed seeds the global RNG. Returns a Vector{Vector{Float32}}.
SNNModels.sample_spikes — Method
sample_spikes(N, rate::Vector, interval::AbstractRange; rate_factor = 1.0f0, dt = 0.125f0) -> Vector{Vector{Float32}}Draw spike trains for N independent neurons from a time-varying rate (Bernoulli approximation of an inhomogeneous Poisson process).
rate[i] is the rate in Hz (a plain number, multiplied by Hz internally) during the i-th step of interval; each step of interval is divided in step(interval) / dt sub-steps, and in every sub-step each neuron spikes with probability rate[i] * Hz * dt * rate_factor. Spike times start at first(interval) + dt. length(rate) == length(interval) is required.
Example
using SpikingNeuralNetworks
@load_units
st = SNN.sample_spikes(5, fill(10.0, 100), 0:10ms:990ms) # 5 neurons at 10 Hz for 1 sSNNModels.shift_spikes! — Method
shift_spikes!(spiketimes::Spiketimes, delay::Number)Add delay (ms) to every spike time, in place.
SNNModels.spikecount — Method
spikecount(pop::AbstractPopulation, Trange::AbstractVector, neurons::Vector{Int})Total number of spikes emitted by the neurons neurons of pop in the interval Trange (open bounds, see spiketimes).
SNNModels.spikes_in_interval — Function
spikes_in_interval(spiketimes::Spiketimes, interval, margin = [0, 0]; collapse = false) -> SpiketimesCopy of the spikes with interval[1] + margin[1] < t <= interval[end] + margin[2] (spike trains must be sorted). collapse is accepted and ignored.
SNNModels.spikes_in_intervals — Method
spikes_in_intervals(spiketimes::Spiketimes, intervals::Vector{Vector{R}}; margin = [0, 0], floor = true)Apply spikes_in_interval to each interval (in parallel with tmap) and return a Vector{Spiketimes}. With floor = true the spikes of each interval are expressed relative to the interval start (interval_standard_spikes!).
SNNModels.spiketimes — Method
spiketimes(Ps; kwargs...) -> SpiketimesConcatenate spike times from all populations in Ps into a single Spiketimes vector. Neurons from the first population occupy indices 1:Ps[1].N, the second population Ps[1].N+1 : Ps[1].N+Ps[2].N, and so on.
Ps can be a NamedTuple (as returned by model.pop) or a Vector of AbstractPopulation/AbstractStimulus. All kwargs are forwarded to the single-population spiketimes dispatch (e.g. interval).
See also: spiketimes_split to keep each population's trains separate.
SNNModels.spiketimes — Method
spiketimes(p; interval=nothing) -> SpiketimesReturn spike times for every neuron in p as a Spiketimes (Vector{Vector{Float32}}), one inner vector per neuron.
Dispatches on the fire recording format stored in p.records[:fire]:
- COO / dense (
meta[:mode][:fire] == :dense): reads the pre-allocatedtimes_buf/neurons_bufflat arrays written by the sim loop. Ifintervalis given, binary-search on the sorted buffer restricts the scan to O(log(Nspikes) + Nspikesininterval) instead of a full linear pass. - Legacy (
push!-based:time/:neuronsdict): used when the population was recorded without the dense infrastructure (nomonitor!call before the sim).
Arguments
p: anAbstractPopulationorAbstractStimuluswith a:firerecord.
Keyword arguments
interval: optional(t0, t1)tuple or anyAbstractRange. Spikes satisfyt > t0andt < t1(both bounds strict). Passnothing(default) to return all recorded spikes.
Notes
- Neurons are indexed
1:p.Nin the output vector; empty inner vectors mean the neuron never fired or fired outside the requested interval. - The returned
Spiketimesis always freshly allocated (safe to mutate). - In the legacy format fewer than two recorded spike events return empty trains.
Example
using SpikingNeuralNetworks
@load_units
E = SNN.Poisson(N = 10, param = SNN.PoissonParameter(20Hz))
SNN.monitor!(E, [:fire])
model = SNN.compose(; E, silent = true)
sim!(model, 1s)
st = SNN.spiketimes(E) # all spikes
st2 = SNN.spiketimes(E; interval = (200ms, 500ms))SNNModels.spiketimes_split — Method
spiketimes_split(Ps; kwargs...) -> (Vector{Spiketimes}, Vector{String})Return, for each element of Ps that has a :fire record, its spiketimes(p; kwargs...), together with the vector of the population names. Elements without a :fire record are skipped.
SNNModels.st_order — Method
st_order(spiketimes::Vector)
st_order(spiketimes::Spiketimes, pop::Vector{Int}, intervals)
st_order(spiketimes::Spiketimes, populations::Vector{Vector{Int}}, intervals, unique_pop = false)Indices that sort the elements of spiketimes (sort(eachindex(spiketimes), by = x -> spiketimes[x]); for a Spiketimes, trains are compared lexicographically, i.e. by first spike).
The methods with pop/populations sort the neurons of pop (each vector of populations) by the time of their first spike inside intervals (a vector of [start, end] pairs; neurons without such a spike come last) and return the sorted neuron indices. (Up to SNNModels 1.8.4 they called the undefined spike_statistics and threw an UndefVarError.)
SNNModels.STTC — Function
STTC(spiketrains::Vector{Vector{Float32}}, Δt, interval = nothing) -> Matrix{Float32}
STTC(pop::AbstractPopulation; ΔT, interval)
STTC(pop::AbstractPopulation, ΔT::Real, interval::AbstractVector)Symmetric matrix of the pairwise STTC values of a set of spike trains (diagonal = 1, pairs with a train without spikes in the interval = 0), computed with threads over rows.
Arguments
spiketrains: A vector of vectors containing the spike times of each neuron.Δt: The coincidence window (ms).interval: recording interval; ifnothing, it spans from the first spike minusΔtto the last spike plusΔt.
The population methods use spiketimes(pop).
SNNModels.STTC — Method
STTC(spiketrainA::Vector{Float32}, spiketrainB::Vector{Float32}, Δt::Float32, interval::AbstractVector)Spike Time Tiling Coefficient between two spike trains,
\[\mathrm{STTC} = \frac{1}{2}\left(\frac{P_A - T_B}{1 - P_A T_B} + \frac{P_B - T_A}{1 - P_B T_A}\right),\]
computed on the spikes inside [t0, t1] = [interval[1], interval[end]]. $P_A$ is the fraction of spikes of A with a spike of B within $\pm\Delta t$; $T_A$ is the length of the union of the windows $[s - \Delta t, s + \Delta t]$ around the spikes of A, clipped to [t0, t1], divided by t1 - t0. A term with $P T = 1$ (0/0) is 1, as in Elephant; the result is 0 if either train has no spike in the interval. The inputs are not modified.
The coefficient saturates when $\Delta t$ times the firing rate is about 1 or more ($T \to 1$): choose $\Delta t$ much shorter than the inter-spike interval.
References
Cutts, C. S., & Eglen, S. J. (2014). Detecting pairwise correlations in spike trains: an objective comparison of methods and application to the study of retinal waves. Journal of Neuroscience, 34(43), 14288–14303.
Example
using SpikingNeuralNetworks
a = Float32[10, 50, 90]
b = Float32[11, 52, 300]
SNN.STTC(a, b, 5.0f0, 0:1:400)SNNModels.asynchronous_state — Function
asynchronous_state(model, interval = nothing, pop = :Exc) -> (cv, ff, si)Summary statistics of the asynchronous-irregular state of the population model.pop.<pop>.
cv: mean over neurons of the ISI coefficient of variationstd(ISI) / (mean(ISI) + 1e-6)(NaN set to 0), with the spikes restricted tointerval.ff:var / meanof all the spike counts of the binned activity matrix (all neurons and bins pooled).si: mean of theN x Ncovariance matrix of the binned spike counts of the neurons (cov(bins, dims = 2)), used as a synchrony index.
interval (default 0s:0.5s:get_time(model)) is an AbstractRange; its step is the bin width.
Example
using SpikingNeuralNetworks
@load_units
Exc = SNN.Poisson(N = 20, param = SNN.PoissonParameter(10Hz))
SNN.monitor!(Exc, [:fire])
model = SNN.compose(; Exc, silent = true)
sim!(model, 2s)
cv, ff, si = SNN.asynchronous_state(model, 0s:100ms:2s, :Exc)SNNModels.gaussian_kernel — Method
gaussian_kernel(σ::Real, ll::Int)Gaussian kernel exp(-t^2 / (2σ^2)), normalised to unit sum, sampled at ll equally spaced points t between -(ll ÷ 2) and ll ÷ 2 (unit spacing when ll is odd).
Arguments
σ: Standard deviation of the Gaussian kernel.length: Length of the kernel.
Returns
kernel: A vector representing the Gaussian kernel.
SNNModels.gaussian_kernel_estimate — Method
gaussian_kernel_estimate(support_vector::Vector, σ::Real; boundary = :continuous)Smooth support_vector with gaussian_kernel(σ, length(support_vector)) by convolution.
Arguments
support_vector: The input vector.σ: Standard deviation of the Gaussian kernel, in samples.boundary::continuousextends the vector periodically (wrap-around) before convolving;:closedpads it with zeros. Any other value throws an error.
Returns
- The smoothed vector, cut from the full convolution of the extended vector: same length as the input for odd lengths, one element shorter for even lengths.
SNNModels.get_maxima — Method
get_maxima(data)Indices x of the strict interior local maxima of data (data[x] > data[x-1] and data[x] > data[x+1]).
SNNModels.is_attractor_state — Method
is_attractor_state(pop::AbstractPopulation, interval::AbstractVector; ratio = 0.3, σ = 10.0f0, false_value = missing)Test whether the time-averaged firing-rate profile over the neurons of pop (ordered by index, e.g. a ring network) is a single bump.
The per-neuron mean rate over interval (from firing_rate(pop; interval)) is smoothed with gaussian_kernel_estimate(rates, σ; boundary = :continuous) (periodic). The profile is unimodal if is_unimodal(kde, ratio) holds for the profile or for the profile shifted by half its length.
Returns
(width, kde): if unimodal,widthis the number of neurons above half of the peak divided byσ;(false_value, kde)otherwise.
SNNModels.is_unimodal — Method
is_unimodal(kernel, ratio)true if at most one local maximum of kernel (see get_maxima) exceeds ratio times the largest local maximum, i.e. maxima below ratio of the main peak are treated as spurious. Throws if kernel has no interior local maximum.
SNNModels.tile_interval — Method
tile_interval(spiketrainA::Vector{Float32}, Δt::Float32, interval::StepRangeLen{Float32})Fraction $T_A$ of interval covered by the windows $±Δt$ around the spikes of spiketrainA (the tiling term of STTC). Sorts spiketrainA in place.
SNNModels.average_conn_strength — Method
average_conn_strength(M::AbstractMatrix, pops::Vector{Vector{Int}}, sparsity = 0.2)Matrix of mean connection strengths between groups of neurons: entry (i, j) is mean(M[pops[i], pops[j]]) / sparsity (post group i, pre group j), i.e. the mean weight of the existing synapses if M has connection density sparsity.
SNNModels.filter_items — Method
filter_items(P; condition::Function = no_noise)Keep the items of P (a NamedTuple of components) that have a name field and for which condition(item) is true. The default condition drops items whose name contains "noise".
Returns
A NamedTuple of the selected items, sorted by their name.
SNNModels.population_indices — Method
population_indices(P)Global neuron indices of each population when the populations of P (a NamedTuple, e.g. model.pop) are concatenated in the order of keys(P), as in spiketimes(model.pop).
Returns
A NamedTuple (sorted by key) mapping each key to the Vector{Int} of its indices.
Example
using SpikingNeuralNetworks
pops = (E = SNN.IF(N = 4), I = SNN.IF(N = 2))
SNN.population_indices(pops) # (E = [1, 2, 3, 4], I = [5, 6])SNNModels.subpopulations — Function
subpopulations(stim, subset = nothing)Neurons targeted by each stimulus of stim (a NamedTuple of stimuli, e.g. model.stim).
Arguments
stim:NamedTupleof stimuli;neurons(s)gives the target neurons of each.subset: optional collection of stimulus names (strings); other stimuli are skipped.
Returns
- A
NamedTuple, sorted by name, mapping each stimulusnameto the unique ids of the neurons it targets.
SNNModels.target_neurons — Function
target_neurons(stim, targets)For each key in targets (strings or symbols), the unique neuron ids targeted by stim[key] (see neurons). Throws if a key is not in stim. Returns a Vector{Vector{Int}}.
Module
SNNModels.SNNModels — Module
SNNModelsCore library of the JuliaSNN ecosystem: neuron population models, synapse and receptor models, connections with long- and short-term plasticity, metaplasticity, stimuli, recording, analysis and input/output utilities.
A network is a NamedTuple assembled with compose (fields pop, syn, stim, name, time) and simulated with sim! (no plasticity) or train! (plasticity active). Quantities are plain Float32 in the unit system loaded by @load_units (ms, mV, pA, pF, nS, cm). Users normally load it through SpikingNeuralNetworks, which re-exports it as SNN.SNNModels.
Umbrella package
SpikingNeuralNetworks re-exports SNNModels, SNNPlots and SNNUtils.
SpikingNeuralNetworks.SpikingNeuralNetworks — Module
SpikingNeuralNetworksUmbrella package of the JuliaSNN ecosystem. It loads and re-exports SNNModels (models, simulation, recording, analysis), SNNPlots (plotting) and SNNUtils (stimulation protocols, analysis and classifiers), defines the alias SNN = SpikingNeuralNetworks, applies the SNNPlots Makie theme (@makie_default) and loads the unit constants (@load_units) at load time.
All exported SNNModels names are reachable as SNN.<name> (e.g. SNN.IF, SNN.sim!).
Example
using SpikingNeuralNetworks
SNN.@load_units
E = SNN.IF(N = 100)
model = SNN.compose(; E, silent = true)
SNN.sim!(model, 100ms)SpikingNeuralNetworks.DOCS_ASSETS_PATH — Constant
DOCS_ASSETS_PATHAbsolute path of docs/src/assets in the SpikingNeuralNetworks package directory (figures used by the documentation and the examples).