-
Thorsten Hater authoredUnverified6cf2687e
proxy.hpp 5.52 KiB
#pragma once
#include <any>
#include <arborio/label_parse.hpp>
#include <arbor/morph/label_dict.hpp>
#include "strprintf.hpp"
namespace pyarb {
struct label_dict_proxy {
using str_map = std::unordered_map<std::string, std::string>;
arb::label_dict dict;
str_map cache;
std::vector<std::string> locsets;
std::vector<std::string> regions;
label_dict_proxy() = default;
label_dict_proxy(const str_map& in) {
for (auto& i: in) {
set(i.first, i.second);
}
}
label_dict_proxy& add_swc_tags() {
set("soma", "(tag 1)");
set("axon", "(tag 2)");
set("dend", "(tag 3)");
set("apic", "(tag 4)");
return *this;
}
label_dict_proxy(const arb::label_dict& label_dict): dict(label_dict) {
update_cache();
}
label_dict_proxy(const label_dict_proxy&) = default;
std::size_t size() const {
return locsets.size() + regions.size();
}
void import(const label_dict_proxy& other, std::string prefix = "") {
dict.import(other.dict, prefix);
clear_cache();
update_cache();
}
void set(const std::string& name, const std::string& desc) {
using namespace std::string_literals;
// The following code takes an input name and a region or locset
// description, e.g.:
// name='reg', desc='(tag 4)'
// name='loc', desc='(terminal)'
// name='foo', desc='(join (tag 2) (tag 3))'
// Then it parses the description, and tests whether the description
// is a region or locset, and updates the label dictionary appropriately.
// Errors occur when:
// * a region is described with a name that matches an existing locset
// (and vice versa.)
// * the description is not well formed, e.g. it contains a syntax error.
// * the description is well-formed, but describes neither a region or locset.
try {
// Evaluate the s-expression to build a region/locset.
auto result = arborio::parse_label_expression(desc);
if (!result) { // an error parsing / evaluating description.
throw result.error();