-
Sam Yates authored
Major changes in Python library and documentation: * Add global state (immutable after initialization) for the Python module that manages the mapping between probe metadata types and the method by which the corresponding [sample data can be collected and presented as Python objects. This is necessary for decoupling the implementation of the simulation wrapper from that of the various cable cell probe types. * Wrap each of the C++ cable cell probe types with a Python function that returns a `probe_info` object. * Add code for converting and accumulating C++ probe metadata and sample data, registered in the module global state against the metadata type info. * Make the `arbor.simulator` object responsible for recording all spike and sample data, with corresponding new methods. * Use NumPy arrays and structured datatypes for returning spike and sample data. * Place Python schedule proxies under an abstract interface so tha...
Unverified1bfe96bc
pyarb.hpp 2.29 KiB
#pragma once
// Common module-global data for use by the pyarb implementation.
#include <functional>
#include <memory>
#include <typeinfo>
#include <unordered_map>
#include <arbor/arbexcept.hpp>
#include <arbor/sampling.hpp>
#include <arbor/util/any_ptr.hpp>
#include <pybind11/pybind11.h>
namespace pyarb {
// Sample recorder object interface.
struct sample_recorder {
virtual void record(arb::util::any_ptr meta, std::size_t n_sample, const arb::sample_record* records) = 0;
virtual pybind11::object samples() const = 0;
virtual pybind11::object meta() const = 0;
virtual void reset() = 0;
virtual ~sample_recorder() {}
};
// Recorder 'factory' type: given an any_ptr to probe metadata of a specific subset of types,
// return a corresponding sample_recorder instance.
using sample_recorder_factory = std::function<std::unique_ptr<sample_recorder> (arb::util::any_ptr)>;
// Holds map: probe metadata pointer type → recorder object factory.
struct recorder_factory_map {
std::unordered_map<std::type_index, sample_recorder_factory> map_;
template <typename Meta>
void assign(sample_recorder_factory rf) {
map_[typeid(const Meta*)] = std::move(rf);
}
std::unique_ptr<sample_recorder> make_recorder(arb::util::any_ptr meta) const {
try {
return map_.at(meta.type())(meta);
}
catch (std::out_of_range&) {
throw arb::arbor_internal_error("unrecognized probe metadata type");
}
}
};
// Probe metadata to Python object converter.
using probe_meta_converter = std::function<pybind11::object (arb::util::any_ptr)>;
struct probe_meta_cvt_map {
std::unordered_map<std::type_index, probe_meta_converter> map_;
template <typename Meta>
void assign(probe_meta_converter cvt) {
map_[typeid(const Meta*)] = std::move(cvt);
}
pybind11::object convert(arb::util::any_ptr meta) const {
if (auto iter = map_.find(meta.type()); iter!=map_.end()) {
return iter->second(meta);
}
else {
return pybind11::none();
}
}
};
// Collection of module-global data.
struct pyarb_global {
recorder_factory_map recorder_factories;
probe_meta_cvt_map probe_meta_converters;
};
using pyarb_global_ptr = std::shared_ptr<pyarb_global>;
} // namespace pyarb