Skip to content
Snippets Groups Projects
Select Git revision
  • 9e4f87fb66e2a8979f1619922d84fa7ceaa5c6e1
  • master default protected
  • tut_ring_allen
  • docs_furo
  • docs_reorder_cable_cell
  • docs_graphviz
  • docs_rtd_dev
  • ebrains_mirror
  • doc_recat
  • docs_spike_source
  • docs_sim_sample_clar
  • docs_pip_warn
  • github_template_updates
  • docs_fix_link
  • cv_default_and_doc_clarification
  • docs_add_numpy_req
  • readme_zenodo_05
  • install_python_fix
  • install_require_numpy
  • typofix_propetries
  • docs_recipe_lookup
  • v0.10.0
  • v0.10.1
  • v0.10.0-rc5
  • v0.10.0-rc4
  • v0.10.0-rc3
  • v0.10.0-rc2
  • v0.10.0-rc
  • v0.9.0
  • v0.9.0-rc
  • v0.8.1
  • v0.8
  • v0.8-rc
  • v0.7
  • v0.6
  • v0.5.2
  • v0.5.1
  • v0.5
  • v0.4
  • v0.3
  • v0.2.2
41 results

spikes.cpp

Blame
  • user avatar
    akuesters authored and Ben Cumming committed
    Add docs for Python wrapper to ReadTheDocs:
    
    - Overview, Common Types, Hardware Management, Recipes, Domain Decomposition, Simulations, Metering
    - Installing Arbor: Optional Requirements (Python), Buidling and Installing (Python Frontend), and Installation (Python Module)
    
    Missing (, since not implemented yet): 
    
    - probes
    - arbor-sup 
    - hint maps in domain_decomposition
    - reset, events, empty schedule in event_generator
    Also does not cover unit testing (since doc is user-centric).
    
    Makes also defaults and units in wrapper consistent.
    
    Fixes  #766
    1f4eacd2
    History
    spikes.cpp 3.08 KiB
    #include <memory>
    #include <vector>
    
    #include <pybind11/pybind11.h>
    #include <pybind11/stl.h>
    
    #include <arbor/spike.hpp>
    #include <arbor/simulation.hpp>
    
    #include "strprintf.hpp"
    
    namespace pyarb {
    
    // A functor that models arb::spike_export_function.
    // Holds a shared pointer to the spike_vec used to store the spikes, so that if
    // the spike_vec in spike_recorder is garbage collected in Python, stores will
    // not seg fault.
    struct spike_callback {
        using spike_vec = std::vector<arb::spike>;
    
        std::shared_ptr<spike_vec> spike_store;
    
        spike_callback(const std::shared_ptr<spike_vec>& state):
            spike_store(state)
        {}
    
        void operator() (const spike_vec& spikes) {
            spike_store->insert(spike_store->end(), spikes.begin(), spikes.end());
        };
    };
    
    // Helper type for recording spikes from a simulation.
    // This type is wrapped in Python, to expose spike_recorder::spike_store.
    struct spike_recorder {
        using spike_vec = std::vector<arb::spike>;
        std::shared_ptr<spike_vec> spike_store;
    
        spike_callback callback() {
            // initialize the spike_store
            spike_store = std::make_shared<spike_vec>();
    
            // The callback holds a copy of spike_store, i.e. the shared
            // pointer is held by both the spike_recorder and the callback, so if
            // the spike_recorder is destructed in the calling Python code, attempts
            // to write to spike_store inside the callback will not seg fault.
            return spike_callback(spike_store);
        }
    
        const spike_vec& spikes() const {
            return *spike_store;
        }
    };
    
    std::shared_ptr<spike_recorder> attach_spike_recorder(arb::simulation& sim) {
        auto r = std::make_shared<spike_recorder>();
        sim.set_global_spike_callback(r->callback());
        return r;
    }
    
    std::string spike_str(const arb::spike& s) {
        return util::pprintf(
                "<arbor.spike: source ({},{}), time {} ms>",
                s.source.gid, s.source.index, s.time);
    }
    
    void register_spike_handling(pybind11::module& m) {
        using namespace pybind11::literals;
    
        pybind11::class_<arb::spike> spike(m, "spike");
        spike
            .def(pybind11::init<>())
            .def_readwrite("source", &arb::spike::source, "The spike source (type: cell_member).")
            .def_readwrite("time", &arb::spike::time, "The spike time [ms].")
            .def("__str__",  &spike_str)
            .def("__repr__", &spike_str);
    
        // Use shared_ptr for spike_recorder, so that all copies of a recorder will
        // see the spikes from the simulation with which the recorder's callback has been
        // registered.
        pybind11::class_<spike_recorder, std::shared_ptr<spike_recorder>> sprec(m, "spike_recorder");
        sprec
            .def(pybind11::init<>())
            .def_property_readonly("spikes", &spike_recorder::spikes, "A list of the recorded spikes.");
    
        m.def("attach_spike_recorder", &attach_spike_recorder,
              "sim"_a,
              "Attach a spike recorder to an arbor simulation.\n"
              "The recorder that is returned will record all spikes generated after it has been\n"
              "attached (spikes generated before attaching are not recorded).");
    }
    
    } // namespace pyarb