From 0cc18b122ab6db1eec8cf8ac6e1b2bb85dbc19fd Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Mon, 11 Sep 2023 10:21:48 +0200 Subject: [PATCH 01/18] Unify loading of Standard Morphology Files. --- arborio/include/arborio/neurolucida.hpp | 21 +--- arborio/include/arborio/neuroml.hpp | 28 +---- arborio/include/arborio/swcio.hpp | 15 ++- arborio/neurolucida.cpp | 96 +++++++++------- arborio/neuroml.cpp | 8 +- arborio/nml_parse_morphology.cpp | 29 +++-- arborio/nml_parse_morphology.hpp | 3 +- arborio/swcio.cpp | 31 ++++- doc/cpp/morphology.rst | 81 ++++++++++--- doc/python/cable_cell.rst | 10 +- doc/python/morphology.rst | 68 ++++++++--- doc/scripts/gen-labels.py | 3 +- example/single/single.cpp | 21 ++-- example/v_clamp/v-clamp.cpp | 20 ++-- python/example/probe_lfpykit.py | 2 +- python/example/single_cell_allen.py | 2 +- python/example/single_cell_detailed.py | 2 +- python/example/single_cell_detailed_recipe.py | 6 +- python/example/single_cell_swc.py | 2 +- python/morphology.cpp | 108 ++++++++++++------ python/test/unit/test_io.py | 6 +- test/unit/test_asc.cpp | 67 ++++++++++- test/unit/test_morphology.cpp | 3 +- test/unit/test_nml_morphology.cpp | 86 +++++++------- test/unit/test_swcio.cpp | 33 ++++-- 25 files changed, 468 insertions(+), 283 deletions(-) diff --git a/arborio/include/arborio/neurolucida.hpp b/arborio/include/arborio/neurolucida.hpp index 260459f883..8019fcf592 100644 --- a/arborio/include/arborio/neurolucida.hpp +++ b/arborio/include/arborio/neurolucida.hpp @@ -6,8 +6,8 @@ #include #include -#include -#include + +#include #include namespace arborio { @@ -33,23 +33,10 @@ struct ARB_SYMBOL_VISIBLE asc_unsupported: asc_exception { std::string message; }; -struct asc_morphology { - // Raw segment tree from ASC, identical to morphology. - arb::segment_tree segment_tree; - - // Morphology constructed from asc description. - arb::morphology morphology; - - // Regions and locsets defined in the asc description. - arb::label_dict labels; -}; - // Perform the parsing of the input as a string. -ARB_ARBORIO_API asc_morphology parse_asc_string(const char* input); -ARB_ARBORIO_API arb::segment_tree parse_asc_string_raw(const char* input); +ARB_ARBORIO_API loaded_morphology parse_asc_string(const char* input); // Load asc morphology from file with name filename. -ARB_ARBORIO_API asc_morphology load_asc(const std::filesystem::path& filename); -ARB_ARBORIO_API arb::segment_tree load_asc_raw(const std::filesystem::path&filename); +ARB_ARBORIO_API loaded_morphology load_asc(const std::filesystem::path& filename); } // namespace arborio diff --git a/arborio/include/arborio/neuroml.hpp b/arborio/include/arborio/neuroml.hpp index 7d889581b4..a17431fccb 100644 --- a/arborio/include/arborio/neuroml.hpp +++ b/arborio/include/arborio/neuroml.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -69,29 +70,6 @@ struct ARB_SYMBOL_VISIBLE nml_cyclic_dependency: neuroml_exception { // Note: segment id values are interpreted as unsigned long long values; // parsing larger segment ids will throw an exception. -struct nml_morphology_data { - // Cell id, or empty if morphology was taken from a top-level element. - std::optional cell_id; - - // Morphology id. - std::string id; - - // Morphology constructed from a single NeuroML element. - arb::morphology morphology; - - // One region expression for each segment id. - arb::label_dict segments; - - // One region expression for each name applied to one or more segments. - arb::label_dict named_segments; - - // One region expression for each segmentGroup id. - arb::label_dict groups; - - // Map from segmentGroup ids to their corresponding segment ids. - std::unordered_map> group_segments; -}; - // Represent NeuroML data determined by provided string. struct ARB_ARBORIO_API neuroml_impl; @@ -126,8 +104,8 @@ struct ARB_ARBORIO_API neuroml { // Parse and retrieve top-level morphology or morphology associated with a cell. // Return nullopt if not found. - std::optional morphology(const std::string& morph_id, enum neuroml_options::values = neuroml_options::none) const; - std::optional cell_morphology(const std::string& cell_id, enum neuroml_options::values = neuroml_options::none) const; + std::optional morphology(const std::string& morph_id, enum neuroml_options::values = neuroml_options::none) const; + std::optional cell_morphology(const std::string& cell_id, enum neuroml_options::values = neuroml_options::none) const; ~neuroml(); diff --git a/arborio/include/arborio/swcio.hpp b/arborio/include/arborio/swcio.hpp index 38b59e0c5a..3d91e61f7a 100644 --- a/arborio/include/arborio/swcio.hpp +++ b/arborio/include/arborio/swcio.hpp @@ -3,9 +3,11 @@ #include #include #include +#include #include -#include + +#include #include namespace arborio { @@ -114,7 +116,6 @@ struct ARB_ARBORIO_API swc_data { // conditions above are encountered. // // SWC records are returned in id order. - ARB_ARBORIO_API swc_data parse_swc(std::istream&); ARB_ARBORIO_API swc_data parse_swc(const std::string&); @@ -126,17 +127,15 @@ ARB_ARBORIO_API swc_data parse_swc(const std::string&); // one segment for each SWC record after the first: this record defines the tag // and distal point of the segment, while the proximal point is taken from the // parent record. - -ARB_ARBORIO_API arb::morphology load_swc_arbor(const swc_data& data); -ARB_ARBORIO_API arb::segment_tree load_swc_arbor_raw(const swc_data& data); +ARB_ARBORIO_API loaded_morphology load_swc_arbor(const swc_data& data); +ARB_ARBORIO_API loaded_morphology load_swc_arbor(const std::filesystem::path& fn); // As above, will convert a valid, ordered sequence of SWC records into a morphology // // Note that 'one-point soma' SWC files are supported here // // Complies inferred SWC rules from NEURON, explicitly listed in the docs. - -ARB_ARBORIO_API arb::morphology load_swc_neuron(const swc_data& data); -ARB_ARBORIO_API arb::segment_tree load_swc_neuron_raw(const swc_data& data); +ARB_ARBORIO_API loaded_morphology load_swc_neuron(const swc_data& data); +ARB_ARBORIO_API loaded_morphology load_swc_neuron(const std::filesystem::path& fn); } // namespace arborio diff --git a/arborio/neurolucida.cpp b/arborio/neurolucida.cpp index 12910e88a2..9672903778 100644 --- a/arborio/neurolucida.cpp +++ b/arborio/neurolucida.cpp @@ -164,11 +164,6 @@ bool is_marker_symbol(const asc::token& t) { // Parse a color expression, which have been observed in the wild in two forms: // (Color Red) ; labeled // (Color RGB (152, 251, 152)) ; RGB literal -struct asc_color { - uint8_t r = 0; - uint8_t g = 0; - uint8_t b = 0; -}; [[maybe_unused]] std::ostream& operator<<(std::ostream& o, const asc_color& c) { @@ -307,16 +302,27 @@ parse_hopefully parse_point(asc::lexer& L) { #define PARSE_POINT(L, X) if (auto rval__ = parse_point(L)) X=*rval__; else return FORWARD_PARSE_ERROR(rval__.error()); -parse_hopefully parse_spine(asc::lexer& L) { +parse_hopefully parse_spine(asc::lexer& L) { + // check and consume opening <( EXPECT_TOKEN(L, tok::lt); - auto& t = L.current(); - while (t.kind!=tok::gt && t.kind!=tok::error && t.kind!=tok::eof) { - L.next(); - } - //if (t.kind!=error && t.kind!=eof) + EXPECT_TOKEN(L, tok::lparen); + + arb::mpoint p; + PARSE_DOUBLE(L, p.x); + PARSE_DOUBLE(L, p.y); + PARSE_DOUBLE(L, p.z); + double diameter; + PARSE_DOUBLE(L, diameter); + p.radius = diameter/2.0; + // Now eat the label + std::string l = L.current().spelling; + L.next(); + + // check and consume closing )> + EXPECT_TOKEN(L, tok::rparen); EXPECT_TOKEN(L, tok::gt); - return arb::mpoint{}; + return asc_spine{l, p}; } #define PARSE_SPINE(L, X) if (auto rval__ = parse_spine(L)) X=std::move(*rval__); else return FORWARD_PARSE_ERROR(rval__.error()); @@ -342,30 +348,33 @@ parse_hopefully parse_name(asc::lexer& L) { #define PARSE_NAME(L, X) {if (auto rval__ = parse_name(L)) X=*rval__; else return FORWARD_PARSE_ERROR(rval__.error());} -struct marker_set { - asc_color color; - std::string name; - std::vector locations; -}; - [[maybe_unused]] -std::ostream& operator<<(std::ostream& o, const marker_set& ms) { +std::ostream& operator<<(std::ostream& o, const asc_marker_set& ms) { o << "(marker-set \"" << ms.name << "\" " << ms.color; for (auto& l: ms.locations) o << " " << l; return o << ")"; } -parse_hopefully parse_markers(asc::lexer& L) { +parse_hopefully parse_markers(asc::lexer& L) { EXPECT_TOKEN(L, tok::lparen); - marker_set markers; + asc_marker_set markers; // parse marker kind keyword auto t = L.current(); if (!is_marker_symbol(t)) { return unexpected(PARSE_ERROR("expected a valid marker type", t.loc)); } + if (t.spelling == "Dot") { + markers.marker = asc_marker::dot; + } else if (t.spelling == "Cross") { + markers.marker = asc_marker::cross; + } else if (t.spelling == "Circle") { + markers.marker = asc_marker::circle; + } else { + // impossible + } L.next(); while (L.current().kind==tok::lparen) { auto n = L.peek(); @@ -392,6 +401,8 @@ parse_hopefully parse_markers(asc::lexer& L) { struct branch { std::vector samples; std::vector children; + std::vector markers; + std::vector spines; }; std::size_t num_samples(const branch& b) { @@ -444,16 +455,15 @@ parse_hopefully parse_branch(asc::lexer& L) { } // A marker statement is always of the form ( MARKER_TYPE ...) else if (t.kind==tok::lparen && is_marker_symbol(p)) { - marker_set markers; + asc_marker_set markers; PARSE_MARKER(L, markers); - // Parse the markers, but don't record information about them. - // These could be grouped into locset by name and added to the label dictionary. + B.markers.push_back(markers); } // Spines are marked by a "less than", i.e. "<", symbol. else if (t.kind==tok::lt) { - arb::mpoint spine; + asc_spine spine; PARSE_SPINE(L, spine); - // parse the spine, but don't record the location. + B.spines.push_back(spine); } // Test for a symbol that indicates a terminal. else if (is_branch_end_symbol(t)) { @@ -610,10 +620,16 @@ parse_hopefully parse_sub_tree(asc::lexer& L) { // Perform the parsing of the input as a string. -ARB_ARBORIO_API arb::segment_tree parse_asc_string_raw(const char* input) { +ARB_ARBORIO_API std::tuple, + std::vector> +parse_asc_string_raw(const char* input) { asc::lexer lexer(input); std::vector sub_trees; + std::vector markers; + std::vector spines; + // Iterate over high-level pseudo-s-expressions in the file. // This pass simply parses the contents of the file, to be interpretted @@ -695,6 +711,7 @@ ARB_ARBORIO_API arb::segment_tree parse_asc_string_raw(const char* input) { arb::mpoint soma_0, soma_1, soma_2; if (soma_count==1u) { const auto& st = sub_trees[soma_contours.front()]; + // NOTE No children allowed!? const auto& samples = st.root.samples; if (samples.size()==1u) { // The soma is described as a sphere with a single sample. @@ -709,10 +726,13 @@ ARB_ARBORIO_API arb::segment_tree parse_asc_string_raw(const char* input) { soma_0.radius = std::accumulate(samples.begin(), samples.end(), 0., [&soma_0](double a, auto& c) {return a+arb::distance(c, soma_0);}) / ns; } + soma_1 = {soma_0.x, soma_0.y-soma_0.radius, soma_0.z, soma_0.radius}; soma_2 = {soma_0.x, soma_0.y+soma_0.radius, soma_0.z, soma_0.radius}; stree.append(arb::mnpos, soma_0, soma_1, 1); stree.append(arb::mnpos, soma_0, soma_2, 1); + spines.insert(spines.end(), st.root.spines.begin(), st.root.spines.end()); + markers.insert(markers.end(), st.root.markers.begin(), st.root.markers.end()); } // Append the dend, axon and apical dendrites. @@ -742,6 +762,9 @@ ARB_ARBORIO_API arb::segment_tree parse_asc_string_raw(const char* input) { auto prox_sample = head.sample; if (!branch.samples.empty()) { // Skip empty branches, which are permitted + spines.insert(spines.end(), branch.spines.begin(), branch.spines.end()); + markers.insert(markers.end(), branch.markers.begin(), branch.markers.end()); + auto it = branch.samples.begin(); // Don't connect the first sample to the distal end of the parent // branch if the parent is the soma center. @@ -768,13 +791,13 @@ ARB_ARBORIO_API arb::segment_tree parse_asc_string_raw(const char* input) { } } - return stree; + return {stree, markers, spines}; } -ARB_ARBORIO_API asc_morphology parse_asc_string(const char* input) { +ARB_ARBORIO_API loaded_morphology parse_asc_string(const char* input) { // Parse segment tree - arb::segment_tree stree = parse_asc_string_raw(input); + const auto& [stree, markers, spines] = parse_asc_string_raw(input); // Construct the morphology. arb::morphology morphology(stree); @@ -786,7 +809,7 @@ ARB_ARBORIO_API asc_morphology parse_asc_string(const char* input) { labels.set("dend", arb::reg::tagged(3)); labels.set("apic", arb::reg::tagged(4)); - return {stree, std::move(morphology), std::move(labels)}; + return {stree, std::move(morphology), std::move(labels), asc_metadata{markers, spines}}; } @@ -809,17 +832,8 @@ inline std::string read_file(const std::filesystem::path& filename) { } -ARB_ARBORIO_API asc_morphology load_asc(const std::filesystem::path& filename) { +ARB_ARBORIO_API loaded_morphology load_asc(const std::filesystem::path& filename) { std::string fstr = read_file(filename); return parse_asc_string(fstr.c_str()); } - - -ARB_ARBORIO_API arb::segment_tree load_asc_raw(const std::filesystem::path& filename) { - std::string fstr = read_file(filename); - return parse_asc_string_raw(fstr.c_str()); -} - - } // namespace arborio - diff --git a/arborio/neuroml.cpp b/arborio/neuroml.cpp index 554b7a6db4..fdc7a1914f 100644 --- a/arborio/neuroml.cpp +++ b/arborio/neuroml.cpp @@ -78,7 +78,7 @@ std::vector neuroml::morphology_ids() const { return result; } -optional neuroml::morphology(const std::string& morph_id, enum neuroml_options::values options) const { +optional neuroml::morphology(const std::string& morph_id, enum neuroml_options::values options) const { auto id = xpath_escape(morph_id); auto query = "//neuroml/morphology[@id=" + id + "]"; auto match = impl_->doc.select_node(query.data()).node(); @@ -86,13 +86,13 @@ optional neuroml::morphology(const std::string& morph_id, e return nml_parse_morphology_element(match, options); } -optional neuroml::cell_morphology(const std::string& cell_id, enum neuroml_options::values options) const { +optional neuroml::cell_morphology(const std::string& cell_id, enum neuroml_options::values options) const { auto id = "//neuroml/cell[@id=" + xpath_escape(cell_id) + "]"; auto query = "(//neuroml/morphology[@id=string((" + id + "/@morphology)[1])] | " + id + "/morphology)[1]"; auto match = impl_->doc.select_node(query.data()).node(); if (match.empty()) return nullopt; - nml_morphology_data M = nml_parse_morphology_element(match, options); - M.cell_id = cell_id; + auto M = nml_parse_morphology_element(match, options); + std::get(M.metadata).cell_id = cell_id; return M; } diff --git a/arborio/nml_parse_morphology.cpp b/arborio/nml_parse_morphology.cpp index 8bcfcf1682..17f8fbc9b9 100644 --- a/arborio/nml_parse_morphology.cpp +++ b/arborio/nml_parse_morphology.cpp @@ -20,7 +20,6 @@ #include "xml.hpp" using std::optional; -using arb::region; using arb::util::expected; using arb::util::unexpected; @@ -398,11 +397,13 @@ static arb::stitched_morphology construct_morphology(const neuroml_segment_tree& return arb::stitched_morphology(std::move(builder)); } -nml_morphology_data nml_parse_morphology_element(const xml_node& morph, - enum neuroml_options::values options) { +loaded_morphology nml_parse_morphology_element(const xml_node& morph, + enum neuroml_options::values options) { using namespace neuroml_options; - nml_morphology_data M; - M.id = get_attr(morph, "id"); + loaded_morphology M; + M.metadata = nml_metadata{}; + auto& L = std::get(M.metadata); + L.id = get_attr(morph, "id"); std::vector segments; @@ -512,13 +513,14 @@ nml_morphology_data nml_parse_morphology_element(const xml_node& morph, groups.push_back(std::move(group)); } - M.group_segments = evaluate_segment_groups(std::move(groups), segtree); + L.group_segments = evaluate_segment_groups(std::move(groups), segtree); // Build morphology and label dictionaries: arb::stitched_morphology stitched = construct_morphology(segtree); M.morphology = stitched.morphology(); - M.segments = stitched.labels(); + M.segment_tree = M.morphology.to_segment_tree(); + L.segments = stitched.labels(); std::unordered_multimap name_to_ids; std::unordered_set names; @@ -534,19 +536,22 @@ nml_morphology_data nml_parse_morphology_element(const xml_node& morph, arb::region r; auto ids = name_to_ids.equal_range(name); for (auto i = ids.first; i!=ids.second; ++i) { - r = join(std::move(r), M.segments.regions().at(std::to_string(i->second))); + r = join(std::move(r), L.segments.regions().at(std::to_string(i->second))); } - M.named_segments.set(name, std::move(r)); + L.named_segments.set(name, std::move(r)); } - for (const auto& [group_id, segment_ids]: M.group_segments) { + for (const auto& [group_id, segment_ids]: L.group_segments) { arb::region r; for (auto id: segment_ids) { - r = join(std::move(r), M.segments.regions().at(std::to_string(id))); + r = join(std::move(r), L.segments.regions().at(std::to_string(id))); } - M.groups.set(group_id, std::move(r)); + L.groups.set(group_id, std::move(r)); } + M.labels.import(L.segments, "seg:"); + M.labels.import(L.named_segments, "nmd:"); + M.labels.import(L.groups, "grp:"); return M; } diff --git a/arborio/nml_parse_morphology.hpp b/arborio/nml_parse_morphology.hpp index eb185604cd..3d697a3cb2 100644 --- a/arborio/nml_parse_morphology.hpp +++ b/arborio/nml_parse_morphology.hpp @@ -1,11 +1,12 @@ #pragma once #include +#include #include namespace arborio { -nml_morphology_data nml_parse_morphology_element(const pugi::xml_node& morph, enum neuroml_options::values); +loaded_morphology nml_parse_morphology_element(const pugi::xml_node& morph, enum neuroml_options::values); } // namespace arborio diff --git a/arborio/swcio.cpp b/arborio/swcio.cpp index f7ae9e79a8..5cdfab8c22 100644 --- a/arborio/swcio.cpp +++ b/arborio/swcio.cpp @@ -6,11 +6,13 @@ #include #include #include +#include #include #include #include #include +#include #include "arbor/morph/primitives.hpp" @@ -160,7 +162,7 @@ ARB_ARBORIO_API swc_data parse_swc(const std::string& text) { return parse_swc(is); } -ARB_ARBORIO_API arb::segment_tree load_swc_arbor_raw(const swc_data& data) { +arb::segment_tree load_swc_arbor_raw(const swc_data& data) { const auto& records = data.records(); if (records.empty()) return {}; @@ -205,7 +207,7 @@ ARB_ARBORIO_API arb::segment_tree load_swc_arbor_raw(const swc_data& data) { return tree; } -ARB_ARBORIO_API arb::segment_tree load_swc_neuron_raw(const swc_data& data) { +arb::segment_tree load_swc_neuron_raw(const swc_data& data) { constexpr int soma_tag = 1; const auto n_samples = data.records().size(); @@ -324,8 +326,29 @@ ARB_ARBORIO_API arb::segment_tree load_swc_neuron_raw(const swc_data& data) { return tree; } -ARB_ARBORIO_API arb::morphology load_swc_neuron(const swc_data& data) { return {load_swc_neuron_raw(data)}; } -ARB_ARBORIO_API arb::morphology load_swc_arbor(const swc_data& data) { return {load_swc_arbor_raw(data)}; } +ARB_ARBORIO_API loaded_morphology load_swc_neuron(const swc_data& data) { + auto raw = load_swc_neuron_raw(data); + arb::label_dict ld; ld.add_swc_tags(); + return {raw, {raw}, ld, swc_metadata{}}; +} + +ARB_ARBORIO_API loaded_morphology load_swc_arbor(const swc_data& data) { + auto raw = load_swc_arbor_raw(data); + arb::label_dict ld; ld.add_swc_tags(); + return {raw, {raw}, ld, swc_metadata{}}; +} + +ARB_ARBORIO_API loaded_morphology load_swc_arbor(const std::filesystem::path& path) { + std::ifstream fd(path); + if (!fd) throw arb::file_not_found_error("unable to open SWC file: "+path.string()); + return load_swc_arbor(parse_swc(fd)); +} + +ARB_ARBORIO_API loaded_morphology load_swc_neuron(const std::filesystem::path& path) { + std::ifstream fd(path); + if (!fd) throw arb::file_not_found_error("unable to open SWC file: "+path.string()); + return load_swc_neuron(parse_swc(fd)); +} } // namespace arborio diff --git a/doc/cpp/morphology.rst b/doc/cpp/morphology.rst index 178878e930..cb353ccf76 100644 --- a/doc/cpp/morphology.rst +++ b/doc/cpp/morphology.rst @@ -475,7 +475,28 @@ The following classes and functions allow the user to inspect the CVs of a cell Supported morphology formats ============================ -Arbor supports morphologies described using the SWC file format and the NeuroML file format. +Arbor supports morphologies described using SWC, Neurolucida ASC, and the NeuroML file formats. +The ingestion of these formats is described below, but each returns a structure + + +.. cpp:class:: loaded_morphology + + .. cpp:member:: arb::segment_tree segment_tree + + Raw segment tree, identical to morphology. + + .. cpp:member:: arb::morphology morphology + + Morphology constructed from description. + + + .. cpp:member:: arb::label_dict labels + + Regions and locsets defined in the description. + + .. cpp:member:: std::variant metadata + + Loader specific metadata, see below in the individual sections. .. _cppswc: @@ -549,6 +570,17 @@ basic checks performed on them. The :cpp:type:`swc_data` object can then be used Returns a :cpp:type:`morphology` constructed according to NEURON's :ref:`SWC specifications `. +.. cpp:function:: morphology load_swc_arbor(const std::filesystem::path& data) + + Returns a :cpp:type:`morphology` constructed according to Arbor's + :ref:`SWC specifications `. + +.. cpp:function:: morphology load_swc_neuron(const std::filesystem::path& data) + + Returns a :cpp:type:`morphology` constructed according to NEURON's + :ref:`SWC specifications `. + + .. _cppasc: Neurolucida ASCII @@ -557,21 +589,40 @@ Neurolucida ASCII Arbor supports reading morphologies described using the :ref:`Neurolucida ASCII file format `. -The :cpp:func:`parse_asc()` function is used to parse the SWC file and generate a :cpp:type:`asc_morphology` object: -a simple struct with two members representing the morphology and a label dictionary with labeled -regions and locations. +The :cpp:func:`parse_asc()` function is used to parse the SWC file and generate a :cpp:type:`loaded_morphology` object: -.. cpp:class:: asc_morphology +.. cpp:function:: loaded_morphology load_asc(const std::filesystem::path& filename) - .. cpp:member:: arb::morphology morphology + Parse a Neurolucida ASCII file. + Throws an exception if there is an error parsing the file. - .. cpp:member:: arb::label_dict labels +.. cpp:class:: asc_metadata -.. cpp:function:: asc_morphology load_asc(const std::filesystem::path& filename) + .. cpp:member:: std::vector spines - Parse a Neurolucida ASCII file. - Throws an exception if there is an error parsing the file. + A list of spines annotated in the ``.asc`` file. + + .. cpp:member:: std::vector spines + + A list of marker set annotated in the ``.asc`` file. +.. cpp:class:: asc_spine + + .. cpp:member:: std::string name + + .. cpp:member:: arb::mpoint location + +.. cpp:class:: asc_marker_set + .. cpp:member:: asc_color color + + .. cpp:member:: asc_marker marker = asc_marker::none + + .. cpp:member:: std::string name + + .. cpp:member:: std::vector locations + +where ``asc_marker`` is an enum of ``dot``, ``circle``, ``cross``, or ``none``, +and ``asc_color`` an RGB triple. .. _cppneuroml: @@ -614,12 +665,12 @@ namespace. Return the id of each top-level ```` element defined in the NeuroML document. - .. cpp:function:: std::optional morphology(const std::string&, enum neuroml_options::value = neuroml_options::none) const + .. cpp:function:: std::optional morphology(const std::string&, enum neuroml_options::value = neuroml_options::none) const Return a representation of the top-level morphology with the supplied identifier, or ``std::nullopt`` if no such morphology could be found. - .. cpp:function:: std::optional cell_morphology(const std::string&, enum neuroml_options::value = neuroml_options::none) const + .. cpp:function:: std::optional cell_morphology(const std::string&, enum neuroml_options::value = neuroml_options::none) const Return a representation of the morphology associated with the cell with the supplied identifier, or ``std::nullopt`` if the cell or its morphology could not be found. @@ -643,7 +694,7 @@ label dictionaries for regions corresponding to its segments and segment groups and id, and a map providing the explicit list of segments contained within each defined segment group. -.. cpp:class:: nml_morphology_data +.. cpp:class:: nml_metadata .. cpp:member:: std::optional cell_id @@ -653,10 +704,6 @@ segment group. The id attribute of the morphology. - .. cpp:member:: arb::morphology morphology - - The corresponding Arbor morphology. - .. cpp:member:: arb::label_dict segments A label dictionary with a region entry for each segment, keyed by the segment id (as a string). diff --git a/doc/python/cable_cell.rst b/doc/python/cable_cell.rst index 23cf266be1..84042ef0b4 100644 --- a/doc/python/cable_cell.rst +++ b/doc/python/cable_cell.rst @@ -37,13 +37,7 @@ Cable cells import arbor # Construct the morphology from an SWC file. - tree = arbor.load_swc_arbor('granule.swc') - morph = arbor.morphology(tree) - - # Define regions using standard SWC tags - labels = arbor.label_dict({'soma': '(tag 1)', - 'axon': '(tag 2)', - 'dend': '(join (tag 3) (tag 4))'}) + lmrf = arbor.load_swc_arbor('granule.swc') # Define decorations decor = arbor.decor() @@ -52,7 +46,7 @@ Cable cells decor.paint('"soma"', arbor.density('hh')) # Construct a cable cell. - cell = arbor.cable_cell(morph, decor, labels) + cell = arbor.cable_cell(lmrf.morphology, decor, lmrf.labels) .. method:: __init__(morphology, decorations, labels) diff --git a/doc/python/morphology.rst b/doc/python/morphology.rst index ae00ea1ce7..f830f0e949 100644 --- a/doc/python/morphology.rst +++ b/doc/python/morphology.rst @@ -641,10 +641,9 @@ SWC NeuroML ------- -.. py:class:: neuroml_morph_data +.. py:class:: nml_metadata - A :class:`neuroml_morphology_data` object contains a representation of a morphology defined in - NeuroML. + A :class:`nml_metadata` object contains extra information specific to NeuroML. .. py:attribute:: cell_id :type: optional @@ -661,11 +660,6 @@ NeuroML A map from each segment group id to its corresponding collection of segments. - .. py:attribute:: morphology - :type: morphology - - The morphology associated with the :class:`neuroml_morph_data` object. - .. py:method:: segments Returns a label dictionary with a region entry for each segment, keyed by the segment id (as a string). @@ -722,7 +716,7 @@ NeuroML :param str morph_id: ID of the top-level morphology. :param bool allow_spherical_root: Treat zero length root segments especially. - :rtype: optional(neuroml_morph_data) + :rtype: optional(loaded_morphology) .. py:method:: cell_morphology(cell_id, allow_spherical_root=false) @@ -731,29 +725,65 @@ NeuroML :param str morph_id: ID of the cell. :param bool allow_spherical_root: Treat zero length root segments especially. - :rtype: optional(neuroml_morph_data) + :rtype: optional(loaded_morphology) .. _pyasc: Neurolucida ----------- -.. py:class:: asc_morphology +.. py:enum:: asc_marker - The morphology and label dictionary meta-data loaded from a Neurolucida ASCII ``.asc`` file. + One of dot, circle, cross, or none. + +.. py:class:: asc_color + + RGB triple. + +.. py:class:: asc_spine + + Marked spine, comprising: + + .. py:attribute:: location + + ``mpoint`` of the spine. + + .. py:attribute:: name + + Associated name. + +.. py:class:: asc_marker_set - .. py:attribute:: morphology + Locations of interest, given as + + .. py:attribute:: locations + + List of ``mpoint``. + + .. py:attribute:: marker + + Associated ``asc_marker``. + + .. py:attribute:: color + + Associated ``asc_color``. + + .. py:attribute:: name + + Associated name. + +.. py:class:: asc_metadata + + The morphology and label dictionary meta-data loaded from a Neurolucida ASCII ``.asc`` file. - The cable cell morphology. + .. py:attribute:: markers - .. py:attribute:: segment_tree + List of marker sets in the input. - The raw segment tree. + .. py:attribute:: spines - .. py:attribute:: labels + List of spines in the input. - The labeled regions and locations extracted from the meta data. The four canonical regions are labeled - ``'soma'``, ``'axon'``, ``'dend'`` and ``'apic'``. .. py:function:: load_asc(filename) diff --git a/doc/scripts/gen-labels.py b/doc/scripts/gen-labels.py index 1cd706745a..473528397f 100644 --- a/doc/scripts/gen-labels.py +++ b/doc/scripts/gen-labels.py @@ -165,7 +165,8 @@ def write_morphology(name, morph): fn = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(__file__), "../fileformat/example.swc") ) -swc_morph = arbor.load_swc_arbor(fn) +swc = arbor.load_swc_arbor(fn) +swc_morph = swc.morphology regions = { "empty": "(region-nil)", diff --git a/example/single/single.cpp b/example/single/single.cpp index 9413102565..b24ca77b99 100644 --- a/example/single/single.cpp +++ b/example/single/single.cpp @@ -30,11 +30,11 @@ struct options { }; options parse_options(int argc, char** argv); -arb::morphology default_morphology(); -arb::morphology read_swc(const std::string& path); +arborio::loaded_morphology default_morphology(); struct single_recipe: public arb::recipe { - explicit single_recipe(arb::morphology m, arb::cv_policy pol): morpho(std::move(m)) { + explicit single_recipe(arborio::loaded_morphology m, arb::cv_policy pol): + morpho(std::move(m.morphology)) { gprop.default_parameters = arb::neuron_parameter_defaults; gprop.default_parameters.discretization = pol; } @@ -82,7 +82,8 @@ struct single_recipe: public arb::recipe { int main(int argc, char** argv) { try { options opt = parse_options(argc, argv); - single_recipe R(opt.swc_file.empty()? default_morphology(): read_swc(opt.swc_file), opt.policy); + single_recipe R(opt.swc_file.empty() ? default_morphology() : arborio::load_swc_arbor(opt.swc_file), + opt.policy); arb::simulation sim(R); @@ -144,18 +145,14 @@ options parse_options(int argc, char** argv) { // of length 200 µm and radius decreasing linearly from 0.5 µm // to 0.2 µm. -arb::morphology default_morphology() { +arborio::loaded_morphology default_morphology() { arb::segment_tree tree; tree.append(arb::mnpos, { -6.3, 0.0, 0.0, 6.3}, { 6.3, 0.0, 0.0, 6.3}, 1); tree.append( 0, { 6.3, 0.0, 0.0, 0.5}, {206.3, 0.0, 0.0, 0.2}, 3); - return arb::morphology(tree); -} - -arb::morphology read_swc(const std::string& path) { - std::ifstream f(path); - if (!f) throw std::runtime_error("unable to open SWC file: "+path); + auto labels = arb::label_dict{}; + labels.add_swc_tags(); - return arborio::load_swc_arbor(arborio::parse_swc(f)); + return {tree, {tree}, labels}; } diff --git a/example/v_clamp/v-clamp.cpp b/example/v_clamp/v-clamp.cpp index 2d00a48112..d5de0d8a6a 100644 --- a/example/v_clamp/v-clamp.cpp +++ b/example/v_clamp/v-clamp.cpp @@ -31,11 +31,10 @@ struct options { }; options parse_options(int argc, char** argv); -arb::morphology default_morphology(); -arb::morphology read_swc(const std::string& path); +arborio::loaded_morphology default_morphology(); struct single_recipe: public arb::recipe { - explicit single_recipe(arb::morphology m, arb::cv_policy pol): morpho(std::move(m)) { + explicit single_recipe(arborio::loaded_morphology m, arb::cv_policy pol): morpho(std::move(m.morphology)) { gprop.default_parameters = arb::neuron_parameter_defaults; gprop.default_parameters.discretization = pol; } @@ -85,7 +84,7 @@ struct single_recipe: public arb::recipe { int main(int argc, char** argv) { try { options opt = parse_options(argc, argv); - single_recipe R(opt.swc_file.empty()? default_morphology(): read_swc(opt.swc_file), opt.policy); + single_recipe R(opt.swc_file.empty()? default_morphology(): arborio::load_swc_arbor(opt.swc_file), opt.policy); R.voltage_clamp = opt.voltage; arb::simulation sim(R); @@ -150,18 +149,13 @@ options parse_options(int argc, char** argv) { // of length 200 µm and radius decreasing linearly from 0.5 µm // to 0.2 µm. -arb::morphology default_morphology() { +arborio::loaded_morphology default_morphology() { arb::segment_tree tree; tree.append(arb::mnpos, { -6.3, 0.0, 0.0, 6.3}, { 6.3, 0.0, 0.0, 6.3}, 1); tree.append( 0, { 6.3, 0.0, 0.0, 0.5}, {206.3, 0.0, 0.0, 0.2}, 3); - return arb::morphology(tree); -} - -arb::morphology read_swc(const std::string& path) { - std::ifstream f(path); - if (!f) throw std::runtime_error("unable to open SWC file: "+path); - - return arborio::load_swc_arbor(arborio::parse_swc(f)); + auto labels = arb::label_dict{}; + labels.add_swc_tags(); + return {tree, {tree}, labels}; } diff --git a/python/example/probe_lfpykit.py b/python/example/probe_lfpykit.py index d7870f6adf..42cc61412c 100644 --- a/python/example/probe_lfpykit.py +++ b/python/example/probe_lfpykit.py @@ -63,7 +63,7 @@ def probes(self, gid): filename = sys.argv[1] # define morphology (needed for ``arbor.place_pwlin`` and ``arbor.cable_cell`` below) -morphology = arbor.load_swc_arbor(filename) +morphology = arbor.load_swc_arbor(filename).morphology # define a location on morphology for current clamp clamp_location = arbor.location(4, 1 / 6) diff --git a/python/example/single_cell_allen.py b/python/example/single_cell_allen.py index df96149279..f7fb4bd1ae 100644 --- a/python/example/single_cell_allen.py +++ b/python/example/single_cell_allen.py @@ -73,7 +73,7 @@ class parameters: def make_cell(swc, fit): # (1) Load the swc file passed into this function - morphology = arbor.load_swc_neuron(swc) + morphology = arbor.load_swc_neuron(swc).morphology # (2) Label the region tags found in the swc with the names used in the parameter fit file. # In addition, label the midpoint of the somarbor. labels = arbor.label_dict().add_swc_tags() diff --git a/python/example/single_cell_detailed.py b/python/example/single_cell_detailed.py index f2e29067ff..913514b2ff 100755 --- a/python/example/single_cell_detailed.py +++ b/python/example/single_cell_detailed.py @@ -17,7 +17,7 @@ sys.exit(0) filename = sys.argv[1] -morph = arbor.load_swc_arbor(filename) +morph = arbor.load_swc_arbor(filename).morphology # (2) Create and populate the label dictionary. diff --git a/python/example/single_cell_detailed_recipe.py b/python/example/single_cell_detailed_recipe.py index bb7f1972ee..e66a1f5a00 100644 --- a/python/example/single_cell_detailed_recipe.py +++ b/python/example/single_cell_detailed_recipe.py @@ -17,7 +17,7 @@ sys.exit(0) filename = sys.argv[1] -morph = arbor.load_swc_arbor(filename) +lmrf = arbor.load_swc_arbor(filename) # (2) Create and populate the label dictionary. @@ -39,7 +39,7 @@ # Add a label for the terminal locations in the "axon" region: "axon_terminal": '(restrict-to (locset "terminal") (region "axon"))', } -).add_swc_tags() # Add SWC pre-defined regions +).import(lmrf.labels) # (3) Create and populate the decor. @@ -68,7 +68,7 @@ # (4) Create the cell. -cell = arbor.cable_cell(morph, decor, labels) +cell = arbor.cable_cell(lmrf.morphology, decor, labels) # (5) Create a class that inherits from arbor.recipe diff --git a/python/example/single_cell_swc.py b/python/example/single_cell_swc.py index ea830594cb..37fb705cba 100755 --- a/python/example/single_cell_swc.py +++ b/python/example/single_cell_swc.py @@ -22,7 +22,7 @@ sys.exit(0) filename = sys.argv[1] -morpho = arbor.load_swc_arbor(filename) +morpho = arbor.load_swc_arbor(filename).morphology # Define the regions and locsets in the model. labels = arbor.label_dict( diff --git a/python/morphology.cpp b/python/morphology.cpp index 3c0e3579a9..958462039b 100644 --- a/python/morphology.cpp +++ b/python/morphology.cpp @@ -295,13 +295,10 @@ void register_morphology(py::module& m) { // Function that creates a morphology/segment_tree from an swc file. // Wraps calls to C++ functions arborio::parse_swc() and arborio::load_swc_arbor(). m.def("load_swc_arbor", - [](py::object fn, bool raw) -> morph_or_tree { + [](py::object fn) -> arborio::loaded_morphology { try { auto contents = util::read_file_or_buffer(fn); auto data = arborio::parse_swc(contents); - if (raw) { - return arborio::load_swc_arbor_raw(data); - } return arborio::load_swc_arbor(data); } catch (arborio::swc_error& e) { @@ -310,7 +307,6 @@ void register_morphology(py::module& m) { } }, "filename_or_stream"_a, - pybind11::arg_v("raw", false, "Return a segment tree instead of a fully formed morphology"), "Generate a morphology/segment_tree from an SWC file following the rules prescribed by Arbor.\n" "Specifically:\n" " * Single-segment somas are disallowed.\n" @@ -319,13 +315,10 @@ void register_morphology(py::module& m) { " * A segment is always created between a sample and its parent, meaning there\n" " are no gaps in the resulting morphology."); m.def("load_swc_neuron", - [](py::object fn, bool raw) -> morph_or_tree { + [](py::object fn) -> arborio::loaded_morphology { try { auto contents = util::read_file_or_buffer(fn); auto data = arborio::parse_swc(contents); - if (raw) { - return arborio::load_swc_neuron_raw(data); - } return arborio::load_swc_neuron(data); } catch (arborio::swc_error& e) { @@ -334,14 +327,12 @@ void register_morphology(py::module& m) { } }, "filename_or_stream"_a, - pybind11::arg_v("raw", false, "Return a segment tree instead of a fully formed morphology"), "Generate a morphology from an SWC file following the rules prescribed by NEURON.\n" "See the documentation https://docs.arbor-sim.org/en/latest/fileformat/swc.html\n" "for a detailed description of the interpretation."); // arb::morphology - py::class_ morph(m, "morphology"); morph // constructors @@ -374,29 +365,76 @@ void register_morphology(py::module& m) { }); // Neurolucida ASCII, or .asc, file format support. - - py::class_ asc_morphology(m, "asc_morphology", - "The morphology and label dictionary meta-data loaded from a Neurolucida ASCII (.asc) file."); - asc_morphology + py::class_ color(m, + "asc_color", + "Neurolucida color tag."); + color + .def_readonly("red", &arborio::asc_color::r) + .def_readonly("blue", &arborio::asc_color::b) + .def_readonly("green", &arborio::asc_color::g); + + + py::class_ spine(m, + "asc_spine", + "Neurolucida spine marker."); + spine + .def_readonly("name", &arborio::asc_spine::name) + .def_readonly("location", &arborio::asc_spine::location); + + + py::enum_ marker(m, + "asc_marker", + "Neurolucida marker type."); + marker + .value("dot", arborio::asc_marker::dot) + .value("cross", arborio::asc_marker::cross) + .value("circle", arborio::asc_marker::circle) + .value("none", arborio::asc_marker::none); + + py::class_ marker_set(m, + "asc_marker_set", + "Neurolucida marker set type."); + + marker_set + .def_readonly("name", &arborio::asc_marker_set::name) + .def_readonly("marker", &arborio::asc_marker_set::marker) + .def_readonly("color", &arborio::asc_marker_set::color) + .def_readonly("locations", &arborio::asc_marker_set::locations); + + py::class_ asc_meta(m, + "asc_metadata", + "Neurolucida metadata type: Spines and marker sets."); + + asc_meta + .def_readonly("markers", &arborio::asc_metadata::markers) + .def_readonly("spines", &arborio::asc_metadata::spines); + + py::class_ loaded_morphology(m, + "loaded_morphology", + "The morphology and label dictionary meta-data loaded from file."); + + py::class_ swc_meta(m, + "swc_metadata", + "SWC metadata type: empty."); + + loaded_morphology .def_readonly("morphology", - &arborio::asc_morphology::morphology, + &arborio::loaded_morphology::morphology, "The cable cell morphology.") .def_readonly("segment_tree", - &arborio::asc_morphology::segment_tree, + &arborio::loaded_morphology::segment_tree, "The raw segment tree.") + .def_readonly("metadata", + &arborio::loaded_morphology::metadata, + "File type specific metadata.") .def_property_readonly("labels", - [](const arborio::asc_morphology& m) {return label_dict_proxy(m.labels);}, - "The four canonical regions are labeled 'soma', 'axon', 'dend' and 'apic'."); - - using asc_morph_or_tree = std::variant; + [](const arborio::loaded_morphology& m) {return label_dict_proxy(m.labels);}, + "Any labels defined by the loaded file."); m.def("load_asc", - [](py::object fn, bool raw) -> asc_morph_or_tree { + [](py::object fn) -> arborio::loaded_morphology { try { auto contents = util::read_file_or_buffer(fn); - if (raw) { - return arborio::parse_asc_string_raw(contents.c_str()); - } return arborio::parse_asc_string(contents.c_str()); } catch (std::exception& e) { @@ -405,32 +443,28 @@ void register_morphology(py::module& m) { } }, "filename_or_stream"_a, - pybind11::arg_v("raw", false, "Return a segment tree instead of a fully formed morphology"), "Load a morphology or segment_tree and meta data from a Neurolucida ASCII .asc file."); // arborio::morphology_data - py::class_ nml_morph_data(m, "neuroml_morph_data"); - nml_morph_data + py::class_ nml_meta(m, "nml_metadata"); + nml_meta .def_readonly("cell_id", - &arborio::nml_morphology_data::cell_id, + &arborio::nml_metadata::cell_id, "Cell id, or empty if morphology was taken from a top-level element.") .def_readonly("id", - &arborio::nml_morphology_data::id, + &arborio::nml_metadata::id, "Morphology id.") - .def_readonly("morphology", - &arborio::nml_morphology_data::morphology, - "Morphology constructed from a signle NeuroML element.") .def("segments", - [](const arborio::nml_morphology_data& md) {return label_dict_proxy(md.segments);}, + [](const arborio::nml_metadata& md) {return label_dict_proxy(md.segments);}, "Label dictionary containing one region expression for each segment id.") .def("named_segments", - [](const arborio::nml_morphology_data& md) {return label_dict_proxy(md.named_segments);}, + [](const arborio::nml_metadata& md) {return label_dict_proxy(md.named_segments);}, "Label dictionary containing one region expression for each name applied to one or more segments.") .def("groups", - [](const arborio::nml_morphology_data& md) {return label_dict_proxy(md.groups);}, + [](const arborio::nml_metadata& md) {return label_dict_proxy(md.groups);}, "Label dictionary containing one region expression for each segmentGroup id.") .def_readonly("group_segments", - &arborio::nml_morphology_data::group_segments, + &arborio::nml_metadata::group_segments, "Map from segmentGroup ids to their corresponding segment ids."); // arborio::neuroml diff --git a/python/test/unit/test_io.py b/python/test/unit/test_io.py index 7c2cdee510..3486a19150 100644 --- a/python/test/unit/test_io.py +++ b/python/test/unit/test_io.py @@ -153,7 +153,7 @@ def test_pathio(self): class TestSwcArborIo(unittest.TestCase): @staticmethod def loaders(): - return (A.load_swc_arbor, partial(A.load_swc_arbor, raw=True)) + return (A.load_swc_arbor.morphology, partial(A.load_swc_arbor.morphology, raw=True)) def test_stringio(self): load_string(self.loaders(), swc_arbor) @@ -171,7 +171,7 @@ def test_pathio(self): class TestSwcNeuronIo(unittest.TestCase): @staticmethod def loaders(): - return (A.load_swc_neuron, partial(A.load_swc_neuron, raw=True)) + return (A.load_swc_neuron.morphology, partial(A.load_swc_neuron.morphology, raw=True)) def test_stringio(self): load_string(self.loaders(), swc_neuron) @@ -189,7 +189,7 @@ def test_pathio(self): class TestAscIo(unittest.TestCase): @staticmethod def loaders(): - return (A.load_asc, partial(A.load_asc, raw=True)) + return (A.load_asc.morphology, partial(A.load_asc.morphology, raw=True)) def test_stringio(self): load_string(self.loaders(), asc) diff --git a/test/unit/test_asc.cpp b/test/unit/test_asc.cpp index ec2cad1685..f441541b66 100644 --- a/test/unit/test_asc.cpp +++ b/test/unit/test_asc.cpp @@ -16,7 +16,7 @@ TEST(asc, file_not_found) { // Declare the implementation of the parser that takes a string input namespace arborio { -asc_morphology parse_asc_string(const char* input); +loaded_morphology parse_asc_string(const char* input); } // Test different forms of empty files. @@ -300,3 +300,68 @@ TEST(asc, soma_connection) { EXPECT_EQ(m.branch_segments(7)[0].prox, (arb::mpoint{0,-5, 0, 1})); } } + +// Soma composed of 2 branches, and a dendrite with a bit more interesting branching. +const char *asc_w_spines_and_markers ="((CellBody)\n" +" (0 0 0 4)\n" +" <(11 12 13 14 S1)>\n" +" (Cross (Color Black) (Name \"M1\") (0 0 0 1) (0 0 1 1))\n" +")\n" +"((Dendrite)\n" +" (0 2 0 2)\n" +" (0 5 0 2)\n" +" (Dot (Color Black) (Name \"M2\") (0 0 0 1))\n" +" <(1 2 3 4 S2)>\n" +" (\n" +" (-5 5 0 2)\n" +" (\n" +" (-5 5 0 2)\n" +" |\n" +" (6 5 0 2)\n" +" )\n" +" |\n" +" (6 5 0 2)\n" +" )\n" +" )"; + +TEST(asc, spine) { + { + auto result = arborio::parse_asc_string(asc_w_spines_and_markers); + const auto& m = result.morphology; + EXPECT_EQ(m.num_branches(), 7u); + // Test soma + EXPECT_EQ(m.branch_segments(0)[0].prox, (arb::mpoint{0, 0, 0, 2})); + EXPECT_EQ(m.branch_segments(0)[0].dist, (arb::mpoint{0,-2, 0, 2})); + EXPECT_EQ(m.branch_segments(1)[0].prox, (arb::mpoint{0, 0, 0, 2})); + EXPECT_EQ(m.branch_segments(1)[0].dist, (arb::mpoint{0, 2, 0, 2})); + // Test dendrite proximal ends + EXPECT_EQ(m.branch_segments(2)[0].prox, (arb::mpoint{ 0, 2, 0, 1})); + EXPECT_EQ(m.branch_segments(3)[0].prox, (arb::mpoint{ 0, 5, 0, 1})); + EXPECT_EQ(m.branch_segments(4)[0].prox, (arb::mpoint{-5, 5, 0, 1})); + EXPECT_EQ(m.branch_segments(5)[0].prox, (arb::mpoint{-5, 5, 0, 1})); + EXPECT_EQ(m.branch_segments(6)[0].prox, (arb::mpoint{ 0, 5, 0, 1})); + // Now check metadata + auto d = std::get(result.metadata); + EXPECT_EQ(d.spines.size(), 2); + EXPECT_EQ(d.spines[0].location.x, 11); + EXPECT_EQ(d.spines[0].location.y, 12); + EXPECT_EQ(d.spines[0].location.z, 13); + EXPECT_EQ(d.spines[0].location.radius, 7); + EXPECT_EQ(d.spines[0].name, "S1"); + + EXPECT_EQ(d.spines[1].location.x, 1); + EXPECT_EQ(d.spines[1].location.y, 2); + EXPECT_EQ(d.spines[1].location.z, 3); + EXPECT_EQ(d.spines[1].location.radius, 2); + EXPECT_EQ(d.spines[1].name, "S2"); + + EXPECT_EQ(d.markers.size(), 2); + EXPECT_EQ(d.markers[0].locations.size(), 2); + EXPECT_EQ(d.markers[0].name, "M1"); + EXPECT_EQ(d.markers[0].marker, arborio::asc_marker::cross); + + EXPECT_EQ(d.markers[1].locations.size(), 1); + EXPECT_EQ(d.markers[1].name, "M2"); + EXPECT_EQ(d.markers[1].marker, arborio::asc_marker::dot); + } +} diff --git a/test/unit/test_morphology.cpp b/test/unit/test_morphology.cpp index 5c305d850e..2104428d72 100644 --- a/test/unit/test_morphology.cpp +++ b/test/unit/test_morphology.cpp @@ -322,7 +322,8 @@ TEST(morphology, swc) { auto swc = arborio::parse_swc(fid); // Build a segmewnt_tree from swc samples. - auto m = arborio::load_swc_arbor(swc); + auto lm = arborio::load_swc_arbor(swc); + const auto& m = lm.morphology; EXPECT_EQ(221u, m.num_branches()); // 219 branches + 2 from divided soma. } #endif diff --git a/test/unit/test_nml_morphology.cpp b/test/unit/test_nml_morphology.cpp index 8c6ecfc039..877e9af396 100644 --- a/test/unit/test_nml_morphology.cpp +++ b/test/unit/test_nml_morphology.cpp @@ -78,16 +78,18 @@ R"~( std::sort(c_ids.begin(), c_ids.end()); EXPECT_EQ((svector{"c3", "c4"}), c_ids); - arborio::nml_morphology_data mdata; - - mdata = N.cell_morphology("c4").value(); - EXPECT_EQ("c4", mdata.cell_id); - EXPECT_EQ("m4", mdata.id); - - mdata = N.cell_morphology("c3").value(); - EXPECT_EQ("c3", mdata.cell_id); - EXPECT_EQ("m1", mdata.id); - + { + auto mdata = N.cell_morphology("c4").value(); + auto meta = std::get(mdata.metadata); + EXPECT_EQ("c4", meta.cell_id); + EXPECT_EQ("m4", meta.id); + } + { + auto mdata = N.cell_morphology("c3").value(); + auto meta = std::get(mdata.metadata); + EXPECT_EQ("c3", meta.cell_id); + EXPECT_EQ("m1", meta.id); + } EXPECT_THROW(N.cell_morphology("mr. bobbins").value(), std::bad_optional_access); } @@ -166,8 +168,9 @@ R"~( { auto m1 = N.morphology("m1").value(); + auto d1 = std::get(m1.metadata); label_dict labels; - labels.import(m1.segments, "seg:"); + labels.import(d1.segments, "seg:"); mprovider P(m1.morphology, labels); EXPECT_TRUE(region_eq(P, reg::named("seg:0"), reg::all())); @@ -178,9 +181,10 @@ R"~( } { - arborio::nml_morphology_data m2 = N.morphology("m2").value(); + auto m2 = N.morphology("m2").value(); + auto d2 = std::get(m2.metadata); label_dict labels; - labels.import(m2.segments, "seg:"); + labels.import(d2.segments, "seg:"); mprovider P(m2.morphology, labels); mextent seg0_extent = thingify(reg::named("seg:0"), P); @@ -206,9 +210,10 @@ R"~( } { - arborio::nml_morphology_data m3 = N.morphology("m3").value(); + auto m3 = N.morphology("m3").value(); + auto d3 = std::get(m3.metadata); label_dict labels; - labels.import(m3.segments, "seg:"); + labels.import(d3.segments, "seg:"); mprovider P(m3.morphology, labels); mextent seg0_extent = thingify(reg::named("seg:0"), P); @@ -240,9 +245,10 @@ R"~( } { for (const char* m_name: {"m4", "m5"}) { - arborio::nml_morphology_data m4_or_5 = N.morphology(m_name).value(); + auto m4_or_5 = N.morphology(m_name).value(); + auto d4_or_5 = std::get(m4_or_5.metadata); label_dict labels; - labels.import(m4_or_5.segments, "seg:"); + labels.import(d4_or_5.segments, "seg:"); mprovider P(m4_or_5.morphology, labels); mextent seg0_extent = thingify(reg::named("seg:0"), P); @@ -329,9 +335,10 @@ R"~( arborio::neuroml N(doc); { - arborio::nml_morphology_data m1 = N.morphology("m1", allow_spherical_root).value(); + auto m1 = N.morphology("m1", allow_spherical_root).value(); + auto d1 = std::get(m1.metadata); label_dict labels; - labels.import(m1.segments, "seg:"); + labels.import(d1.segments, "seg:"); mprovider P(m1.morphology, labels); EXPECT_TRUE(region_eq(P, reg::branch(0), reg::all())); @@ -358,9 +365,10 @@ R"~( } { // With spherical root _not_ provided, treat it just as a simple zero-length segment. - arborio::nml_morphology_data m1 = N.morphology("m1", none).value(); + auto m1 = N.morphology("m1", none).value(); + auto d1 = std::get(m1.metadata); label_dict labels; - labels.import(m1.segments, "seg:"); + labels.import(d1.segments, "seg:"); mprovider P(m1.morphology, labels); EXPECT_TRUE(region_eq(P, reg::branch(0), reg::all())); @@ -371,9 +379,10 @@ R"~( EXPECT_EQ(p0, G.at(mlocation{0, 1})); } { - arborio::nml_morphology_data m2 = N.morphology("m2", allow_spherical_root).value(); + auto m2 = N.morphology("m2", allow_spherical_root).value(); + auto d2 = std::get(m2.metadata); label_dict labels; - labels.import(m2.segments, "seg:"); + labels.import(d2.segments, "seg:"); mprovider P(m2.morphology, labels); EXPECT_TRUE(region_eq(P, reg::branch(0), reg::all())); @@ -387,9 +396,10 @@ R"~( (p0==points[1] && p1==points[0])); } { - arborio::nml_morphology_data m3 = N.morphology("m3", allow_spherical_root).value(); + auto m3 = N.morphology("m3", allow_spherical_root).value(); + auto d3 = std::get(m3.metadata); label_dict labels; - labels.import(m3.segments, "seg:"); + labels.import(d3.segments, "seg:"); mprovider P(m3.morphology, labels); place_pwlin G(P.morphology()); @@ -409,9 +419,10 @@ R"~( EXPECT_EQ(p2, s1d); } { - arborio::nml_morphology_data m4 = N.morphology("m4", allow_spherical_root).value(); + auto m4 = N.morphology("m4", allow_spherical_root).value(); + auto d4 = std::get(m4.metadata); label_dict labels; - labels.import(m4.segments, "seg:"); + labels.import(d4.segments, "seg:"); mprovider P(m4.morphology, labels); place_pwlin G(P.morphology()); @@ -593,22 +604,16 @@ R"~( using reg::named; { - arborio::nml_morphology_data m1 = N.morphology("m1").value(); - label_dict labels; - labels.import(m1.segments); - labels.import(m1.groups); - mprovider P(m1.morphology, labels); + auto m1 = N.morphology("m1").value(); + mprovider P(m1.morphology, m1.labels); EXPECT_TRUE(region_eq(P, named("group-a"), named("0"))); EXPECT_TRUE(region_eq(P, named("group-b"), named("2"))); EXPECT_TRUE(region_eq(P, named("group-c"), join(named("2"), named("1")))); } { - arborio::nml_morphology_data m2 = N.morphology("m2").value(); - label_dict labels; - labels.import(m2.segments); - labels.import(m2.groups); - mprovider P(m2.morphology, labels); + auto m2 = N.morphology("m2").value(); + mprovider P(m2.morphology, m2.labels); EXPECT_TRUE(region_eq(P, named("group-a"), join(named("0"), named("2")))); EXPECT_TRUE(region_eq(P, named("group-c"), join(named("0"), named("1"), named("2")))); @@ -762,11 +767,8 @@ R"~( arborio::neuroml N(doc); - arborio::nml_morphology_data m1 = N.morphology("m1").value(); - label_dict labels; - labels.import(m1.segments); - labels.import(m1.groups); - mprovider P(m1.morphology, labels); + auto m1 = N.morphology("m1").value(); + mprovider P(m1.morphology, m1.labels); // Note: paths/subTrees respect segment parent–child relationships, // not morphological distality. diff --git a/test/unit/test_swcio.cpp b/test/unit/test_swcio.cpp index dacd87805e..918f735d7c 100644 --- a/test/unit/test_swcio.cpp +++ b/test/unit/test_swcio.cpp @@ -270,7 +270,8 @@ TEST(swc_parser, arbor_compliant) { {7, 3, p4.x, p4.y, p4.z, p4.radius, 4} }; - auto morpho = load_swc_arbor(swc); + auto loaded = load_swc_arbor(swc); + const auto& morpho = loaded.morphology; ASSERT_EQ(3u, morpho.num_branches()); EXPECT_EQ(mnpos, morpho.branch_parent(0)); @@ -315,7 +316,8 @@ TEST(swc_parser, arbor_compliant) { {4, 3, p3.x, p3.y, p3.z, p3.radius, 2}, }; - auto morpho = load_swc_arbor(swc); + auto loaded = load_swc_arbor(swc); + auto morpho = loaded.morphology; ASSERT_EQ(2u, morpho.num_branches()); EXPECT_EQ(mnpos, morpho.branch_parent(0)); @@ -377,7 +379,9 @@ TEST(swc_parser, neuron_compliant) { std::vector swc{ {1, 1, p0.x, p0.y, p0.z, p0.radius, -1} }; - auto morpho = load_swc_neuron(swc); + + auto loaded = load_swc_neuron(swc); + const auto& morpho = loaded.morphology; mpoint prox{p0.x-p0.radius, p0.y, p0.z, p0.radius}; mpoint dist{p0.x+p0.radius, p0.y, p0.z, p0.radius}; @@ -406,7 +410,8 @@ TEST(swc_parser, neuron_compliant) { {1, 1, p0.x, p0.y, p0.z, p0.radius, -1}, {2, 1, p1.x, p1.y, p1.z, p1.radius, 1} }; - auto morpho = load_swc_neuron(swc); + auto loaded = load_swc_arbor(swc); + const auto& morpho = loaded.morphology; ASSERT_EQ(1u, morpho.num_branches()); @@ -431,7 +436,9 @@ TEST(swc_parser, neuron_compliant) { {2, 1, p1.x, p1.y, p1.z, p1.radius, 1}, {3, 1, p2.x, p2.y, p2.z, p2.radius, 2} }; - auto morpho = load_swc_neuron(swc); + + auto loaded = load_swc_neuron(swc); + const auto& morpho = loaded.morphology; ASSERT_EQ(1u, morpho.num_branches()); @@ -466,7 +473,8 @@ TEST(swc_parser, neuron_compliant) { {10, 1, p4.x, p4.y, p4.z, p4.radius, 8}, {12, 1, p5.x, p5.y, p5.z, p5.radius, 10} }; - auto morpho = load_swc_neuron(swc); + auto loaded = load_swc_neuron(swc); + const auto& morpho = loaded.morphology; ASSERT_EQ(1u, morpho.num_branches()); @@ -507,7 +515,8 @@ TEST(swc_parser, neuron_compliant) { {2, 3, p1.x, p1.y, p1.z, p1.radius, 1}, {3, 3, p2.x, p2.y, p2.z, p2.radius, 2} }; - auto morpho = load_swc_neuron(swc); + auto loaded = load_swc_neuron(swc); + const auto& morpho = loaded.morphology; mpoint prox{-10, 0, 0, 10}; mpoint dist{ 10, 0, 0, 10}; @@ -548,7 +557,8 @@ TEST(swc_parser, neuron_compliant) { {23, 1, p0.x, p0.y, p0.z, p0.radius, -1}, {83, 3, p1.x, p1.y, p1.z, p1.radius, 23} }; - auto morpho = load_swc_neuron(swc); + auto loaded = load_swc_neuron(swc); + const auto& morpho = loaded.morphology; mpoint prox{-10, 0, 0, 10}; mpoint dist{ 10, 0, 0, 10}; @@ -592,7 +602,8 @@ TEST(swc_parser, neuron_compliant) { {3, 3, p2.x, p2.y, p2.z, p2.radius, 2}, {4, 3, p3.x, p3.y, p3.z, p3.radius, 3} }; - auto morpho = load_swc_neuron(swc); + auto loaded = load_swc_neuron(swc); + const auto& morpho = loaded.morphology; ASSERT_EQ(1u, morpho.num_branches()); @@ -658,7 +669,8 @@ TEST(swc_parser, neuron_compliant) { {18, 3, -8, 15, 0, 1, 17} }; - auto morpho = load_swc_neuron(swc); + auto loaded = load_swc_neuron(swc); + const auto& morpho = loaded.morphology; ASSERT_EQ(10u, morpho.num_branches()); @@ -739,6 +751,7 @@ TEST(swc_parser, neuron_compliant) { EXPECT_EQ(p17, segs_9[0].dist); } } + TEST(swc_parser, not_neuron_compliant) { using namespace arborio; { From 53ee484355e35fd647b6355b551f1416d5cf6a8e Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Mon, 11 Sep 2023 10:44:33 +0200 Subject: [PATCH 02/18] The attachment. --- arborio/include/arborio/loaded_morphology.hpp | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 arborio/include/arborio/loaded_morphology.hpp diff --git a/arborio/include/arborio/loaded_morphology.hpp b/arborio/include/arborio/loaded_morphology.hpp new file mode 100644 index 0000000000..f407566ce2 --- /dev/null +++ b/arborio/include/arborio/loaded_morphology.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include + +#include +#include +#include + +namespace arborio { + +struct ARB_SYMBOL_VISIBLE swc_metadata {}; + +struct ARB_SYMBOL_VISIBLE asc_color { + uint8_t r = 0; + uint8_t g = 0; + uint8_t b = 0; +}; + +struct ARB_SYMBOL_VISIBLE asc_spine { + std::string name; + arb::mpoint location; +}; + +enum ARB_SYMBOL_VISIBLE asc_marker { dot, circle, cross, none }; + +struct ARB_SYMBOL_VISIBLE asc_marker_set { + asc_color color; + asc_marker marker = asc_marker::none; + std::string name; + std::vector locations; +}; + +struct ARB_SYMBOL_VISIBLE asc_metadata { + std::vector markers; + std::vector spines; +}; + +// Bundle some detailed metadata for neuroml ingestion. +struct ARB_SYMBOL_VISIBLE nml_metadata { + // Cell id, or empty if morphology was taken from a top-level element. + std::optional cell_id; + + // Morphology id. + std::string id; + + // One region expression for each segment id. + arb::label_dict segments; + + // One region expression for each name applied to one or more segments. + arb::label_dict named_segments; + + // One region expression for each segmentGroup id. + arb::label_dict groups; + + // Map from segmentGroup ids to their corresponding segment ids. + std::unordered_map> group_segments; +}; + +// Interface for ingesting morphology data +struct ARB_SYMBOL_VISIBLE loaded_morphology { + // Raw segment tree, identical to morphology. + arb::segment_tree segment_tree; + + // Morphology constructed from description. + arb::morphology morphology; + + // Regions and locsets defined in the description. + arb::label_dict labels; + + // Loader specific metadata + std::variant metadata; +}; + +} From c50a7dbdb211f89134bfd4beb800eb1e733a34e5 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Mon, 11 Sep 2023 11:08:16 +0200 Subject: [PATCH 03/18] Also pull in variant. --- arborio/include/arborio/loaded_morphology.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/arborio/include/arborio/loaded_morphology.hpp b/arborio/include/arborio/loaded_morphology.hpp index f407566ce2..82d743c14c 100644 --- a/arborio/include/arborio/loaded_morphology.hpp +++ b/arborio/include/arborio/loaded_morphology.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include From a8a5e4ff145dfcf195253baaa0cb59e2696aa20e Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Mon, 11 Sep 2023 12:18:24 +0200 Subject: [PATCH 04/18] Remove `import` -> `extend`. --- arbor/include/arbor/morph/label_dict.hpp | 2 +- arbor/morph/label_dict.cpp | 2 +- arborio/nml_parse_morphology.cpp | 6 +++--- python/cells.cpp | 4 ++-- python/example/single_cell_detailed_recipe.py | 2 +- python/proxy.hpp | 4 ++-- python/test/unit/test_io.py | 10 ++++++++-- test/unit/test_nml_morphology.cpp | 18 +++++++++--------- 8 files changed, 27 insertions(+), 21 deletions(-) diff --git a/arbor/include/arbor/morph/label_dict.hpp b/arbor/include/arbor/morph/label_dict.hpp index f7c43ec6bb..62101a8c57 100644 --- a/arbor/include/arbor/morph/label_dict.hpp +++ b/arbor/include/arbor/morph/label_dict.hpp @@ -24,7 +24,7 @@ class ARB_ARBOR_API label_dict { // construct a label dict with SWC tags predefined label_dict& add_swc_tags(); - void import(const label_dict& other, const std::string& prefix = ""); + void extend(const label_dict& other, const std::string& prefix = ""); label_dict& set(const std::string& name, locset ls); label_dict& set(const std::string& name, region reg); diff --git a/arbor/morph/label_dict.cpp b/arbor/morph/label_dict.cpp index ba0c4d83cd..56c074cf32 100644 --- a/arbor/morph/label_dict.cpp +++ b/arbor/morph/label_dict.cpp @@ -45,7 +45,7 @@ label_dict& label_dict::set(const std::string& name, arb::iexpr e) { return *this; } -void label_dict::import(const label_dict& other, const std::string& prefix) { +void label_dict::extend(const label_dict& other, const std::string& prefix) { for (const auto& entry: other.locsets()) { set(prefix+entry.first, entry.second); } diff --git a/arborio/nml_parse_morphology.cpp b/arborio/nml_parse_morphology.cpp index 17f8fbc9b9..13f3377564 100644 --- a/arborio/nml_parse_morphology.cpp +++ b/arborio/nml_parse_morphology.cpp @@ -549,9 +549,9 @@ loaded_morphology nml_parse_morphology_element(const xml_node& morph, L.groups.set(group_id, std::move(r)); } - M.labels.import(L.segments, "seg:"); - M.labels.import(L.named_segments, "nmd:"); - M.labels.import(L.groups, "grp:"); + M.labels.extend(L.segments, "seg:"); + M.labels.extend(L.named_segments, "nmd:"); + M.labels.extend(L.groups, "grp:"); return M; } diff --git a/python/cells.cpp b/python/cells.cpp index f46bcf8aaf..c916451584 100644 --- a/python/cells.cpp +++ b/python/cells.cpp @@ -301,13 +301,13 @@ void register_cells(pybind11::module& m) { }, pybind11::keep_alive<0, 1>()) .def("append", [](label_dict_proxy& l, const label_dict_proxy& other, const char* prefix) { - l.import(other, prefix); + l.extend(other, prefix); }, "other"_a, "The label_dict to be imported" "prefix"_a="", "optional prefix appended to the region and locset labels", "Import the entries of a another label dictionary with an optional prefix.") .def("update", [](label_dict_proxy& l, const label_dict_proxy& other) { - l.import(other); + l.extend(other); }, "other"_a, "The label_dict to be imported" "Import the entries of a another label dictionary.") diff --git a/python/example/single_cell_detailed_recipe.py b/python/example/single_cell_detailed_recipe.py index e66a1f5a00..f6837d06a2 100644 --- a/python/example/single_cell_detailed_recipe.py +++ b/python/example/single_cell_detailed_recipe.py @@ -39,7 +39,7 @@ # Add a label for the terminal locations in the "axon" region: "axon_terminal": '(restrict-to (locset "terminal") (region "axon"))', } -).import(lmrf.labels) +).extend(lmrf.labels) # (3) Create and populate the decor. diff --git a/python/proxy.hpp b/python/proxy.hpp index 31333e132e..5ecf5968cc 100644 --- a/python/proxy.hpp +++ b/python/proxy.hpp @@ -50,8 +50,8 @@ struct label_dict_proxy { return locsets.size() + regions.size() + iexpressions.size(); } - void import(const label_dict_proxy& other, std::string prefix = "") { - dict.import(other.dict, prefix); + void extend(const label_dict_proxy& other, std::string prefix = "") { + dict.extend(other.dict, prefix); clear_cache(); update_cache(); diff --git a/python/test/unit/test_io.py b/python/test/unit/test_io.py index 3486a19150..08ec2f98f2 100644 --- a/python/test/unit/test_io.py +++ b/python/test/unit/test_io.py @@ -153,7 +153,10 @@ def test_pathio(self): class TestSwcArborIo(unittest.TestCase): @staticmethod def loaders(): - return (A.load_swc_arbor.morphology, partial(A.load_swc_arbor.morphology, raw=True)) + return ( + A.load_swc_arbor.morphology, + partial(A.load_swc_arbor.morphology, raw=True), + ) def test_stringio(self): load_string(self.loaders(), swc_arbor) @@ -171,7 +174,10 @@ def test_pathio(self): class TestSwcNeuronIo(unittest.TestCase): @staticmethod def loaders(): - return (A.load_swc_neuron.morphology, partial(A.load_swc_neuron.morphology, raw=True)) + return ( + A.load_swc_neuron.morphology, + partial(A.load_swc_neuron.morphology, raw=True), + ) def test_stringio(self): load_string(self.loaders(), swc_neuron) diff --git a/test/unit/test_nml_morphology.cpp b/test/unit/test_nml_morphology.cpp index 877e9af396..d2d0cfb270 100644 --- a/test/unit/test_nml_morphology.cpp +++ b/test/unit/test_nml_morphology.cpp @@ -170,7 +170,7 @@ R"~( auto m1 = N.morphology("m1").value(); auto d1 = std::get(m1.metadata); label_dict labels; - labels.import(d1.segments, "seg:"); + labels.extend(d1.segments, "seg:"); mprovider P(m1.morphology, labels); EXPECT_TRUE(region_eq(P, reg::named("seg:0"), reg::all())); @@ -184,7 +184,7 @@ R"~( auto m2 = N.morphology("m2").value(); auto d2 = std::get(m2.metadata); label_dict labels; - labels.import(d2.segments, "seg:"); + labels.extend(d2.segments, "seg:"); mprovider P(m2.morphology, labels); mextent seg0_extent = thingify(reg::named("seg:0"), P); @@ -213,7 +213,7 @@ R"~( auto m3 = N.morphology("m3").value(); auto d3 = std::get(m3.metadata); label_dict labels; - labels.import(d3.segments, "seg:"); + labels.extend(d3.segments, "seg:"); mprovider P(m3.morphology, labels); mextent seg0_extent = thingify(reg::named("seg:0"), P); @@ -248,7 +248,7 @@ R"~( auto m4_or_5 = N.morphology(m_name).value(); auto d4_or_5 = std::get(m4_or_5.metadata); label_dict labels; - labels.import(d4_or_5.segments, "seg:"); + labels.extend(d4_or_5.segments, "seg:"); mprovider P(m4_or_5.morphology, labels); mextent seg0_extent = thingify(reg::named("seg:0"), P); @@ -338,7 +338,7 @@ R"~( auto m1 = N.morphology("m1", allow_spherical_root).value(); auto d1 = std::get(m1.metadata); label_dict labels; - labels.import(d1.segments, "seg:"); + labels.extend(d1.segments, "seg:"); mprovider P(m1.morphology, labels); EXPECT_TRUE(region_eq(P, reg::branch(0), reg::all())); @@ -368,7 +368,7 @@ R"~( auto m1 = N.morphology("m1", none).value(); auto d1 = std::get(m1.metadata); label_dict labels; - labels.import(d1.segments, "seg:"); + labels.extend(d1.segments, "seg:"); mprovider P(m1.morphology, labels); EXPECT_TRUE(region_eq(P, reg::branch(0), reg::all())); @@ -382,7 +382,7 @@ R"~( auto m2 = N.morphology("m2", allow_spherical_root).value(); auto d2 = std::get(m2.metadata); label_dict labels; - labels.import(d2.segments, "seg:"); + labels.extend(d2.segments, "seg:"); mprovider P(m2.morphology, labels); EXPECT_TRUE(region_eq(P, reg::branch(0), reg::all())); @@ -399,7 +399,7 @@ R"~( auto m3 = N.morphology("m3", allow_spherical_root).value(); auto d3 = std::get(m3.metadata); label_dict labels; - labels.import(d3.segments, "seg:"); + labels.extend(d3.segments, "seg:"); mprovider P(m3.morphology, labels); place_pwlin G(P.morphology()); @@ -422,7 +422,7 @@ R"~( auto m4 = N.morphology("m4", allow_spherical_root).value(); auto d4 = std::get(m4.metadata); label_dict labels; - labels.import(d4.segments, "seg:"); + labels.extend(d4.segments, "seg:"); mprovider P(m4.morphology, labels); place_pwlin G(P.morphology()); From d99c893716aea6e5e89b1ea3265d94a179cfbd2b Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Mon, 11 Sep 2023 12:23:08 +0200 Subject: [PATCH 05/18] Fix bench. --- test/ubench/fvm_discretize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ubench/fvm_discretize.cpp b/test/ubench/fvm_discretize.cpp index 7d0c6bb836..ce9cc719cc 100644 --- a/test/ubench/fvm_discretize.cpp +++ b/test/ubench/fvm_discretize.cpp @@ -26,7 +26,7 @@ arb::morphology from_swc(const std::string& path) { std::ifstream in(path); if (!in) throw std::runtime_error("could not open "+path); - return arborio::load_swc_arbor(arborio::parse_swc(in)); + return arborio::load_swc_arbor(arborio::parse_swc(in)).morphology; } void run_cv_geom(benchmark::State& state) { From 6b068a963d7899b37d6adb824ab96d9bd3df1295 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Mon, 11 Sep 2023 15:52:18 +0200 Subject: [PATCH 06/18] Revert prefixes. --- arborio/nml_parse_morphology.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arborio/nml_parse_morphology.cpp b/arborio/nml_parse_morphology.cpp index 13f3377564..f6731c67ee 100644 --- a/arborio/nml_parse_morphology.cpp +++ b/arborio/nml_parse_morphology.cpp @@ -549,9 +549,9 @@ loaded_morphology nml_parse_morphology_element(const xml_node& morph, L.groups.set(group_id, std::move(r)); } - M.labels.extend(L.segments, "seg:"); - M.labels.extend(L.named_segments, "nmd:"); - M.labels.extend(L.groups, "grp:"); + M.labels.extend(L.segments); + M.labels.extend(L.named_segments); + M.labels.extend(L.groups); return M; } From 6d9a60d52d466b34b688c62ca99532fb3356b448 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:42:43 +0200 Subject: [PATCH 07/18] Fix python fixtures. --- python/test/unit/test_io.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/python/test/unit/test_io.py b/python/test/unit/test_io.py index 08ec2f98f2..ff2a2dac76 100644 --- a/python/test/unit/test_io.py +++ b/python/test/unit/test_io.py @@ -154,8 +154,8 @@ class TestSwcArborIo(unittest.TestCase): @staticmethod def loaders(): return ( - A.load_swc_arbor.morphology, - partial(A.load_swc_arbor.morphology, raw=True), + lambda f: A.load_swc_arbor(f).morphology, + lambda f: A.load_swc_arbor(f).segment_tree, ) def test_stringio(self): @@ -175,8 +175,8 @@ class TestSwcNeuronIo(unittest.TestCase): @staticmethod def loaders(): return ( - A.load_swc_neuron.morphology, - partial(A.load_swc_neuron.morphology, raw=True), + A.load_swc_neuron(f).morphology, + A.load_swc_neuron(f).segment_tree, ) def test_stringio(self): @@ -195,7 +195,10 @@ def test_pathio(self): class TestAscIo(unittest.TestCase): @staticmethod def loaders(): - return (A.load_asc.morphology, partial(A.load_asc.morphology, raw=True)) + return ( + A.load_asc(f).morphology, + A.load_asc(f).segment_tree, + ) def test_stringio(self): load_string(self.loaders(), asc) From 387e8495baba956253d6b91e03d66d460f69b5b7 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 12 Sep 2023 13:01:18 +0200 Subject: [PATCH 08/18] Fix python fixtures some more. --- python/test/unit/test_io.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/python/test/unit/test_io.py b/python/test/unit/test_io.py index ff2a2dac76..87d04bedc2 100644 --- a/python/test/unit/test_io.py +++ b/python/test/unit/test_io.py @@ -5,7 +5,6 @@ from pathlib import Path from tempfile import TemporaryDirectory as TD from io import StringIO -from functools import partial acc = """(arbor-component @@ -175,8 +174,8 @@ class TestSwcNeuronIo(unittest.TestCase): @staticmethod def loaders(): return ( - A.load_swc_neuron(f).morphology, - A.load_swc_neuron(f).segment_tree, + lambda f: A.load_swc_neuron(f).morphology, + lambda f: A.load_swc_neuron(f).segment_tree, ) def test_stringio(self): @@ -196,8 +195,8 @@ class TestAscIo(unittest.TestCase): @staticmethod def loaders(): return ( - A.load_asc(f).morphology, - A.load_asc(f).segment_tree, + lambda f: A.load_asc(f).morphology, + lambda f: A.load_asc(f).segment_tree, ) def test_stringio(self): From 4f93bbbc37b1350377dc1b7771c47d1af9f77515 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 12 Sep 2023 14:20:56 +0200 Subject: [PATCH 09/18] Use proper Python parole. --- python/example/single_cell_detailed_recipe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/example/single_cell_detailed_recipe.py b/python/example/single_cell_detailed_recipe.py index f6837d06a2..128f732d3c 100644 --- a/python/example/single_cell_detailed_recipe.py +++ b/python/example/single_cell_detailed_recipe.py @@ -39,7 +39,7 @@ # Add a label for the terminal locations in the "axon" region: "axon_terminal": '(restrict-to (locset "terminal") (region "axon"))', } -).extend(lmrf.labels) +).append(lmrf.labels) # (3) Create and populate the decor. From c84e16075ccf9c664b413166582ac22317e6c290 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 12 Sep 2023 15:29:14 +0200 Subject: [PATCH 10/18] Make label_dict chainable. Simplify nml example. --- arbor/include/arbor/morph/label_dict.hpp | 2 +- arbor/morph/label_dict.cpp | 3 ++- python/cells.cpp | 4 ++-- python/example/single_cell_nml.py | 13 ++----------- python/proxy.hpp | 4 ++-- 5 files changed, 9 insertions(+), 17 deletions(-) diff --git a/arbor/include/arbor/morph/label_dict.hpp b/arbor/include/arbor/morph/label_dict.hpp index 62101a8c57..7d909ed0c7 100644 --- a/arbor/include/arbor/morph/label_dict.hpp +++ b/arbor/include/arbor/morph/label_dict.hpp @@ -24,7 +24,7 @@ class ARB_ARBOR_API label_dict { // construct a label dict with SWC tags predefined label_dict& add_swc_tags(); - void extend(const label_dict& other, const std::string& prefix = ""); + label_dict& extend(const label_dict& other, const std::string& prefix = ""); label_dict& set(const std::string& name, locset ls); label_dict& set(const std::string& name, region reg); diff --git a/arbor/morph/label_dict.cpp b/arbor/morph/label_dict.cpp index 56c074cf32..11ac3e5a18 100644 --- a/arbor/morph/label_dict.cpp +++ b/arbor/morph/label_dict.cpp @@ -45,7 +45,7 @@ label_dict& label_dict::set(const std::string& name, arb::iexpr e) { return *this; } -void label_dict::extend(const label_dict& other, const std::string& prefix) { +label_dict& label_dict::extend(const label_dict& other, const std::string& prefix) { for (const auto& entry: other.locsets()) { set(prefix+entry.first, entry.second); } @@ -55,6 +55,7 @@ void label_dict::extend(const label_dict& other, const std::string& prefix) { for (const auto& entry: other.iexpressions()) { set(prefix+entry.first, entry.second); } + return *this; } std::optional label_dict::region(const std::string& name) const { diff --git a/python/cells.cpp b/python/cells.cpp index c916451584..2ab93afe76 100644 --- a/python/cells.cpp +++ b/python/cells.cpp @@ -301,13 +301,13 @@ void register_cells(pybind11::module& m) { }, pybind11::keep_alive<0, 1>()) .def("append", [](label_dict_proxy& l, const label_dict_proxy& other, const char* prefix) { - l.extend(other, prefix); + return l.extend(other, prefix); }, "other"_a, "The label_dict to be imported" "prefix"_a="", "optional prefix appended to the region and locset labels", "Import the entries of a another label dictionary with an optional prefix.") .def("update", [](label_dict_proxy& l, const label_dict_proxy& other) { - l.extend(other); + return l.extend(other); }, "other"_a, "The label_dict to be imported" "Import the entries of a another label dictionary.") diff --git a/python/example/single_cell_nml.py b/python/example/single_cell_nml.py index b506ef53a4..eb22432eec 100755 --- a/python/example/single_cell_nml.py +++ b/python/example/single_cell_nml.py @@ -22,23 +22,14 @@ # Get the morphology. morpho = morpho_data.morphology -# Get the region label dictionaries associated with the morphology. -morpho_segments = morpho_data.segments() -morpho_named = morpho_data.named_segments() -morpho_groups = morpho_data.groups() - -# Create new label dict with some locsets. +# Create new label dict with some locsets and add to it all the NeuroML dictionaries. labels = arbor.label_dict( { "stim_site": "(location 1 0.5)", # site for the stimulus, in the middle of branch 1. "axon_end": '(restrict-to (terminal) (region "axon"))', # end of the axon. "root": "(root)", # the start of the soma in this morphology is at the root of the cell. } -) -# Add to it all the NeuroML dictionaries. -labels.append(morpho_segments) -labels.append(morpho_named) -labels.append(morpho_groups) +).append(morpho_data.labels) # Optional: print out the regions and locsets available in the label dictionary. print("Label dictionary regions: ", labels.regions, "\n") diff --git a/python/proxy.hpp b/python/proxy.hpp index 5ecf5968cc..4f2fb3b506 100644 --- a/python/proxy.hpp +++ b/python/proxy.hpp @@ -50,11 +50,11 @@ struct label_dict_proxy { return locsets.size() + regions.size() + iexpressions.size(); } - void extend(const label_dict_proxy& other, std::string prefix = "") { + auto extend(const label_dict_proxy& other, std::string prefix = "") { dict.extend(other.dict, prefix); - clear_cache(); update_cache(); + return *this; } void set(const std::string& name, const std::string& desc) { From 8f7b7e01d623c5beb1c39626eaa9efdff362547d Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 5 Mar 2024 08:25:00 +0100 Subject: [PATCH 11/18] Clean-up; more stub work. --- python/identifiers.cpp | 30 ++++++++++++++++++-------- python/morphology.cpp | 7 +++--- python/stubs/arbor/__init__.pyi | 8 +++---- python/stubs/arbor/_arbor/__init__.pyi | 28 ++++++++++-------------- python/stubs/arbor/_arbor/units.pyi | 8 +++---- 5 files changed, 43 insertions(+), 38 deletions(-) diff --git a/python/identifiers.cpp b/python/identifiers.cpp index e58a8a035d..b837658d02 100644 --- a/python/identifiers.cpp +++ b/python/identifiers.cpp @@ -50,9 +50,14 @@ void register_identifiers(py::module& m) { "Construct a cell_local_label identifier with arguments:\n" " label: The identifier of a group of one or more items on a cell.\n" " policy: The policy for selecting one of possibly multiple items associated with the label.\n") - .def(py::init([](py::tuple t) { - if (py::len(t)!=2) throw std::runtime_error("tuple length != 2"); - return arb::cell_local_label_type{t[0].cast(), t[1].cast()}; + .def(py::init([](const std::tuple& t) { + return arb::cell_local_label_type{std::get(t), std::get(t)}; + }), + "Construct a cell_local_label identifier with tuple argument (label, policy):\n" + " label: The identifier of a group of one or more items on a cell.\n" + " policy: The policy for selecting one of possibly multiple items associated with the label.\n") + .def(py::init([](const std::pair& t) { + return arb::cell_local_label_type{std::get(t), std::get(t)}; }), "Construct a cell_local_label identifier with tuple argument (label, policy):\n" " label: The identifier of a group of one or more items on a cell.\n" @@ -64,8 +69,9 @@ void register_identifiers(py::module& m) { .def("__str__", [](arb::cell_local_label_type m) {return pprintf("", m.tag, m.policy);}) .def("__repr__",[](arb::cell_local_label_type m) {return pprintf("", m.tag, m.policy);}); - py::implicitly_convertible(); - py::implicitly_convertible(); + py::implicitly_convertible, arb::cell_local_label_type>(); + py::implicitly_convertible, arb::cell_local_label_type>(); + py::implicitly_convertible(); py::class_ cell_global_label_type(m, "cell_global_label", "For global identification of an item.\n\n" @@ -89,13 +95,18 @@ void register_identifiers(py::module& m) { "Construct a cell_global_label identifier with arguments:\n" " gid: The global identifier of the cell.\n" " label: The cell_local_label representing the label and selection policy of an item on the cell.\n") - .def(py::init([](py::tuple t) { - if (py::len(t)!=2) throw std::runtime_error("tuple length != 2"); - return arb::cell_global_label_type{t[0].cast(), t[1].cast()}; + .def(py::init([](const std::tuple& t) { + return arb::cell_global_label_type{std::get(t), std::get(t)}; }), "Construct a cell_global_label identifier with tuple argument (gid, label):\n" " gid: The global identifier of the cell.\n" " label: The cell_local_label representing the label and selection policy of an item on the cell.\n") + .def(py::init([](const std::tuple& t) { + return arb::cell_global_label_type{std::get(t), std::get(t)}; + }), + "Construct a cell_global_label identifier with tuple argument (gid, label):\n" + " gid: The global identifier of the cell.\n" + " label: The tag of an item on the cell.\n") .def_readwrite("gid", &arb::cell_global_label_type::gid, "The global identifier of the cell.") .def_readwrite("label", &arb::cell_global_label_type::label, @@ -103,7 +114,8 @@ void register_identifiers(py::module& m) { .def("__str__", [](arb::cell_global_label_type m) {return pprintf("", m.gid, m.label.tag, m.label.policy);}) .def("__repr__",[](arb::cell_global_label_type m) {return pprintf("", m.gid, m.label.tag, m.label.policy);}); - py::implicitly_convertible(); + py::implicitly_convertible, arb::cell_global_label_type>(); + py::implicitly_convertible, arb::cell_global_label_type>(); py::class_ cell_member(m, "cell_member", "For global identification of a cell-local item.\n\n" diff --git a/python/morphology.cpp b/python/morphology.cpp index 3f4799c9a8..03715c5768 100644 --- a/python/morphology.cpp +++ b/python/morphology.cpp @@ -95,9 +95,8 @@ void register_morphology(py::module& m) { .def(py::init(), "x"_a, "y"_a, "z"_a, "radius"_a, "Create an mpoint object from parameters x, y, z, and radius, specified in µm.") - .def(py::init([](py::tuple t) { - if (py::len(t)!=4) throw std::runtime_error("tuple length != 4"); - return arb::mpoint{t[0].cast(), t[1].cast(), t[2].cast(), t[3].cast()}; }), + .def(py::init([](const std::tuple& t) { + return arb::mpoint{std::get<0>(t), std::get<1>(t), std::get<2>(t), std::get<3>(t)}; }), "Create an mpoint object from a tuple (x, y, z, radius), specified in µm.") .def_readonly("x", &arb::mpoint::x, "X coordinate [μm].") .def_readonly("y", &arb::mpoint::y, "Y coordinate [μm].") @@ -112,7 +111,7 @@ void register_morphology(py::module& m) { .def("__repr__", [](const arb::mpoint& p) {return util::pprintf("{}", p);}); - py::implicitly_convertible(); + py::implicitly_convertible, arb::mpoint>(); // arb::msegment msegment diff --git a/python/stubs/arbor/__init__.pyi b/python/stubs/arbor/__init__.pyi index 12a28c9754..4534d60857 100644 --- a/python/stubs/arbor/__init__.pyi +++ b/python/stubs/arbor/__init__.pyi @@ -271,17 +271,17 @@ __config__: dict = { "neuroml": True, "bundled": True, "version": "0.9.1-dev", - "source": "2023-12-08T14:40:50+01:00 327c56d229571dac097e7400a9b5e04fc8d7a514 modified", - "build_config": "DEBUG", + "source": "2024-02-21T20:23:01+01:00 2e2f329f5e2afd70c180dec5578eb886d9119141 modified", + "build_config": "RELEASE", "arch": "native", "prefix": "/usr/local", "python_lib_path": "/opt/homebrew/lib/python3.11/site-packages", "binary_path": "bin", "lib_path": "lib", "data_path": "share", - "CXX": "/opt/homebrew/bin/clang++", + "CXX": "/opt/homebrew/bin/g++-13", "pybind-version": "2.11.1", - "timestamp": "Jan 2 2024 09:57:33", + "timestamp": "Feb 21 2024 21:48:32", } __version__: str = "0.9.1-dev" mnpos: int = 4294967295 diff --git a/python/stubs/arbor/_arbor/__init__.pyi b/python/stubs/arbor/_arbor/__init__.pyi index a0ae1484c9..1241cd6b2d 100644 --- a/python/stubs/arbor/_arbor/__init__.pyi +++ b/python/stubs/arbor/_arbor/__init__.pyi @@ -413,8 +413,6 @@ class cable_global_properties: @property def axial_resistivity(self) -> float | None: ... - @axial_resistivity.setter - def axial_resistivity(self, arg1: float) -> None: ... @property def catalogue(self) -> catalogue: """ @@ -445,16 +443,10 @@ class cable_global_properties: @property def membrane_capacitance(self) -> float | None: ... - @membrane_capacitance.setter - def membrane_capacitance(self, arg1: float) -> None: ... @property def membrane_potential(self) -> float | None: ... - @membrane_potential.setter - def membrane_potential(self, arg1: float) -> None: ... @property def temperature(self) -> float | None: ... - @temperature.setter - def temperature(self, arg1: float) -> None: ... class cable_probe_point_info: """ @@ -980,10 +972,10 @@ class decor: def paint( self, region: str, - Vm: units.quantity | str | None = None, - cm: units.quantity | str | None = None, - rL: units.quantity | str | None = None, - tempK: units.quantity | str | None = None, + Vm: units.quantity | tuple[units.quantity, str] | None = None, + cm: units.quantity | tuple[units.quantity, str] | None = None, + rL: units.quantity | tuple[units.quantity, str] | None = None, + tempK: units.quantity | tuple[units.quantity, str] | None = None, ) -> decor: """ Set cable properties on a region. @@ -992,6 +984,7 @@ class decor: * cm: membrane capacitance [F/m²]. * rL: axial resistivity [Ω·cm]. * tempK: temperature [Kelvin]. + Each value can be given as a plain quantity or a tuple of (quantity, 'scale') where scale is an iexpr. """ @typing.overload @@ -1000,10 +993,10 @@ class decor: region: str, *, ion: str, - int_con: units.quantity | None = None, - ext_con: units.quantity | None = None, - rev_pot: units.quantity | None = None, - diff: units.quantity | None = None, + int_con: units.quantity | tuple[units.quantity, str] | None = None, + ext_con: units.quantity | tuple[units.quantity, str] | None = None, + rev_pot: units.quantity | tuple[units.quantity, str] | None = None, + diff: units.quantity | tuple[units.quantity, str] | None = None, ) -> decor: """ Set ion species properties conditions on a region. @@ -1012,6 +1005,7 @@ class decor: * rev_pot: reversal potential [mV]. * method: mechanism for calculating reversal potential. * diff: diffusivity [m^2/s]. + Each value can be given as a plain quantity or a tuple of (quantity, 'scale') where scale is an iexpr. """ def paintings( @@ -1893,7 +1887,7 @@ class membrane_potential: Setting the initial membrane voltage. """ - def __init__(self, arg0: units.quantity, arg1: str | None) -> None: ... + def __init__(self, arg0: units.quantity) -> None: ... def __repr__(self) -> str: ... class meter_manager: diff --git a/python/stubs/arbor/_arbor/units.pyi b/python/stubs/arbor/_arbor/units.pyi index aa56715574..664b21ae32 100644 --- a/python/stubs/arbor/_arbor/units.pyi +++ b/python/stubs/arbor/_arbor/units.pyi @@ -166,22 +166,22 @@ mM: unit # value = umol/L mS: unit # value = mS mV: unit # value = mV mega: unit # value = 1000000 -micro: unit # value = 9.99999997475242708e-07 -milli: unit # value = 0.00100000004749745131 +micro: unit # value = 9.99999999999999955e-07 +milli: unit # value = 0.00100000000000000002 mm: unit # value = mm mm2: unit # value = mm^2 mol: unit # value = mol ms: unit # value = ms nA: unit # value = nA nF: unit # value = nF -nano: unit # value = 9.99999971718068537e-10 +nano: unit # value = 1e-09 nil: unit # value = nm: unit # value = nm nm2: unit # value = nm^2 ns: unit # value = ns pA: unit # value = pA pF: unit # value = pF -pico: unit # value = 9.999999960041972e-13 +pico: unit # value = 10e-13 rad: unit # value = rad s: unit # value = s uA: unit # value = uA From 0500fa4b97208dc01a62099a75d6cf00b1f1c0e5 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 5 Mar 2024 09:25:15 +0100 Subject: [PATCH 12/18] Clean-up stubs and fix allen example. --- python/example/single_cell_allen.py | 18 +- python/morphology.cpp | 3 - python/stubs/arbor/__init__.pyi | 175 +- python/stubs/arbor/_arbor/__init__.pyi | 2024 ++++++++++-------------- python/stubs/arbor/_arbor/env.pyi | 17 +- python/stubs/arbor/_arbor/py.typed | 0 python/stubs/arbor/_arbor/units.pyi | 135 +- python/stubs/arbor/py.typed | 0 python/stubs/py.typed | 0 9 files changed, 866 insertions(+), 1506 deletions(-) delete mode 100644 python/stubs/arbor/_arbor/py.typed delete mode 100644 python/stubs/arbor/py.typed delete mode 100644 python/stubs/py.typed diff --git a/python/example/single_cell_allen.py b/python/example/single_cell_allen.py index f2cb8b7359..0b43daf8dd 100644 --- a/python/example/single_cell_allen.py +++ b/python/example/single_cell_allen.py @@ -23,10 +23,10 @@ def load_allen_fit(fit): # cable parameters convenience class @dataclass class parameters: - cm: Optional[float] = None - temp: Optional[float] = None - Vm: Optional[float] = None - rL: Optional[float] = None + cm: Optional[U.quantity] = None + temp: Optional[U.quantity] = None + Vm: Optional[U.quantity] = None + rL: Optional[U.quantity] = None param = defaultdict(parameters) mechs = defaultdict(dict) @@ -42,7 +42,7 @@ class parameters: if name == "cm": param[region].cm = value * U.uF / U.cm2 elif name == "Ra": - param[region].rL = (value * U.Ohm * U.cm,) + param[region].rL = value * U.Ohm * U.cm elif name == "Vm": param[region].Vm = value * U.mV elif name == "celsius": @@ -103,9 +103,9 @@ def make_cell(base, swc, fit): decor.paint( f'"{region}"', tempK=vs.temp, - # Vm=vs.Vm, - # cm=vs.cm, - # rL=vs.rL, + Vm=vs.Vm, + cm=vs.cm, + rL=vs.rL, ) # (7) set reversal potentials @@ -152,7 +152,7 @@ def make_cell(base, swc, fit): # (16) Load and scale reference reference = ( - 1e3 * pd.read_csv(here / "single_cell_allen_neuron_ref.csv")["U/mV"] + offset + 1e3 * pd.read_csv(here / "single_cell_allen_neuron_ref.csv")["U/mV"][:-1] + offset ) # (17) Plot diff --git a/python/morphology.cpp b/python/morphology.cpp index 03715c5768..117515f065 100644 --- a/python/morphology.cpp +++ b/python/morphology.cpp @@ -294,9 +294,6 @@ void register_morphology(py::module& m) { .def("__str__", [](const arb::segment_tree& s) { return util::pprintf("", s);}); - - using morph_or_tree = std::variant; - // Function that creates a morphology/segment_tree from an swc file. // Wraps calls to C++ functions arborio::parse_swc() and arborio::load_swc_arbor(). m.def("load_swc_arbor", diff --git a/python/stubs/arbor/__init__.pyi b/python/stubs/arbor/__init__.pyi index 4534d60857..d0737f1027 100644 --- a/python/stubs/arbor/__init__.pyi +++ b/python/stubs/arbor/__init__.pyi @@ -5,7 +5,11 @@ from arbor._arbor import MechCatItemIterator from arbor._arbor import MechCatKeyIterator from arbor._arbor import MechCatValueIterator from arbor._arbor import allen_catalogue -from arbor._arbor import asc_morphology +from arbor._arbor import asc_color +from arbor._arbor import asc_marker +from arbor._arbor import asc_marker_set +from arbor._arbor import asc_metadata +from arbor._arbor import asc_spine from arbor._arbor import axial_resistivity from arbor._arbor import backend from arbor._arbor import bbp_catalogue @@ -81,6 +85,7 @@ from arbor._arbor import load_catalogue from arbor._arbor import load_component from arbor._arbor import load_swc_arbor from arbor._arbor import load_swc_neuron +from arbor._arbor import loaded_morphology from arbor._arbor import location from arbor._arbor import mechanism from arbor._arbor import mechanism_field @@ -94,8 +99,8 @@ from arbor._arbor import morphology_provider from arbor._arbor import mpoint from arbor._arbor import msegment from arbor._arbor import neuroml -from arbor._arbor import neuroml_morph_data from arbor._arbor import neuron_cable_properties +from arbor._arbor import nml_metadata from arbor._arbor import partition_by_group from arbor._arbor import partition_hint from arbor._arbor import partition_load_balance @@ -118,6 +123,7 @@ from arbor._arbor import spike from arbor._arbor import spike_recording from arbor._arbor import spike_source_cell from arbor._arbor import stochastic_catalogue +from arbor._arbor import swc_metadata from arbor._arbor import synapse from arbor._arbor import temperature from arbor._arbor import threshold_detector @@ -126,162 +132,11 @@ from arbor._arbor import units from arbor._arbor import voltage_process from arbor._arbor import write_component from . import _arbor - -__all__ = [ - "ArbFileNotFoundError", - "ArbValueError", - "MechCatItemIterator", - "MechCatKeyIterator", - "MechCatValueIterator", - "allen_catalogue", - "asc_morphology", - "axial_resistivity", - "backend", - "bbp_catalogue", - "benchmark_cell", - "build_catalogue", - "cable", - "cable_cell", - "cable_component", - "cable_global_properties", - "cable_probe_axial_current", - "cable_probe_density_state", - "cable_probe_density_state_cell", - "cable_probe_ion_current_cell", - "cable_probe_ion_current_density", - "cable_probe_ion_diff_concentration", - "cable_probe_ion_diff_concentration_cell", - "cable_probe_ion_ext_concentration", - "cable_probe_ion_ext_concentration_cell", - "cable_probe_ion_int_concentration", - "cable_probe_ion_int_concentration_cell", - "cable_probe_membrane_voltage", - "cable_probe_membrane_voltage_cell", - "cable_probe_point_info", - "cable_probe_point_state", - "cable_probe_point_state_cell", - "cable_probe_stimulus_current_cell", - "cable_probe_total_current_cell", - "cable_probe_total_ion_current_cell", - "cable_probe_total_ion_current_density", - "catalogue", - "cell_address", - "cell_cv_data", - "cell_global_label", - "cell_kind", - "cell_local_label", - "cell_member", - "component_meta_data", - "config", - "connection", - "context", - "cv_data", - "cv_policy", - "cv_policy_every_segment", - "cv_policy_explicit", - "cv_policy_fixed_per_branch", - "cv_policy_max_extent", - "cv_policy_single", - "decor", - "default_catalogue", - "density", - "domain_decomposition", - "env", - "event_generator", - "explicit_schedule", - "ext_concentration", - "extent", - "gap_junction_connection", - "group_description", - "iclamp", - "int_concentration", - "intersect_region", - "ion_data", - "ion_dependency", - "ion_diffusivity", - "ion_settings", - "isometry", - "junction", - "label_dict", - "lif_cell", - "lif_probe_metadata", - "lif_probe_voltage", - "load_asc", - "load_catalogue", - "load_component", - "load_swc_arbor", - "load_swc_neuron", - "location", - "mechanism", - "mechanism_field", - "mechanism_info", - "membrane_capacitance", - "membrane_potential", - "meter_manager", - "meter_report", - "mnpos", - "modcc", - "morphology", - "morphology_provider", - "mpoint", - "msegment", - "neuroml", - "neuroml_morph_data", - "neuron_cable_properties", - "partition_by_group", - "partition_hint", - "partition_load_balance", - "place_pwlin", - "poisson_schedule", - "print_config", - "probe", - "proc_allocation", - "recipe", - "regular_schedule", - "reversal_potential", - "reversal_potential_method", - "scaled_mechanism", - "schedule_base", - "segment_tree", - "selection_policy", - "simulation", - "single_cell_model", - "spike", - "spike_recording", - "spike_source_cell", - "stochastic_catalogue", - "synapse", - "temperature", - "threshold_detector", - "trace", - "units", - "voltage_process", - "write_component", -] - -def build_catalogue(): ... -def modcc(): ... - -__config__: dict = { - "mpi": False, - "mpi4py": False, - "gpu": None, - "vectorize": True, - "profiling": False, - "neuroml": True, - "bundled": True, - "version": "0.9.1-dev", - "source": "2024-02-21T20:23:01+01:00 2e2f329f5e2afd70c180dec5578eb886d9119141 modified", - "build_config": "RELEASE", - "arch": "native", - "prefix": "/usr/local", - "python_lib_path": "/opt/homebrew/lib/python3.11/site-packages", - "binary_path": "bin", - "lib_path": "lib", - "data_path": "share", - "CXX": "/opt/homebrew/bin/g++-13", - "pybind-version": "2.11.1", - "timestamp": "Feb 21 2024 21:48:32", -} -__version__: str = "0.9.1-dev" +__all__ = ['ArbFileNotFoundError', 'ArbValueError', 'MechCatItemIterator', 'MechCatKeyIterator', 'MechCatValueIterator', 'allen_catalogue', 'asc_color', 'asc_marker', 'asc_marker_set', 'asc_metadata', 'asc_spine', 'axial_resistivity', 'backend', 'bbp_catalogue', 'benchmark_cell', 'build_catalogue', 'cable', 'cable_cell', 'cable_component', 'cable_global_properties', 'cable_probe_axial_current', 'cable_probe_density_state', 'cable_probe_density_state_cell', 'cable_probe_ion_current_cell', 'cable_probe_ion_current_density', 'cable_probe_ion_diff_concentration', 'cable_probe_ion_diff_concentration_cell', 'cable_probe_ion_ext_concentration', 'cable_probe_ion_ext_concentration_cell', 'cable_probe_ion_int_concentration', 'cable_probe_ion_int_concentration_cell', 'cable_probe_membrane_voltage', 'cable_probe_membrane_voltage_cell', 'cable_probe_point_info', 'cable_probe_point_state', 'cable_probe_point_state_cell', 'cable_probe_stimulus_current_cell', 'cable_probe_total_current_cell', 'cable_probe_total_ion_current_cell', 'cable_probe_total_ion_current_density', 'catalogue', 'cell_address', 'cell_cv_data', 'cell_global_label', 'cell_kind', 'cell_local_label', 'cell_member', 'component_meta_data', 'config', 'connection', 'context', 'cv_data', 'cv_policy', 'cv_policy_every_segment', 'cv_policy_explicit', 'cv_policy_fixed_per_branch', 'cv_policy_max_extent', 'cv_policy_single', 'decor', 'default_catalogue', 'density', 'domain_decomposition', 'env', 'event_generator', 'explicit_schedule', 'ext_concentration', 'extent', 'gap_junction_connection', 'group_description', 'iclamp', 'int_concentration', 'intersect_region', 'ion_data', 'ion_dependency', 'ion_diffusivity', 'ion_settings', 'isometry', 'junction', 'label_dict', 'lif_cell', 'lif_probe_metadata', 'lif_probe_voltage', 'load_asc', 'load_catalogue', 'load_component', 'load_swc_arbor', 'load_swc_neuron', 'loaded_morphology', 'location', 'mechanism', 'mechanism_field', 'mechanism_info', 'membrane_capacitance', 'membrane_potential', 'meter_manager', 'meter_report', 'mnpos', 'modcc', 'morphology', 'morphology_provider', 'mpoint', 'msegment', 'neuroml', 'neuron_cable_properties', 'nml_metadata', 'partition_by_group', 'partition_hint', 'partition_load_balance', 'place_pwlin', 'poisson_schedule', 'print_config', 'probe', 'proc_allocation', 'recipe', 'regular_schedule', 'reversal_potential', 'reversal_potential_method', 'scaled_mechanism', 'schedule_base', 'segment_tree', 'selection_policy', 'simulation', 'single_cell_model', 'spike', 'spike_recording', 'spike_source_cell', 'stochastic_catalogue', 'swc_metadata', 'synapse', 'temperature', 'threshold_detector', 'trace', 'units', 'voltage_process', 'write_component'] +def build_catalogue(): + ... +def modcc(): + ... +__config__: dict = {'mpi': False, 'mpi4py': False, 'gpu': None, 'vectorize': True, 'profiling': False, 'neuroml': True, 'bundled': True, 'version': '0.9.1-dev', 'source': '2024-03-01T14:59:23+01:00 dcdfe101f389cb4854ac3d0a067feeb280600c88 modified', 'build_config': 'DEBUG', 'arch': 'native', 'prefix': '/usr/local', 'python_lib_path': '/usr/local/lib/python3.12/site-packages', 'binary_path': 'bin', 'lib_path': 'lib', 'data_path': 'share', 'CXX': '/opt/homebrew/bin/clang++', 'pybind-version': '2.11.1', 'timestamp': 'Mar 4 2024 20:56:20'} +__version__: str = '0.9.1-dev' mnpos: int = 4294967295 diff --git a/python/stubs/arbor/_arbor/__init__.pyi b/python/stubs/arbor/_arbor/__init__.pyi index 1241cd6b2d..4e518c25fd 100644 --- a/python/stubs/arbor/_arbor/__init__.pyi +++ b/python/stubs/arbor/_arbor/__init__.pyi @@ -1,222 +1,171 @@ """ arbor: multicompartment neural network models. """ - from __future__ import annotations import typing from . import env from . import units - -__all__ = [ - "ArbFileNotFoundError", - "ArbValueError", - "MechCatItemIterator", - "MechCatKeyIterator", - "MechCatValueIterator", - "allen_catalogue", - "asc_morphology", - "axial_resistivity", - "backend", - "bbp_catalogue", - "benchmark_cell", - "cable", - "cable_cell", - "cable_component", - "cable_global_properties", - "cable_probe_axial_current", - "cable_probe_density_state", - "cable_probe_density_state_cell", - "cable_probe_ion_current_cell", - "cable_probe_ion_current_density", - "cable_probe_ion_diff_concentration", - "cable_probe_ion_diff_concentration_cell", - "cable_probe_ion_ext_concentration", - "cable_probe_ion_ext_concentration_cell", - "cable_probe_ion_int_concentration", - "cable_probe_ion_int_concentration_cell", - "cable_probe_membrane_voltage", - "cable_probe_membrane_voltage_cell", - "cable_probe_point_info", - "cable_probe_point_state", - "cable_probe_point_state_cell", - "cable_probe_stimulus_current_cell", - "cable_probe_total_current_cell", - "cable_probe_total_ion_current_cell", - "cable_probe_total_ion_current_density", - "catalogue", - "cell_address", - "cell_cv_data", - "cell_global_label", - "cell_kind", - "cell_local_label", - "cell_member", - "component_meta_data", - "config", - "connection", - "context", - "cv_data", - "cv_policy", - "cv_policy_every_segment", - "cv_policy_explicit", - "cv_policy_fixed_per_branch", - "cv_policy_max_extent", - "cv_policy_single", - "decor", - "default_catalogue", - "density", - "domain_decomposition", - "env", - "event_generator", - "explicit_schedule", - "ext_concentration", - "extent", - "gap_junction_connection", - "group_description", - "iclamp", - "int_concentration", - "intersect_region", - "ion_data", - "ion_dependency", - "ion_diffusivity", - "ion_settings", - "isometry", - "junction", - "label_dict", - "lif_cell", - "lif_probe_metadata", - "lif_probe_voltage", - "load_asc", - "load_catalogue", - "load_component", - "load_swc_arbor", - "load_swc_neuron", - "location", - "mechanism", - "mechanism_field", - "mechanism_info", - "membrane_capacitance", - "membrane_potential", - "meter_manager", - "meter_report", - "mnpos", - "morphology", - "morphology_provider", - "mpoint", - "msegment", - "neuroml", - "neuroml_morph_data", - "neuron_cable_properties", - "partition_by_group", - "partition_hint", - "partition_load_balance", - "place_pwlin", - "poisson_schedule", - "print_config", - "probe", - "proc_allocation", - "recipe", - "regular_schedule", - "reversal_potential", - "reversal_potential_method", - "scaled_mechanism", - "schedule_base", - "segment_tree", - "selection_policy", - "simulation", - "single_cell_model", - "spike", - "spike_recording", - "spike_source_cell", - "stochastic_catalogue", - "synapse", - "temperature", - "threshold_detector", - "trace", - "units", - "voltage_process", - "write_component", -] - +__all__ = ['ArbFileNotFoundError', 'ArbValueError', 'MechCatItemIterator', 'MechCatKeyIterator', 'MechCatValueIterator', 'allen_catalogue', 'asc_color', 'asc_marker', 'asc_marker_set', 'asc_metadata', 'asc_spine', 'axial_resistivity', 'backend', 'bbp_catalogue', 'benchmark_cell', 'cable', 'cable_cell', 'cable_component', 'cable_global_properties', 'cable_probe_axial_current', 'cable_probe_density_state', 'cable_probe_density_state_cell', 'cable_probe_ion_current_cell', 'cable_probe_ion_current_density', 'cable_probe_ion_diff_concentration', 'cable_probe_ion_diff_concentration_cell', 'cable_probe_ion_ext_concentration', 'cable_probe_ion_ext_concentration_cell', 'cable_probe_ion_int_concentration', 'cable_probe_ion_int_concentration_cell', 'cable_probe_membrane_voltage', 'cable_probe_membrane_voltage_cell', 'cable_probe_point_info', 'cable_probe_point_state', 'cable_probe_point_state_cell', 'cable_probe_stimulus_current_cell', 'cable_probe_total_current_cell', 'cable_probe_total_ion_current_cell', 'cable_probe_total_ion_current_density', 'catalogue', 'cell_address', 'cell_cv_data', 'cell_global_label', 'cell_kind', 'cell_local_label', 'cell_member', 'component_meta_data', 'config', 'connection', 'context', 'cv_data', 'cv_policy', 'cv_policy_every_segment', 'cv_policy_explicit', 'cv_policy_fixed_per_branch', 'cv_policy_max_extent', 'cv_policy_single', 'decor', 'default_catalogue', 'density', 'domain_decomposition', 'env', 'event_generator', 'explicit_schedule', 'ext_concentration', 'extent', 'gap_junction_connection', 'group_description', 'iclamp', 'int_concentration', 'intersect_region', 'ion_data', 'ion_dependency', 'ion_diffusivity', 'ion_settings', 'isometry', 'junction', 'label_dict', 'lif_cell', 'lif_probe_metadata', 'lif_probe_voltage', 'load_asc', 'load_catalogue', 'load_component', 'load_swc_arbor', 'load_swc_neuron', 'loaded_morphology', 'location', 'mechanism', 'mechanism_field', 'mechanism_info', 'membrane_capacitance', 'membrane_potential', 'meter_manager', 'meter_report', 'mnpos', 'morphology', 'morphology_provider', 'mpoint', 'msegment', 'neuroml', 'neuron_cable_properties', 'nml_metadata', 'partition_by_group', 'partition_hint', 'partition_load_balance', 'place_pwlin', 'poisson_schedule', 'print_config', 'probe', 'proc_allocation', 'recipe', 'regular_schedule', 'reversal_potential', 'reversal_potential_method', 'scaled_mechanism', 'schedule_base', 'segment_tree', 'selection_policy', 'simulation', 'single_cell_model', 'spike', 'spike_recording', 'spike_source_cell', 'stochastic_catalogue', 'swc_metadata', 'synapse', 'temperature', 'threshold_detector', 'trace', 'units', 'voltage_process', 'write_component'] class ArbFileNotFoundError(FileNotFoundError): pass - class ArbValueError(ValueError): pass - class MechCatItemIterator: - def __iter__(self) -> MechCatItemIterator: ... - def __next__(self) -> tuple[str, mechanism_info]: ... - + def __iter__(self) -> MechCatItemIterator: + ... + def __next__(self) -> tuple[str, mechanism_info]: + ... class MechCatKeyIterator: - def __iter__(self) -> MechCatKeyIterator: ... - def __next__(self) -> str: ... - + def __iter__(self) -> MechCatKeyIterator: + ... + def __next__(self) -> str: + ... class MechCatValueIterator: - def __iter__(self) -> MechCatValueIterator: ... - def __next__(self) -> mechanism_info: ... - -class asc_morphology: + def __iter__(self) -> MechCatValueIterator: + ... + def __next__(self) -> mechanism_info: + ... +class asc_color: """ - The morphology and label dictionary meta-data loaded from a Neurolucida ASCII (.asc) file. + Neurolucida color tag. """ - @property - def labels(self) -> label_dict: - """ - The four canonical regions are labeled 'soma', 'axon', 'dend' and 'apic'. - """ - + def blue(self) -> int: + ... @property - def morphology(self) -> morphology: - """ - The cable cell morphology. - """ - + def green(self) -> int: + ... @property - def segment_tree(self) -> segment_tree: - """ - The raw segment tree. - """ - + def red(self) -> int: + ... +class asc_marker: + """ + Neurolucida marker type. + + Members: + + dot + + cross + + circle + + none + """ + __members__: typing.ClassVar[dict[str, asc_marker]] # value = {'dot': , 'cross': , 'circle': , 'none': } + circle: typing.ClassVar[asc_marker] # value = + cross: typing.ClassVar[asc_marker] # value = + dot: typing.ClassVar[asc_marker] # value = + none: typing.ClassVar[asc_marker] # value = + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: int) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: int) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... +class asc_marker_set: + """ + Neurolucida marker set type. + """ + @property + def color(self) -> asc_color: + ... + @property + def locations(self) -> list[mpoint]: + ... + @property + def marker(self) -> asc_marker: + ... + @property + def name(self) -> str: + ... +class asc_metadata: + """ + Neurolucida metadata type: Spines and marker sets. + """ + @property + def markers(self) -> list[asc_marker_set]: + ... + @property + def spines(self) -> list[asc_spine]: + ... +class asc_spine: + """ + Neurolucida spine marker. + """ + @property + def location(self) -> mpoint: + ... + @property + def name(self) -> str: + ... class axial_resistivity: """ Setting the axial resistivity. """ - - def __init__(self, arg0: units.quantity) -> None: ... - def __repr__(self) -> str: ... - + def __init__(self, arg0: units.quantity) -> None: + ... + def __repr__(self) -> str: + ... class backend: """ Enumeration used to indicate which hardware backend to execute a cell group on. - + Members: - + gpu : Use GPU backend. - + multicore : Use multicore backend. """ - - __members__: typing.ClassVar[ - dict[str, backend] - ] # value = {'gpu': , 'multicore': } - gpu: typing.ClassVar[backend] # value = - multicore: typing.ClassVar[backend] # value = - def __eq__(self, other: typing.Any) -> bool: ... - def __getstate__(self) -> int: ... - def __hash__(self) -> int: ... - def __index__(self) -> int: ... - def __init__(self, value: int) -> None: ... - def __int__(self) -> int: ... - def __ne__(self, other: typing.Any) -> bool: ... - def __repr__(self) -> str: ... - def __setstate__(self, state: int) -> None: ... - def __str__(self) -> str: ... - @property - def name(self) -> str: ... - @property - def value(self) -> int: ... - + __members__: typing.ClassVar[dict[str, backend]] # value = {'gpu': , 'multicore': } + gpu: typing.ClassVar[backend] # value = + multicore: typing.ClassVar[backend] # value = + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: int) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: int) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... class benchmark_cell: """ A benchmarking cell, used by Arbor developers to test communication performance. @@ -225,153 +174,118 @@ class benchmark_cell: for example if realtime_ratio=2, a cell will take 2 seconds of CPU time to simulate 1 second. """ - @typing.overload - def __init__( - self, - source_label: str, - target_label: str, - schedule: regular_schedule, - realtime_ratio: float = 1.0, - ) -> None: + def __init__(self, source_label: str, target_label: str, schedule: regular_schedule, realtime_ratio: float = 1.0) -> None: """ Construct a benchmark cell that generates spikes on 'source_label' at regular intervals. The cell has one source labeled 'source_label', and one target labeled 'target_label'. """ - @typing.overload - def __init__( - self, - source_label: str, - target_label: str, - schedule: explicit_schedule, - realtime_ratio: float = 1.0, - ) -> None: + def __init__(self, source_label: str, target_label: str, schedule: explicit_schedule, realtime_ratio: float = 1.0) -> None: """ Construct a benchmark cell that generates spikes on 'source_label' at a sequence of user-defined times. The cell has one source labeled 'source_label', and one target labeled 'target_label'. """ - @typing.overload - def __init__( - self, - source_label: str, - target_label: str, - schedule: poisson_schedule, - realtime_ratio: float = 1.0, - ) -> None: + def __init__(self, source_label: str, target_label: str, schedule: poisson_schedule, realtime_ratio: float = 1.0) -> None: """ Construct a benchmark cell that generates spikeson 'source_label' at times defined by a Poisson sequence. The cell has one source labeled 'source_label', and one target labeled 'target_label'. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... - + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... class cable: __hash__: typing.ClassVar[None] = None - def __eq__(self, arg0: cable) -> bool: ... - def __init__(self, branch: int, prox: float, dist: float) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __eq__(self, arg0: cable) -> bool: + ... + def __init__(self, branch: int, prox: float, dist: float) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def branch(self) -> int: """ The id of the branch on which the cable lies. """ - @property def dist(self) -> float: """ The relative position of the distal end of the cable on its branch ∈ [0,1]. """ - @property def prox(self) -> float: """ The relative position of the proximal end of the cable on its branch ∈ [0,1]. """ - class cable_cell: """ Represents morphologically-detailed cell models, with morphology represented as a tree of one-dimensional cable segments. """ - @typing.overload - def __init__( - self, morphology: morphology, decor: decor, labels: label_dict | None = None - ) -> None: + def __init__(self, morphology: morphology, decor: decor, labels: label_dict | None = None) -> None: """ Construct with a morphology, decor, and label dictionary. """ - @typing.overload - def __init__( - self, segment_tree: segment_tree, decor: decor, labels: label_dict | None = None - ) -> None: + def __init__(self, segment_tree: segment_tree, decor: decor, labels: label_dict | None = None) -> None: """ Construct with a morphology derived from a segment tree, decor, and label dictionary. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def cables(self, label: str) -> list[cable]: """ The cable segments of the cell morphology for a region label. """ - def locations(self, label: str) -> list[location]: """ The locations of the cell morphology for a locset label. """ - @property def num_branches(self) -> int: """ The number of unbranched cable sections in the morphology. """ - class cable_component: - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def component(self) -> morphology | label_dict | decor | cable_cell: """ cable-cell component. """ - @property def meta_data(self) -> component_meta_data: """ cable-cell component meta-data. """ - @meta_data.setter - def meta_data(self, arg0: component_meta_data) -> None: ... - + def meta_data(self, arg0: component_meta_data) -> None: + ... class cable_global_properties: membrane_voltage_limit: float | None @typing.overload - def __init__(self) -> None: ... + def __init__(self) -> None: + ... @typing.overload - def __init__(self, arg0: cable_global_properties) -> None: ... - def __str__(self) -> str: ... + def __init__(self, arg0: cable_global_properties) -> None: + ... + def __str__(self) -> str: + ... def check(self) -> None: """ Test whether all default parameters and ion species properties have been set. """ - - def set_ion( - self, - ion: str, - valence: int | None = None, - int_con: units.quantity | None = None, - ext_con: units.quantity | None = None, - rev_pot: units.quantity | None = None, - method: typing.Any = None, - diff: units.quantity | None = None, - ) -> None: + def set_ion(self, ion: str, valence: int | None = None, int_con: units.quantity | None = None, ext_con: units.quantity | None = None, rev_pot: units.quantity | None = None, method: typing.Any = None, diff: units.quantity | None = None) -> None: """ Set the global default properties of ion species named 'ion'. * valence: valence of the ion species [e]. @@ -389,14 +303,7 @@ class cable_global_properties: reversal potential is global for all compartments in the cell, and can't be overriden locally. """ - - def set_property( - self, - Vm: units.quantity | None = None, - cm: units.quantity | None = None, - rL: units.quantity | None = None, - tempK: units.quantity | None = None, - ) -> None: + def set_property(self, Vm: units.quantity | None = None, cm: units.quantity | None = None, rL: units.quantity | None = None, tempK: units.quantity | None = None) -> None: """ Set global default values for cable and cell properties. * Vm: initial membrane voltage [mV]. @@ -405,179 +312,169 @@ class cable_global_properties: * tempK: temperature [Kelvin]. These values can be overridden on specific regions using the paint interface. """ - def unset_ion(self, arg0: str) -> None: """ Remove ion species from properties. """ - @property - def axial_resistivity(self) -> float | None: ... + def axial_resistivity(self) -> float | None: + ... @property def catalogue(self) -> catalogue: """ The mechanism catalogue. """ - @catalogue.setter - def catalogue(self, arg0: catalogue) -> None: ... + def catalogue(self, arg0: catalogue) -> None: + ... @property def coalesce_synapses(self) -> bool: """ Flag for enabling/disabling linear syanpse coalescing. """ - @coalesce_synapses.setter - def coalesce_synapses(self, arg0: bool) -> None: ... + def coalesce_synapses(self, arg0: bool) -> None: + ... @property - def ion_data(self) -> dict[str, ion_data]: ... + def ion_data(self) -> dict[str, ion_data]: + ... @property - def ion_reversal_potential(self) -> dict[str, mechanism]: ... + def ion_reversal_potential(self) -> dict[str, mechanism]: + ... @property - def ion_valence(self) -> dict[str, int]: ... + def ion_valence(self) -> dict[str, int]: + ... @property def ions(self) -> dict[str, ion_settings]: """ Return a view of all ion settings. """ - @property - def membrane_capacitance(self) -> float | None: ... + def membrane_capacitance(self) -> float | None: + ... @property - def membrane_potential(self) -> float | None: ... + def membrane_potential(self) -> float | None: + ... @property - def temperature(self) -> float | None: ... - + def temperature(self) -> float | None: + ... class cable_probe_point_info: """ Probe metadata associated with a cable cell probe for point process state. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def location(self) -> location: """ Location of point process instance on cell. """ - @location.setter - def location(self, arg0: location) -> None: ... + def location(self, arg0: location) -> None: + ... @property def multiplicity(self) -> int: """ Number of coalesced point processes (linear synapses) associated with this instance. """ - @multiplicity.setter - def multiplicity(self, arg0: int) -> None: ... + def multiplicity(self, arg0: int) -> None: + ... @property def target(self) -> int: """ The target index of the point process instance on the cell. """ - @target.setter - def target(self, arg0: int) -> None: ... - + def target(self, arg0: int) -> None: + ... class catalogue: def __contains__(self, name: str) -> bool: """ Is 'name' in the catalogue? """ - - def __getitem__(self, arg0: str) -> mechanism_info: ... + def __getitem__(self, arg0: str) -> mechanism_info: + ... @typing.overload - def __init__(self) -> None: ... + def __init__(self) -> None: + ... @typing.overload - def __init__(self, arg0: catalogue) -> None: ... + def __init__(self, arg0: catalogue) -> None: + ... def __iter__(self) -> MechCatKeyIterator: """ Return an iterator over all mechanism names in this catalogues. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... - def derive( - self, - name: str, - parent: str, - globals: dict[str, float] = {}, - ions: dict[str, str] = {}, - ) -> None: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... + def derive(self, name: str, parent: str, globals: dict[str, float] = {}, ions: dict[str, str] = {}) -> None: + ... def extend(self, other: catalogue, prefix: str) -> None: """ Import another catalogue, possibly with a prefix. Will overwrite in case of name collisions. """ - def is_derived(self, name: str) -> bool: """ Is 'name' a derived mechanism or can it be implicitly derived? """ - def items(self) -> MechCatItemIterator: """ Return an iterator over all (name, mechanism) tuples in this catalogues. """ - def keys(self) -> MechCatKeyIterator: """ Return an iterator over all mechanism names in this catalogues. """ - def values(self) -> MechCatValueIterator: """ Return an iterator over all mechanism info values in this catalogues. """ - class cell_address: gid: int tag: str - class cell_cv_data: """ Provides information on the CVs representing the discretization of a cable-cell. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def cables(self, index: int) -> list[cable]: """ Return a list of cables representing the CV at the given index. """ - def children(self, index: int) -> list[int]: """ Return a list of indices of the CVs representing the children of the CV at the given index. """ - def parent(self, index: int) -> int: """ Return the index of the CV representing the parent of the CV at the given index. """ - @property def num_cv(self) -> int: """ Return the number of CVs in the cell. """ - class cell_global_label: """ For global identification of an item. - + cell_global_label members: (1) a unique cell identified by its gid. (2) a cell_local_label, referring to a labeled group of items on the cell and a policy for selecting a single item out of the group. """ - @typing.overload def __init__(self, gid: int, label: str) -> None: """ Construct a cell_global_label identifier from a gid and a label argument identifying an item on the cell. The default round_robin policy is used for selecting one of possibly multiple items on the cell associated with the label. """ - @typing.overload def __init__(self, gid: int, label: cell_local_label) -> None: """ @@ -585,7 +482,6 @@ class cell_global_label: gid: The global identifier of the cell. label: The cell_local_label representing the label and selection policy of an item on the cell. """ - @typing.overload def __init__(self, arg0: tuple) -> None: """ @@ -593,79 +489,85 @@ class cell_global_label: gid: The global identifier of the cell. label: The cell_local_label representing the label and selection policy of an item on the cell. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def gid(self) -> int: """ The global identifier of the cell. """ - @gid.setter - def gid(self, arg0: int) -> None: ... + def gid(self, arg0: int) -> None: + ... @property def label(self) -> cell_local_label: """ The cell_local_label representing the label and selection policy of an item on the cell. """ - @label.setter - def label(self, arg0: cell_local_label) -> None: ... - + def label(self, arg0: cell_local_label) -> None: + ... class cell_kind: """ Enumeration used to identify the cell kind, used by the model to group equal kinds in the same cell group. - + Members: - + benchmark : Proxy cell used for benchmarking. - + cable : A cell with morphology described by branching 1D cable segments. - + lif : Leaky-integrate and fire neuron. - + spike_source : Proxy cell that generates spikes from a spike sequence provided by the user. """ - - __members__: typing.ClassVar[ - dict[str, cell_kind] - ] # value = {'benchmark': , 'cable': , 'lif': , 'spike_source': } + __members__: typing.ClassVar[dict[str, cell_kind]] # value = {'benchmark': , 'cable': , 'lif': , 'spike_source': } benchmark: typing.ClassVar[cell_kind] # value = cable: typing.ClassVar[cell_kind] # value = lif: typing.ClassVar[cell_kind] # value = spike_source: typing.ClassVar[cell_kind] # value = - def __eq__(self, other: typing.Any) -> bool: ... - def __getstate__(self) -> int: ... - def __hash__(self) -> int: ... - def __index__(self) -> int: ... - def __init__(self, value: int) -> None: ... - def __int__(self) -> int: ... - def __ne__(self, other: typing.Any) -> bool: ... - def __repr__(self) -> str: ... - def __setstate__(self, state: int) -> None: ... - def __str__(self) -> str: ... - @property - def name(self) -> str: ... - @property - def value(self) -> int: ... - + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: int) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: int) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... class cell_local_label: """ For local identification of an item. - + cell_local_label identifies: (1) a labeled group of one or more items on one or more locations on the cell. (2) a policy for selecting one of the items. """ - @typing.overload def __init__(self, label: str) -> None: """ Construct a cell_local_label identifier from a label argument identifying a group of one or more items on a cell. The default round_robin policy is used for selecting one of possibly multiple items associated with the label. """ - @typing.overload def __init__(self, label: str, policy: selection_policy) -> None: """ @@ -673,7 +575,6 @@ class cell_local_label: label: The identifier of a group of one or more items on a cell. policy: The policy for selecting one of possibly multiple items associated with the label. """ - @typing.overload def __init__(self, arg0: tuple) -> None: """ @@ -681,35 +582,34 @@ class cell_local_label: label: The identifier of a group of one or more items on a cell. policy: The policy for selecting one of possibly multiple items associated with the label. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def label(self) -> str: """ The identifier of a a group of one or more items on a cell. """ - @label.setter - def label(self, arg0: str) -> None: ... + def label(self, arg0: str) -> None: + ... @property def policy(self) -> selection_policy: """ The policy for selecting one of possibly multiple items associated with the label. """ - @policy.setter - def policy(self, arg0: selection_policy) -> None: ... - + def policy(self, arg0: selection_policy) -> None: + ... class cell_member: """ For global identification of a cell-local item. - + Items of cell_member must: (1) be associated with a unique cell, identified by the member gid; (2) identify an item within a cell-local collection by the member index. """ - @typing.overload def __init__(self, gid: int, index: int) -> None: """ @@ -717,7 +617,6 @@ class cell_member: gid: The global identifier of the cell. index: The cell-local index of the item. """ - @typing.overload def __init__(self, arg0: tuple) -> None: """ @@ -725,49 +624,41 @@ class cell_member: gid: The global identifier of the cell. index: The cell-local index of the item. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def gid(self) -> int: """ The global identifier of the cell. """ - @gid.setter - def gid(self, arg0: int) -> None: ... + def gid(self, arg0: int) -> None: + ... @property def index(self) -> int: """ Cell-local index of the item. """ - @index.setter - def index(self, arg0: int) -> None: ... - + def index(self, arg0: int) -> None: + ... class component_meta_data: @property def version(self) -> str: """ cable-cell component version. """ - @version.setter - def version(self, arg0: str) -> None: ... - + def version(self, arg0: str) -> None: + ... class connection: """ Describes a connection between two cells: Defined by source and destination end points (that is pre-synaptic and post-synaptic respectively), a connection weight and a delay time. """ - - def __init__( - self, - source: cell_global_label, - dest: cell_local_label, - weight: float, - delay: units.quantity, - ) -> None: + def __init__(self, source: cell_global_label, dest: cell_local_label, weight: float, delay: units.quantity) -> None: """ Construct a connection with arguments: source: The source end point of the connection. @@ -775,64 +666,53 @@ class connection: weight: The weight delivered to the target synapse (unit defined by the type of synapse target). delay: The delay of the connection [ms]. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def delay(self) -> float: """ The delay time of the connection [ms]. """ - @delay.setter - def delay(self, arg0: float) -> None: ... + def delay(self, arg0: float) -> None: + ... @property def dest(self) -> cell_local_label: """ The destination label of the connection. """ - @dest.setter - def dest(self, arg0: cell_local_label) -> None: ... + def dest(self, arg0: cell_local_label) -> None: + ... @property def source(self) -> cell_global_label: """ The source gid and label of the connection. """ - @source.setter - def source(self, arg0: cell_global_label) -> None: ... + def source(self, arg0: cell_global_label) -> None: + ... @property def weight(self) -> float: """ The weight of the connection. """ - @weight.setter - def weight(self, arg0: float) -> None: ... - + def weight(self, arg0: float) -> None: + ... class context: """ An opaque handle for the hardware resources used in a simulation. """ - @typing.overload def __init__(self) -> None: """ Construct a local context with proc_allocation = env.default_allocation(). """ - @typing.overload - def __init__( - self, - *, - threads: int = 1, - gpu_id: typing.Any = None, - mpi: typing.Any = None, - inter: typing.Any = None, - bind_procs: bool = False, - bind_threads: bool = False, - ) -> None: + def __init__(self, *, threads: int = 1, gpu_id: typing.Any = None, mpi: typing.Any = None, inter: typing.Any = None, bind_procs: bool = False, bind_threads: bool = False) -> None: """ Construct a context with arguments: threads: The number of threads available locally for execution. Must be set to 1 at minimum. 1 by default. @@ -842,141 +722,106 @@ class context: bind_procs: Create process binding mask. bind_threads: Create thread binding mask. """ - @typing.overload - def __init__( - self, - alloc: proc_allocation, - *, - mpi: typing.Any = None, - inter: typing.Any = None, - ) -> None: + def __init__(self, alloc: proc_allocation, *, mpi: typing.Any = None, inter: typing.Any = None) -> None: """ Construct a context with arguments: alloc: The computational resources to be used for the simulation. mpi: The MPI communicator, None by default. Only available if arbor.__config__['mpi']==True. inter: An MPI intercommunicator used to connect to external simulations, None by default. Only available if arbor.__config__['mpi']==True. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def has_gpu(self) -> bool: """ Whether the context has a GPU. """ - @property def has_mpi(self) -> bool: """ Whether the context uses MPI for distributed communication. """ - @property def rank(self) -> int: """ The numeric id of the local domain (equivalent to MPI rank). """ - @property def ranks(self) -> int: """ The number of distributed domains (equivalent to the number of MPI ranks). """ - @property def threads(self) -> int: """ The number of threads in the context's thread pool. """ - class cv_policy: """ Describes the rules used to discretize (compartmentalise) a cable cell morphology. """ - - def __add__(self, arg0: cv_policy) -> cv_policy: ... + def __add__(self, arg0: cv_policy) -> cv_policy: + ... def __init__(self, expression: str) -> None: """ A valid CV policy expression """ - - def __or__(self, arg0: cv_policy) -> cv_policy: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __or__(self, arg0: cv_policy) -> cv_policy: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def domain(self) -> str: """ The domain on which the policy is applied. """ - class decor: """ Description of the decorations to be applied to a cable cell, that is the painted, placed and defaulted properties, mecahanisms, ion species etc. """ - - @typing.overload - def __init__(self) -> None: ... - @typing.overload - def __init__(self, arg0: decor) -> None: ... - def defaults( - self, - ) -> list[ - membrane_potential - | axial_resistivity - | temperature - | membrane_capacitance - | ion_diffusivity - | int_concentration - | ext_concentration - | reversal_potential - | reversal_potential_method - | cv_policy - ]: + @typing.overload + def __init__(self) -> None: + ... + @typing.overload + def __init__(self, arg0: decor) -> None: + ... + def defaults(self) -> list[membrane_potential | axial_resistivity | temperature | membrane_capacitance | ion_diffusivity | int_concentration | ext_concentration | reversal_potential | reversal_potential_method | cv_policy]: """ Return a view of all defaults. """ - @typing.overload def discretization(self, policy: cv_policy) -> decor: """ A cv_policy used to discretise the cell into compartments for simulation """ - @typing.overload def discretization(self, policy: str) -> decor: """ An s-expression string representing a cv_policy used to discretise the cell into compartments for simulation """ - @typing.overload def paint(self, region: str, mechanism: density) -> decor: """ Associate a density mechanism with a region. """ - @typing.overload def paint(self, region: str, mechanism: voltage_process) -> decor: """ Associate a voltage process mechanism with a region. """ - @typing.overload def paint(self, region: str, mechanism: scaled_mechanism) -> None: """ Associate a scaled density mechanism with a region. """ - @typing.overload - def paint( - self, - region: str, - Vm: units.quantity | tuple[units.quantity, str] | None = None, - cm: units.quantity | tuple[units.quantity, str] | None = None, - rL: units.quantity | tuple[units.quantity, str] | None = None, - tempK: units.quantity | tuple[units.quantity, str] | None = None, - ) -> decor: + def paint(self, region: str, Vm: units.quantity | tuple[units.quantity, str] | None = None, cm: units.quantity | tuple[units.quantity, str] | None = None, rL: units.quantity | tuple[units.quantity, str] | None = None, tempK: units.quantity | tuple[units.quantity, str] | None = None) -> decor: """ Set cable properties on a region. Set global default values for cable and cell properties. @@ -986,18 +831,8 @@ class decor: * tempK: temperature [Kelvin]. Each value can be given as a plain quantity or a tuple of (quantity, 'scale') where scale is an iexpr. """ - @typing.overload - def paint( - self, - region: str, - *, - ion: str, - int_con: units.quantity | tuple[units.quantity, str] | None = None, - ext_con: units.quantity | tuple[units.quantity, str] | None = None, - rev_pot: units.quantity | tuple[units.quantity, str] | None = None, - diff: units.quantity | tuple[units.quantity, str] | None = None, - ) -> decor: + def paint(self, region: str, *, ion: str, int_con: units.quantity | tuple[units.quantity, str] | None = None, ext_con: units.quantity | tuple[units.quantity, str] | None = None, rev_pot: units.quantity | tuple[units.quantity, str] | None = None, diff: units.quantity | tuple[units.quantity, str] | None = None) -> decor: """ Set ion species properties conditions on a region. * int_con: initial internal concentration [mM]. @@ -1007,69 +842,35 @@ class decor: * diff: diffusivity [m^2/s]. Each value can be given as a plain quantity or a tuple of (quantity, 'scale') where scale is an iexpr. """ - - def paintings( - self, - ) -> list[ - tuple[ - str, - membrane_potential - | axial_resistivity - | temperature - | membrane_capacitance - | ion_diffusivity - | int_concentration - | ext_concentration - | reversal_potential - | density - | voltage_process - | scaled_mechanism, - ] - ]: + def paintings(self) -> list[tuple[str, membrane_potential | axial_resistivity | temperature | membrane_capacitance | ion_diffusivity | int_concentration | ext_concentration | reversal_potential | density | voltage_process | scaled_mechanism]]: """ Return a view of all painted items. """ - @typing.overload def place(self, locations: str, synapse: synapse, label: str) -> decor: """ Place one instance of 'synapse' on each location in 'locations'.The group of synapses has the label 'label', used for forming connections between cells. """ - @typing.overload def place(self, locations: str, junction: junction, label: str) -> decor: """ Place one instance of 'junction' on each location in 'locations'.The group of junctions has the label 'label', used for forming gap-junction connections between cells. """ - @typing.overload def place(self, locations: str, iclamp: iclamp, label: str) -> decor: """ Add a current stimulus at each location in locations.The group of current stimuli has the label 'label'. """ - @typing.overload def place(self, locations: str, detector: threshold_detector, label: str) -> decor: """ Add a voltage spike detector at each location in locations.The group of spike detectors has the label 'label', used for forming connections between cells. """ - - def placements( - self, - ) -> list[tuple[str, iclamp | threshold_detector | synapse | junction, str]]: + def placements(self) -> list[tuple[str, iclamp | threshold_detector | synapse | junction, str]]: """ Return a view of all placed items. """ - - def set_ion( - self, - ion: str, - int_con: units.quantity | None = None, - ext_con: units.quantity | None = None, - rev_pot: units.quantity | None = None, - method: typing.Any = None, - diff: units.quantity | None = None, - ) -> decor: + def set_ion(self, ion: str, int_con: units.quantity | None = None, ext_con: units.quantity | None = None, rev_pot: units.quantity | None = None, method: typing.Any = None, diff: units.quantity | None = None) -> decor: """ Set the cell-level properties of ion species named 'ion'. * int_con: initial internal concentration [mM]. @@ -1086,14 +887,7 @@ class decor: reversal potential is global for all compartments in the cell, and can't be overriden locally. """ - - def set_property( - self, - Vm: units.quantity | None = None, - cm: units.quantity | None = None, - rL: units.quantity | None = None, - tempK: units.quantity | None = None, - ) -> decor: + def set_property(self, Vm: units.quantity | None = None, cm: units.quantity | None = None, rL: units.quantity | None = None, tempK: units.quantity | None = None) -> decor: """ Set default values for cable and cell properties: * Vm: initial membrane voltage [mV]. @@ -1102,372 +896,331 @@ class decor: * tempK: temperature [Kelvin]. These values can be overridden on specific regions using the paint interface. """ - class density: """ For painting a density mechanism on a region. """ - @typing.overload - def __init__(self, arg0: str) -> None: ... + def __init__(self, arg0: str) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism) -> None: ... + def __init__(self, arg0: mechanism) -> None: + ... @typing.overload - def __init__(self, arg0: str, arg1: dict[str, float]) -> None: ... + def __init__(self, arg0: str, arg1: dict[str, float]) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: ... + def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: + ... @typing.overload - def __init__(self, arg0: str, **kwargs) -> None: ... + def __init__(self, arg0: str, **kwargs) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism, **kwargs) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self, arg0: mechanism, **kwargs) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def mech(self) -> mechanism: """ The underlying mechanism. """ - class domain_decomposition: """ The domain decomposition is responsible for describing the distribution of cells across cell groups and domains. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def gid_domain(self, gid: int) -> int: """ Query the domain id that a cell assigned to (using global identifier gid). """ - @property def domain_id(self) -> int: """ The index of the local domain. Always 0 for non-distributed models, and corresponds to the MPI rank for distributed runs. """ - @property def groups(self) -> list[group_description]: """ Descriptions of the cell groups on the local domain. """ - @property def num_domains(self) -> int: """ Number of domains that the model is distributed over. """ - @property def num_global_cells(self) -> int: """ Total number of cells in the global model (sum of num_local_cells over all domains). """ - @property def num_groups(self) -> int: """ Total number of cell groups in the local domain. """ - @property def num_local_cells(self) -> int: """ Total number of cells in the local domain. """ - class event_generator: - def __init__( - self, target: cell_local_label, weight: float, sched: schedule_base - ) -> None: + def __init__(self, target: cell_local_label, weight: float, sched: schedule_base) -> None: """ Construct an event generator with arguments: target: The target synapse label and selection policy. weight: The weight of events to deliver. sched: A schedule of the events. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def target(self) -> cell_local_label: """ The target synapse (gid, local_id). """ - @target.setter - def target(self, arg0: cell_local_label) -> None: ... + def target(self, arg0: cell_local_label) -> None: + ... @property def weight(self) -> float: """ The weight of events to deliver. """ - @weight.setter - def weight(self, arg0: float) -> None: ... - + def weight(self, arg0: float) -> None: + ... class explicit_schedule(schedule_base): """ Describes an explicit schedule at a predetermined (sorted) sequence of times. """ - @typing.overload def __init__(self) -> None: """ Construct an empty explicit schedule. """ - @typing.overload def __init__(self, times: list[units.quantity]) -> None: """ Construct an explicit schedule with argument: times: A list of times [ms], [] by default. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def events(self, arg0: float, arg1: float) -> list[float]: """ A view of monotonically increasing time values in the half-open interval [t0, t1) in [ms]. """ - @property def times_ms(self) -> list[float]: """ A list of times [ms]. """ - @times_ms.setter - def times_ms(self, arg1: list[float]) -> None: ... - + def times_ms(self, arg1: list[float]) -> None: + ... class ext_concentration: """ Setting the initial external ion concentration. """ - - def __init__(self, arg0: str, arg1: units.quantity) -> None: ... - def __repr__(self) -> str: ... - + def __init__(self, arg0: str, arg1: units.quantity) -> None: + ... + def __repr__(self) -> str: + ... class extent: """ A potentially empty region on a morphology. """ - class gap_junction_connection: """ Describes a gap junction between two gap junction sites. """ - - def __init__( - self, peer: cell_global_label, local: cell_local_label, weight: float - ) -> None: + def __init__(self, peer: cell_global_label, local: cell_local_label, weight: float) -> None: """ Construct a gap junction connection with arguments: peer: remote half of the gap junction connection. local: local half of the gap junction connection. weight: Gap junction connection weight [unit-less]. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def local(self) -> cell_local_label: """ Local label of the gap junction connection. """ - @local.setter - def local(self, arg0: cell_local_label) -> None: ... + def local(self, arg0: cell_local_label) -> None: + ... @property def peer(self) -> cell_global_label: """ Remote gid and label of the gap junction connection. """ - @peer.setter - def peer(self, arg0: cell_global_label) -> None: ... + def peer(self, arg0: cell_global_label) -> None: + ... @property def weight(self) -> float: """ Gap junction connection weight [unit-less]. """ - @weight.setter - def weight(self, arg0: float) -> None: ... - + def weight(self, arg0: float) -> None: + ... class group_description: """ The indexes of a set of cells of the same kind that are grouped together in a cell group. """ - def __init__(self, kind: cell_kind, gids: list[int], backend: backend) -> None: """ Construct a group description with cell kind, list of gids, and backend kind. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def backend(self) -> backend: """ The hardware backend on which the cell group will run. """ - @property def gids(self) -> list[int]: """ The list of gids of the cells in the group. """ - @property def kind(self) -> cell_kind: """ The type of cell in the cell group. """ - class iclamp: """ A current clamp for injecting a DC or fixed frequency current governed by a piecewise linear envelope. """ - @typing.overload - def __init__( - self, - tstart: units.quantity, - duration: units.quantity, - current: units.quantity, - *, - frequency: units.quantity = ..., - phase: units.quantity = ..., - ) -> None: + def __init__(self, tstart: units.quantity, duration: units.quantity, current: units.quantity, *, frequency: units.quantity = ..., phase: units.quantity = ...) -> None: """ Construct finite duration current clamp, constant amplitude """ - @typing.overload - def __init__( - self, - current: units.quantity, - *, - frequency: units.quantity = ..., - phase: units.quantity = ..., - ) -> None: + def __init__(self, current: units.quantity, *, frequency: units.quantity = ..., phase: units.quantity = ...) -> None: """ Construct constant amplitude current clamp """ - @typing.overload - def __init__( - self, - envelope: list[tuple[units.quantity, units.quantity]], - *, - frequency: units.quantity = ..., - phase: units.quantity = ..., - ) -> None: + def __init__(self, envelope: list[tuple[units.quantity, units.quantity]], *, frequency: units.quantity = ..., phase: units.quantity = ...) -> None: """ Construct current clamp according to (time, amplitude) linear envelope """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def envelope(self) -> list[tuple[float, float]]: """ List of (time [ms], amplitude [nA]) points comprising the piecewise linear envelope """ - @property def frequency(self) -> float: """ Oscillation frequency (kHz), zero implies DC stimulus. """ - @property def phase(self) -> float: """ Oscillation initial phase (rad) """ - class int_concentration: """ Setting the initial internal ion concentration. """ - - def __init__(self, arg0: str, arg1: units.quantity) -> None: ... - def __repr__(self) -> str: ... - + def __init__(self, arg0: str, arg1: units.quantity) -> None: + ... + def __repr__(self) -> str: + ... class ion_data: @property def charge(self) -> int: """ Valence. """ - @property def diffusivity(self) -> float | None: """ Diffusivity. """ - @property def external_concentration(self) -> float | None: """ External concentration. """ - @property def internal_concentration(self) -> float | None: """ Internal concentration. """ - @property def reversal_concentration(self) -> float | None: """ Reversal potential. """ - @property def reversal_potential(self) -> float | None: """ Reversal potential. """ - @property def reversal_potential_method(self) -> str: """ Reversal potential method. """ - class ion_dependency: """ Information about a mechanism's dependence on an ion species. """ - - def __init__(self, arg0: ion_dependency) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self, arg0: ion_dependency) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property - def read_rev_pot(self) -> bool: ... + def read_rev_pot(self) -> bool: + ... @property - def write_ext_con(self) -> bool: ... + def write_ext_con(self) -> bool: + ... @property - def write_int_con(self) -> bool: ... + def write_int_con(self) -> bool: + ... @property - def write_rev_pot(self) -> bool: ... - + def write_rev_pot(self) -> bool: + ... class ion_diffusivity: """ Setting the ion diffusivity. """ - - def __init__(self, arg0: str, arg1: units.quantity) -> None: ... - def __repr__(self) -> str: ... - + def __init__(self, arg0: str, arg1: units.quantity) -> None: + ... + def __repr__(self) -> str: + ... class ion_settings: pass - class isometry: @staticmethod @typing.overload @@ -1475,122 +1228,121 @@ class isometry: """ Construct a rotation isometry of angle theta about the axis in direction (x, y, z). """ - @staticmethod @typing.overload def rotate(theta: float, axis: tuple) -> isometry: """ Construct a rotation isometry of angle theta about the given axis in the direction described by a tuple. """ - @staticmethod @typing.overload def translate(x: float, y: float, z: float) -> isometry: """ Construct a translation isometry from displacements x, y, and z. """ - @staticmethod @typing.overload def translate(arg0: tuple) -> isometry: """ Construct a translation isometry from the first three components of a tuple. """ - @staticmethod @typing.overload def translate(arg0: mpoint) -> isometry: """ Construct a translation isometry from the x, y, and z components of an mpoint. """ - @typing.overload def __call__(self, arg0: mpoint) -> mpoint: """ Apply isometry to mpoint argument. """ - @typing.overload def __call__(self, arg0: tuple) -> tuple: """ Apply isometry to first three components of tuple argument. """ - def __init__(self) -> None: """ Construct a trivial isometry. """ - - def __mul__(self, arg0: isometry) -> isometry: ... - + def __mul__(self, arg0: isometry) -> isometry: + ... class junction: """ For placing a gap-junction mechanism on a locset. """ - @typing.overload - def __init__(self, arg0: str) -> None: ... + def __init__(self, arg0: str) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism) -> None: ... + def __init__(self, arg0: mechanism) -> None: + ... @typing.overload - def __init__(self, arg0: str, arg1: dict[str, float]) -> None: ... + def __init__(self, arg0: str, arg1: dict[str, float]) -> None: + ... @typing.overload - def __init__(self, arg0: str, **kwargs) -> None: ... + def __init__(self, arg0: str, **kwargs) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: ... + def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism, **kwargs) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self, arg0: mechanism, **kwargs) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def mech(self) -> mechanism: """ The underlying mechanism. """ - class label_dict: """ A dictionary of labelled region and locset definitions, with a unique label assigned to each definition. """ - @staticmethod def append(*args, **kwargs) -> None: """ Import the entries of a another label dictionary with an optional prefix. """ - - def __contains__(self, arg0: str) -> bool: ... - def __getitem__(self, arg0: str) -> str: ... + def __contains__(self, arg0: str) -> bool: + ... + def __getitem__(self, arg0: str) -> str: + ... @typing.overload def __init__(self) -> None: """ Create an empty label dictionary. """ - @typing.overload def __init__(self, arg0: dict[str, str]) -> None: """ Initialize a label dictionary from a dictionary with string labels as keys, and corresponding definitions as strings. """ - @typing.overload def __init__(self, arg0: label_dict) -> None: """ Initialize a label dictionary from another one """ - @typing.overload def __init__(self, arg0: typing.Iterator) -> None: """ Initialize a label dictionary from an iterable of key, definition pairs """ - - def __iter__(self) -> typing.Iterator: ... - def __len__(self) -> int: ... - def __repr__(self) -> str: ... - def __setitem__(self, arg0: str, arg1: str) -> None: ... - def __str__(self) -> str: ... + def __iter__(self) -> typing.Iterator: + ... + def __len__(self) -> int: + ... + def __repr__(self) -> str: + ... + def __setitem__(self, arg0: str, arg1: str) -> None: + ... + def __str__(self) -> str: + ... def add_swc_tags(self) -> label_dict: """ Add standard SWC tagged regions. @@ -1599,44 +1351,31 @@ class label_dict: - dend: (tag 3) - apic: (tag 4) """ - - def items(self) -> typing.Iterator: ... - def keys(self) -> typing.Iterator: ... + def items(self) -> typing.Iterator: + ... + def keys(self) -> typing.Iterator: + ... def update(self, other: label_dict) -> None: """ The label_dict to be importedImport the entries of a another label dictionary. """ - - def values(self) -> typing.Iterator: ... + def values(self) -> typing.Iterator: + ... @property def locsets(self) -> list[str]: """ The locset definitions. """ - @property def regions(self) -> list[str]: """ The region definitions. """ - class lif_cell: """ A leaky integrate-and-fire cell. """ - - def __init__( - self, - source_label: str, - target_label: str, - *, - tau_m: units.quantity | None = None, - V_th: units.quantity | None = None, - C_m: units.quantity | None = None, - E_L: units.quantity | None = None, - V_m: units.quantity | None = None, - t_ref: units.quantity | None = None, - ) -> None: + def __init__(self, source_label: str, target_label: str, *, tau_m: units.quantity | None = None, V_th: units.quantity | None = None, C_m: units.quantity | None = None, E_L: units.quantity | None = None, V_m: units.quantity | None = None, t_ref: units.quantity | None = None) -> None: """ Construct a lif cell with one source labeled 'source_label', and one target labeled 'target_label'.Can optionally take physical parameters: * tau_m: Membrane potential decaying constant [ms]. @@ -1646,122 +1385,143 @@ class lif_cell: * V_m: Initial value of the Membrane potential [mV]. * t_ref: Refractory period [ms]. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def C_m(self) -> units.quantity: """ Membrane capacitance [pF]. """ - @C_m.setter - def C_m(self, arg0: units.quantity) -> None: ... + def C_m(self, arg0: units.quantity) -> None: + ... @property def E_L(self) -> units.quantity: """ Resting potential [mV]. """ - @E_L.setter - def E_L(self, arg0: units.quantity) -> None: ... + def E_L(self, arg0: units.quantity) -> None: + ... @property def E_R(self) -> units.quantity: """ Reset potential [mV]. """ - @E_R.setter - def E_R(self, arg0: units.quantity) -> None: ... + def E_R(self, arg0: units.quantity) -> None: + ... @property def V_m(self) -> units.quantity: """ Initial value of the Membrane potential [mV]. """ - @V_m.setter - def V_m(self, arg0: units.quantity) -> None: ... + def V_m(self, arg0: units.quantity) -> None: + ... @property def V_th(self) -> units.quantity: """ Firing threshold [mV]. """ - @V_th.setter - def V_th(self, arg0: units.quantity) -> None: ... + def V_th(self, arg0: units.quantity) -> None: + ... @property def source(self) -> str: """ Label of the single build-in source on the cell. """ - @source.setter - def source(self, arg0: str) -> None: ... + def source(self, arg0: str) -> None: + ... @property def t_ref(self) -> units.quantity: """ Refractory period [ms]. """ - @t_ref.setter - def t_ref(self, arg0: units.quantity) -> None: ... + def t_ref(self, arg0: units.quantity) -> None: + ... @property def target(self) -> str: """ Label of the single build-in target on the cell. """ - @target.setter - def target(self, arg0: str) -> None: ... + def target(self, arg0: str) -> None: + ... @property def tau_m(self) -> units.quantity: """ Membrane potential decaying constant [ms]. """ - @tau_m.setter - def tau_m(self, arg0: units.quantity) -> None: ... - + def tau_m(self, arg0: units.quantity) -> None: + ... class lif_probe_metadata: """ Probe metadata associated with a LIF cell probe. """ - +class loaded_morphology: + """ + The morphology and label dictionary meta-data loaded from file. + """ + @property + def labels(self) -> label_dict: + """ + Any labels defined by the loaded file. + """ + @property + def metadata(self) -> swc_metadata | asc_metadata | nml_metadata: + """ + File type specific metadata. + """ + @property + def morphology(self) -> morphology: + """ + The cable cell morphology. + """ + @property + def segment_tree(self) -> segment_tree: + """ + The raw segment tree. + """ class location: """ A location on a cable cell. """ - __hash__: typing.ClassVar[None] = None - def __eq__(self, arg0: location) -> bool: ... + def __eq__(self, arg0: location) -> bool: + ... def __init__(self, branch: int, pos: float) -> None: """ Construct a location specification holding: branch: The id of the branch. pos: The relative position (from 0., proximal, to 1., distal) on the branch. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def branch(self) -> int: """ The id of the branch. """ - @property def pos(self) -> float: """ The relative position on the branch (∈ [0.,1.], where 0. means proximal and 1. distal). """ - class mechanism: @typing.overload def __init__(self, name: str) -> None: """ The name of the mechanism """ - @typing.overload def __init__(self, name: str, params: dict[str, float]) -> None: """ @@ -1770,11 +1530,10 @@ class mechanism: will create parameters for the 'expsyn' mechanism, with the provided value for 'tau' overrides the default. If a parameter is not set, the default (as defined in NMODL) is used. - + Example overriding a global parameter: m = arbor.mechanism('nernst/R=8.3145,F=96485') """ - @typing.overload def __init__(self, name: str, **kwargs) -> None: """ @@ -1783,350 +1542,276 @@ class mechanism: will create parameters for the 'expsyn' mechanism, with the provided value for 'tau' overrides the default. If a parameter is not set, the default (as defined in NMODL) is used. - + Example overriding a global parameter: m = arbor.mechanism('nernst/R=8.3145,F=96485') """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def set(self, name: str, value: float) -> None: """ Set parameter value. """ - @property def name(self) -> str: """ The name of the mechanism. """ - @property def values(self) -> dict[str, float]: """ A dictionary of parameter values with parameter name as key. """ - class mechanism_field: """ Basic information about a mechanism field. """ - - def __init__(self, arg0: mechanism_field) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self, arg0: mechanism_field) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property - def default(self) -> float: ... + def default(self) -> float: + ... @property - def max(self) -> float: ... + def max(self) -> float: + ... @property - def min(self) -> float: ... + def min(self) -> float: + ... @property - def units(self) -> str: ... - + def units(self) -> str: + ... class mechanism_info: """ Meta data about a mechanism's fields and ion dependendencies. """ - - def __init__(self, arg0: mechanism_info) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self, arg0: mechanism_info) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def globals(self) -> dict[str, mechanism_field]: """ Global fields have one value common to an instance of a mechanism, are constant in time and set at instantiation. """ - @property def ions(self) -> dict[str, ion_dependency]: """ Ion dependencies. """ - @property def kind(self) -> str: """ String representation of the kind of the mechanism. """ - @property def linear(self) -> bool: """ True if a synapse mechanism has linear current contributions so that multiple instances on the same compartment can be coalesced. """ - @property def parameters(self) -> dict[str, mechanism_field]: """ Parameter fields may vary across the extent of a mechanism, but are constant in time and set at instantiation. """ - @property def post_events(self) -> bool: """ True if a synapse mechanism has a `POST_EVENT` procedure defined. """ - @property def state(self) -> dict[str, mechanism_field]: """ State fields vary in time and across the extent of a mechanism, and potentially can be sampled at run-time. """ - class membrane_capacitance: """ Setting the membrane capacitance. """ - - def __init__(self, arg0: units.quantity) -> None: ... - def __repr__(self) -> str: ... - + def __init__(self, arg0: units.quantity) -> None: + ... + def __repr__(self) -> str: + ... class membrane_potential: """ Setting the initial membrane voltage. """ - - def __init__(self, arg0: units.quantity) -> None: ... - def __repr__(self) -> str: ... - + def __init__(self, arg0: units.quantity) -> None: + ... + def __repr__(self) -> str: + ... class meter_manager: """ Manage metering by setting checkpoints and starting the timing region. """ - - def __init__(self) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def checkpoint(self, name: str, context: context) -> None: """ Create a new checkpoint. Records the time since the last checkpoint(or the call to start if no previous checkpoints exist),and restarts the timer for the next checkpoint. """ - def start(self, context: context) -> None: """ Start the metering. Records a time stamp, that marks the start of the first checkpoint timing region. """ - @property def checkpoint_names(self) -> list[str]: """ A list of all metering checkpoint names. """ - @property def times(self) -> list[float]: """ A list of all metering times. """ - class meter_report: """ Summarises the performance meter results, used to print a report to screen or file. If a distributed context is used, the report will contain a summary of results from all MPI ranks. """ - - def __init__(self, manager: meter_manager, context: context) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... - + def __init__(self, manager: meter_manager, context: context) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... class morphology: """ A cell morphology. """ - - def __init__(self, arg0: segment_tree) -> None: ... - def __str__(self) -> str: ... - def branch_children(self, i: int) -> list[int]: - """ - The child branches of branch i. - """ - - def branch_parent(self, i: int) -> int: - """ - The parent branch of branch i. - """ - - def branch_segments(self, i: int) -> list[msegment]: - """ - A list of the segments in branch i, ordered from proximal to distal ends of the branch. - """ - - def to_segment_tree(self) -> segment_tree: - """ - Convert this morphology to a segment_tree. - """ - - @property - def empty(self) -> bool: - """ - Whether the morphology is empty. - """ - - @property - def num_branches(self) -> int: - """ - The number of branches in the morphology. - """ - class morphology_provider: def __init__(self, morphology: morphology) -> None: """ Construct a morphology provider. """ - def reify_locset(self, arg0: str) -> list[location]: """ Turn a locset into a list of locations. """ - def reify_region(self, arg0: str) -> extent: """ Turn a region into an extent. """ - class mpoint: __hash__: typing.ClassVar[None] = None - def __eq__(self, arg0: mpoint) -> bool: ... + def __eq__(self, arg0: mpoint) -> bool: + ... @typing.overload def __init__(self, x: float, y: float, z: float, radius: float) -> None: """ Create an mpoint object from parameters x, y, z, and radius, specified in µm. """ - @typing.overload def __init__(self, arg0: tuple) -> None: """ Create an mpoint object from a tuple (x, y, z, radius), specified in µm. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def radius(self) -> float: """ Radius of cable at sample location centred at coordinates [μm]. """ - @property def x(self) -> float: """ X coordinate [μm]. """ - @property def y(self) -> float: """ Y coordinate [μm]. """ - @property def z(self) -> float: """ Z coordinate [μm]. """ - class msegment: @property def dist(self) -> mpoint: """ the location and radius of the distal end. """ - @property def prox(self) -> mpoint: """ the location and radius of the proximal end. """ - @property def tag(self) -> int: """ tag meta-data. """ - class neuroml: def __init__(self, arg0: typing.Any) -> None: """ Construct NML morphology from filename or stream. """ - def cell_ids(self) -> list[str]: """ Query top-level cells. """ - - def cell_morphology( - self, cell_id: str, allow_spherical_root: bool = False - ) -> neuroml_morph_data | None: + def cell_morphology(self, cell_id: str, allow_spherical_root: bool = False) -> loaded_morphology | None: """ Retrieve nml_morph_data associated with cell_id. """ - - def morphology( - self, morph_id: str, allow_spherical_root: bool = False - ) -> neuroml_morph_data | None: + def morphology(self, morph_id: str, allow_spherical_root: bool = False) -> loaded_morphology | None: """ Retrieve top-level nml_morph_data associated with morph_id. """ - def morphology_ids(self) -> list[str]: """ Query top-level standalone morphologies. """ - -class neuroml_morph_data: +class nml_metadata: def groups(self) -> label_dict: """ Label dictionary containing one region expression for each segmentGroup id. """ - def named_segments(self) -> label_dict: """ Label dictionary containing one region expression for each name applied to one or more segments. """ - def segments(self) -> label_dict: """ Label dictionary containing one region expression for each segment id. """ - @property def cell_id(self) -> str | None: """ Cell id, or empty if morphology was taken from a top-level element. """ - @property def group_segments(self) -> dict[str, list[int]]: """ Map from segmentGroup ids to their corresponding segment ids. """ - @property def id(self) -> str: """ Morphology id. """ - - @property - def morphology(self) -> morphology: - """ - Morphology constructed from a signle NeuroML element. - """ - class partition_hint: """ Provide a hint on how the cell groups should be partitioned. """ - max_size: typing.ClassVar[int] = 18446744073709551615 - def __init__( - self, - cpu_group_size: int = 1, - gpu_group_size: int = 18446744073709551615, - prefer_gpu: bool = True, - ) -> None: + def __init__(self, cpu_group_size: int = 1, gpu_group_size: int = 18446744073709551615, prefer_gpu: bool = True) -> None: """ Construct a partition hint with arguments: cpu_group_size: The size of cell group assigned to CPU, each cell in its own group by default. @@ -2135,78 +1820,64 @@ class partition_hint: Must be positive, else set to default value. prefer_gpu: Whether GPU is preferred, True by default. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def cpu_group_size(self) -> int: """ The size of cell group assigned to CPU. """ - @cpu_group_size.setter - def cpu_group_size(self, arg0: int) -> None: ... + def cpu_group_size(self, arg0: int) -> None: + ... @property def gpu_group_size(self) -> int: """ The size of cell group assigned to GPU. """ - @gpu_group_size.setter - def gpu_group_size(self, arg0: int) -> None: ... + def gpu_group_size(self, arg0: int) -> None: + ... @property def prefer_gpu(self) -> bool: """ Whether GPU usage is preferred. """ - @prefer_gpu.setter - def prefer_gpu(self, arg0: bool) -> None: ... - + def prefer_gpu(self, arg0: bool) -> None: + ... class place_pwlin: def __init__(self, morphology: morphology, isometry: isometry = ...) -> None: """ Construct a piecewise-linear placement object from the given morphology and optional isometry. """ - def all_at(self, location: location) -> list[mpoint]: """ Return list of all possible interpolated mpoints corresponding to the location argument. """ - def all_segments(self, arg0: list[cable]) -> list[msegment]: """ Return maximal list of non-overlapping full or partial msegments whose union is coterminous with the extent of the given list of cables. """ - def at(self, location: location) -> mpoint: """ Return an interpolated mpoint corresponding to the location argument. """ - def closest(self, arg0: float, arg1: float, arg2: float) -> tuple: """ Find the location on the morphology that is closest to a 3d point. Returns the location and its distance from the point. """ - def segments(self, arg0: list[cable]) -> list[msegment]: """ Return minimal list of full or partial msegments whose union is coterminous with the extent of the given list of cables. """ - class poisson_schedule(schedule_base): """ Describes a schedule according to a Poisson process within the interval [tstart, tstop). """ - - def __init__( - self, - freq: units.quantity, - *, - tstart: units.quantity = ..., - seed: int = 0, - tstop: units.quantity | None = None, - ) -> None: + def __init__(self, freq: units.quantity, *, tstart: units.quantity = ..., seed: int = 0, tstop: units.quantity | None = None) -> None: """ Construct a Poisson schedule with arguments: tstart: The delivery time of the first event in the sequence [ms], 0 by default. @@ -2214,64 +1885,56 @@ class poisson_schedule(schedule_base): seed: The seed for the random number generator, 0 by default. tstop: No events delivered after this time [ms], None by default. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def events(self, arg0: units.quantity, arg1: units.quantity) -> list[float]: """ A view of monotonically increasing time values in the half-open interval [t0, t1). """ - @property def freq(self) -> units.quantity: """ The expected frequency [kHz]. """ - @freq.setter - def freq(self, arg1: units.quantity) -> None: ... + def freq(self, arg1: units.quantity) -> None: + ... @property def seed(self) -> int: """ The seed for the random number generator. """ - @seed.setter - def seed(self, arg0: int) -> None: ... + def seed(self, arg0: int) -> None: + ... @property def tstart(self) -> units.quantity: """ The delivery time of the first event in the sequence [ms]. """ - @tstart.setter - def tstart(self, arg1: units.quantity) -> None: ... + def tstart(self, arg1: units.quantity) -> None: + ... @property def tstop(self) -> units.quantity: """ No events delivered after this time [ms]. """ - @tstop.setter - def tstop(self, arg1: units.quantity) -> None: ... - + def tstop(self, arg1: units.quantity) -> None: + ... class probe: - def __repr__(self) -> str: ... - def __str__(self) -> str: ... - + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... class proc_allocation: """ Enumerates the computational resources on a node to be used for simulation. """ - - def __init__( - self, - *, - threads: int = 1, - gpu_id: typing.Any = None, - bind_procs: bool = False, - bind_threads: bool = False, - ) -> None: + def __init__(self, *, threads: int = 1, gpu_id: typing.Any = None, bind_procs: bool = False, bind_threads: bool = False) -> None: """ Construct an allocation with arguments: threads: The number of threads available locally for execution. Must be set to 1 at minimum. 1 by default. @@ -2279,482 +1942,424 @@ class proc_allocation: bind_procs: Create process binding mask. bind_threads: Create thread binding mask. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def bind_procs(self) -> bool: """ Try to bind MPI procs? """ - @bind_procs.setter - def bind_procs(self, arg1: bool) -> None: ... + def bind_procs(self, arg1: bool) -> None: + ... @property def bind_threads(self) -> bool: """ Try to bind threads? """ - @bind_threads.setter - def bind_threads(self, arg1: bool) -> None: ... + def bind_threads(self, arg1: bool) -> None: + ... @property def gpu_id(self) -> int | None: """ The identifier of the GPU to use. Corresponds to the integer parameter used to identify GPUs in CUDA API calls. """ - @gpu_id.setter - def gpu_id(self, arg1: typing.Any) -> None: ... + def gpu_id(self, arg1: typing.Any) -> None: + ... @property def has_gpu(self) -> bool: """ Whether a GPU is being used (True/False). """ - @property def threads(self) -> int: """ The number of threads available locally for execution. """ - @threads.setter - def threads(self, arg1: int) -> None: ... - + def threads(self, arg1: int) -> None: + ... class recipe: """ A description of a model, describing the cells and the network via a cell-centric interface. """ - - def __init__(self) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def cell_description(self, gid: int) -> typing.Any: """ High level description of the cell with global identifier gid. """ - def cell_kind(self, gid: int) -> cell_kind: """ The kind of cell with global identifier gid. """ - def connections_on(self, gid: int) -> list[connection]: """ A list of all the incoming connections to gid, [] by default. """ - def event_generators(self, gid: int) -> list[typing.Any]: """ A list of all the event generators that are attached to gid, [] by default. """ - def external_connections_on(self, gid: int) -> list[connection]: """ A list of all the incoming connections from _remote_ locations to gid, [] by default. """ - def gap_junctions_on(self, gid: int) -> list[gap_junction_connection]: """ A list of the gap junctions connected to gid, [] by default. """ - def global_properties(self, kind: cell_kind) -> typing.Any: """ The default properties applied to all cells of type 'kind' in the model. """ - def num_cells(self) -> int: """ The number of cells in the model. """ - def probes(self, gid: int) -> list[probe]: """ The probes to allow monitoring. """ - class regular_schedule(schedule_base): """ Describes a regular schedule with multiples of dt within the interval [tstart, tstop). """ - @typing.overload - def __init__( - self, - tstart: units.quantity, - dt: units.quantity, - tstop: units.quantity | None = None, - ) -> None: + def __init__(self, tstart: units.quantity, dt: units.quantity, tstop: units.quantity | None = None) -> None: """ Construct a regular schedule with arguments: tstart: The delivery time of the first event in the sequence [ms]. dt: The interval between time points [ms]. tstop: No events delivered after this time [ms], None by default. """ - @typing.overload def __init__(self, dt: units.quantity) -> None: """ Construct a regular schedule, starting from t = 0 and never terminating, with arguments: dt: The interval between time points [ms]. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def events(self, arg0: float, arg1: float) -> list[float]: """ A view of monotonically increasing time values in the half-open interval [t0, t1). """ - @property def dt(self) -> units.quantity: """ The interval between time points [ms]. """ - @dt.setter - def dt(self, arg1: units.quantity) -> None: ... + def dt(self, arg1: units.quantity) -> None: + ... @property def tstart(self) -> units.quantity: """ The delivery time of the first event in the sequence [ms]. """ - @tstart.setter - def tstart(self, arg1: units.quantity) -> None: ... + def tstart(self, arg1: units.quantity) -> None: + ... @property def tstop(self) -> units.quantity | None: """ No events delivered after this time [ms]. """ - @tstop.setter - def tstop(self, arg1: units.quantity | None) -> None: ... - + def tstop(self, arg1: units.quantity | None) -> None: + ... class reversal_potential: """ Setting the initial reversal potential. """ - - def __init__(self, arg0: str, arg1: units.quantity) -> None: ... - def __repr__(self) -> str: ... - + def __init__(self, arg0: str, arg1: units.quantity) -> None: + ... + def __repr__(self) -> str: + ... class reversal_potential_method: """ Describes the mechanism used to compute eX for ion X. """ - - def __init__(self, arg0: str, arg1: mechanism) -> None: ... - def __repr__(self) -> str: ... - + def __init__(self, arg0: str, arg1: mechanism) -> None: + ... + def __repr__(self) -> str: + ... class scaled_mechanism: """ For painting a scaled density mechanism on a region. """ - @typing.overload - def __init__(self, arg0: density) -> None: ... + def __init__(self, arg0: density) -> None: + ... @typing.overload - def __init__(self, arg0: density, arg1: dict[str, str]) -> None: ... + def __init__(self, arg0: density, arg1: dict[str, str]) -> None: + ... @typing.overload - def __init__(self, arg0: density, **kwargs) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self, arg0: density, **kwargs) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def scale(self, name: str, ex: str) -> scaled_mechanism: """ Add a scaling expression to a parameter. """ - class schedule_base: """ Schedule abstract base class. """ - class segment_tree: - def __init__(self) -> None: ... - def __str__(self) -> str: ... + def __init__(self) -> None: + ... + def __str__(self) -> str: + ... @typing.overload def append(self, parent: int, prox: mpoint, dist: mpoint, tag: int) -> int: """ Append a segment to the tree. """ - @typing.overload def append(self, parent: int, dist: mpoint, tag: int) -> int: """ Append a segment to the tree. """ - @typing.overload - def append( - self, parent: int, x: float, y: float, z: float, radius: float, tag: int - ) -> int: + def append(self, parent: int, x: float, y: float, z: float, radius: float, tag: int) -> int: """ Append a segment to the tree, using the distal location of the parent segment as the proximal end. """ - def apply_isometry(self, arg0: isometry) -> segment_tree: """ Apply an isometry to all segments in the tree. """ - def equivalent(self, arg0: segment_tree) -> bool: """ Two trees are equivalent, but not neccessarily identical, ie they have the same segments and structure. """ - def is_fork(self, i: int) -> bool: """ True if segment has more than one child. """ - def is_root(self, i: int) -> bool: """ True if segment has no parent. """ - def is_terminal(self, i: int) -> bool: """ True if segment has no children. """ - def join_at(self, arg0: int, arg1: segment_tree) -> segment_tree: """ Join two subtrees at a given id, such that said id becomes the parent of the inserted sub-tree. """ - - def reserve(self, arg0: int) -> None: ... + def reserve(self, arg0: int) -> None: + ... def split_at(self, arg0: int) -> tuple[segment_tree, segment_tree]: """ Split into a pair of trees at the given id, such that one tree is the subtree rooted at id and the other is the original tree without said subtree. """ - def tag_roots(self, arg0: int) -> list[int]: """ Get roots of tag region of this segment tree. """ - @property def empty(self) -> bool: """ Indicates whether the tree is empty (i.e. whether it has size 0) """ - @property def parents(self) -> list[int]: """ A list with the parent index of each segment. """ - @property def segments(self) -> list[msegment]: """ A list of the segments. """ - @property def size(self) -> int: """ The number of segments in the tree. """ - class selection_policy: """ Enumeration used to identify a selection policy, used by the model for selecting one of possibly multiple locations on the cell associated with a labeled item. - + Members: - + round_robin : Iterate round-robin over all possible locations. - + round_robin_halt : Halts at the current location until the round_robin policy is called (again). - + univalent : Assert that there is only one possible location associated with a labeled item on the cell. The model throws an exception if the assertion fails. """ - - __members__: typing.ClassVar[ - dict[str, selection_policy] - ] # value = {'round_robin': , 'round_robin_halt': , 'univalent': } - round_robin: typing.ClassVar[ - selection_policy - ] # value = - round_robin_halt: typing.ClassVar[ - selection_policy - ] # value = - univalent: typing.ClassVar[ - selection_policy - ] # value = - def __eq__(self, other: typing.Any) -> bool: ... - def __getstate__(self) -> int: ... - def __hash__(self) -> int: ... - def __index__(self) -> int: ... - def __init__(self, value: int) -> None: ... - def __int__(self) -> int: ... - def __ne__(self, other: typing.Any) -> bool: ... - def __repr__(self) -> str: ... - def __setstate__(self, state: int) -> None: ... - def __str__(self) -> str: ... - @property - def name(self) -> str: ... - @property - def value(self) -> int: ... - + __members__: typing.ClassVar[dict[str, selection_policy]] # value = {'round_robin': , 'round_robin_halt': , 'univalent': } + round_robin: typing.ClassVar[selection_policy] # value = + round_robin_halt: typing.ClassVar[selection_policy] # value = + univalent: typing.ClassVar[selection_policy] # value = + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: int) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: int) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... class simulation: """ The executable form of a model. A simulation is constructed from a recipe, and then used to update and monitor model state. """ - @staticmethod - def deserialize(*args, **kwargs) -> None: ... - def __init__( - self, - recipe: recipe, - context: context | None = None, - domains: domain_decomposition | None = None, - seed: int = 0, - ) -> None: + def deserialize(*args, **kwargs) -> None: + ... + def __init__(self, recipe: recipe, context: context | None = None, domains: domain_decomposition | None = None, seed: int = 0) -> None: """ Initialize the model described by a recipe, with cells and network distributed according to the domain decomposition and computational resources described by a context. Initialize PRNG using seed """ - def clear_samplers(self) -> None: """ Clearing spike and sample information. restoring memory """ - @typing.overload def probe_metadata(self, probeset_id: cell_address) -> list: """ Retrieve metadata associated with given probe id. """ - @typing.overload def probe_metadata(self, addr: tuple[int, str]) -> list: """ Retrieve metadata associated with given probe id. """ - @typing.overload def probe_metadata(self, gid: int, tag: str) -> list: """ Retrieve metadata associated with given probe id. """ - def progress_banner(self) -> None: """ Show a text progress bar during simulation. """ - def record(self, arg0: spike_recording) -> None: """ Disable or enable local or global spike recording. """ - def remove_all_samplers(self, arg0: int) -> None: """ Remove all sampling on the simulatr. """ - def remove_sampler(self, handle: int) -> None: """ Remove sampling associated with the given handle. """ - def reset(self) -> None: """ Reset the state of the simulation to its initial state. """ - def run(self, tfinal: units.quantity, dt: units.quantity = ...) -> float: """ Run the simulation from current simulation time to tfinal [ms], with maximum time step size dt [ms]. """ - @typing.overload def sample(self, probeset_id: cell_address, schedule: schedule_base) -> int: """ Record data from probes with given probeset_id according to supplied schedule. Returns handle for retrieving data or removing the sampling. """ - @typing.overload def sample(self, gid: int, tag: str, schedule: schedule_base) -> int: """ Record data from probes with given probeset_id=(gid, tag) according to supplied schedule. Returns handle for retrieving data or removing the sampling. """ - @typing.overload def sample(self, probeset_id: tuple[int, str], schedule: schedule_base) -> int: """ Record data from probes with given probeset_id=(gid, tag) according to supplied schedule. Returns handle for retrieving data or removing the sampling. """ - def samples(self, handle: int) -> list: """ Retrieve sample data as a list, one element per probe associated with the query. """ - def serialize(self) -> str: """ Serialize the simulation object to a JSON string. """ - def set_remote_spike_filter(self, pred: typing.Callable[[spike], bool]) -> None: """ Add a callback to filter spikes going out over external connections. `pred` isa callable on the `spike` type. **Caution**: This will be extremely slow; use C++ if you want to make use of this. """ - def spikes(self) -> typing.Any: """ Retrieve recorded spikes as numpy array. """ - def update(self, recipe: recipe) -> None: """ Rebuild the connection table from recipe::connections_on and the eventgenerators based on recipe::event_generators. """ - class single_cell_model: """ Wrapper for simplified description, and execution, of single cell models. """ - @typing.overload - def __init__( - self, tree: segment_tree, decor: decor, labels: label_dict = ... - ) -> None: + def __init__(self, tree: segment_tree, decor: decor, labels: label_dict = ...) -> None: """ Build single cell model from cable cell components """ - @typing.overload - def __init__( - self, morph: morphology, decor: decor, labels: label_dict = ... - ) -> None: + def __init__(self, morph: morphology, decor: decor, labels: label_dict = ...) -> None: """ Build single cell model from cable cell components """ - @typing.overload def __init__(self, cell: cable_cell) -> None: """ Initialise a single cell model for a cable cell. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... def event_generator(self, event_generator: event_generator) -> None: """ Register an event generator. event_generator: An Arbor event generator. """ - @typing.overload def probe(self, what: str, where: str, tag: str, frequency: units.quantity) -> None: """ @@ -2764,11 +2369,8 @@ class single_cell_model: tag: Unique name for this probe. frequency: The target frequency at which to sample [kHz]. """ - @typing.overload - def probe( - self, what: str, where: location, tag: str, frequency: units.quantity - ) -> None: + def probe(self, what: str, where: location, tag: str, frequency: units.quantity) -> None: """ Sample a variable on the cell. what: Name of the variable to record (currently only 'voltage'). @@ -2776,392 +2378,374 @@ class single_cell_model: tag: Unique name for this probe. frequency: The target frequency at which to sample [kHz]. """ - def run(self, tfinal: units.quantity, dt: units.quantity = ...) -> None: """ Run model from t=0 to t=tfinal ms. """ - @property def cable_cell(self) -> cable_cell: """ The cable cell held by this model. """ - @property def properties(self) -> cable_global_properties: """ Global properties. """ - @properties.setter - def properties(self, arg0: cable_global_properties) -> None: ... + def properties(self, arg0: cable_global_properties) -> None: + ... @property def spikes(self) -> list[float]: """ Holds spike times [ms] after a call to run(). """ - @property def traces(self) -> list[trace]: """ Holds sample traces after a call to run(). """ - class spike: - def __init__(self, arg0: cell_member, arg1: float) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self, arg0: cell_member, arg1: float) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def source(self) -> cell_member: """ The global identifier of the cell. """ - @source.setter - def source(self, arg0: cell_member) -> None: ... + def source(self, arg0: cell_member) -> None: + ... @property def time(self) -> float: """ The time of spike. """ - @time.setter - def time(self, arg0: float) -> None: ... - + def time(self, arg0: float) -> None: + ... class spike_recording: """ Members: - + off - + local - + all """ - - __members__: typing.ClassVar[ - dict[str, spike_recording] - ] # value = {'off': , 'local': , 'all': } + __members__: typing.ClassVar[dict[str, spike_recording]] # value = {'off': , 'local': , 'all': } all: typing.ClassVar[spike_recording] # value = local: typing.ClassVar[spike_recording] # value = off: typing.ClassVar[spike_recording] # value = - def __eq__(self, other: typing.Any) -> bool: ... - def __getstate__(self) -> int: ... - def __hash__(self) -> int: ... - def __index__(self) -> int: ... - def __init__(self, value: int) -> None: ... - def __int__(self) -> int: ... - def __ne__(self, other: typing.Any) -> bool: ... - def __repr__(self) -> str: ... - def __setstate__(self, state: int) -> None: ... - def __str__(self) -> str: ... - @property - def name(self) -> str: ... - @property - def value(self) -> int: ... - + def __eq__(self, other: typing.Any) -> bool: + ... + def __getstate__(self) -> int: + ... + def __hash__(self) -> int: + ... + def __index__(self) -> int: + ... + def __init__(self, value: int) -> None: + ... + def __int__(self) -> int: + ... + def __ne__(self, other: typing.Any) -> bool: + ... + def __repr__(self) -> str: + ... + def __setstate__(self, state: int) -> None: + ... + def __str__(self) -> str: + ... + @property + def name(self) -> str: + ... + @property + def value(self) -> int: + ... class spike_source_cell: """ A spike source cell, that generates a user-defined sequence of spikes that act as inputs for other cells in the network. """ - @typing.overload def __init__(self, source_label: str, schedule: regular_schedule) -> None: """ Construct a spike source cell with a single source labeled 'source_label'. The cell generates spikes on 'source_label' at regular intervals. """ - @typing.overload def __init__(self, source_label: str, schedule: explicit_schedule) -> None: """ Construct a spike source cell with a single source labeled 'source_label'. The cell generates spikes on 'source_label' at a sequence of user-defined times. """ - @typing.overload def __init__(self, source_label: str, schedule: poisson_schedule) -> None: """ Construct a spike source cell with a single source labeled 'source_label'. The cell generates spikes on 'source_label' at times defined by a Poisson sequence. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... - + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... +class swc_metadata: + """ + SWC metadata type: empty. + """ class synapse: """ For placing a synaptic mechanism on a locset. """ - @typing.overload - def __init__(self, arg0: str) -> None: ... + def __init__(self, arg0: str) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism) -> None: ... + def __init__(self, arg0: mechanism) -> None: + ... @typing.overload - def __init__(self, arg0: str, arg1: dict[str, float]) -> None: ... + def __init__(self, arg0: str, arg1: dict[str, float]) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: ... + def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: + ... @typing.overload - def __init__(self, arg0: str, **kwargs) -> None: ... + def __init__(self, arg0: str, **kwargs) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism, **kwargs) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self, arg0: mechanism, **kwargs) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def mech(self) -> mechanism: """ The underlying mechanism. """ - class temperature: """ Setting the temperature. """ - - def __init__(self, arg0: units.quantity) -> None: ... - def __repr__(self) -> str: ... - + def __init__(self, arg0: units.quantity) -> None: + ... + def __repr__(self) -> str: + ... class threshold_detector: """ A spike detector, generates a spike when voltage crosses a threshold. Can be used as source endpoint for an arbor.connection. """ - def __init__(self, threshold: units.quantity) -> None: """ Voltage threshold of spike detector [mV] """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def threshold(self) -> float: """ Voltage threshold of spike detector [mV] """ - class trace: """ Values and meta-data for a sample-trace on a single cell model. """ - - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def location(self) -> location: """ Location on cell morphology. """ - @property def time(self) -> list[float]: """ Time stamps of samples [ms]. """ - @property def value(self) -> list[float]: """ Sample values. """ - @property def variable(self) -> str: """ Name of the variable being recorded. """ - class voltage_process: """ For painting a voltage_process mechanism on a region. """ - @typing.overload - def __init__(self, arg0: str) -> None: ... + def __init__(self, arg0: str) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism) -> None: ... + def __init__(self, arg0: mechanism) -> None: + ... @typing.overload - def __init__(self, arg0: str, arg1: dict[str, float]) -> None: ... + def __init__(self, arg0: str, arg1: dict[str, float]) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: ... + def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: + ... @typing.overload - def __init__(self, arg0: mechanism, **kwargs) -> None: ... + def __init__(self, arg0: mechanism, **kwargs) -> None: + ... @typing.overload - def __init__(self, arg0: str, **kwargs) -> None: ... - def __repr__(self) -> str: ... - def __str__(self) -> str: ... + def __init__(self, arg0: str, **kwargs) -> None: + ... + def __repr__(self) -> str: + ... + def __str__(self) -> str: + ... @property def mech(self) -> mechanism: """ The underlying mechanism. """ - -def allen_catalogue() -> catalogue: ... -def bbp_catalogue() -> catalogue: ... +def allen_catalogue() -> catalogue: + ... +def bbp_catalogue() -> catalogue: + ... def cable_probe_axial_current(where: str, tag: str) -> probe: """ Probe specification for cable cell axial current at points in a location set. """ - -def cable_probe_density_state( - where: str, mechanism: str, state: str, tag: str -) -> probe: +def cable_probe_density_state(where: str, mechanism: str, state: str, tag: str) -> probe: """ Probe specification for a cable cell density mechanism state variable at points in a location set. """ - def cable_probe_density_state_cell(mechanism: str, state: str, tag: str) -> probe: """ Probe specification for a cable cell density mechanism state variable on each cable in each CV where defined. """ - def cable_probe_ion_current_cell(ion: str, tag: str) -> probe: """ Probe specification for cable cell ionic current across each cable in each CV. """ - def cable_probe_ion_current_density(where: str, ion: str, tag: str) -> probe: """ Probe specification for cable cell ionic current density at points in a location set. """ - def cable_probe_ion_diff_concentration(where: str, ion: str, tag: str) -> probe: """ Probe specification for cable cell diffusive ionic concentration at points in a location set. """ - def cable_probe_ion_diff_concentration_cell(ion: str, tag: str) -> probe: """ Probe specification for cable cell diffusive ionic concentration for each cable in each CV. """ - def cable_probe_ion_ext_concentration(where: str, ion: str, tag: str) -> probe: """ Probe specification for cable cell external ionic concentration at points in a location set. """ - def cable_probe_ion_ext_concentration_cell(ion: str, tag: str) -> probe: """ Probe specification for cable cell external ionic concentration for each cable in each CV. """ - def cable_probe_ion_int_concentration(where: str, ion: str, tag: str) -> probe: """ Probe specification for cable cell internal ionic concentration at points in a location set. """ - def cable_probe_ion_int_concentration_cell(ion: str, tag: str) -> probe: """ Probe specification for cable cell internal ionic concentration for each cable in each CV. """ - def cable_probe_membrane_voltage(where: str, tag: str) -> probe: """ Probe specification for cable cell membrane voltage interpolated at points in a location set. """ - def cable_probe_membrane_voltage_cell(tag: str) -> probe: """ Probe specification for cable cell membrane voltage associated with each cable in each CV. """ - def cable_probe_point_state(target: int, mechanism: str, state: str, tag: str) -> probe: """ Probe specification for a cable cell point mechanism state variable value at a given target index. """ - def cable_probe_point_state_cell(mechanism: str, state: str, tag: str) -> probe: """ Probe specification for a cable cell point mechanism state variable value at every corresponding target. """ - def cable_probe_stimulus_current_cell(tag: str) -> probe: """ Probe specification for cable cell stimulus current across each cable in each CV. """ - def cable_probe_total_current_cell(tag: str) -> probe: """ Probe specification for cable cell total transmembrane current for each cable in each CV. """ - def cable_probe_total_ion_current_cell(tag: str) -> probe: """ Probe specification for cable cell total transmembrane current excluding capacitive currents for each cable in each CV. """ - def cable_probe_total_ion_current_density(where: str, tag: str) -> probe: """ Probe specification for cable cell total transmembrane current density excluding capacitive currents at points in a location set. """ - def config() -> dict: """ Get Arbor's configuration. """ - def cv_data(cell: cable_cell) -> cell_cv_data | None: """ Returns a cell_cv_data object representing the CVs comprising the cable-cell according to the discretization policy provided in the decor of the cell. Returns None if no CV-policy was provided in the decor. """ - -def cv_policy_every_segment(domain: str = "(all)") -> cv_policy: +def cv_policy_every_segment(domain: str = '(all)') -> cv_policy: """ Policy to create one compartment per component of a region. """ - -def cv_policy_explicit(locset: str, domain: str = "(all)") -> cv_policy: +def cv_policy_explicit(locset: str, domain: str = '(all)') -> cv_policy: """ Policy to create compartments at explicit locations. """ - -def cv_policy_fixed_per_branch(n: int, domain: str = "(all)") -> cv_policy: +def cv_policy_fixed_per_branch(n: int, domain: str = '(all)') -> cv_policy: """ Policy to use the same number of CVs for each branch. """ - -def cv_policy_max_extent(length: float, domain: str = "(all)") -> cv_policy: +def cv_policy_max_extent(length: float, domain: str = '(all)') -> cv_policy: """ Policy to use as many CVs as required to ensure that no CV has a length longer than a given value. """ - -def cv_policy_single(domain: str = "(all)") -> cv_policy: +def cv_policy_single(domain: str = '(all)') -> cv_policy: """ Policy to create one compartment per component of a region. """ - -def default_catalogue() -> catalogue: ... +def default_catalogue() -> catalogue: + ... def intersect_region(reg: str, data: cell_cv_data, integrate_along: str) -> list[tuple]: """ Returns a list of [index, proportion] tuples identifying the CVs present in the region. `index` is the index of the CV in the cell_cv_data object provided as an argument. `proportion` is the proportion of the CV (itegrated by area or length) included in the region. """ - def lif_probe_voltage(tag: str) -> probe: """ Probe specification for LIF cell membrane voltage. """ - -def load_asc( - filename_or_stream: typing.Any, raw: bool = False -) -> segment_tree | asc_morphology: +def load_asc(filename_or_stream: typing.Any) -> loaded_morphology: """ - Load a morphology or segment_tree (raw=True) and meta data from a Neurolucida ASCII .asc file. + Load a morphology or segment_tree and meta data from a Neurolucida ASCII .asc file. """ - -def load_catalogue(arg0: typing.Any) -> catalogue: ... +def load_catalogue(arg0: typing.Any) -> catalogue: + ... def load_component(filename_or_descriptor: typing.Any) -> cable_component: """ Load arbor-component (decor, morphology, label_dict, cable_cell) from file. """ - -def load_swc_arbor( - filename_or_stream: typing.Any, raw: bool = False -) -> segment_tree | morphology: +def load_swc_arbor(filename_or_stream: typing.Any) -> loaded_morphology: """ - Generate a morphology/segment_tree (raw=False/True) from an SWC file following the rules prescribed by Arbor. + Generate a morphology/segment_tree from an SWC file following the rules prescribed by Arbor. Specifically: * Single-segment somas are disallowed. * There are no special rules related to somata. They can be one or multiple branches @@ -3169,76 +2753,58 @@ def load_swc_arbor( * A segment is always created between a sample and its parent, meaning there are no gaps in the resulting morphology. """ - -def load_swc_neuron( - filename_or_stream: typing.Any, raw: bool = False -) -> segment_tree | morphology: +def load_swc_neuron(filename_or_stream: typing.Any) -> loaded_morphology: """ - Generate a morphology/segment_tree (raw=False/True) from an SWC file following the rules prescribed by NEURON. + Generate a morphology from an SWC file following the rules prescribed by NEURON. See the documentation https://docs.arbor-sim.org/en/latest/fileformat/swc.html for a detailed description of the interpretation. """ - def neuron_cable_properties() -> cable_global_properties: """ default NEURON cable_global_properties """ - -def partition_by_group( - recipe: recipe, context: context, groups: list[group_description] -) -> domain_decomposition: +def partition_by_group(recipe: recipe, context: context, groups: list[group_description]) -> domain_decomposition: """ - Construct a domain_decomposition that assigned the groups of cell provided as argument + Construct a domain_decomposition that assigned the groups of cell provided as argument to the local hardware resources described by context on the calling rank. The cell_groups are guaranteed to be present on the calling rank. """ - -def partition_load_balance( - recipe: recipe, context: context, hints: dict[cell_kind, partition_hint] = {} -) -> domain_decomposition: +def partition_load_balance(recipe: recipe, context: context, hints: dict[cell_kind, partition_hint] = {}) -> domain_decomposition: """ Construct a domain_decomposition that distributes the cells in the model described by recipe over the distributed and local hardware resources described by context. Optionally, provide a dictionary of partition hints for certain cell kinds, by default empty. """ - def print_config() -> None: """ Print Arbor's configuration. """ - -def stochastic_catalogue() -> catalogue: ... +def stochastic_catalogue() -> catalogue: + ... @typing.overload -def write_component( - object: cable_component, filename_or_descriptor: typing.Any -) -> None: +def write_component(object: cable_component, filename_or_descriptor: typing.Any) -> None: """ Write cable_component to file. """ - @typing.overload def write_component(object: decor, filename_or_descriptor: typing.Any) -> None: """ Write decor to file. """ - @typing.overload def write_component(object: label_dict, filename_or_descriptor: typing.Any) -> None: """ Write label_dict to file. """ - @typing.overload def write_component(object: morphology, filename_or_descriptor: typing.Any) -> None: """ Write morphology to file. """ - @typing.overload def write_component(object: cable_cell, filename_or_descriptor: typing.Any) -> None: """ Write cable_cell to file. """ - -__version__: str = "0.9.1-dev" +__version__: str = '0.9.1-dev' mnpos: int = 4294967295 diff --git a/python/stubs/arbor/_arbor/env.pyi b/python/stubs/arbor/_arbor/env.pyi index 72be0ec6da..2073f67e99 100644 --- a/python/stubs/arbor/_arbor/env.pyi +++ b/python/stubs/arbor/_arbor/env.pyi @@ -1,46 +1,31 @@ """ Wrappers for arborenv. """ - from __future__ import annotations import arbor._arbor import typing - -__all__ = [ - "default_allocation", - "default_concurrency", - "default_gpu", - "find_private_gpu", - "get_env_num_threads", - "thread_concurrency", -] - +__all__ = ['default_allocation', 'default_concurrency', 'default_gpu', 'find_private_gpu', 'get_env_num_threads', 'thread_concurrency'] def default_allocation() -> arbor._arbor.proc_allocation: """ Attempts to detect the number of locally available CPU cores. Returns 1 if unable to detect the number of cores. Use with caution in combination with MPI. """ - def default_concurrency() -> arbor._arbor.proc_allocation: """ Returns number of threads to use from get_env_num_threads(), or else from thread_concurrency() if get_env_num_threads() returns zero. """ - def default_gpu() -> int | None: """ Determine GPU id to use from the ARBENV_GPU_ID environment variable, or from the first available GPU id of those detected. """ - def find_private_gpu(arg0: typing.Any) -> None: """ Identify a private GPU id per node, only available if built with GPU and MPI. mpi: The MPI communicator. """ - def get_env_num_threads() -> int: """ Retrieve user-specified number of threads to use from the environment variable ARBENV_NUM_THREADS. """ - def thread_concurrency() -> int: """ Attempts to detect the number of locally available CPU cores. Returns 1 if unable to detect the number of cores. Use with caution in combination with MPI. diff --git a/python/stubs/arbor/_arbor/py.typed b/python/stubs/arbor/_arbor/py.typed deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/python/stubs/arbor/_arbor/units.pyi b/python/stubs/arbor/_arbor/units.pyi index 664b21ae32..3cbb1f7811 100644 --- a/python/stubs/arbor/_arbor/units.pyi +++ b/python/stubs/arbor/_arbor/units.pyi @@ -1,146 +1,103 @@ """ Units and quantities for driving the user interface. """ - from __future__ import annotations import typing - -__all__ = [ - "A", - "C", - "Celsius", - "F", - "Hz", - "Kelvin", - "M", - "MOhm", - "Ohm", - "S", - "V", - "cm", - "cm2", - "deg", - "giga", - "kHz", - "kOhm", - "kilo", - "m", - "m2", - "mA", - "mM", - "mS", - "mV", - "mega", - "micro", - "milli", - "mm", - "mm2", - "mol", - "ms", - "nA", - "nF", - "nano", - "nil", - "nm", - "nm2", - "ns", - "pA", - "pF", - "pico", - "quantity", - "rad", - "s", - "uA", - "uF", - "uS", - "um", - "um2", - "unit", - "us", -] - +__all__ = ['A', 'C', 'Celsius', 'F', 'Hz', 'Kelvin', 'M', 'MOhm', 'Ohm', 'S', 'V', 'cm', 'cm2', 'deg', 'giga', 'kHz', 'kOhm', 'kilo', 'm', 'm2', 'mA', 'mM', 'mS', 'mV', 'mega', 'micro', 'milli', 'mm', 'mm2', 'mol', 'ms', 'nA', 'nF', 'nano', 'nil', 'nm', 'nm2', 'ns', 'pA', 'pF', 'pico', 'quantity', 'rad', 's', 'uA', 'uF', 'uS', 'um', 'um2', 'unit', 'us'] class quantity: """ A quantity, comprising a magnitude and a unit. """ - __hash__: typing.ClassVar[None] = None - def __add__(self, arg0: quantity) -> quantity: ... - def __eq__(self, arg0: quantity) -> bool: ... + def __add__(self, arg0: quantity) -> quantity: + ... + def __eq__(self, arg0: quantity) -> bool: + ... @typing.overload - def __mul__(self, arg0: quantity) -> quantity: ... + def __mul__(self, arg0: quantity) -> quantity: + ... @typing.overload - def __mul__(self, arg0: float) -> quantity: ... + def __mul__(self, arg0: float) -> quantity: + ... @typing.overload - def __mul__(self, arg0: unit) -> quantity: ... - def __ne__(self, arg0: quantity) -> bool: ... - def __pow__(self: unit, arg0: int) -> unit: ... + def __mul__(self, arg0: unit) -> quantity: + ... + def __ne__(self, arg0: quantity) -> bool: + ... + def __pow__(self: unit, arg0: int) -> unit: + ... def __repr__(self) -> str: """ Convert quantity to string. """ - - def __rmul__(self, arg0: float) -> quantity: ... - def __rtruediv__(self, arg0: float) -> quantity: ... + def __rmul__(self, arg0: float) -> quantity: + ... + def __rtruediv__(self, arg0: float) -> quantity: + ... def __str__(self) -> str: """ Convert quantity to string. """ - - def __sub__(self, arg0: quantity) -> quantity: ... + def __sub__(self, arg0: quantity) -> quantity: + ... @typing.overload - def __truediv__(self, arg0: quantity) -> quantity: ... + def __truediv__(self, arg0: quantity) -> quantity: + ... @typing.overload - def __truediv__(self, arg0: float) -> quantity: ... + def __truediv__(self, arg0: float) -> quantity: + ... @typing.overload - def __truediv__(self, arg0: unit) -> quantity: ... + def __truediv__(self, arg0: unit) -> quantity: + ... def value_as(self, unit: unit) -> float: """ Convert quantity to given unit and return magnitude. """ - @property def units(self) -> unit: """ Return units. """ - @property def value(self) -> float: """ Return magnitude. """ - class unit: """ A unit. """ - __hash__: typing.ClassVar[None] = None - def __eq__(self, arg0: unit) -> bool: ... + def __eq__(self, arg0: unit) -> bool: + ... @typing.overload - def __mul__(self, arg0: unit) -> unit: ... + def __mul__(self, arg0: unit) -> unit: + ... @typing.overload - def __mul__(self, arg0: float) -> quantity: ... - def __ne__(self, arg0: unit) -> bool: ... - def __pow__(self, arg0: int) -> unit: ... + def __mul__(self, arg0: float) -> quantity: + ... + def __ne__(self, arg0: unit) -> bool: + ... + def __pow__(self, arg0: int) -> unit: + ... def __repr__(self) -> str: """ Convert unit to string. """ - - def __rmul__(self, arg0: float) -> quantity: ... - def __rtruediv__(self, arg0: float) -> quantity: ... + def __rmul__(self, arg0: float) -> quantity: + ... + def __rtruediv__(self, arg0: float) -> quantity: + ... def __str__(self) -> str: """ Convert unit to string. """ - @typing.overload - def __truediv__(self, arg0: unit) -> unit: ... + def __truediv__(self, arg0: unit) -> unit: + ... @typing.overload - def __truediv__(self, arg0: float) -> quantity: ... - + def __truediv__(self, arg0: float) -> quantity: + ... A: unit # value = A C: unit # value = C Celsius: unit # value = °C @@ -175,7 +132,7 @@ ms: unit # value = ms nA: unit # value = nA nF: unit # value = nF nano: unit # value = 1e-09 -nil: unit # value = +nil: unit # value = nm: unit # value = nm nm2: unit # value = nm^2 ns: unit # value = ns diff --git a/python/stubs/arbor/py.typed b/python/stubs/arbor/py.typed deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/python/stubs/py.typed b/python/stubs/py.typed deleted file mode 100644 index e69de29bb2..0000000000 From ca7a7a6380e9a441ce2cbaf4110813e6391dba2d Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 5 Mar 2024 09:33:38 +0100 Subject: [PATCH 13/18] appease the linter. --- python/stubs/arbor/__init__.pyi | 171 ++- python/stubs/arbor/_arbor/__init__.pyi | 1934 +++++++++++++++--------- python/stubs/arbor/_arbor/env.pyi | 17 +- python/stubs/arbor/_arbor/units.pyi | 135 +- 4 files changed, 1480 insertions(+), 777 deletions(-) diff --git a/python/stubs/arbor/__init__.pyi b/python/stubs/arbor/__init__.pyi index d0737f1027..83f19fd01b 100644 --- a/python/stubs/arbor/__init__.pyi +++ b/python/stubs/arbor/__init__.pyi @@ -132,11 +132,168 @@ from arbor._arbor import units from arbor._arbor import voltage_process from arbor._arbor import write_component from . import _arbor -__all__ = ['ArbFileNotFoundError', 'ArbValueError', 'MechCatItemIterator', 'MechCatKeyIterator', 'MechCatValueIterator', 'allen_catalogue', 'asc_color', 'asc_marker', 'asc_marker_set', 'asc_metadata', 'asc_spine', 'axial_resistivity', 'backend', 'bbp_catalogue', 'benchmark_cell', 'build_catalogue', 'cable', 'cable_cell', 'cable_component', 'cable_global_properties', 'cable_probe_axial_current', 'cable_probe_density_state', 'cable_probe_density_state_cell', 'cable_probe_ion_current_cell', 'cable_probe_ion_current_density', 'cable_probe_ion_diff_concentration', 'cable_probe_ion_diff_concentration_cell', 'cable_probe_ion_ext_concentration', 'cable_probe_ion_ext_concentration_cell', 'cable_probe_ion_int_concentration', 'cable_probe_ion_int_concentration_cell', 'cable_probe_membrane_voltage', 'cable_probe_membrane_voltage_cell', 'cable_probe_point_info', 'cable_probe_point_state', 'cable_probe_point_state_cell', 'cable_probe_stimulus_current_cell', 'cable_probe_total_current_cell', 'cable_probe_total_ion_current_cell', 'cable_probe_total_ion_current_density', 'catalogue', 'cell_address', 'cell_cv_data', 'cell_global_label', 'cell_kind', 'cell_local_label', 'cell_member', 'component_meta_data', 'config', 'connection', 'context', 'cv_data', 'cv_policy', 'cv_policy_every_segment', 'cv_policy_explicit', 'cv_policy_fixed_per_branch', 'cv_policy_max_extent', 'cv_policy_single', 'decor', 'default_catalogue', 'density', 'domain_decomposition', 'env', 'event_generator', 'explicit_schedule', 'ext_concentration', 'extent', 'gap_junction_connection', 'group_description', 'iclamp', 'int_concentration', 'intersect_region', 'ion_data', 'ion_dependency', 'ion_diffusivity', 'ion_settings', 'isometry', 'junction', 'label_dict', 'lif_cell', 'lif_probe_metadata', 'lif_probe_voltage', 'load_asc', 'load_catalogue', 'load_component', 'load_swc_arbor', 'load_swc_neuron', 'loaded_morphology', 'location', 'mechanism', 'mechanism_field', 'mechanism_info', 'membrane_capacitance', 'membrane_potential', 'meter_manager', 'meter_report', 'mnpos', 'modcc', 'morphology', 'morphology_provider', 'mpoint', 'msegment', 'neuroml', 'neuron_cable_properties', 'nml_metadata', 'partition_by_group', 'partition_hint', 'partition_load_balance', 'place_pwlin', 'poisson_schedule', 'print_config', 'probe', 'proc_allocation', 'recipe', 'regular_schedule', 'reversal_potential', 'reversal_potential_method', 'scaled_mechanism', 'schedule_base', 'segment_tree', 'selection_policy', 'simulation', 'single_cell_model', 'spike', 'spike_recording', 'spike_source_cell', 'stochastic_catalogue', 'swc_metadata', 'synapse', 'temperature', 'threshold_detector', 'trace', 'units', 'voltage_process', 'write_component'] -def build_catalogue(): - ... -def modcc(): - ... -__config__: dict = {'mpi': False, 'mpi4py': False, 'gpu': None, 'vectorize': True, 'profiling': False, 'neuroml': True, 'bundled': True, 'version': '0.9.1-dev', 'source': '2024-03-01T14:59:23+01:00 dcdfe101f389cb4854ac3d0a067feeb280600c88 modified', 'build_config': 'DEBUG', 'arch': 'native', 'prefix': '/usr/local', 'python_lib_path': '/usr/local/lib/python3.12/site-packages', 'binary_path': 'bin', 'lib_path': 'lib', 'data_path': 'share', 'CXX': '/opt/homebrew/bin/clang++', 'pybind-version': '2.11.1', 'timestamp': 'Mar 4 2024 20:56:20'} -__version__: str = '0.9.1-dev' + +__all__ = [ + "ArbFileNotFoundError", + "ArbValueError", + "MechCatItemIterator", + "MechCatKeyIterator", + "MechCatValueIterator", + "allen_catalogue", + "asc_color", + "asc_marker", + "asc_marker_set", + "asc_metadata", + "asc_spine", + "axial_resistivity", + "backend", + "bbp_catalogue", + "benchmark_cell", + "build_catalogue", + "cable", + "cable_cell", + "cable_component", + "cable_global_properties", + "cable_probe_axial_current", + "cable_probe_density_state", + "cable_probe_density_state_cell", + "cable_probe_ion_current_cell", + "cable_probe_ion_current_density", + "cable_probe_ion_diff_concentration", + "cable_probe_ion_diff_concentration_cell", + "cable_probe_ion_ext_concentration", + "cable_probe_ion_ext_concentration_cell", + "cable_probe_ion_int_concentration", + "cable_probe_ion_int_concentration_cell", + "cable_probe_membrane_voltage", + "cable_probe_membrane_voltage_cell", + "cable_probe_point_info", + "cable_probe_point_state", + "cable_probe_point_state_cell", + "cable_probe_stimulus_current_cell", + "cable_probe_total_current_cell", + "cable_probe_total_ion_current_cell", + "cable_probe_total_ion_current_density", + "catalogue", + "cell_address", + "cell_cv_data", + "cell_global_label", + "cell_kind", + "cell_local_label", + "cell_member", + "component_meta_data", + "config", + "connection", + "context", + "cv_data", + "cv_policy", + "cv_policy_every_segment", + "cv_policy_explicit", + "cv_policy_fixed_per_branch", + "cv_policy_max_extent", + "cv_policy_single", + "decor", + "default_catalogue", + "density", + "domain_decomposition", + "env", + "event_generator", + "explicit_schedule", + "ext_concentration", + "extent", + "gap_junction_connection", + "group_description", + "iclamp", + "int_concentration", + "intersect_region", + "ion_data", + "ion_dependency", + "ion_diffusivity", + "ion_settings", + "isometry", + "junction", + "label_dict", + "lif_cell", + "lif_probe_metadata", + "lif_probe_voltage", + "load_asc", + "load_catalogue", + "load_component", + "load_swc_arbor", + "load_swc_neuron", + "loaded_morphology", + "location", + "mechanism", + "mechanism_field", + "mechanism_info", + "membrane_capacitance", + "membrane_potential", + "meter_manager", + "meter_report", + "mnpos", + "modcc", + "morphology", + "morphology_provider", + "mpoint", + "msegment", + "neuroml", + "neuron_cable_properties", + "nml_metadata", + "partition_by_group", + "partition_hint", + "partition_load_balance", + "place_pwlin", + "poisson_schedule", + "print_config", + "probe", + "proc_allocation", + "recipe", + "regular_schedule", + "reversal_potential", + "reversal_potential_method", + "scaled_mechanism", + "schedule_base", + "segment_tree", + "selection_policy", + "simulation", + "single_cell_model", + "spike", + "spike_recording", + "spike_source_cell", + "stochastic_catalogue", + "swc_metadata", + "synapse", + "temperature", + "threshold_detector", + "trace", + "units", + "voltage_process", + "write_component", +] + +def build_catalogue(): ... +def modcc(): ... + +__config__: dict = { + "mpi": False, + "mpi4py": False, + "gpu": None, + "vectorize": True, + "profiling": False, + "neuroml": True, + "bundled": True, + "version": "0.9.1-dev", + "source": "2024-03-01T14:59:23+01:00 dcdfe101f389cb4854ac3d0a067feeb280600c88 modified", + "build_config": "DEBUG", + "arch": "native", + "prefix": "/usr/local", + "python_lib_path": "/usr/local/lib/python3.12/site-packages", + "binary_path": "bin", + "lib_path": "lib", + "data_path": "share", + "CXX": "/opt/homebrew/bin/clang++", + "pybind-version": "2.11.1", + "timestamp": "Mar 4 2024 20:56:20", +} +__version__: str = "0.9.1-dev" mnpos: int = 4294967295 diff --git a/python/stubs/arbor/_arbor/__init__.pyi b/python/stubs/arbor/_arbor/__init__.pyi index 4e518c25fd..0190cf4c2f 100644 --- a/python/stubs/arbor/_arbor/__init__.pyi +++ b/python/stubs/arbor/_arbor/__init__.pyi @@ -1,171 +1,288 @@ """ arbor: multicompartment neural network models. """ + from __future__ import annotations import typing from . import env from . import units -__all__ = ['ArbFileNotFoundError', 'ArbValueError', 'MechCatItemIterator', 'MechCatKeyIterator', 'MechCatValueIterator', 'allen_catalogue', 'asc_color', 'asc_marker', 'asc_marker_set', 'asc_metadata', 'asc_spine', 'axial_resistivity', 'backend', 'bbp_catalogue', 'benchmark_cell', 'cable', 'cable_cell', 'cable_component', 'cable_global_properties', 'cable_probe_axial_current', 'cable_probe_density_state', 'cable_probe_density_state_cell', 'cable_probe_ion_current_cell', 'cable_probe_ion_current_density', 'cable_probe_ion_diff_concentration', 'cable_probe_ion_diff_concentration_cell', 'cable_probe_ion_ext_concentration', 'cable_probe_ion_ext_concentration_cell', 'cable_probe_ion_int_concentration', 'cable_probe_ion_int_concentration_cell', 'cable_probe_membrane_voltage', 'cable_probe_membrane_voltage_cell', 'cable_probe_point_info', 'cable_probe_point_state', 'cable_probe_point_state_cell', 'cable_probe_stimulus_current_cell', 'cable_probe_total_current_cell', 'cable_probe_total_ion_current_cell', 'cable_probe_total_ion_current_density', 'catalogue', 'cell_address', 'cell_cv_data', 'cell_global_label', 'cell_kind', 'cell_local_label', 'cell_member', 'component_meta_data', 'config', 'connection', 'context', 'cv_data', 'cv_policy', 'cv_policy_every_segment', 'cv_policy_explicit', 'cv_policy_fixed_per_branch', 'cv_policy_max_extent', 'cv_policy_single', 'decor', 'default_catalogue', 'density', 'domain_decomposition', 'env', 'event_generator', 'explicit_schedule', 'ext_concentration', 'extent', 'gap_junction_connection', 'group_description', 'iclamp', 'int_concentration', 'intersect_region', 'ion_data', 'ion_dependency', 'ion_diffusivity', 'ion_settings', 'isometry', 'junction', 'label_dict', 'lif_cell', 'lif_probe_metadata', 'lif_probe_voltage', 'load_asc', 'load_catalogue', 'load_component', 'load_swc_arbor', 'load_swc_neuron', 'loaded_morphology', 'location', 'mechanism', 'mechanism_field', 'mechanism_info', 'membrane_capacitance', 'membrane_potential', 'meter_manager', 'meter_report', 'mnpos', 'morphology', 'morphology_provider', 'mpoint', 'msegment', 'neuroml', 'neuron_cable_properties', 'nml_metadata', 'partition_by_group', 'partition_hint', 'partition_load_balance', 'place_pwlin', 'poisson_schedule', 'print_config', 'probe', 'proc_allocation', 'recipe', 'regular_schedule', 'reversal_potential', 'reversal_potential_method', 'scaled_mechanism', 'schedule_base', 'segment_tree', 'selection_policy', 'simulation', 'single_cell_model', 'spike', 'spike_recording', 'spike_source_cell', 'stochastic_catalogue', 'swc_metadata', 'synapse', 'temperature', 'threshold_detector', 'trace', 'units', 'voltage_process', 'write_component'] + +__all__ = [ + "ArbFileNotFoundError", + "ArbValueError", + "MechCatItemIterator", + "MechCatKeyIterator", + "MechCatValueIterator", + "allen_catalogue", + "asc_color", + "asc_marker", + "asc_marker_set", + "asc_metadata", + "asc_spine", + "axial_resistivity", + "backend", + "bbp_catalogue", + "benchmark_cell", + "cable", + "cable_cell", + "cable_component", + "cable_global_properties", + "cable_probe_axial_current", + "cable_probe_density_state", + "cable_probe_density_state_cell", + "cable_probe_ion_current_cell", + "cable_probe_ion_current_density", + "cable_probe_ion_diff_concentration", + "cable_probe_ion_diff_concentration_cell", + "cable_probe_ion_ext_concentration", + "cable_probe_ion_ext_concentration_cell", + "cable_probe_ion_int_concentration", + "cable_probe_ion_int_concentration_cell", + "cable_probe_membrane_voltage", + "cable_probe_membrane_voltage_cell", + "cable_probe_point_info", + "cable_probe_point_state", + "cable_probe_point_state_cell", + "cable_probe_stimulus_current_cell", + "cable_probe_total_current_cell", + "cable_probe_total_ion_current_cell", + "cable_probe_total_ion_current_density", + "catalogue", + "cell_address", + "cell_cv_data", + "cell_global_label", + "cell_kind", + "cell_local_label", + "cell_member", + "component_meta_data", + "config", + "connection", + "context", + "cv_data", + "cv_policy", + "cv_policy_every_segment", + "cv_policy_explicit", + "cv_policy_fixed_per_branch", + "cv_policy_max_extent", + "cv_policy_single", + "decor", + "default_catalogue", + "density", + "domain_decomposition", + "env", + "event_generator", + "explicit_schedule", + "ext_concentration", + "extent", + "gap_junction_connection", + "group_description", + "iclamp", + "int_concentration", + "intersect_region", + "ion_data", + "ion_dependency", + "ion_diffusivity", + "ion_settings", + "isometry", + "junction", + "label_dict", + "lif_cell", + "lif_probe_metadata", + "lif_probe_voltage", + "load_asc", + "load_catalogue", + "load_component", + "load_swc_arbor", + "load_swc_neuron", + "loaded_morphology", + "location", + "mechanism", + "mechanism_field", + "mechanism_info", + "membrane_capacitance", + "membrane_potential", + "meter_manager", + "meter_report", + "mnpos", + "morphology", + "morphology_provider", + "mpoint", + "msegment", + "neuroml", + "neuron_cable_properties", + "nml_metadata", + "partition_by_group", + "partition_hint", + "partition_load_balance", + "place_pwlin", + "poisson_schedule", + "print_config", + "probe", + "proc_allocation", + "recipe", + "regular_schedule", + "reversal_potential", + "reversal_potential_method", + "scaled_mechanism", + "schedule_base", + "segment_tree", + "selection_policy", + "simulation", + "single_cell_model", + "spike", + "spike_recording", + "spike_source_cell", + "stochastic_catalogue", + "swc_metadata", + "synapse", + "temperature", + "threshold_detector", + "trace", + "units", + "voltage_process", + "write_component", +] + class ArbFileNotFoundError(FileNotFoundError): pass + class ArbValueError(ValueError): pass + class MechCatItemIterator: - def __iter__(self) -> MechCatItemIterator: - ... - def __next__(self) -> tuple[str, mechanism_info]: - ... + def __iter__(self) -> MechCatItemIterator: ... + def __next__(self) -> tuple[str, mechanism_info]: ... + class MechCatKeyIterator: - def __iter__(self) -> MechCatKeyIterator: - ... - def __next__(self) -> str: - ... + def __iter__(self) -> MechCatKeyIterator: ... + def __next__(self) -> str: ... + class MechCatValueIterator: - def __iter__(self) -> MechCatValueIterator: - ... - def __next__(self) -> mechanism_info: - ... + def __iter__(self) -> MechCatValueIterator: ... + def __next__(self) -> mechanism_info: ... + class asc_color: """ Neurolucida color tag. """ + @property - def blue(self) -> int: - ... + def blue(self) -> int: ... @property - def green(self) -> int: - ... + def green(self) -> int: ... @property - def red(self) -> int: - ... + def red(self) -> int: ... + class asc_marker: """ Neurolucida marker type. - + Members: - + dot - + cross - + circle - + none """ - __members__: typing.ClassVar[dict[str, asc_marker]] # value = {'dot': , 'cross': , 'circle': , 'none': } + + __members__: typing.ClassVar[ + dict[str, asc_marker] + ] # value = {'dot': , 'cross': , 'circle': , 'none': } circle: typing.ClassVar[asc_marker] # value = cross: typing.ClassVar[asc_marker] # value = dot: typing.ClassVar[asc_marker] # value = none: typing.ClassVar[asc_marker] # value = - def __eq__(self, other: typing.Any) -> bool: - ... - def __getstate__(self) -> int: - ... - def __hash__(self) -> int: - ... - def __index__(self) -> int: - ... - def __init__(self, value: int) -> None: - ... - def __int__(self) -> int: - ... - def __ne__(self, other: typing.Any) -> bool: - ... - def __repr__(self) -> str: - ... - def __setstate__(self, state: int) -> None: - ... - def __str__(self) -> str: - ... - @property - def name(self) -> str: - ... - @property - def value(self) -> int: - ... + def __eq__(self, other: typing.Any) -> bool: ... + def __getstate__(self) -> int: ... + def __hash__(self) -> int: ... + def __index__(self) -> int: ... + def __init__(self, value: int) -> None: ... + def __int__(self) -> int: ... + def __ne__(self, other: typing.Any) -> bool: ... + def __repr__(self) -> str: ... + def __setstate__(self, state: int) -> None: ... + def __str__(self) -> str: ... + @property + def name(self) -> str: ... + @property + def value(self) -> int: ... + class asc_marker_set: """ Neurolucida marker set type. """ + @property - def color(self) -> asc_color: - ... + def color(self) -> asc_color: ... @property - def locations(self) -> list[mpoint]: - ... + def locations(self) -> list[mpoint]: ... @property - def marker(self) -> asc_marker: - ... + def marker(self) -> asc_marker: ... @property - def name(self) -> str: - ... + def name(self) -> str: ... + class asc_metadata: """ Neurolucida metadata type: Spines and marker sets. """ + @property - def markers(self) -> list[asc_marker_set]: - ... + def markers(self) -> list[asc_marker_set]: ... @property - def spines(self) -> list[asc_spine]: - ... + def spines(self) -> list[asc_spine]: ... + class asc_spine: """ Neurolucida spine marker. """ + @property - def location(self) -> mpoint: - ... + def location(self) -> mpoint: ... @property - def name(self) -> str: - ... + def name(self) -> str: ... + class axial_resistivity: """ Setting the axial resistivity. """ - def __init__(self, arg0: units.quantity) -> None: - ... - def __repr__(self) -> str: - ... + + def __init__(self, arg0: units.quantity) -> None: ... + def __repr__(self) -> str: ... + class backend: """ Enumeration used to indicate which hardware backend to execute a cell group on. - + Members: - + gpu : Use GPU backend. - + multicore : Use multicore backend. """ - __members__: typing.ClassVar[dict[str, backend]] # value = {'gpu': , 'multicore': } + + __members__: typing.ClassVar[ + dict[str, backend] + ] # value = {'gpu': , 'multicore': } gpu: typing.ClassVar[backend] # value = multicore: typing.ClassVar[backend] # value = - def __eq__(self, other: typing.Any) -> bool: - ... - def __getstate__(self) -> int: - ... - def __hash__(self) -> int: - ... - def __index__(self) -> int: - ... - def __init__(self, value: int) -> None: - ... - def __int__(self) -> int: - ... - def __ne__(self, other: typing.Any) -> bool: - ... - def __repr__(self) -> str: - ... - def __setstate__(self, state: int) -> None: - ... - def __str__(self) -> str: - ... - @property - def name(self) -> str: - ... - @property - def value(self) -> int: - ... + def __eq__(self, other: typing.Any) -> bool: ... + def __getstate__(self) -> int: ... + def __hash__(self) -> int: ... + def __index__(self) -> int: ... + def __init__(self, value: int) -> None: ... + def __int__(self) -> int: ... + def __ne__(self, other: typing.Any) -> bool: ... + def __repr__(self) -> str: ... + def __setstate__(self, state: int) -> None: ... + def __str__(self) -> str: ... + @property + def name(self) -> str: ... + @property + def value(self) -> int: ... + class benchmark_cell: """ A benchmarking cell, used by Arbor developers to test communication performance. @@ -174,118 +291,153 @@ class benchmark_cell: for example if realtime_ratio=2, a cell will take 2 seconds of CPU time to simulate 1 second. """ + @typing.overload - def __init__(self, source_label: str, target_label: str, schedule: regular_schedule, realtime_ratio: float = 1.0) -> None: + def __init__( + self, + source_label: str, + target_label: str, + schedule: regular_schedule, + realtime_ratio: float = 1.0, + ) -> None: """ Construct a benchmark cell that generates spikes on 'source_label' at regular intervals. The cell has one source labeled 'source_label', and one target labeled 'target_label'. """ + @typing.overload - def __init__(self, source_label: str, target_label: str, schedule: explicit_schedule, realtime_ratio: float = 1.0) -> None: + def __init__( + self, + source_label: str, + target_label: str, + schedule: explicit_schedule, + realtime_ratio: float = 1.0, + ) -> None: """ Construct a benchmark cell that generates spikes on 'source_label' at a sequence of user-defined times. The cell has one source labeled 'source_label', and one target labeled 'target_label'. """ + @typing.overload - def __init__(self, source_label: str, target_label: str, schedule: poisson_schedule, realtime_ratio: float = 1.0) -> None: + def __init__( + self, + source_label: str, + target_label: str, + schedule: poisson_schedule, + realtime_ratio: float = 1.0, + ) -> None: """ Construct a benchmark cell that generates spikeson 'source_label' at times defined by a Poisson sequence. The cell has one source labeled 'source_label', and one target labeled 'target_label'. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... + class cable: __hash__: typing.ClassVar[None] = None - def __eq__(self, arg0: cable) -> bool: - ... - def __init__(self, branch: int, prox: float, dist: float) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + def __eq__(self, arg0: cable) -> bool: ... + def __init__(self, branch: int, prox: float, dist: float) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def branch(self) -> int: """ The id of the branch on which the cable lies. """ + @property def dist(self) -> float: """ The relative position of the distal end of the cable on its branch ∈ [0,1]. """ + @property def prox(self) -> float: """ The relative position of the proximal end of the cable on its branch ∈ [0,1]. """ + class cable_cell: """ Represents morphologically-detailed cell models, with morphology represented as a tree of one-dimensional cable segments. """ + @typing.overload - def __init__(self, morphology: morphology, decor: decor, labels: label_dict | None = None) -> None: + def __init__( + self, morphology: morphology, decor: decor, labels: label_dict | None = None + ) -> None: """ Construct with a morphology, decor, and label dictionary. """ + @typing.overload - def __init__(self, segment_tree: segment_tree, decor: decor, labels: label_dict | None = None) -> None: + def __init__( + self, segment_tree: segment_tree, decor: decor, labels: label_dict | None = None + ) -> None: """ Construct with a morphology derived from a segment tree, decor, and label dictionary. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def cables(self, label: str) -> list[cable]: """ The cable segments of the cell morphology for a region label. """ + def locations(self, label: str) -> list[location]: """ The locations of the cell morphology for a locset label. """ + @property def num_branches(self) -> int: """ The number of unbranched cable sections in the morphology. """ + class cable_component: - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def component(self) -> morphology | label_dict | decor | cable_cell: """ cable-cell component. """ + @property def meta_data(self) -> component_meta_data: """ cable-cell component meta-data. """ + @meta_data.setter - def meta_data(self, arg0: component_meta_data) -> None: - ... + def meta_data(self, arg0: component_meta_data) -> None: ... + class cable_global_properties: membrane_voltage_limit: float | None @typing.overload - def __init__(self) -> None: - ... + def __init__(self) -> None: ... @typing.overload - def __init__(self, arg0: cable_global_properties) -> None: - ... - def __str__(self) -> str: - ... + def __init__(self, arg0: cable_global_properties) -> None: ... + def __str__(self) -> str: ... def check(self) -> None: """ Test whether all default parameters and ion species properties have been set. """ - def set_ion(self, ion: str, valence: int | None = None, int_con: units.quantity | None = None, ext_con: units.quantity | None = None, rev_pot: units.quantity | None = None, method: typing.Any = None, diff: units.quantity | None = None) -> None: + + def set_ion( + self, + ion: str, + valence: int | None = None, + int_con: units.quantity | None = None, + ext_con: units.quantity | None = None, + rev_pot: units.quantity | None = None, + method: typing.Any = None, + diff: units.quantity | None = None, + ) -> None: """ Set the global default properties of ion species named 'ion'. * valence: valence of the ion species [e]. @@ -303,7 +455,14 @@ class cable_global_properties: reversal potential is global for all compartments in the cell, and can't be overriden locally. """ - def set_property(self, Vm: units.quantity | None = None, cm: units.quantity | None = None, rL: units.quantity | None = None, tempK: units.quantity | None = None) -> None: + + def set_property( + self, + Vm: units.quantity | None = None, + cm: units.quantity | None = None, + rL: units.quantity | None = None, + tempK: units.quantity | None = None, + ) -> None: """ Set global default values for cable and cell properties. * Vm: initial membrane voltage [mV]. @@ -312,169 +471,179 @@ class cable_global_properties: * tempK: temperature [Kelvin]. These values can be overridden on specific regions using the paint interface. """ + def unset_ion(self, arg0: str) -> None: """ Remove ion species from properties. """ + @property - def axial_resistivity(self) -> float | None: - ... + def axial_resistivity(self) -> float | None: ... @property def catalogue(self) -> catalogue: """ The mechanism catalogue. """ + @catalogue.setter - def catalogue(self, arg0: catalogue) -> None: - ... + def catalogue(self, arg0: catalogue) -> None: ... @property def coalesce_synapses(self) -> bool: """ Flag for enabling/disabling linear syanpse coalescing. """ + @coalesce_synapses.setter - def coalesce_synapses(self, arg0: bool) -> None: - ... + def coalesce_synapses(self, arg0: bool) -> None: ... @property - def ion_data(self) -> dict[str, ion_data]: - ... + def ion_data(self) -> dict[str, ion_data]: ... @property - def ion_reversal_potential(self) -> dict[str, mechanism]: - ... + def ion_reversal_potential(self) -> dict[str, mechanism]: ... @property - def ion_valence(self) -> dict[str, int]: - ... + def ion_valence(self) -> dict[str, int]: ... @property def ions(self) -> dict[str, ion_settings]: """ Return a view of all ion settings. """ + @property - def membrane_capacitance(self) -> float | None: - ... + def membrane_capacitance(self) -> float | None: ... @property - def membrane_potential(self) -> float | None: - ... + def membrane_potential(self) -> float | None: ... @property - def temperature(self) -> float | None: - ... + def temperature(self) -> float | None: ... + class cable_probe_point_info: """ Probe metadata associated with a cable cell probe for point process state. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def location(self) -> location: """ Location of point process instance on cell. """ + @location.setter - def location(self, arg0: location) -> None: - ... + def location(self, arg0: location) -> None: ... @property def multiplicity(self) -> int: """ Number of coalesced point processes (linear synapses) associated with this instance. """ + @multiplicity.setter - def multiplicity(self, arg0: int) -> None: - ... + def multiplicity(self, arg0: int) -> None: ... @property def target(self) -> int: """ The target index of the point process instance on the cell. """ + @target.setter - def target(self, arg0: int) -> None: - ... + def target(self, arg0: int) -> None: ... + class catalogue: def __contains__(self, name: str) -> bool: """ Is 'name' in the catalogue? """ - def __getitem__(self, arg0: str) -> mechanism_info: - ... + + def __getitem__(self, arg0: str) -> mechanism_info: ... @typing.overload - def __init__(self) -> None: - ... + def __init__(self) -> None: ... @typing.overload - def __init__(self, arg0: catalogue) -> None: - ... + def __init__(self, arg0: catalogue) -> None: ... def __iter__(self) -> MechCatKeyIterator: """ Return an iterator over all mechanism names in this catalogues. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... - def derive(self, name: str, parent: str, globals: dict[str, float] = {}, ions: dict[str, str] = {}) -> None: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... + def derive( + self, + name: str, + parent: str, + globals: dict[str, float] = {}, + ions: dict[str, str] = {}, + ) -> None: ... def extend(self, other: catalogue, prefix: str) -> None: """ Import another catalogue, possibly with a prefix. Will overwrite in case of name collisions. """ + def is_derived(self, name: str) -> bool: """ Is 'name' a derived mechanism or can it be implicitly derived? """ + def items(self) -> MechCatItemIterator: """ Return an iterator over all (name, mechanism) tuples in this catalogues. """ + def keys(self) -> MechCatKeyIterator: """ Return an iterator over all mechanism names in this catalogues. """ + def values(self) -> MechCatValueIterator: """ Return an iterator over all mechanism info values in this catalogues. """ + class cell_address: gid: int tag: str + class cell_cv_data: """ Provides information on the CVs representing the discretization of a cable-cell. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def cables(self, index: int) -> list[cable]: """ Return a list of cables representing the CV at the given index. """ + def children(self, index: int) -> list[int]: """ Return a list of indices of the CVs representing the children of the CV at the given index. """ + def parent(self, index: int) -> int: """ Return the index of the CV representing the parent of the CV at the given index. """ + @property def num_cv(self) -> int: """ Return the number of CVs in the cell. """ + class cell_global_label: """ For global identification of an item. - + cell_global_label members: (1) a unique cell identified by its gid. (2) a cell_local_label, referring to a labeled group of items on the cell and a policy for selecting a single item out of the group. """ + @typing.overload def __init__(self, gid: int, label: str) -> None: """ Construct a cell_global_label identifier from a gid and a label argument identifying an item on the cell. The default round_robin policy is used for selecting one of possibly multiple items on the cell associated with the label. """ + @typing.overload def __init__(self, gid: int, label: cell_local_label) -> None: """ @@ -482,6 +651,7 @@ class cell_global_label: gid: The global identifier of the cell. label: The cell_local_label representing the label and selection policy of an item on the cell. """ + @typing.overload def __init__(self, arg0: tuple) -> None: """ @@ -489,85 +659,79 @@ class cell_global_label: gid: The global identifier of the cell. label: The cell_local_label representing the label and selection policy of an item on the cell. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def gid(self) -> int: """ The global identifier of the cell. """ + @gid.setter - def gid(self, arg0: int) -> None: - ... + def gid(self, arg0: int) -> None: ... @property def label(self) -> cell_local_label: """ The cell_local_label representing the label and selection policy of an item on the cell. """ + @label.setter - def label(self, arg0: cell_local_label) -> None: - ... + def label(self, arg0: cell_local_label) -> None: ... + class cell_kind: """ Enumeration used to identify the cell kind, used by the model to group equal kinds in the same cell group. - + Members: - + benchmark : Proxy cell used for benchmarking. - + cable : A cell with morphology described by branching 1D cable segments. - + lif : Leaky-integrate and fire neuron. - + spike_source : Proxy cell that generates spikes from a spike sequence provided by the user. """ - __members__: typing.ClassVar[dict[str, cell_kind]] # value = {'benchmark': , 'cable': , 'lif': , 'spike_source': } + + __members__: typing.ClassVar[ + dict[str, cell_kind] + ] # value = {'benchmark': , 'cable': , 'lif': , 'spike_source': } benchmark: typing.ClassVar[cell_kind] # value = cable: typing.ClassVar[cell_kind] # value = lif: typing.ClassVar[cell_kind] # value = spike_source: typing.ClassVar[cell_kind] # value = - def __eq__(self, other: typing.Any) -> bool: - ... - def __getstate__(self) -> int: - ... - def __hash__(self) -> int: - ... - def __index__(self) -> int: - ... - def __init__(self, value: int) -> None: - ... - def __int__(self) -> int: - ... - def __ne__(self, other: typing.Any) -> bool: - ... - def __repr__(self) -> str: - ... - def __setstate__(self, state: int) -> None: - ... - def __str__(self) -> str: - ... - @property - def name(self) -> str: - ... - @property - def value(self) -> int: - ... + def __eq__(self, other: typing.Any) -> bool: ... + def __getstate__(self) -> int: ... + def __hash__(self) -> int: ... + def __index__(self) -> int: ... + def __init__(self, value: int) -> None: ... + def __int__(self) -> int: ... + def __ne__(self, other: typing.Any) -> bool: ... + def __repr__(self) -> str: ... + def __setstate__(self, state: int) -> None: ... + def __str__(self) -> str: ... + @property + def name(self) -> str: ... + @property + def value(self) -> int: ... + class cell_local_label: """ For local identification of an item. - + cell_local_label identifies: (1) a labeled group of one or more items on one or more locations on the cell. (2) a policy for selecting one of the items. """ + @typing.overload def __init__(self, label: str) -> None: """ Construct a cell_local_label identifier from a label argument identifying a group of one or more items on a cell. The default round_robin policy is used for selecting one of possibly multiple items associated with the label. """ + @typing.overload def __init__(self, label: str, policy: selection_policy) -> None: """ @@ -575,6 +739,7 @@ class cell_local_label: label: The identifier of a group of one or more items on a cell. policy: The policy for selecting one of possibly multiple items associated with the label. """ + @typing.overload def __init__(self, arg0: tuple) -> None: """ @@ -582,34 +747,35 @@ class cell_local_label: label: The identifier of a group of one or more items on a cell. policy: The policy for selecting one of possibly multiple items associated with the label. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def label(self) -> str: """ The identifier of a a group of one or more items on a cell. """ + @label.setter - def label(self, arg0: str) -> None: - ... + def label(self, arg0: str) -> None: ... @property def policy(self) -> selection_policy: """ The policy for selecting one of possibly multiple items associated with the label. """ + @policy.setter - def policy(self, arg0: selection_policy) -> None: - ... + def policy(self, arg0: selection_policy) -> None: ... + class cell_member: """ For global identification of a cell-local item. - + Items of cell_member must: (1) be associated with a unique cell, identified by the member gid; (2) identify an item within a cell-local collection by the member index. """ + @typing.overload def __init__(self, gid: int, index: int) -> None: """ @@ -617,6 +783,7 @@ class cell_member: gid: The global identifier of the cell. index: The cell-local index of the item. """ + @typing.overload def __init__(self, arg0: tuple) -> None: """ @@ -624,41 +791,49 @@ class cell_member: gid: The global identifier of the cell. index: The cell-local index of the item. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def gid(self) -> int: """ The global identifier of the cell. """ + @gid.setter - def gid(self, arg0: int) -> None: - ... + def gid(self, arg0: int) -> None: ... @property def index(self) -> int: """ Cell-local index of the item. """ + @index.setter - def index(self, arg0: int) -> None: - ... + def index(self, arg0: int) -> None: ... + class component_meta_data: @property def version(self) -> str: """ cable-cell component version. """ + @version.setter - def version(self, arg0: str) -> None: - ... + def version(self, arg0: str) -> None: ... + class connection: """ Describes a connection between two cells: Defined by source and destination end points (that is pre-synaptic and post-synaptic respectively), a connection weight and a delay time. """ - def __init__(self, source: cell_global_label, dest: cell_local_label, weight: float, delay: units.quantity) -> None: + + def __init__( + self, + source: cell_global_label, + dest: cell_local_label, + weight: float, + delay: units.quantity, + ) -> None: """ Construct a connection with arguments: source: The source end point of the connection. @@ -666,53 +841,64 @@ class connection: weight: The weight delivered to the target synapse (unit defined by the type of synapse target). delay: The delay of the connection [ms]. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def delay(self) -> float: """ The delay time of the connection [ms]. """ + @delay.setter - def delay(self, arg0: float) -> None: - ... + def delay(self, arg0: float) -> None: ... @property def dest(self) -> cell_local_label: """ The destination label of the connection. """ + @dest.setter - def dest(self, arg0: cell_local_label) -> None: - ... + def dest(self, arg0: cell_local_label) -> None: ... @property def source(self) -> cell_global_label: """ The source gid and label of the connection. """ + @source.setter - def source(self, arg0: cell_global_label) -> None: - ... + def source(self, arg0: cell_global_label) -> None: ... @property def weight(self) -> float: """ The weight of the connection. """ + @weight.setter - def weight(self, arg0: float) -> None: - ... + def weight(self, arg0: float) -> None: ... + class context: """ An opaque handle for the hardware resources used in a simulation. """ + @typing.overload def __init__(self) -> None: """ Construct a local context with proc_allocation = env.default_allocation(). """ + @typing.overload - def __init__(self, *, threads: int = 1, gpu_id: typing.Any = None, mpi: typing.Any = None, inter: typing.Any = None, bind_procs: bool = False, bind_threads: bool = False) -> None: + def __init__( + self, + *, + threads: int = 1, + gpu_id: typing.Any = None, + mpi: typing.Any = None, + inter: typing.Any = None, + bind_procs: bool = False, + bind_threads: bool = False, + ) -> None: """ Construct a context with arguments: threads: The number of threads available locally for execution. Must be set to 1 at minimum. 1 by default. @@ -722,106 +908,141 @@ class context: bind_procs: Create process binding mask. bind_threads: Create thread binding mask. """ + @typing.overload - def __init__(self, alloc: proc_allocation, *, mpi: typing.Any = None, inter: typing.Any = None) -> None: + def __init__( + self, + alloc: proc_allocation, + *, + mpi: typing.Any = None, + inter: typing.Any = None, + ) -> None: """ Construct a context with arguments: alloc: The computational resources to be used for the simulation. mpi: The MPI communicator, None by default. Only available if arbor.__config__['mpi']==True. inter: An MPI intercommunicator used to connect to external simulations, None by default. Only available if arbor.__config__['mpi']==True. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def has_gpu(self) -> bool: """ Whether the context has a GPU. """ + @property def has_mpi(self) -> bool: """ Whether the context uses MPI for distributed communication. """ + @property def rank(self) -> int: """ The numeric id of the local domain (equivalent to MPI rank). """ + @property def ranks(self) -> int: """ The number of distributed domains (equivalent to the number of MPI ranks). """ + @property def threads(self) -> int: """ The number of threads in the context's thread pool. """ + class cv_policy: """ Describes the rules used to discretize (compartmentalise) a cable cell morphology. """ - def __add__(self, arg0: cv_policy) -> cv_policy: - ... + + def __add__(self, arg0: cv_policy) -> cv_policy: ... def __init__(self, expression: str) -> None: """ A valid CV policy expression """ - def __or__(self, arg0: cv_policy) -> cv_policy: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __or__(self, arg0: cv_policy) -> cv_policy: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def domain(self) -> str: """ The domain on which the policy is applied. """ + class decor: """ Description of the decorations to be applied to a cable cell, that is the painted, placed and defaulted properties, mecahanisms, ion species etc. """ - @typing.overload - def __init__(self) -> None: - ... - @typing.overload - def __init__(self, arg0: decor) -> None: - ... - def defaults(self) -> list[membrane_potential | axial_resistivity | temperature | membrane_capacitance | ion_diffusivity | int_concentration | ext_concentration | reversal_potential | reversal_potential_method | cv_policy]: + + @typing.overload + def __init__(self) -> None: ... + @typing.overload + def __init__(self, arg0: decor) -> None: ... + def defaults( + self, + ) -> list[ + membrane_potential + | axial_resistivity + | temperature + | membrane_capacitance + | ion_diffusivity + | int_concentration + | ext_concentration + | reversal_potential + | reversal_potential_method + | cv_policy + ]: """ Return a view of all defaults. """ + @typing.overload def discretization(self, policy: cv_policy) -> decor: """ A cv_policy used to discretise the cell into compartments for simulation """ + @typing.overload def discretization(self, policy: str) -> decor: """ An s-expression string representing a cv_policy used to discretise the cell into compartments for simulation """ + @typing.overload def paint(self, region: str, mechanism: density) -> decor: """ Associate a density mechanism with a region. """ + @typing.overload def paint(self, region: str, mechanism: voltage_process) -> decor: """ Associate a voltage process mechanism with a region. """ + @typing.overload def paint(self, region: str, mechanism: scaled_mechanism) -> None: """ Associate a scaled density mechanism with a region. """ + @typing.overload - def paint(self, region: str, Vm: units.quantity | tuple[units.quantity, str] | None = None, cm: units.quantity | tuple[units.quantity, str] | None = None, rL: units.quantity | tuple[units.quantity, str] | None = None, tempK: units.quantity | tuple[units.quantity, str] | None = None) -> decor: + def paint( + self, + region: str, + Vm: units.quantity | tuple[units.quantity, str] | None = None, + cm: units.quantity | tuple[units.quantity, str] | None = None, + rL: units.quantity | tuple[units.quantity, str] | None = None, + tempK: units.quantity | tuple[units.quantity, str] | None = None, + ) -> decor: """ Set cable properties on a region. Set global default values for cable and cell properties. @@ -831,8 +1052,18 @@ class decor: * tempK: temperature [Kelvin]. Each value can be given as a plain quantity or a tuple of (quantity, 'scale') where scale is an iexpr. """ + @typing.overload - def paint(self, region: str, *, ion: str, int_con: units.quantity | tuple[units.quantity, str] | None = None, ext_con: units.quantity | tuple[units.quantity, str] | None = None, rev_pot: units.quantity | tuple[units.quantity, str] | None = None, diff: units.quantity | tuple[units.quantity, str] | None = None) -> decor: + def paint( + self, + region: str, + *, + ion: str, + int_con: units.quantity | tuple[units.quantity, str] | None = None, + ext_con: units.quantity | tuple[units.quantity, str] | None = None, + rev_pot: units.quantity | tuple[units.quantity, str] | None = None, + diff: units.quantity | tuple[units.quantity, str] | None = None, + ) -> decor: """ Set ion species properties conditions on a region. * int_con: initial internal concentration [mM]. @@ -842,35 +1073,69 @@ class decor: * diff: diffusivity [m^2/s]. Each value can be given as a plain quantity or a tuple of (quantity, 'scale') where scale is an iexpr. """ - def paintings(self) -> list[tuple[str, membrane_potential | axial_resistivity | temperature | membrane_capacitance | ion_diffusivity | int_concentration | ext_concentration | reversal_potential | density | voltage_process | scaled_mechanism]]: + + def paintings( + self, + ) -> list[ + tuple[ + str, + membrane_potential + | axial_resistivity + | temperature + | membrane_capacitance + | ion_diffusivity + | int_concentration + | ext_concentration + | reversal_potential + | density + | voltage_process + | scaled_mechanism, + ] + ]: """ Return a view of all painted items. """ + @typing.overload def place(self, locations: str, synapse: synapse, label: str) -> decor: """ Place one instance of 'synapse' on each location in 'locations'.The group of synapses has the label 'label', used for forming connections between cells. """ + @typing.overload def place(self, locations: str, junction: junction, label: str) -> decor: """ Place one instance of 'junction' on each location in 'locations'.The group of junctions has the label 'label', used for forming gap-junction connections between cells. """ + @typing.overload def place(self, locations: str, iclamp: iclamp, label: str) -> decor: """ Add a current stimulus at each location in locations.The group of current stimuli has the label 'label'. """ + @typing.overload def place(self, locations: str, detector: threshold_detector, label: str) -> decor: """ Add a voltage spike detector at each location in locations.The group of spike detectors has the label 'label', used for forming connections between cells. """ - def placements(self) -> list[tuple[str, iclamp | threshold_detector | synapse | junction, str]]: + + def placements( + self, + ) -> list[tuple[str, iclamp | threshold_detector | synapse | junction, str]]: """ Return a view of all placed items. """ - def set_ion(self, ion: str, int_con: units.quantity | None = None, ext_con: units.quantity | None = None, rev_pot: units.quantity | None = None, method: typing.Any = None, diff: units.quantity | None = None) -> decor: + + def set_ion( + self, + ion: str, + int_con: units.quantity | None = None, + ext_con: units.quantity | None = None, + rev_pot: units.quantity | None = None, + method: typing.Any = None, + diff: units.quantity | None = None, + ) -> decor: """ Set the cell-level properties of ion species named 'ion'. * int_con: initial internal concentration [mM]. @@ -887,7 +1152,14 @@ class decor: reversal potential is global for all compartments in the cell, and can't be overriden locally. """ - def set_property(self, Vm: units.quantity | None = None, cm: units.quantity | None = None, rL: units.quantity | None = None, tempK: units.quantity | None = None) -> decor: + + def set_property( + self, + Vm: units.quantity | None = None, + cm: units.quantity | None = None, + rL: units.quantity | None = None, + tempK: units.quantity | None = None, + ) -> decor: """ Set default values for cable and cell properties: * Vm: initial membrane voltage [mV]. @@ -896,331 +1168,372 @@ class decor: * tempK: temperature [Kelvin]. These values can be overridden on specific regions using the paint interface. """ + class density: """ For painting a density mechanism on a region. """ + @typing.overload - def __init__(self, arg0: str) -> None: - ... + def __init__(self, arg0: str) -> None: ... @typing.overload - def __init__(self, arg0: mechanism) -> None: - ... + def __init__(self, arg0: mechanism) -> None: ... @typing.overload - def __init__(self, arg0: str, arg1: dict[str, float]) -> None: - ... + def __init__(self, arg0: str, arg1: dict[str, float]) -> None: ... @typing.overload - def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: - ... + def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: ... @typing.overload - def __init__(self, arg0: str, **kwargs) -> None: - ... + def __init__(self, arg0: str, **kwargs) -> None: ... @typing.overload - def __init__(self, arg0: mechanism, **kwargs) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + def __init__(self, arg0: mechanism, **kwargs) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def mech(self) -> mechanism: """ The underlying mechanism. """ + class domain_decomposition: """ The domain decomposition is responsible for describing the distribution of cells across cell groups and domains. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def gid_domain(self, gid: int) -> int: """ Query the domain id that a cell assigned to (using global identifier gid). """ + @property def domain_id(self) -> int: """ The index of the local domain. Always 0 for non-distributed models, and corresponds to the MPI rank for distributed runs. """ + @property def groups(self) -> list[group_description]: """ Descriptions of the cell groups on the local domain. """ + @property def num_domains(self) -> int: """ Number of domains that the model is distributed over. """ + @property def num_global_cells(self) -> int: """ Total number of cells in the global model (sum of num_local_cells over all domains). """ + @property def num_groups(self) -> int: """ Total number of cell groups in the local domain. """ + @property def num_local_cells(self) -> int: """ Total number of cells in the local domain. """ + class event_generator: - def __init__(self, target: cell_local_label, weight: float, sched: schedule_base) -> None: + def __init__( + self, target: cell_local_label, weight: float, sched: schedule_base + ) -> None: """ Construct an event generator with arguments: target: The target synapse label and selection policy. weight: The weight of events to deliver. sched: A schedule of the events. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def target(self) -> cell_local_label: """ The target synapse (gid, local_id). """ + @target.setter - def target(self, arg0: cell_local_label) -> None: - ... + def target(self, arg0: cell_local_label) -> None: ... @property def weight(self) -> float: """ The weight of events to deliver. """ + @weight.setter - def weight(self, arg0: float) -> None: - ... + def weight(self, arg0: float) -> None: ... + class explicit_schedule(schedule_base): """ Describes an explicit schedule at a predetermined (sorted) sequence of times. """ + @typing.overload def __init__(self) -> None: """ Construct an empty explicit schedule. """ + @typing.overload def __init__(self, times: list[units.quantity]) -> None: """ Construct an explicit schedule with argument: times: A list of times [ms], [] by default. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def events(self, arg0: float, arg1: float) -> list[float]: """ A view of monotonically increasing time values in the half-open interval [t0, t1) in [ms]. """ + @property def times_ms(self) -> list[float]: """ A list of times [ms]. """ + @times_ms.setter - def times_ms(self, arg1: list[float]) -> None: - ... + def times_ms(self, arg1: list[float]) -> None: ... + class ext_concentration: """ Setting the initial external ion concentration. """ - def __init__(self, arg0: str, arg1: units.quantity) -> None: - ... - def __repr__(self) -> str: - ... + + def __init__(self, arg0: str, arg1: units.quantity) -> None: ... + def __repr__(self) -> str: ... + class extent: """ A potentially empty region on a morphology. """ + class gap_junction_connection: """ Describes a gap junction between two gap junction sites. """ - def __init__(self, peer: cell_global_label, local: cell_local_label, weight: float) -> None: + + def __init__( + self, peer: cell_global_label, local: cell_local_label, weight: float + ) -> None: """ Construct a gap junction connection with arguments: peer: remote half of the gap junction connection. local: local half of the gap junction connection. weight: Gap junction connection weight [unit-less]. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def local(self) -> cell_local_label: """ Local label of the gap junction connection. """ + @local.setter - def local(self, arg0: cell_local_label) -> None: - ... + def local(self, arg0: cell_local_label) -> None: ... @property def peer(self) -> cell_global_label: """ Remote gid and label of the gap junction connection. """ + @peer.setter - def peer(self, arg0: cell_global_label) -> None: - ... + def peer(self, arg0: cell_global_label) -> None: ... @property def weight(self) -> float: """ Gap junction connection weight [unit-less]. """ + @weight.setter - def weight(self, arg0: float) -> None: - ... + def weight(self, arg0: float) -> None: ... + class group_description: """ The indexes of a set of cells of the same kind that are grouped together in a cell group. """ + def __init__(self, kind: cell_kind, gids: list[int], backend: backend) -> None: """ Construct a group description with cell kind, list of gids, and backend kind. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def backend(self) -> backend: """ The hardware backend on which the cell group will run. """ + @property def gids(self) -> list[int]: """ The list of gids of the cells in the group. """ + @property def kind(self) -> cell_kind: """ The type of cell in the cell group. """ + class iclamp: """ A current clamp for injecting a DC or fixed frequency current governed by a piecewise linear envelope. """ + @typing.overload - def __init__(self, tstart: units.quantity, duration: units.quantity, current: units.quantity, *, frequency: units.quantity = ..., phase: units.quantity = ...) -> None: + def __init__( + self, + tstart: units.quantity, + duration: units.quantity, + current: units.quantity, + *, + frequency: units.quantity = ..., + phase: units.quantity = ..., + ) -> None: """ Construct finite duration current clamp, constant amplitude """ + @typing.overload - def __init__(self, current: units.quantity, *, frequency: units.quantity = ..., phase: units.quantity = ...) -> None: + def __init__( + self, + current: units.quantity, + *, + frequency: units.quantity = ..., + phase: units.quantity = ..., + ) -> None: """ Construct constant amplitude current clamp """ + @typing.overload - def __init__(self, envelope: list[tuple[units.quantity, units.quantity]], *, frequency: units.quantity = ..., phase: units.quantity = ...) -> None: + def __init__( + self, + envelope: list[tuple[units.quantity, units.quantity]], + *, + frequency: units.quantity = ..., + phase: units.quantity = ..., + ) -> None: """ Construct current clamp according to (time, amplitude) linear envelope """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def envelope(self) -> list[tuple[float, float]]: """ List of (time [ms], amplitude [nA]) points comprising the piecewise linear envelope """ + @property def frequency(self) -> float: """ Oscillation frequency (kHz), zero implies DC stimulus. """ + @property def phase(self) -> float: """ Oscillation initial phase (rad) """ + class int_concentration: """ Setting the initial internal ion concentration. """ - def __init__(self, arg0: str, arg1: units.quantity) -> None: - ... - def __repr__(self) -> str: - ... + + def __init__(self, arg0: str, arg1: units.quantity) -> None: ... + def __repr__(self) -> str: ... + class ion_data: @property def charge(self) -> int: """ Valence. """ + @property def diffusivity(self) -> float | None: """ Diffusivity. """ + @property def external_concentration(self) -> float | None: """ External concentration. """ + @property def internal_concentration(self) -> float | None: """ Internal concentration. """ + @property def reversal_concentration(self) -> float | None: """ Reversal potential. """ + @property def reversal_potential(self) -> float | None: """ Reversal potential. """ + @property def reversal_potential_method(self) -> str: """ Reversal potential method. """ + class ion_dependency: """ Information about a mechanism's dependence on an ion species. """ - def __init__(self, arg0: ion_dependency) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __init__(self, arg0: ion_dependency) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property - def read_rev_pot(self) -> bool: - ... + def read_rev_pot(self) -> bool: ... @property - def write_ext_con(self) -> bool: - ... + def write_ext_con(self) -> bool: ... @property - def write_int_con(self) -> bool: - ... + def write_int_con(self) -> bool: ... @property - def write_rev_pot(self) -> bool: - ... + def write_rev_pot(self) -> bool: ... + class ion_diffusivity: """ Setting the ion diffusivity. """ - def __init__(self, arg0: str, arg1: units.quantity) -> None: - ... - def __repr__(self) -> str: - ... + + def __init__(self, arg0: str, arg1: units.quantity) -> None: ... + def __repr__(self) -> str: ... + class ion_settings: pass + class isometry: @staticmethod @typing.overload @@ -1228,121 +1541,122 @@ class isometry: """ Construct a rotation isometry of angle theta about the axis in direction (x, y, z). """ + @staticmethod @typing.overload def rotate(theta: float, axis: tuple) -> isometry: """ Construct a rotation isometry of angle theta about the given axis in the direction described by a tuple. """ + @staticmethod @typing.overload def translate(x: float, y: float, z: float) -> isometry: """ Construct a translation isometry from displacements x, y, and z. """ + @staticmethod @typing.overload def translate(arg0: tuple) -> isometry: """ Construct a translation isometry from the first three components of a tuple. """ + @staticmethod @typing.overload def translate(arg0: mpoint) -> isometry: """ Construct a translation isometry from the x, y, and z components of an mpoint. """ + @typing.overload def __call__(self, arg0: mpoint) -> mpoint: """ Apply isometry to mpoint argument. """ + @typing.overload def __call__(self, arg0: tuple) -> tuple: """ Apply isometry to first three components of tuple argument. """ + def __init__(self) -> None: """ Construct a trivial isometry. """ - def __mul__(self, arg0: isometry) -> isometry: - ... + + def __mul__(self, arg0: isometry) -> isometry: ... + class junction: """ For placing a gap-junction mechanism on a locset. """ + @typing.overload - def __init__(self, arg0: str) -> None: - ... + def __init__(self, arg0: str) -> None: ... @typing.overload - def __init__(self, arg0: mechanism) -> None: - ... + def __init__(self, arg0: mechanism) -> None: ... @typing.overload - def __init__(self, arg0: str, arg1: dict[str, float]) -> None: - ... + def __init__(self, arg0: str, arg1: dict[str, float]) -> None: ... @typing.overload - def __init__(self, arg0: str, **kwargs) -> None: - ... + def __init__(self, arg0: str, **kwargs) -> None: ... @typing.overload - def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: - ... + def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: ... @typing.overload - def __init__(self, arg0: mechanism, **kwargs) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + def __init__(self, arg0: mechanism, **kwargs) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def mech(self) -> mechanism: """ The underlying mechanism. """ + class label_dict: """ A dictionary of labelled region and locset definitions, with a unique label assigned to each definition. """ + @staticmethod def append(*args, **kwargs) -> None: """ Import the entries of a another label dictionary with an optional prefix. """ - def __contains__(self, arg0: str) -> bool: - ... - def __getitem__(self, arg0: str) -> str: - ... + + def __contains__(self, arg0: str) -> bool: ... + def __getitem__(self, arg0: str) -> str: ... @typing.overload def __init__(self) -> None: """ Create an empty label dictionary. """ + @typing.overload def __init__(self, arg0: dict[str, str]) -> None: """ Initialize a label dictionary from a dictionary with string labels as keys, and corresponding definitions as strings. """ + @typing.overload def __init__(self, arg0: label_dict) -> None: """ Initialize a label dictionary from another one """ + @typing.overload def __init__(self, arg0: typing.Iterator) -> None: """ Initialize a label dictionary from an iterable of key, definition pairs """ - def __iter__(self) -> typing.Iterator: - ... - def __len__(self) -> int: - ... - def __repr__(self) -> str: - ... - def __setitem__(self, arg0: str, arg1: str) -> None: - ... - def __str__(self) -> str: - ... + + def __iter__(self) -> typing.Iterator: ... + def __len__(self) -> int: ... + def __repr__(self) -> str: ... + def __setitem__(self, arg0: str, arg1: str) -> None: ... + def __str__(self) -> str: ... def add_swc_tags(self) -> label_dict: """ Add standard SWC tagged regions. @@ -1351,31 +1665,44 @@ class label_dict: - dend: (tag 3) - apic: (tag 4) """ - def items(self) -> typing.Iterator: - ... - def keys(self) -> typing.Iterator: - ... + + def items(self) -> typing.Iterator: ... + def keys(self) -> typing.Iterator: ... def update(self, other: label_dict) -> None: """ The label_dict to be importedImport the entries of a another label dictionary. """ - def values(self) -> typing.Iterator: - ... + + def values(self) -> typing.Iterator: ... @property def locsets(self) -> list[str]: """ The locset definitions. """ + @property def regions(self) -> list[str]: """ The region definitions. """ + class lif_cell: """ A leaky integrate-and-fire cell. """ - def __init__(self, source_label: str, target_label: str, *, tau_m: units.quantity | None = None, V_th: units.quantity | None = None, C_m: units.quantity | None = None, E_L: units.quantity | None = None, V_m: units.quantity | None = None, t_ref: units.quantity | None = None) -> None: + + def __init__( + self, + source_label: str, + target_label: str, + *, + tau_m: units.quantity | None = None, + V_th: units.quantity | None = None, + C_m: units.quantity | None = None, + E_L: units.quantity | None = None, + V_m: units.quantity | None = None, + t_ref: units.quantity | None = None, + ) -> None: """ Construct a lif cell with one source labeled 'source_label', and one target labeled 'target_label'.Can optionally take physical parameters: * tau_m: Membrane potential decaying constant [ms]. @@ -1385,143 +1712,151 @@ class lif_cell: * V_m: Initial value of the Membrane potential [mV]. * t_ref: Refractory period [ms]. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def C_m(self) -> units.quantity: """ Membrane capacitance [pF]. """ + @C_m.setter - def C_m(self, arg0: units.quantity) -> None: - ... + def C_m(self, arg0: units.quantity) -> None: ... @property def E_L(self) -> units.quantity: """ Resting potential [mV]. """ + @E_L.setter - def E_L(self, arg0: units.quantity) -> None: - ... + def E_L(self, arg0: units.quantity) -> None: ... @property def E_R(self) -> units.quantity: """ Reset potential [mV]. """ + @E_R.setter - def E_R(self, arg0: units.quantity) -> None: - ... + def E_R(self, arg0: units.quantity) -> None: ... @property def V_m(self) -> units.quantity: """ Initial value of the Membrane potential [mV]. """ + @V_m.setter - def V_m(self, arg0: units.quantity) -> None: - ... + def V_m(self, arg0: units.quantity) -> None: ... @property def V_th(self) -> units.quantity: """ Firing threshold [mV]. """ + @V_th.setter - def V_th(self, arg0: units.quantity) -> None: - ... + def V_th(self, arg0: units.quantity) -> None: ... @property def source(self) -> str: """ Label of the single build-in source on the cell. """ + @source.setter - def source(self, arg0: str) -> None: - ... + def source(self, arg0: str) -> None: ... @property def t_ref(self) -> units.quantity: """ Refractory period [ms]. """ + @t_ref.setter - def t_ref(self, arg0: units.quantity) -> None: - ... + def t_ref(self, arg0: units.quantity) -> None: ... @property def target(self) -> str: """ Label of the single build-in target on the cell. """ + @target.setter - def target(self, arg0: str) -> None: - ... + def target(self, arg0: str) -> None: ... @property def tau_m(self) -> units.quantity: """ Membrane potential decaying constant [ms]. """ + @tau_m.setter - def tau_m(self, arg0: units.quantity) -> None: - ... + def tau_m(self, arg0: units.quantity) -> None: ... + class lif_probe_metadata: """ Probe metadata associated with a LIF cell probe. """ + class loaded_morphology: """ The morphology and label dictionary meta-data loaded from file. """ + @property def labels(self) -> label_dict: """ Any labels defined by the loaded file. """ + @property def metadata(self) -> swc_metadata | asc_metadata | nml_metadata: """ File type specific metadata. """ + @property def morphology(self) -> morphology: """ The cable cell morphology. """ + @property def segment_tree(self) -> segment_tree: """ The raw segment tree. """ + class location: """ A location on a cable cell. """ + __hash__: typing.ClassVar[None] = None - def __eq__(self, arg0: location) -> bool: - ... + def __eq__(self, arg0: location) -> bool: ... def __init__(self, branch: int, pos: float) -> None: """ Construct a location specification holding: branch: The id of the branch. pos: The relative position (from 0., proximal, to 1., distal) on the branch. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def branch(self) -> int: """ The id of the branch. """ + @property def pos(self) -> float: """ The relative position on the branch (∈ [0.,1.], where 0. means proximal and 1. distal). """ + class mechanism: @typing.overload def __init__(self, name: str) -> None: """ The name of the mechanism """ + @typing.overload def __init__(self, name: str, params: dict[str, float]) -> None: """ @@ -1530,10 +1865,11 @@ class mechanism: will create parameters for the 'expsyn' mechanism, with the provided value for 'tau' overrides the default. If a parameter is not set, the default (as defined in NMODL) is used. - + Example overriding a global parameter: m = arbor.mechanism('nernst/R=8.3145,F=96485') """ + @typing.overload def __init__(self, name: str, **kwargs) -> None: """ @@ -1542,276 +1878,310 @@ class mechanism: will create parameters for the 'expsyn' mechanism, with the provided value for 'tau' overrides the default. If a parameter is not set, the default (as defined in NMODL) is used. - + Example overriding a global parameter: m = arbor.mechanism('nernst/R=8.3145,F=96485') """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def set(self, name: str, value: float) -> None: """ Set parameter value. """ + @property def name(self) -> str: """ The name of the mechanism. """ + @property def values(self) -> dict[str, float]: """ A dictionary of parameter values with parameter name as key. """ + class mechanism_field: """ Basic information about a mechanism field. """ - def __init__(self, arg0: mechanism_field) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __init__(self, arg0: mechanism_field) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property - def default(self) -> float: - ... + def default(self) -> float: ... @property - def max(self) -> float: - ... + def max(self) -> float: ... @property - def min(self) -> float: - ... + def min(self) -> float: ... @property - def units(self) -> str: - ... + def units(self) -> str: ... + class mechanism_info: """ Meta data about a mechanism's fields and ion dependendencies. """ - def __init__(self, arg0: mechanism_info) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __init__(self, arg0: mechanism_info) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def globals(self) -> dict[str, mechanism_field]: """ Global fields have one value common to an instance of a mechanism, are constant in time and set at instantiation. """ + @property def ions(self) -> dict[str, ion_dependency]: """ Ion dependencies. """ + @property def kind(self) -> str: """ String representation of the kind of the mechanism. """ + @property def linear(self) -> bool: """ True if a synapse mechanism has linear current contributions so that multiple instances on the same compartment can be coalesced. """ + @property def parameters(self) -> dict[str, mechanism_field]: """ Parameter fields may vary across the extent of a mechanism, but are constant in time and set at instantiation. """ + @property def post_events(self) -> bool: """ True if a synapse mechanism has a `POST_EVENT` procedure defined. """ + @property def state(self) -> dict[str, mechanism_field]: """ State fields vary in time and across the extent of a mechanism, and potentially can be sampled at run-time. """ + class membrane_capacitance: """ Setting the membrane capacitance. """ - def __init__(self, arg0: units.quantity) -> None: - ... - def __repr__(self) -> str: - ... + + def __init__(self, arg0: units.quantity) -> None: ... + def __repr__(self) -> str: ... + class membrane_potential: """ Setting the initial membrane voltage. """ - def __init__(self, arg0: units.quantity) -> None: - ... - def __repr__(self) -> str: - ... + + def __init__(self, arg0: units.quantity) -> None: ... + def __repr__(self) -> str: ... + class meter_manager: """ Manage metering by setting checkpoints and starting the timing region. """ - def __init__(self) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __init__(self) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def checkpoint(self, name: str, context: context) -> None: """ Create a new checkpoint. Records the time since the last checkpoint(or the call to start if no previous checkpoints exist),and restarts the timer for the next checkpoint. """ + def start(self, context: context) -> None: """ Start the metering. Records a time stamp, that marks the start of the first checkpoint timing region. """ + @property def checkpoint_names(self) -> list[str]: """ A list of all metering checkpoint names. """ + @property def times(self) -> list[float]: """ A list of all metering times. """ + class meter_report: """ Summarises the performance meter results, used to print a report to screen or file. If a distributed context is used, the report will contain a summary of results from all MPI ranks. """ - def __init__(self, manager: meter_manager, context: context) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __init__(self, manager: meter_manager, context: context) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... + class morphology: """ A cell morphology. """ + class morphology_provider: def __init__(self, morphology: morphology) -> None: """ Construct a morphology provider. """ + def reify_locset(self, arg0: str) -> list[location]: """ Turn a locset into a list of locations. """ + def reify_region(self, arg0: str) -> extent: """ Turn a region into an extent. """ + class mpoint: __hash__: typing.ClassVar[None] = None - def __eq__(self, arg0: mpoint) -> bool: - ... + def __eq__(self, arg0: mpoint) -> bool: ... @typing.overload def __init__(self, x: float, y: float, z: float, radius: float) -> None: """ Create an mpoint object from parameters x, y, z, and radius, specified in µm. """ + @typing.overload def __init__(self, arg0: tuple) -> None: """ Create an mpoint object from a tuple (x, y, z, radius), specified in µm. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def radius(self) -> float: """ Radius of cable at sample location centred at coordinates [μm]. """ + @property def x(self) -> float: """ X coordinate [μm]. """ + @property def y(self) -> float: """ Y coordinate [μm]. """ + @property def z(self) -> float: """ Z coordinate [μm]. """ + class msegment: @property def dist(self) -> mpoint: """ the location and radius of the distal end. """ + @property def prox(self) -> mpoint: """ the location and radius of the proximal end. """ + @property def tag(self) -> int: """ tag meta-data. """ + class neuroml: def __init__(self, arg0: typing.Any) -> None: """ Construct NML morphology from filename or stream. """ + def cell_ids(self) -> list[str]: """ Query top-level cells. """ - def cell_morphology(self, cell_id: str, allow_spherical_root: bool = False) -> loaded_morphology | None: + + def cell_morphology( + self, cell_id: str, allow_spherical_root: bool = False + ) -> loaded_morphology | None: """ Retrieve nml_morph_data associated with cell_id. """ - def morphology(self, morph_id: str, allow_spherical_root: bool = False) -> loaded_morphology | None: + + def morphology( + self, morph_id: str, allow_spherical_root: bool = False + ) -> loaded_morphology | None: """ Retrieve top-level nml_morph_data associated with morph_id. """ + def morphology_ids(self) -> list[str]: """ Query top-level standalone morphologies. """ + class nml_metadata: def groups(self) -> label_dict: """ Label dictionary containing one region expression for each segmentGroup id. """ + def named_segments(self) -> label_dict: """ Label dictionary containing one region expression for each name applied to one or more segments. """ + def segments(self) -> label_dict: """ Label dictionary containing one region expression for each segment id. """ + @property def cell_id(self) -> str | None: """ Cell id, or empty if morphology was taken from a top-level element. """ + @property def group_segments(self) -> dict[str, list[int]]: """ Map from segmentGroup ids to their corresponding segment ids. """ + @property def id(self) -> str: """ Morphology id. """ + class partition_hint: """ Provide a hint on how the cell groups should be partitioned. """ + max_size: typing.ClassVar[int] = 18446744073709551615 - def __init__(self, cpu_group_size: int = 1, gpu_group_size: int = 18446744073709551615, prefer_gpu: bool = True) -> None: + def __init__( + self, + cpu_group_size: int = 1, + gpu_group_size: int = 18446744073709551615, + prefer_gpu: bool = True, + ) -> None: """ Construct a partition hint with arguments: cpu_group_size: The size of cell group assigned to CPU, each cell in its own group by default. @@ -1820,64 +2190,78 @@ class partition_hint: Must be positive, else set to default value. prefer_gpu: Whether GPU is preferred, True by default. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def cpu_group_size(self) -> int: """ The size of cell group assigned to CPU. """ + @cpu_group_size.setter - def cpu_group_size(self, arg0: int) -> None: - ... + def cpu_group_size(self, arg0: int) -> None: ... @property def gpu_group_size(self) -> int: """ The size of cell group assigned to GPU. """ + @gpu_group_size.setter - def gpu_group_size(self, arg0: int) -> None: - ... + def gpu_group_size(self, arg0: int) -> None: ... @property def prefer_gpu(self) -> bool: """ Whether GPU usage is preferred. """ + @prefer_gpu.setter - def prefer_gpu(self, arg0: bool) -> None: - ... + def prefer_gpu(self, arg0: bool) -> None: ... + class place_pwlin: def __init__(self, morphology: morphology, isometry: isometry = ...) -> None: """ Construct a piecewise-linear placement object from the given morphology and optional isometry. """ + def all_at(self, location: location) -> list[mpoint]: """ Return list of all possible interpolated mpoints corresponding to the location argument. """ + def all_segments(self, arg0: list[cable]) -> list[msegment]: """ Return maximal list of non-overlapping full or partial msegments whose union is coterminous with the extent of the given list of cables. """ + def at(self, location: location) -> mpoint: """ Return an interpolated mpoint corresponding to the location argument. """ + def closest(self, arg0: float, arg1: float, arg2: float) -> tuple: """ Find the location on the morphology that is closest to a 3d point. Returns the location and its distance from the point. """ + def segments(self, arg0: list[cable]) -> list[msegment]: """ Return minimal list of full or partial msegments whose union is coterminous with the extent of the given list of cables. """ + class poisson_schedule(schedule_base): """ Describes a schedule according to a Poisson process within the interval [tstart, tstop). """ - def __init__(self, freq: units.quantity, *, tstart: units.quantity = ..., seed: int = 0, tstop: units.quantity | None = None) -> None: + + def __init__( + self, + freq: units.quantity, + *, + tstart: units.quantity = ..., + seed: int = 0, + tstop: units.quantity | None = None, + ) -> None: """ Construct a Poisson schedule with arguments: tstart: The delivery time of the first event in the sequence [ms], 0 by default. @@ -1885,56 +2269,64 @@ class poisson_schedule(schedule_base): seed: The seed for the random number generator, 0 by default. tstop: No events delivered after this time [ms], None by default. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def events(self, arg0: units.quantity, arg1: units.quantity) -> list[float]: """ A view of monotonically increasing time values in the half-open interval [t0, t1). """ + @property def freq(self) -> units.quantity: """ The expected frequency [kHz]. """ + @freq.setter - def freq(self, arg1: units.quantity) -> None: - ... + def freq(self, arg1: units.quantity) -> None: ... @property def seed(self) -> int: """ The seed for the random number generator. """ + @seed.setter - def seed(self, arg0: int) -> None: - ... + def seed(self, arg0: int) -> None: ... @property def tstart(self) -> units.quantity: """ The delivery time of the first event in the sequence [ms]. """ + @tstart.setter - def tstart(self, arg1: units.quantity) -> None: - ... + def tstart(self, arg1: units.quantity) -> None: ... @property def tstop(self) -> units.quantity: """ No events delivered after this time [ms]. """ + @tstop.setter - def tstop(self, arg1: units.quantity) -> None: - ... + def tstop(self, arg1: units.quantity) -> None: ... + class probe: - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... + class proc_allocation: """ Enumerates the computational resources on a node to be used for simulation. """ - def __init__(self, *, threads: int = 1, gpu_id: typing.Any = None, bind_procs: bool = False, bind_threads: bool = False) -> None: + + def __init__( + self, + *, + threads: int = 1, + gpu_id: typing.Any = None, + bind_procs: bool = False, + bind_threads: bool = False, + ) -> None: """ Construct an allocation with arguments: threads: The number of threads available locally for execution. Must be set to 1 at minimum. 1 by default. @@ -1942,424 +2334,482 @@ class proc_allocation: bind_procs: Create process binding mask. bind_threads: Create thread binding mask. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def bind_procs(self) -> bool: """ Try to bind MPI procs? """ + @bind_procs.setter - def bind_procs(self, arg1: bool) -> None: - ... + def bind_procs(self, arg1: bool) -> None: ... @property def bind_threads(self) -> bool: """ Try to bind threads? """ + @bind_threads.setter - def bind_threads(self, arg1: bool) -> None: - ... + def bind_threads(self, arg1: bool) -> None: ... @property def gpu_id(self) -> int | None: """ The identifier of the GPU to use. Corresponds to the integer parameter used to identify GPUs in CUDA API calls. """ + @gpu_id.setter - def gpu_id(self, arg1: typing.Any) -> None: - ... + def gpu_id(self, arg1: typing.Any) -> None: ... @property def has_gpu(self) -> bool: """ Whether a GPU is being used (True/False). """ + @property def threads(self) -> int: """ The number of threads available locally for execution. """ + @threads.setter - def threads(self, arg1: int) -> None: - ... + def threads(self, arg1: int) -> None: ... + class recipe: """ A description of a model, describing the cells and the network via a cell-centric interface. """ - def __init__(self) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __init__(self) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def cell_description(self, gid: int) -> typing.Any: """ High level description of the cell with global identifier gid. """ + def cell_kind(self, gid: int) -> cell_kind: """ The kind of cell with global identifier gid. """ + def connections_on(self, gid: int) -> list[connection]: """ A list of all the incoming connections to gid, [] by default. """ + def event_generators(self, gid: int) -> list[typing.Any]: """ A list of all the event generators that are attached to gid, [] by default. """ + def external_connections_on(self, gid: int) -> list[connection]: """ A list of all the incoming connections from _remote_ locations to gid, [] by default. """ + def gap_junctions_on(self, gid: int) -> list[gap_junction_connection]: """ A list of the gap junctions connected to gid, [] by default. """ + def global_properties(self, kind: cell_kind) -> typing.Any: """ The default properties applied to all cells of type 'kind' in the model. """ + def num_cells(self) -> int: """ The number of cells in the model. """ + def probes(self, gid: int) -> list[probe]: """ The probes to allow monitoring. """ + class regular_schedule(schedule_base): """ Describes a regular schedule with multiples of dt within the interval [tstart, tstop). """ + @typing.overload - def __init__(self, tstart: units.quantity, dt: units.quantity, tstop: units.quantity | None = None) -> None: + def __init__( + self, + tstart: units.quantity, + dt: units.quantity, + tstop: units.quantity | None = None, + ) -> None: """ Construct a regular schedule with arguments: tstart: The delivery time of the first event in the sequence [ms]. dt: The interval between time points [ms]. tstop: No events delivered after this time [ms], None by default. """ + @typing.overload def __init__(self, dt: units.quantity) -> None: """ Construct a regular schedule, starting from t = 0 and never terminating, with arguments: dt: The interval between time points [ms]. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def events(self, arg0: float, arg1: float) -> list[float]: """ A view of monotonically increasing time values in the half-open interval [t0, t1). """ + @property def dt(self) -> units.quantity: """ The interval between time points [ms]. """ + @dt.setter - def dt(self, arg1: units.quantity) -> None: - ... + def dt(self, arg1: units.quantity) -> None: ... @property def tstart(self) -> units.quantity: """ The delivery time of the first event in the sequence [ms]. """ + @tstart.setter - def tstart(self, arg1: units.quantity) -> None: - ... + def tstart(self, arg1: units.quantity) -> None: ... @property def tstop(self) -> units.quantity | None: """ No events delivered after this time [ms]. """ + @tstop.setter - def tstop(self, arg1: units.quantity | None) -> None: - ... + def tstop(self, arg1: units.quantity | None) -> None: ... + class reversal_potential: """ Setting the initial reversal potential. """ - def __init__(self, arg0: str, arg1: units.quantity) -> None: - ... - def __repr__(self) -> str: - ... + + def __init__(self, arg0: str, arg1: units.quantity) -> None: ... + def __repr__(self) -> str: ... + class reversal_potential_method: """ Describes the mechanism used to compute eX for ion X. """ - def __init__(self, arg0: str, arg1: mechanism) -> None: - ... - def __repr__(self) -> str: - ... + + def __init__(self, arg0: str, arg1: mechanism) -> None: ... + def __repr__(self) -> str: ... + class scaled_mechanism: """ For painting a scaled density mechanism on a region. """ + @typing.overload - def __init__(self, arg0: density) -> None: - ... + def __init__(self, arg0: density) -> None: ... @typing.overload - def __init__(self, arg0: density, arg1: dict[str, str]) -> None: - ... + def __init__(self, arg0: density, arg1: dict[str, str]) -> None: ... @typing.overload - def __init__(self, arg0: density, **kwargs) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + def __init__(self, arg0: density, **kwargs) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def scale(self, name: str, ex: str) -> scaled_mechanism: """ Add a scaling expression to a parameter. """ + class schedule_base: """ Schedule abstract base class. """ + class segment_tree: - def __init__(self) -> None: - ... - def __str__(self) -> str: - ... + def __init__(self) -> None: ... + def __str__(self) -> str: ... @typing.overload def append(self, parent: int, prox: mpoint, dist: mpoint, tag: int) -> int: """ Append a segment to the tree. """ + @typing.overload def append(self, parent: int, dist: mpoint, tag: int) -> int: """ Append a segment to the tree. """ + @typing.overload - def append(self, parent: int, x: float, y: float, z: float, radius: float, tag: int) -> int: + def append( + self, parent: int, x: float, y: float, z: float, radius: float, tag: int + ) -> int: """ Append a segment to the tree, using the distal location of the parent segment as the proximal end. """ + def apply_isometry(self, arg0: isometry) -> segment_tree: """ Apply an isometry to all segments in the tree. """ + def equivalent(self, arg0: segment_tree) -> bool: """ Two trees are equivalent, but not neccessarily identical, ie they have the same segments and structure. """ + def is_fork(self, i: int) -> bool: """ True if segment has more than one child. """ + def is_root(self, i: int) -> bool: """ True if segment has no parent. """ + def is_terminal(self, i: int) -> bool: """ True if segment has no children. """ + def join_at(self, arg0: int, arg1: segment_tree) -> segment_tree: """ Join two subtrees at a given id, such that said id becomes the parent of the inserted sub-tree. """ - def reserve(self, arg0: int) -> None: - ... + + def reserve(self, arg0: int) -> None: ... def split_at(self, arg0: int) -> tuple[segment_tree, segment_tree]: """ Split into a pair of trees at the given id, such that one tree is the subtree rooted at id and the other is the original tree without said subtree. """ + def tag_roots(self, arg0: int) -> list[int]: """ Get roots of tag region of this segment tree. """ + @property def empty(self) -> bool: """ Indicates whether the tree is empty (i.e. whether it has size 0) """ + @property def parents(self) -> list[int]: """ A list with the parent index of each segment. """ + @property def segments(self) -> list[msegment]: """ A list of the segments. """ + @property def size(self) -> int: """ The number of segments in the tree. """ + class selection_policy: """ Enumeration used to identify a selection policy, used by the model for selecting one of possibly multiple locations on the cell associated with a labeled item. - + Members: - + round_robin : Iterate round-robin over all possible locations. - + round_robin_halt : Halts at the current location until the round_robin policy is called (again). - + univalent : Assert that there is only one possible location associated with a labeled item on the cell. The model throws an exception if the assertion fails. """ - __members__: typing.ClassVar[dict[str, selection_policy]] # value = {'round_robin': , 'round_robin_halt': , 'univalent': } - round_robin: typing.ClassVar[selection_policy] # value = - round_robin_halt: typing.ClassVar[selection_policy] # value = - univalent: typing.ClassVar[selection_policy] # value = - def __eq__(self, other: typing.Any) -> bool: - ... - def __getstate__(self) -> int: - ... - def __hash__(self) -> int: - ... - def __index__(self) -> int: - ... - def __init__(self, value: int) -> None: - ... - def __int__(self) -> int: - ... - def __ne__(self, other: typing.Any) -> bool: - ... - def __repr__(self) -> str: - ... - def __setstate__(self, state: int) -> None: - ... - def __str__(self) -> str: - ... - @property - def name(self) -> str: - ... - @property - def value(self) -> int: - ... + + __members__: typing.ClassVar[ + dict[str, selection_policy] + ] # value = {'round_robin': , 'round_robin_halt': , 'univalent': } + round_robin: typing.ClassVar[ + selection_policy + ] # value = + round_robin_halt: typing.ClassVar[ + selection_policy + ] # value = + univalent: typing.ClassVar[ + selection_policy + ] # value = + def __eq__(self, other: typing.Any) -> bool: ... + def __getstate__(self) -> int: ... + def __hash__(self) -> int: ... + def __index__(self) -> int: ... + def __init__(self, value: int) -> None: ... + def __int__(self) -> int: ... + def __ne__(self, other: typing.Any) -> bool: ... + def __repr__(self) -> str: ... + def __setstate__(self, state: int) -> None: ... + def __str__(self) -> str: ... + @property + def name(self) -> str: ... + @property + def value(self) -> int: ... + class simulation: """ The executable form of a model. A simulation is constructed from a recipe, and then used to update and monitor model state. """ + @staticmethod - def deserialize(*args, **kwargs) -> None: - ... - def __init__(self, recipe: recipe, context: context | None = None, domains: domain_decomposition | None = None, seed: int = 0) -> None: + def deserialize(*args, **kwargs) -> None: ... + def __init__( + self, + recipe: recipe, + context: context | None = None, + domains: domain_decomposition | None = None, + seed: int = 0, + ) -> None: """ Initialize the model described by a recipe, with cells and network distributed according to the domain decomposition and computational resources described by a context. Initialize PRNG using seed """ + def clear_samplers(self) -> None: """ Clearing spike and sample information. restoring memory """ + @typing.overload def probe_metadata(self, probeset_id: cell_address) -> list: """ Retrieve metadata associated with given probe id. """ + @typing.overload def probe_metadata(self, addr: tuple[int, str]) -> list: """ Retrieve metadata associated with given probe id. """ + @typing.overload def probe_metadata(self, gid: int, tag: str) -> list: """ Retrieve metadata associated with given probe id. """ + def progress_banner(self) -> None: """ Show a text progress bar during simulation. """ + def record(self, arg0: spike_recording) -> None: """ Disable or enable local or global spike recording. """ + def remove_all_samplers(self, arg0: int) -> None: """ Remove all sampling on the simulatr. """ + def remove_sampler(self, handle: int) -> None: """ Remove sampling associated with the given handle. """ + def reset(self) -> None: """ Reset the state of the simulation to its initial state. """ + def run(self, tfinal: units.quantity, dt: units.quantity = ...) -> float: """ Run the simulation from current simulation time to tfinal [ms], with maximum time step size dt [ms]. """ + @typing.overload def sample(self, probeset_id: cell_address, schedule: schedule_base) -> int: """ Record data from probes with given probeset_id according to supplied schedule. Returns handle for retrieving data or removing the sampling. """ + @typing.overload def sample(self, gid: int, tag: str, schedule: schedule_base) -> int: """ Record data from probes with given probeset_id=(gid, tag) according to supplied schedule. Returns handle for retrieving data or removing the sampling. """ + @typing.overload def sample(self, probeset_id: tuple[int, str], schedule: schedule_base) -> int: """ Record data from probes with given probeset_id=(gid, tag) according to supplied schedule. Returns handle for retrieving data or removing the sampling. """ + def samples(self, handle: int) -> list: """ Retrieve sample data as a list, one element per probe associated with the query. """ + def serialize(self) -> str: """ Serialize the simulation object to a JSON string. """ + def set_remote_spike_filter(self, pred: typing.Callable[[spike], bool]) -> None: """ Add a callback to filter spikes going out over external connections. `pred` isa callable on the `spike` type. **Caution**: This will be extremely slow; use C++ if you want to make use of this. """ + def spikes(self) -> typing.Any: """ Retrieve recorded spikes as numpy array. """ + def update(self, recipe: recipe) -> None: """ Rebuild the connection table from recipe::connections_on and the eventgenerators based on recipe::event_generators. """ + class single_cell_model: """ Wrapper for simplified description, and execution, of single cell models. """ + @typing.overload - def __init__(self, tree: segment_tree, decor: decor, labels: label_dict = ...) -> None: + def __init__( + self, tree: segment_tree, decor: decor, labels: label_dict = ... + ) -> None: """ Build single cell model from cable cell components """ + @typing.overload - def __init__(self, morph: morphology, decor: decor, labels: label_dict = ...) -> None: + def __init__( + self, morph: morphology, decor: decor, labels: label_dict = ... + ) -> None: """ Build single cell model from cable cell components """ + @typing.overload def __init__(self, cell: cable_cell) -> None: """ Initialise a single cell model for a cable cell. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... def event_generator(self, event_generator: event_generator) -> None: """ Register an event generator. event_generator: An Arbor event generator. """ + @typing.overload def probe(self, what: str, where: str, tag: str, frequency: units.quantity) -> None: """ @@ -2369,8 +2819,11 @@ class single_cell_model: tag: Unique name for this probe. frequency: The target frequency at which to sample [kHz]. """ + @typing.overload - def probe(self, what: str, where: location, tag: str, frequency: units.quantity) -> None: + def probe( + self, what: str, where: location, tag: str, frequency: units.quantity + ) -> None: """ Sample a variable on the cell. what: Name of the variable to record (currently only 'voltage'). @@ -2378,371 +2831,390 @@ class single_cell_model: tag: Unique name for this probe. frequency: The target frequency at which to sample [kHz]. """ + def run(self, tfinal: units.quantity, dt: units.quantity = ...) -> None: """ Run model from t=0 to t=tfinal ms. """ + @property def cable_cell(self) -> cable_cell: """ The cable cell held by this model. """ + @property def properties(self) -> cable_global_properties: """ Global properties. """ + @properties.setter - def properties(self, arg0: cable_global_properties) -> None: - ... + def properties(self, arg0: cable_global_properties) -> None: ... @property def spikes(self) -> list[float]: """ Holds spike times [ms] after a call to run(). """ + @property def traces(self) -> list[trace]: """ Holds sample traces after a call to run(). """ + class spike: - def __init__(self, arg0: cell_member, arg1: float) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + def __init__(self, arg0: cell_member, arg1: float) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def source(self) -> cell_member: """ The global identifier of the cell. """ + @source.setter - def source(self, arg0: cell_member) -> None: - ... + def source(self, arg0: cell_member) -> None: ... @property def time(self) -> float: """ The time of spike. """ + @time.setter - def time(self, arg0: float) -> None: - ... + def time(self, arg0: float) -> None: ... + class spike_recording: """ Members: - + off - + local - + all """ - __members__: typing.ClassVar[dict[str, spike_recording]] # value = {'off': , 'local': , 'all': } + + __members__: typing.ClassVar[ + dict[str, spike_recording] + ] # value = {'off': , 'local': , 'all': } all: typing.ClassVar[spike_recording] # value = local: typing.ClassVar[spike_recording] # value = off: typing.ClassVar[spike_recording] # value = - def __eq__(self, other: typing.Any) -> bool: - ... - def __getstate__(self) -> int: - ... - def __hash__(self) -> int: - ... - def __index__(self) -> int: - ... - def __init__(self, value: int) -> None: - ... - def __int__(self) -> int: - ... - def __ne__(self, other: typing.Any) -> bool: - ... - def __repr__(self) -> str: - ... - def __setstate__(self, state: int) -> None: - ... - def __str__(self) -> str: - ... - @property - def name(self) -> str: - ... - @property - def value(self) -> int: - ... + def __eq__(self, other: typing.Any) -> bool: ... + def __getstate__(self) -> int: ... + def __hash__(self) -> int: ... + def __index__(self) -> int: ... + def __init__(self, value: int) -> None: ... + def __int__(self) -> int: ... + def __ne__(self, other: typing.Any) -> bool: ... + def __repr__(self) -> str: ... + def __setstate__(self, state: int) -> None: ... + def __str__(self) -> str: ... + @property + def name(self) -> str: ... + @property + def value(self) -> int: ... + class spike_source_cell: """ A spike source cell, that generates a user-defined sequence of spikes that act as inputs for other cells in the network. """ + @typing.overload def __init__(self, source_label: str, schedule: regular_schedule) -> None: """ Construct a spike source cell with a single source labeled 'source_label'. The cell generates spikes on 'source_label' at regular intervals. """ + @typing.overload def __init__(self, source_label: str, schedule: explicit_schedule) -> None: """ Construct a spike source cell with a single source labeled 'source_label'. The cell generates spikes on 'source_label' at a sequence of user-defined times. """ + @typing.overload def __init__(self, source_label: str, schedule: poisson_schedule) -> None: """ Construct a spike source cell with a single source labeled 'source_label'. The cell generates spikes on 'source_label' at times defined by a Poisson sequence. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... + class swc_metadata: """ SWC metadata type: empty. """ + class synapse: """ For placing a synaptic mechanism on a locset. """ + @typing.overload - def __init__(self, arg0: str) -> None: - ... + def __init__(self, arg0: str) -> None: ... @typing.overload - def __init__(self, arg0: mechanism) -> None: - ... + def __init__(self, arg0: mechanism) -> None: ... @typing.overload - def __init__(self, arg0: str, arg1: dict[str, float]) -> None: - ... + def __init__(self, arg0: str, arg1: dict[str, float]) -> None: ... @typing.overload - def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: - ... + def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: ... @typing.overload - def __init__(self, arg0: str, **kwargs) -> None: - ... + def __init__(self, arg0: str, **kwargs) -> None: ... @typing.overload - def __init__(self, arg0: mechanism, **kwargs) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + def __init__(self, arg0: mechanism, **kwargs) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def mech(self) -> mechanism: """ The underlying mechanism. """ + class temperature: """ Setting the temperature. """ - def __init__(self, arg0: units.quantity) -> None: - ... - def __repr__(self) -> str: - ... + + def __init__(self, arg0: units.quantity) -> None: ... + def __repr__(self) -> str: ... + class threshold_detector: """ A spike detector, generates a spike when voltage crosses a threshold. Can be used as source endpoint for an arbor.connection. """ + def __init__(self, threshold: units.quantity) -> None: """ Voltage threshold of spike detector [mV] """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def threshold(self) -> float: """ Voltage threshold of spike detector [mV] """ + class trace: """ Values and meta-data for a sample-trace on a single cell model. """ - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def location(self) -> location: """ Location on cell morphology. """ + @property def time(self) -> list[float]: """ Time stamps of samples [ms]. """ + @property def value(self) -> list[float]: """ Sample values. """ + @property def variable(self) -> str: """ Name of the variable being recorded. """ + class voltage_process: """ For painting a voltage_process mechanism on a region. """ + @typing.overload - def __init__(self, arg0: str) -> None: - ... + def __init__(self, arg0: str) -> None: ... @typing.overload - def __init__(self, arg0: mechanism) -> None: - ... + def __init__(self, arg0: mechanism) -> None: ... @typing.overload - def __init__(self, arg0: str, arg1: dict[str, float]) -> None: - ... + def __init__(self, arg0: str, arg1: dict[str, float]) -> None: ... @typing.overload - def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: - ... + def __init__(self, arg0: mechanism, arg1: dict[str, float]) -> None: ... @typing.overload - def __init__(self, arg0: mechanism, **kwargs) -> None: - ... + def __init__(self, arg0: mechanism, **kwargs) -> None: ... @typing.overload - def __init__(self, arg0: str, **kwargs) -> None: - ... - def __repr__(self) -> str: - ... - def __str__(self) -> str: - ... + def __init__(self, arg0: str, **kwargs) -> None: ... + def __repr__(self) -> str: ... + def __str__(self) -> str: ... @property def mech(self) -> mechanism: """ The underlying mechanism. """ -def allen_catalogue() -> catalogue: - ... -def bbp_catalogue() -> catalogue: - ... + +def allen_catalogue() -> catalogue: ... +def bbp_catalogue() -> catalogue: ... def cable_probe_axial_current(where: str, tag: str) -> probe: """ Probe specification for cable cell axial current at points in a location set. """ -def cable_probe_density_state(where: str, mechanism: str, state: str, tag: str) -> probe: + +def cable_probe_density_state( + where: str, mechanism: str, state: str, tag: str +) -> probe: """ Probe specification for a cable cell density mechanism state variable at points in a location set. """ + def cable_probe_density_state_cell(mechanism: str, state: str, tag: str) -> probe: """ Probe specification for a cable cell density mechanism state variable on each cable in each CV where defined. """ + def cable_probe_ion_current_cell(ion: str, tag: str) -> probe: """ Probe specification for cable cell ionic current across each cable in each CV. """ + def cable_probe_ion_current_density(where: str, ion: str, tag: str) -> probe: """ Probe specification for cable cell ionic current density at points in a location set. """ + def cable_probe_ion_diff_concentration(where: str, ion: str, tag: str) -> probe: """ Probe specification for cable cell diffusive ionic concentration at points in a location set. """ + def cable_probe_ion_diff_concentration_cell(ion: str, tag: str) -> probe: """ Probe specification for cable cell diffusive ionic concentration for each cable in each CV. """ + def cable_probe_ion_ext_concentration(where: str, ion: str, tag: str) -> probe: """ Probe specification for cable cell external ionic concentration at points in a location set. """ + def cable_probe_ion_ext_concentration_cell(ion: str, tag: str) -> probe: """ Probe specification for cable cell external ionic concentration for each cable in each CV. """ + def cable_probe_ion_int_concentration(where: str, ion: str, tag: str) -> probe: """ Probe specification for cable cell internal ionic concentration at points in a location set. """ + def cable_probe_ion_int_concentration_cell(ion: str, tag: str) -> probe: """ Probe specification for cable cell internal ionic concentration for each cable in each CV. """ + def cable_probe_membrane_voltage(where: str, tag: str) -> probe: """ Probe specification for cable cell membrane voltage interpolated at points in a location set. """ + def cable_probe_membrane_voltage_cell(tag: str) -> probe: """ Probe specification for cable cell membrane voltage associated with each cable in each CV. """ + def cable_probe_point_state(target: int, mechanism: str, state: str, tag: str) -> probe: """ Probe specification for a cable cell point mechanism state variable value at a given target index. """ + def cable_probe_point_state_cell(mechanism: str, state: str, tag: str) -> probe: """ Probe specification for a cable cell point mechanism state variable value at every corresponding target. """ + def cable_probe_stimulus_current_cell(tag: str) -> probe: """ Probe specification for cable cell stimulus current across each cable in each CV. """ + def cable_probe_total_current_cell(tag: str) -> probe: """ Probe specification for cable cell total transmembrane current for each cable in each CV. """ + def cable_probe_total_ion_current_cell(tag: str) -> probe: """ Probe specification for cable cell total transmembrane current excluding capacitive currents for each cable in each CV. """ + def cable_probe_total_ion_current_density(where: str, tag: str) -> probe: """ Probe specification for cable cell total transmembrane current density excluding capacitive currents at points in a location set. """ + def config() -> dict: """ Get Arbor's configuration. """ + def cv_data(cell: cable_cell) -> cell_cv_data | None: """ Returns a cell_cv_data object representing the CVs comprising the cable-cell according to the discretization policy provided in the decor of the cell. Returns None if no CV-policy was provided in the decor. """ -def cv_policy_every_segment(domain: str = '(all)') -> cv_policy: + +def cv_policy_every_segment(domain: str = "(all)") -> cv_policy: """ Policy to create one compartment per component of a region. """ -def cv_policy_explicit(locset: str, domain: str = '(all)') -> cv_policy: + +def cv_policy_explicit(locset: str, domain: str = "(all)") -> cv_policy: """ Policy to create compartments at explicit locations. """ -def cv_policy_fixed_per_branch(n: int, domain: str = '(all)') -> cv_policy: + +def cv_policy_fixed_per_branch(n: int, domain: str = "(all)") -> cv_policy: """ Policy to use the same number of CVs for each branch. """ -def cv_policy_max_extent(length: float, domain: str = '(all)') -> cv_policy: + +def cv_policy_max_extent(length: float, domain: str = "(all)") -> cv_policy: """ Policy to use as many CVs as required to ensure that no CV has a length longer than a given value. """ -def cv_policy_single(domain: str = '(all)') -> cv_policy: + +def cv_policy_single(domain: str = "(all)") -> cv_policy: """ Policy to create one compartment per component of a region. """ -def default_catalogue() -> catalogue: - ... + +def default_catalogue() -> catalogue: ... def intersect_region(reg: str, data: cell_cv_data, integrate_along: str) -> list[tuple]: """ Returns a list of [index, proportion] tuples identifying the CVs present in the region. `index` is the index of the CV in the cell_cv_data object provided as an argument. `proportion` is the proportion of the CV (itegrated by area or length) included in the region. """ + def lif_probe_voltage(tag: str) -> probe: """ Probe specification for LIF cell membrane voltage. """ + def load_asc(filename_or_stream: typing.Any) -> loaded_morphology: """ Load a morphology or segment_tree and meta data from a Neurolucida ASCII .asc file. """ -def load_catalogue(arg0: typing.Any) -> catalogue: - ... + +def load_catalogue(arg0: typing.Any) -> catalogue: ... def load_component(filename_or_descriptor: typing.Any) -> cable_component: """ Load arbor-component (decor, morphology, label_dict, cable_cell) from file. """ + def load_swc_arbor(filename_or_stream: typing.Any) -> loaded_morphology: """ Generate a morphology/segment_tree from an SWC file following the rules prescribed by Arbor. @@ -2753,58 +3225,74 @@ def load_swc_arbor(filename_or_stream: typing.Any) -> loaded_morphology: * A segment is always created between a sample and its parent, meaning there are no gaps in the resulting morphology. """ + def load_swc_neuron(filename_or_stream: typing.Any) -> loaded_morphology: """ Generate a morphology from an SWC file following the rules prescribed by NEURON. See the documentation https://docs.arbor-sim.org/en/latest/fileformat/swc.html for a detailed description of the interpretation. """ + def neuron_cable_properties() -> cable_global_properties: """ default NEURON cable_global_properties """ -def partition_by_group(recipe: recipe, context: context, groups: list[group_description]) -> domain_decomposition: + +def partition_by_group( + recipe: recipe, context: context, groups: list[group_description] +) -> domain_decomposition: """ - Construct a domain_decomposition that assigned the groups of cell provided as argument + Construct a domain_decomposition that assigned the groups of cell provided as argument to the local hardware resources described by context on the calling rank. The cell_groups are guaranteed to be present on the calling rank. """ -def partition_load_balance(recipe: recipe, context: context, hints: dict[cell_kind, partition_hint] = {}) -> domain_decomposition: + +def partition_load_balance( + recipe: recipe, context: context, hints: dict[cell_kind, partition_hint] = {} +) -> domain_decomposition: """ Construct a domain_decomposition that distributes the cells in the model described by recipe over the distributed and local hardware resources described by context. Optionally, provide a dictionary of partition hints for certain cell kinds, by default empty. """ + def print_config() -> None: """ Print Arbor's configuration. """ -def stochastic_catalogue() -> catalogue: - ... + +def stochastic_catalogue() -> catalogue: ... @typing.overload -def write_component(object: cable_component, filename_or_descriptor: typing.Any) -> None: +def write_component( + object: cable_component, filename_or_descriptor: typing.Any +) -> None: """ Write cable_component to file. """ + @typing.overload def write_component(object: decor, filename_or_descriptor: typing.Any) -> None: """ Write decor to file. """ + @typing.overload def write_component(object: label_dict, filename_or_descriptor: typing.Any) -> None: """ Write label_dict to file. """ + @typing.overload def write_component(object: morphology, filename_or_descriptor: typing.Any) -> None: """ Write morphology to file. """ + @typing.overload def write_component(object: cable_cell, filename_or_descriptor: typing.Any) -> None: """ Write cable_cell to file. """ -__version__: str = '0.9.1-dev' + +__version__: str = "0.9.1-dev" mnpos: int = 4294967295 diff --git a/python/stubs/arbor/_arbor/env.pyi b/python/stubs/arbor/_arbor/env.pyi index 2073f67e99..72be0ec6da 100644 --- a/python/stubs/arbor/_arbor/env.pyi +++ b/python/stubs/arbor/_arbor/env.pyi @@ -1,31 +1,46 @@ """ Wrappers for arborenv. """ + from __future__ import annotations import arbor._arbor import typing -__all__ = ['default_allocation', 'default_concurrency', 'default_gpu', 'find_private_gpu', 'get_env_num_threads', 'thread_concurrency'] + +__all__ = [ + "default_allocation", + "default_concurrency", + "default_gpu", + "find_private_gpu", + "get_env_num_threads", + "thread_concurrency", +] + def default_allocation() -> arbor._arbor.proc_allocation: """ Attempts to detect the number of locally available CPU cores. Returns 1 if unable to detect the number of cores. Use with caution in combination with MPI. """ + def default_concurrency() -> arbor._arbor.proc_allocation: """ Returns number of threads to use from get_env_num_threads(), or else from thread_concurrency() if get_env_num_threads() returns zero. """ + def default_gpu() -> int | None: """ Determine GPU id to use from the ARBENV_GPU_ID environment variable, or from the first available GPU id of those detected. """ + def find_private_gpu(arg0: typing.Any) -> None: """ Identify a private GPU id per node, only available if built with GPU and MPI. mpi: The MPI communicator. """ + def get_env_num_threads() -> int: """ Retrieve user-specified number of threads to use from the environment variable ARBENV_NUM_THREADS. """ + def thread_concurrency() -> int: """ Attempts to detect the number of locally available CPU cores. Returns 1 if unable to detect the number of cores. Use with caution in combination with MPI. diff --git a/python/stubs/arbor/_arbor/units.pyi b/python/stubs/arbor/_arbor/units.pyi index 3cbb1f7811..664b21ae32 100644 --- a/python/stubs/arbor/_arbor/units.pyi +++ b/python/stubs/arbor/_arbor/units.pyi @@ -1,103 +1,146 @@ """ Units and quantities for driving the user interface. """ + from __future__ import annotations import typing -__all__ = ['A', 'C', 'Celsius', 'F', 'Hz', 'Kelvin', 'M', 'MOhm', 'Ohm', 'S', 'V', 'cm', 'cm2', 'deg', 'giga', 'kHz', 'kOhm', 'kilo', 'm', 'm2', 'mA', 'mM', 'mS', 'mV', 'mega', 'micro', 'milli', 'mm', 'mm2', 'mol', 'ms', 'nA', 'nF', 'nano', 'nil', 'nm', 'nm2', 'ns', 'pA', 'pF', 'pico', 'quantity', 'rad', 's', 'uA', 'uF', 'uS', 'um', 'um2', 'unit', 'us'] + +__all__ = [ + "A", + "C", + "Celsius", + "F", + "Hz", + "Kelvin", + "M", + "MOhm", + "Ohm", + "S", + "V", + "cm", + "cm2", + "deg", + "giga", + "kHz", + "kOhm", + "kilo", + "m", + "m2", + "mA", + "mM", + "mS", + "mV", + "mega", + "micro", + "milli", + "mm", + "mm2", + "mol", + "ms", + "nA", + "nF", + "nano", + "nil", + "nm", + "nm2", + "ns", + "pA", + "pF", + "pico", + "quantity", + "rad", + "s", + "uA", + "uF", + "uS", + "um", + "um2", + "unit", + "us", +] + class quantity: """ A quantity, comprising a magnitude and a unit. """ + __hash__: typing.ClassVar[None] = None - def __add__(self, arg0: quantity) -> quantity: - ... - def __eq__(self, arg0: quantity) -> bool: - ... + def __add__(self, arg0: quantity) -> quantity: ... + def __eq__(self, arg0: quantity) -> bool: ... @typing.overload - def __mul__(self, arg0: quantity) -> quantity: - ... + def __mul__(self, arg0: quantity) -> quantity: ... @typing.overload - def __mul__(self, arg0: float) -> quantity: - ... + def __mul__(self, arg0: float) -> quantity: ... @typing.overload - def __mul__(self, arg0: unit) -> quantity: - ... - def __ne__(self, arg0: quantity) -> bool: - ... - def __pow__(self: unit, arg0: int) -> unit: - ... + def __mul__(self, arg0: unit) -> quantity: ... + def __ne__(self, arg0: quantity) -> bool: ... + def __pow__(self: unit, arg0: int) -> unit: ... def __repr__(self) -> str: """ Convert quantity to string. """ - def __rmul__(self, arg0: float) -> quantity: - ... - def __rtruediv__(self, arg0: float) -> quantity: - ... + + def __rmul__(self, arg0: float) -> quantity: ... + def __rtruediv__(self, arg0: float) -> quantity: ... def __str__(self) -> str: """ Convert quantity to string. """ - def __sub__(self, arg0: quantity) -> quantity: - ... + + def __sub__(self, arg0: quantity) -> quantity: ... @typing.overload - def __truediv__(self, arg0: quantity) -> quantity: - ... + def __truediv__(self, arg0: quantity) -> quantity: ... @typing.overload - def __truediv__(self, arg0: float) -> quantity: - ... + def __truediv__(self, arg0: float) -> quantity: ... @typing.overload - def __truediv__(self, arg0: unit) -> quantity: - ... + def __truediv__(self, arg0: unit) -> quantity: ... def value_as(self, unit: unit) -> float: """ Convert quantity to given unit and return magnitude. """ + @property def units(self) -> unit: """ Return units. """ + @property def value(self) -> float: """ Return magnitude. """ + class unit: """ A unit. """ + __hash__: typing.ClassVar[None] = None - def __eq__(self, arg0: unit) -> bool: - ... + def __eq__(self, arg0: unit) -> bool: ... @typing.overload - def __mul__(self, arg0: unit) -> unit: - ... + def __mul__(self, arg0: unit) -> unit: ... @typing.overload - def __mul__(self, arg0: float) -> quantity: - ... - def __ne__(self, arg0: unit) -> bool: - ... - def __pow__(self, arg0: int) -> unit: - ... + def __mul__(self, arg0: float) -> quantity: ... + def __ne__(self, arg0: unit) -> bool: ... + def __pow__(self, arg0: int) -> unit: ... def __repr__(self) -> str: """ Convert unit to string. """ - def __rmul__(self, arg0: float) -> quantity: - ... - def __rtruediv__(self, arg0: float) -> quantity: - ... + + def __rmul__(self, arg0: float) -> quantity: ... + def __rtruediv__(self, arg0: float) -> quantity: ... def __str__(self) -> str: """ Convert unit to string. """ + @typing.overload - def __truediv__(self, arg0: unit) -> unit: - ... + def __truediv__(self, arg0: unit) -> unit: ... @typing.overload - def __truediv__(self, arg0: float) -> quantity: - ... + def __truediv__(self, arg0: float) -> quantity: ... + A: unit # value = A C: unit # value = C Celsius: unit # value = °C @@ -132,7 +175,7 @@ ms: unit # value = ms nA: unit # value = nA nF: unit # value = nF nano: unit # value = 1e-09 -nil: unit # value = +nil: unit # value = nm: unit # value = nm nm2: unit # value = nm^2 ns: unit # value = ns From 6a61a5fadaa7387ecbe7c64320c25808bdc6dfef Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 5 Mar 2024 09:53:28 +0100 Subject: [PATCH 14/18] reinstall missing morph bindings. --- python/morphology.cpp | 36 +++++++++++++++++++++++++++++++++++- python/pyarb.cpp | 2 ++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/python/morphology.cpp b/python/morphology.cpp index 117515f065..1a3c305e48 100644 --- a/python/morphology.cpp +++ b/python/morphology.cpp @@ -111,7 +111,8 @@ void register_morphology(py::module& m) { .def("__repr__", [](const arb::mpoint& p) {return util::pprintf("{}", p);}); - py::implicitly_convertible, arb::mpoint>(); + py::implicitly_convertible&, arb::mpoint>(); + py::implicitly_convertible(); // arb::msegment msegment @@ -294,6 +295,39 @@ void register_morphology(py::module& m) { .def("__str__", [](const arb::segment_tree& s) { return util::pprintf("", s);}); + // arb::morphology + morph + // constructors + .def(py::init( + [](arb::segment_tree t){ + return arb::morphology(std::move(t)); + })) + // morphology's interface is read-only by design, so most of it can + // be implemented as read-only properties. + .def_property_readonly("empty", + [](const arb::morphology& m){return m.empty();}, + "Whether the morphology is empty.") + .def_property_readonly("num_branches", + [](const arb::morphology& m){return m.num_branches();}, + "The number of branches in the morphology.") + .def("branch_parent", &arb::morphology::branch_parent, + "i"_a, "The parent branch of branch i.") + .def("branch_children", &arb::morphology::branch_children, + "i"_a, "The child branches of branch i.") + .def("branch_segments", + [](const arb::morphology& m, arb::msize_t i) { + return m.branch_segments(i); + }, + "i"_a, "A list of the segments in branch i, ordered from proximal to distal ends of the branch.") + .def("to_segment_tree", &arb::morphology::to_segment_tree, + "Convert this morphology to a segment_tree.") + .def("__str__", + [](const arb::morphology& m) { + return util::pprintf("", m); + }); + + py::implicitly_convertible(); + // Function that creates a morphology/segment_tree from an swc file. // Wraps calls to C++ functions arborio::parse_swc() and arborio::load_swc_arbor(). m.def("load_swc_arbor", diff --git a/python/pyarb.cpp b/python/pyarb.cpp index a835da7963..7f77d673a2 100644 --- a/python/pyarb.cpp +++ b/python/pyarb.cpp @@ -9,6 +9,7 @@ #include #include "pyarb.hpp" +#include "arbor/morph/primitives.hpp" // Forward declarations of functions used to register API // types and functions to be exposed to Python. @@ -96,6 +97,7 @@ PYBIND11_MODULE(_arbor, m) { pybind11::register_exception(m, "ArbFileNotFoundError", PyExc_FileNotFoundError); pybind11::register_exception(m, "ArbValueError", PyExc_ValueError); + pybind11::implicitly_convertible&, arb::mpoint>(); #ifdef ARB_MPI_ENABLED pyarb::register_mpi(m); From d614b16a420fd6b82a08efaf78468cd7846e392a Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 5 Mar 2024 09:54:13 +0100 Subject: [PATCH 15/18] reinstall missing morph bindings; stubs! --- python/stubs/arbor/_arbor/__init__.pyi | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/python/stubs/arbor/_arbor/__init__.pyi b/python/stubs/arbor/_arbor/__init__.pyi index 0190cf4c2f..94e4178308 100644 --- a/python/stubs/arbor/_arbor/__init__.pyi +++ b/python/stubs/arbor/_arbor/__init__.pyi @@ -653,13 +653,21 @@ class cell_global_label: """ @typing.overload - def __init__(self, arg0: tuple) -> None: + def __init__(self, arg0: tuple[int, cell_local_label]) -> None: """ Construct a cell_global_label identifier with tuple argument (gid, label): gid: The global identifier of the cell. label: The cell_local_label representing the label and selection policy of an item on the cell. """ + @typing.overload + def __init__(self, arg0: tuple[int, str]) -> None: + """ + Construct a cell_global_label identifier with tuple argument (gid, label): + gid: The global identifier of the cell. + label: The tag of an item on the cell. + """ + def __repr__(self) -> str: ... def __str__(self) -> str: ... @property @@ -741,7 +749,15 @@ class cell_local_label: """ @typing.overload - def __init__(self, arg0: tuple) -> None: + def __init__(self, arg0: tuple[str, selection_policy]) -> None: + """ + Construct a cell_local_label identifier with tuple argument (label, policy): + label: The identifier of a group of one or more items on a cell. + policy: The policy for selecting one of possibly multiple items associated with the label. + """ + + @typing.overload + def __init__(self, arg0: tuple[str, selection_policy]) -> None: """ Construct a cell_local_label identifier with tuple argument (label, policy): label: The identifier of a group of one or more items on a cell. @@ -1621,7 +1637,7 @@ class label_dict: """ @staticmethod - def append(*args, **kwargs) -> None: + def append(*args, **kwargs) -> label_dict: """ Import the entries of a another label dictionary with an optional prefix. """ @@ -1668,7 +1684,7 @@ class label_dict: def items(self) -> typing.Iterator: ... def keys(self) -> typing.Iterator: ... - def update(self, other: label_dict) -> None: + def update(self, other: label_dict) -> label_dict: """ The label_dict to be importedImport the entries of a another label dictionary. """ @@ -2056,7 +2072,7 @@ class mpoint: """ @typing.overload - def __init__(self, arg0: tuple) -> None: + def __init__(self, arg0: tuple[float, float, float, float]) -> None: """ Create an mpoint object from a tuple (x, y, z, radius), specified in µm. """ From 04f5cc2a1d0b191c69f06069b92a46e388aec5d8 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 5 Mar 2024 10:03:30 +0100 Subject: [PATCH 16/18] Better annotations. --- arborio/include/arborio/loaded_morphology.hpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/arborio/include/arborio/loaded_morphology.hpp b/arborio/include/arborio/loaded_morphology.hpp index 82d743c14c..84dbc41806 100644 --- a/arborio/include/arborio/loaded_morphology.hpp +++ b/arborio/include/arborio/loaded_morphology.hpp @@ -1,7 +1,8 @@ #pragma once #include -#include + +#include #include #include @@ -9,29 +10,29 @@ namespace arborio { -struct ARB_SYMBOL_VISIBLE swc_metadata {}; +struct ARB_ARBORIO_API swc_metadata {}; -struct ARB_SYMBOL_VISIBLE asc_color { +struct ARB_ARBORIO_API asc_color { uint8_t r = 0; uint8_t g = 0; uint8_t b = 0; }; -struct ARB_SYMBOL_VISIBLE asc_spine { +struct ARB_ARBORIO_API asc_spine { std::string name; arb::mpoint location; }; -enum ARB_SYMBOL_VISIBLE asc_marker { dot, circle, cross, none }; +enum ARB_ARBORIO_API asc_marker { dot, circle, cross, none }; -struct ARB_SYMBOL_VISIBLE asc_marker_set { +struct ARB_ARBORIO_API asc_marker_set { asc_color color; asc_marker marker = asc_marker::none; std::string name; std::vector locations; }; -struct ARB_SYMBOL_VISIBLE asc_metadata { +struct ARB_ARBORIO_API asc_metadata { std::vector markers; std::vector spines; }; @@ -58,7 +59,7 @@ struct ARB_SYMBOL_VISIBLE nml_metadata { }; // Interface for ingesting morphology data -struct ARB_SYMBOL_VISIBLE loaded_morphology { +struct ARB_ARBORIO_API loaded_morphology { // Raw segment tree, identical to morphology. arb::segment_tree segment_tree; From 322369f09cf6ede6b3fe36bbb0f42ef426397b46 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 5 Mar 2024 10:34:15 +0100 Subject: [PATCH 17/18] more conversions --- python/identifiers.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/identifiers.cpp b/python/identifiers.cpp index b837658d02..be12c7d345 100644 --- a/python/identifiers.cpp +++ b/python/identifiers.cpp @@ -71,6 +71,7 @@ void register_identifiers(py::module& m) { py::implicitly_convertible, arb::cell_local_label_type>(); py::implicitly_convertible, arb::cell_local_label_type>(); + py::implicitly_convertible(); py::implicitly_convertible(); py::class_ cell_global_label_type(m, "cell_global_label", @@ -116,6 +117,7 @@ void register_identifiers(py::module& m) { py::implicitly_convertible, arb::cell_global_label_type>(); py::implicitly_convertible, arb::cell_global_label_type>(); + py::implicitly_convertible(); py::class_ cell_member(m, "cell_member", "For global identification of a cell-local item.\n\n" From 8a995f45fe2ecd88164fde86df0130fe4aa3b932 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Tue, 5 Mar 2024 12:21:12 +0100 Subject: [PATCH 18/18] Return ref, not copy. --- python/label_dict.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/label_dict.hpp b/python/label_dict.hpp index 01079e7a04..1e60451234 100644 --- a/python/label_dict.hpp +++ b/python/label_dict.hpp @@ -48,7 +48,7 @@ struct label_dict_proxy { return locsets.size() + regions.size() + iexpressions.size(); } - auto extend(const label_dict_proxy& other, std::string prefix = "") { + auto& extend(const label_dict_proxy& other, std::string prefix = "") { dict.extend(other.dict, prefix); clear_cache(); update_cache();