pub mod calcium;
pub mod error;
pub mod network;
pub mod neurotransmitter;
pub mod plasticity;
pub mod receptor;
pub mod synapse;
pub mod vesicle;
pub use error::{Result, SynapseError};
pub use synapse::{Synapse, SynapseBuilder, SynapseType};
pub use network::{SynapticNetwork, NetworkStats};
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
#[cfg(test)]
mod integration_tests {
use super::*;
use synapse::Synapse;
use network::SynapticNetwork;
#[test]
fn test_complete_synaptic_transmission() {
let mut syn = Synapse::excitatory(1.0, 1.0).unwrap();
assert_eq!(syn.conductance(), 0.0);
syn.presynaptic_spike(0.0).unwrap();
let mut max_conductance = 0.0_f64;
let mut max_nt = 0.0_f64;
for t in 0..100 {
syn.update(t as f64 * 0.1, -65.0, 0.1).unwrap();
max_conductance = max_conductance.max(syn.conductance());
max_nt = max_nt.max(syn.neurotransmitter.get_concentration());
}
assert!(max_conductance > 0.0 || max_nt > 0.0,
"max_conductance: {}, max_nt: {}", max_conductance, max_nt);
}
#[test]
fn test_stdp_learning_window() {
let mut syn_pot = Synapse::excitatory(0.5, 1.0).unwrap();
let w0 = syn_pot.weight;
syn_pot.presynaptic_spike(0.0).unwrap();
syn_pot.postsynaptic_spike(10.0).unwrap();
assert!(syn_pot.weight > w0, "Pre before post should potentiate");
let mut syn_dep = Synapse::excitatory(0.5, 1.0).unwrap();
let w0 = syn_dep.weight;
syn_dep.postsynaptic_spike(0.0).unwrap();
syn_dep.presynaptic_spike(10.0).unwrap();
assert!(syn_dep.weight < w0, "Post before pre should depress");
}
#[test]
fn test_short_term_plasticity() {
let mut syn = Synapse::depressing_excitatory(1.0, 1.0).unwrap();
let initial_prob = syn.vesicle_pool.release_probability();
for i in 0..5 {
syn.presynaptic_spike(i as f64 * 10.0).unwrap();
for _ in 0..10 {
syn.update((i as f64 + 0.1) * 10.0, -65.0, 1.0).unwrap();
}
}
assert!(syn.vesicle_pool.release_probability() < initial_prob);
}
#[test]
fn test_network_connectivity() {
let mut net = SynapticNetwork::new(5);
for i in 0..4 {
let syn = Synapse::excitatory(1.0, 1.0).unwrap();
net.add_connection(i, i + 1, syn).unwrap();
}
let stats = net.connectivity_stats();
assert_eq!(stats.n_connections, 4);
assert_eq!(stats.n_neurons, 5);
}
#[test]
fn test_excitatory_inhibitory_balance() {
let mut net = SynapticNetwork::new(3);
let exc = Synapse::excitatory(1.0, 1.0).unwrap();
net.add_connection(0, 2, exc).unwrap();
let inh = Synapse::inhibitory(1.0, 1.0).unwrap();
net.add_connection(1, 2, inh).unwrap();
net.spike(0).unwrap();
net.spike(1).unwrap();
let voltages = vec![-65.0; 3];
for _ in 0..30 {
net.update(&voltages, 0.1).unwrap();
}
let inputs = net.get_inputs(2);
assert_eq!(inputs.len(), 2);
}
#[test]
fn test_calcium_dynamics() {
let mut syn = Synapse::excitatory(1.0, 1.0).unwrap();
let initial_ca = syn.postsynaptic_calcium.get_concentration();
syn.postsynaptic_spike(0.0).unwrap();
assert!(syn.postsynaptic_calcium.get_concentration() > initial_ca);
for _ in 0..100 {
syn.update(1.0, -65.0, 0.1).unwrap();
}
let final_ca = syn.postsynaptic_calcium.get_concentration();
assert!(final_ca <= syn.postsynaptic_calcium.get_concentration());
}
#[test]
fn test_nmda_voltage_dependence() {
use receptor::NMDAReceptor;
let nmda = NMDAReceptor::new();
let block_neg = nmda.mg_block(-70.0);
let block_zero = nmda.mg_block(0.0);
let block_pos = nmda.mg_block(40.0);
assert!(block_neg < block_zero);
assert!(block_zero < block_pos);
}
#[test]
fn test_receptor_kinetics() {
use receptor::{AMPAReceptor, ReceptorDynamics};
let mut ampa = AMPAReceptor::new();
for _ in 0..50 {
ampa.update(1.0, -65.0, 0.1).unwrap();
}
let peak = ampa.get_conductance();
assert!(peak > 0.0);
for _ in 0..100 {
ampa.update(0.0, -65.0, 0.1).unwrap();
}
assert!(ampa.get_conductance() < peak);
}
}