sc_neurocore_engine/bindings/
hindmarsh_rose.rs1use numpy::{IntoPyArray, PyArray1};
12use pyo3::exceptions::PyFloatingPointError;
13use pyo3::prelude::*;
14use pyo3::types::PyDict;
15
16use crate::neurons::HindmarshRoseNeuron;
17
18type PyHindmarshRoseBatch<'py> = (Bound<'py, PyArray1<f64>>, i64, f64, f64, f64);
19
20py_neuron_default!("HindmarshRoseNeuron", PyHindmarshRoseNeuron, HindmarshRoseNeuron, state x, state y, state z);
21
22pub(super) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> {
24 module.add_class::<PyHindmarshRoseNeuron>()?;
25 module.add_function(wrap_pyfunction!(py_hindmarsh_rose_simulate, module)?)?;
26 Ok(())
27}
28
29#[pyfunction]
37#[pyo3(signature = (x0, y0, z0, b, r, s, x_rest, dt, x_threshold, n_steps, current))]
38#[allow(clippy::too_many_arguments)]
39fn py_hindmarsh_rose_simulate<'py>(
40 py: Python<'py>,
41 x0: f64,
42 y0: f64,
43 z0: f64,
44 b: f64,
45 r: f64,
46 s: f64,
47 x_rest: f64,
48 dt: f64,
49 x_threshold: f64,
50 n_steps: usize,
51 current: f64,
52) -> PyResult<PyHindmarshRoseBatch<'py>> {
53 let mut neuron = HindmarshRoseNeuron {
54 x: x0,
55 y: y0,
56 z: z0,
57 b,
58 r,
59 s,
60 x_rest,
61 dt,
62 x_threshold,
63 };
64 let Some((trace, spikes)) = neuron.try_simulate(n_steps, current) else {
65 return Err(PyFloatingPointError::new_err(
66 "Hindmarsh-Rose Rust batch rejected an invalid candidate",
67 ));
68 };
69 Ok((trace.into_pyarray(py), spikes, neuron.x, neuron.y, neuron.z))
70}