Skip to content

Commit

Permalink
Guard against 'malformed' ACC
Browse files Browse the repository at this point in the history
Throw errors on unrecognised ACC mechanism formatting.
  • Loading branch information
thorstenhater authored Apr 14, 2022
1 parent 452c325 commit b79b3c4
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
35 changes: 35 additions & 0 deletions data/lukasgd-segv-apr22.acc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(arbor-component
(meta-data
(version "0.1-dev"))
(cable-cell
(morphology
(branch 0 -1
(segment 0
(point -5.000000 0.000000 0.000000 5.000000)
(point 0.000000 0.000000 0.000000 5.000000)
1)
(segment 1
(point 0.000000 0.000000 0.000000 5.000000)
(point 5.000000 0.000000 0.000000 5.000000)
1)))
(label-dict
(region-def "all"
(all))
(region-def "apic"
(tag 4))
(region-def "axon"
(tag 2))
(region-def "dend"
(tag 3))
(region-def "soma"
(tag 1)))
(decor
(paint
(region "soma")
(membrane-capacitance 1.000000))
(paint
(region "soma")
(density
(mechanism "hh"
("gkbar" 0.027125)
("gnabar" 0.102993)))))))
18 changes: 12 additions & 6 deletions src/gui_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ namespace {
} catch (const arb::arbor_exception& e) {
log_debug("Failed to load ACC: {}", e.what());
loader_error = e.what();
} catch (const std::runtime_error& e) {
log_debug("Failed to load ACC: {}", e.what());
loader_error = e.what();
}

if (!loader_error.empty()) {
Expand Down Expand Up @@ -1105,16 +1108,19 @@ void gui_state::deserialize(const std::filesystem::path& fn) {
state->ion_par_defs[{region, *ion}].Er = t.value;
}
void operator()(const arb::density& d) {
const auto& t = d.mech;
auto& t = d.mech;
auto id = state->mechanisms.add(region);
auto& data = state->mechanisms[id];
auto cat = t.name();
auto name = t.name();
{ auto sep = std::find(name.begin(), name.end(), ':'); name.erase(name.begin(), sep + 2); }
{ auto sep = std::find(cat.begin(), cat.end(), ':'); cat.erase(sep, cat.end()); }
log_debug("Loading mech {} from cat {} ({})", name, cat, t.name());
auto pos = name.find("::");
if (pos == std::string::npos
|| pos == 0
|| pos + 2 >= name.size()) log_error(fmt::format("Mechanism specifier '{}' is not in format 'cat::name'.", name));
auto cat = name.substr(0, pos);
auto mech = name.substr(pos+2);
log_debug("Loading mech {} from cat {} ({})", mech, cat, name);
// TODO What about derived mechs?
make_mechanism(data, cat, name, t.values());
make_mechanism(data, cat, mech, t.values());
}
};

Expand Down
8 changes: 6 additions & 2 deletions src/mechanism.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@

#include <fmt/format.h>

#include "utils.hpp"
#include "gui.hpp"

std::unordered_map<std::string, arb::mechanism_catalogue> catalogues = default_catalogues;

void make_mechanism(mechanism_def& data,
const std::string& cat_name, const std::string& name,
const std::unordered_map<std::string, double>& values) {
if (name.empty()) log_error("Empty mechanism name. Selector must be 'cat::mech'.");
data.name = name;
data.cat = cat_name;
auto cat = catalogues.at(cat_name);
auto info = cat[name];
if (!catalogues.contains(data.cat)) log_error(fmt::format("Unknown catalogue: {}", data.cat));
auto cat = catalogues[data.cat];
if (!cat.has(data.name)) log_error(fmt::format("Unknown mechanism {} in catalogue {}", data.name, data.cat));
auto info = cat[data.name];
data.globals.clear();
data.parameters.clear();
data.states.clear();
Expand Down

0 comments on commit b79b3c4

Please sign in to comment.