Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit 8bdc1c4

Browse files
author
Weina Ji
authored
SimulationConfig: modifications as a list to preserve the order (#359)
1 parent bcdcaeb commit 8bdc1c4

File tree

7 files changed

+51
-67
lines changed

7 files changed

+51
-67
lines changed

include/bbp/sonata/config.h

+6-10
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,8 @@ class SONATA_API SimulationConfig
324324
std::string nodeSet;
325325
/// Name of the manipulation. Supported values are “TTX” and “ConfigureAllSections”.
326326
ModificationType type;
327+
/// Name of the modification setting.
328+
std::string name;
327329
};
328330

329331
struct ModificationTTX: public ModificationBase {};
@@ -337,8 +339,6 @@ class SONATA_API SimulationConfig
337339

338340
using Modification = nonstd::variant<ModificationTTX, ModificationConfigureAllSections>;
339341

340-
using ModificationMap = std::unordered_map<std::string, Modification>;
341-
342342
/**
343343
* Parameters defining global experimental conditions.
344344
*/
@@ -366,14 +366,10 @@ class SONATA_API SimulationConfig
366366
/// dictionaries of variables' names and values.
367367
std::unordered_map<std::string, std::unordered_map<std::string, variantValueType>>
368368
mechanisms;
369-
/// Collection of dictionaries with each member decribing a modification that mimics
370-
/// experimental manipulations to the circuit.
371-
ModificationMap modifications;
372-
/// Returns the names of the modifications
373-
std::set<std::string> listModificationNames() const;
374-
/// Returns the given modification parameters
375-
/// \throws SonataError if the given modification name does not exist
376-
const Modification& getModification(const std::string& name) const;
369+
/// List of modifications that mimics experimental manipulations to the circuit.
370+
std::vector<Modification> modifications;
371+
/// Method to return the full list of modifications in the Conditions section.
372+
const std::vector<Modification>& getModifications() const noexcept;
377373
};
378374
/**
379375
* List of report parameters collected during the simulation

python/bindings.cpp

+2-8
Original file line numberDiff line numberDiff line change
@@ -695,21 +695,15 @@ PYBIND11_MODULE(_libsonata, m) {
695695
.def_readonly("mechanisms",
696696
&SimulationConfig::Conditions::mechanisms,
697697
DOC_SIMULATIONCONFIG(Conditions, mechanisms))
698-
.def_property_readonly("list_modification_names",
699-
&SimulationConfig::Conditions::listModificationNames,
700-
DOC_SIMULATIONCONFIG(Conditions, listModificationNames))
701-
.def("modification",
702-
&SimulationConfig::Conditions::getModification,
703-
"name"_a,
704-
DOC_SIMULATIONCONFIG(Conditions, getModification));
698+
.def("modifications", &SimulationConfig::Conditions::getModifications);
705699

706700

707701
py::enum_<SimulationConfig::Conditions::SpikeLocation>(conditions, "SpikeLocation")
708702
.value("soma", SimulationConfig::Conditions::SpikeLocation::soma)
709703
.value("AIS", SimulationConfig::Conditions::SpikeLocation::AIS);
710704

711705
py::class_<SimulationConfig::ModificationBase> modificationBase(simConf, "ModificationBase");
712-
modificationBase
706+
modificationBase.def_readonly("name", &SimulationConfig::ModificationBase::name)
713707
.def_readonly("node_set",
714708
&SimulationConfig::ModificationBase::nodeSet,
715709
DOC_SIMULATIONCONFIG(ModificationBase, nodeSet))

python/generated/docstrings.h

+7-9
Original file line numberDiff line numberDiff line change
@@ -713,22 +713,18 @@ R"doc(Extracellular calcium concentration, being applied to the synapse
713713
uHill parameter in order to scale the U parameter of synapses. Default
714714
is None.)doc";
715715

716-
static const char *__doc_bbp_sonata_SimulationConfig_Conditions_getModification =
717-
R"doc(Returns the given modification parameters
718-
719-
Throws:
720-
SonataError if the given modification name does not exist)doc";
721-
722-
static const char *__doc_bbp_sonata_SimulationConfig_Conditions_listModificationNames = R"doc(Returns the names of the modifications)doc";
716+
static const char *__doc_bbp_sonata_SimulationConfig_Conditions_getModifications =
717+
R"doc(Method to return the full list of modifications in the Conditions
718+
section.)doc";
723719

724720
static const char *__doc_bbp_sonata_SimulationConfig_Conditions_mechanisms =
725721
R"doc(Properties to assign values to variables in synapse MOD files. The
726722
format is a dictionary with keys being the SUFFIX names and values
727723
being dictionaries of variables' names and values.)doc";
728724

729725
static const char *__doc_bbp_sonata_SimulationConfig_Conditions_modifications =
730-
R"doc(Collection of dictionaries with each member decribing a modification
731-
that mimics experimental manipulations to the circuit.)doc";
726+
R"doc(List of modifications that mimics experimental manipulations to the
727+
circuit.)doc";
732728

733729
static const char *__doc_bbp_sonata_SimulationConfig_Conditions_randomizeGabaRiseTime =
734730
R"doc(Enable legacy behavior to randomize the GABA_A rise time in the helper
@@ -1022,6 +1018,8 @@ static const char *__doc_bbp_sonata_SimulationConfig_ModificationBase_Modificati
10221018

10231019
static const char *__doc_bbp_sonata_SimulationConfig_ModificationBase_ModificationType_invalid = R"doc()doc";
10241020

1021+
static const char *__doc_bbp_sonata_SimulationConfig_ModificationBase_name = R"doc(Name of the modification setting.)doc";
1022+
10251023
static const char *__doc_bbp_sonata_SimulationConfig_ModificationBase_nodeSet = R"doc(Node set which receives the manipulation)doc";
10261024

10271025
static const char *__doc_bbp_sonata_SimulationConfig_ModificationBase_type =

python/tests/test_config.py

+6-8
Original file line numberDiff line numberDiff line change
@@ -434,14 +434,12 @@ def test_basic(self):
434434
'property1': False},
435435
'GluSynapse': {'property4': 'test',
436436
'property3': 0.025}})
437-
self.assertEqual(self.config.conditions.list_modification_names, {"applyTTX", "no_SK_E2"})
438-
self.assertEqual(self.config.conditions.modification("applyTTX").type.name, "TTX")
439-
self.assertEqual(self.config.conditions.modification("applyTTX").node_set, "single")
440-
self.assertEqual(self.config.conditions.modification("no_SK_E2").type.name,
441-
"ConfigureAllSections")
442-
self.assertEqual(self.config.conditions.modification("no_SK_E2").node_set, "single")
443-
self.assertEqual(self.config.conditions.modification("no_SK_E2").section_configure,
444-
"%s.gSK_E2bar_SK_E2 = 0")
437+
modifications = {o.name: o for o in self.config.conditions.modifications()}
438+
self.assertEqual(modifications["applyTTX"].type.name, "TTX")
439+
self.assertEqual(modifications["applyTTX"].node_set, "single")
440+
self.assertEqual(modifications["no_SK_E2"].type.name, "ConfigureAllSections")
441+
self.assertEqual(modifications["no_SK_E2"].node_set, "single")
442+
self.assertEqual(modifications["no_SK_E2"].section_configure, "%s.gSK_E2bar_SK_E2 = 0")
445443

446444
self.assertEqual(self.config.list_report_names,
447445
{ "axonal_comp_centers", "cell_imembrane", "compartment", "soma", "lfp" })

src/config.cpp

+16-19
Original file line numberDiff line numberDiff line change
@@ -612,11 +612,16 @@ void parseConditionsMechanisms(
612612
}
613613

614614
void parseConditionsModifications(const nlohmann::json& it,
615-
SimulationConfig::ModificationMap& buf) {
615+
std::vector<SimulationConfig::Modification>& buf) {
616616
const auto sectionIt = it.find("modifications");
617-
if (sectionIt == it.end()) {
617+
if (sectionIt == it.end() || sectionIt->is_null()) {
618618
return;
619619
}
620+
if (!sectionIt->is_array()) {
621+
throw SonataError("`modifications` must be an array");
622+
}
623+
buf.reserve(sectionIt->size());
624+
620625
for (auto& mIt : sectionIt->items()) {
621626
const auto valueIt = mIt.value();
622627
const auto debugStr = fmt::format("modification {}", mIt.key());
@@ -628,16 +633,18 @@ void parseConditionsModifications(const nlohmann::json& it,
628633
case SimulationConfig::ModificationBase::ModificationType::TTX: {
629634
SimulationConfig::ModificationTTX result;
630635
result.type = type;
636+
parseMandatory(valueIt, "name", debugStr, result.name);
631637
parseMandatory(valueIt, "node_set", debugStr, result.nodeSet);
632-
buf[mIt.key()] = result;
638+
buf.push_back(std::move(result));
633639
break;
634640
}
635641
case SimulationConfig::ModificationBase::ModificationType::ConfigureAllSections: {
636642
SimulationConfig::ModificationConfigureAllSections result;
637643
result.type = type;
644+
parseMandatory(valueIt, "name", debugStr, result.name);
638645
parseMandatory(valueIt, "node_set", debugStr, result.nodeSet);
639646
parseMandatory(valueIt, "section_configure", debugStr, result.sectionConfigure);
640-
buf[mIt.key()] = result;
647+
buf.push_back(std::move(result));
641648
break;
642649
}
643650
default:
@@ -1383,6 +1390,11 @@ const SimulationConfig::Conditions& SimulationConfig::getConditions() const noex
13831390
return _conditions;
13841391
}
13851392

1393+
const std::vector<SimulationConfig::Modification>& SimulationConfig::Conditions::getModifications()
1394+
const noexcept {
1395+
return modifications;
1396+
}
1397+
13861398
const std::string& SimulationConfig::getNetwork() const noexcept {
13871399
return _network;
13881400
}
@@ -1445,20 +1457,5 @@ const std::string& SimulationConfig::getExpandedJSON() const {
14451457
return _expandedJSON;
14461458
}
14471459

1448-
std::set<std::string> SimulationConfig::Conditions::listModificationNames() const {
1449-
return getMapKeys(modifications);
1450-
}
1451-
1452-
const SimulationConfig::Modification& SimulationConfig::Conditions::getModification(
1453-
const std::string& name) const {
1454-
const auto it = modifications.find(name);
1455-
if (it == modifications.end()) {
1456-
throw SonataError(
1457-
fmt::format("The modification '{}' is not present in the simulation config file",
1458-
name));
1459-
}
1460-
return it->second;
1461-
}
1462-
14631460
} // namespace sonata
14641461
} // namespace bbp

tests/data/config/simulation_config.json

+8-6
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,19 @@
4848
"property4": "test"
4949
}
5050
},
51-
"modifications": {
52-
"applyTTX": {
51+
"modifications": [
52+
{
5353
"node_set": "single",
54-
"type": "TTX"
54+
"type": "TTX",
55+
"name": "applyTTX"
5556
},
56-
"no_SK_E2": {
57+
{
5758
"node_set": "single",
5859
"type": "ConfigureAllSections",
59-
"section_configure": "%s.gSK_E2bar_SK_E2 = 0"
60+
"section_configure": "%s.gSK_E2bar_SK_E2 = 0",
61+
"name": "no_SK_E2"
6062
}
61-
}
63+
]
6264
},
6365
"inputs": {
6466
"ex_linear": {

tests/test_config.cpp

+6-7
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,14 @@ TEST_CASE("SimulationConfig") {
345345
itr = config.getConditions().mechanisms.find("GluSynapse");
346346
CHECK(nonstd::get<double>(itr->second.find("property3")->second) == 0.025);
347347
CHECK(nonstd::get<std::string>(itr->second.find("property4")->second) == "test");
348-
CHECK(config.getConditions().listModificationNames() ==
349-
std::set<std::string>{"applyTTX", "no_SK_E2"});
350-
const auto TTX = nonstd::get<SimulationConfig::ModificationTTX>(
351-
config.getConditions().getModification("applyTTX"));
352-
const auto configAllSects = nonstd::get<SimulationConfig::ModificationConfigureAllSections>(
353-
config.getConditions().getModification("no_SK_E2"));
354-
CHECK_THROWS_AS(config.getConditions().getModification("DoesNotExist"), SonataError);
348+
const auto modifications = config.getConditions().getModifications();
349+
CHECK(modifications.size() == 2);
350+
const auto TTX = nonstd::get<SimulationConfig::ModificationTTX>(modifications[0]);
351+
CHECK(TTX.name == "applyTTX");
355352
CHECK(TTX.type == SimulationConfig::ModificationBase::ModificationType::TTX);
356353
CHECK(TTX.nodeSet == "single");
354+
const auto configAllSects = nonstd::get<SimulationConfig::ModificationConfigureAllSections>(modifications[1]);
355+
CHECK(configAllSects.name == "no_SK_E2");
357356
CHECK(configAllSects.type ==
358357
SimulationConfig::ModificationBase::ModificationType::ConfigureAllSections);
359358
CHECK(configAllSects.sectionConfigure == "%s.gSK_E2bar_SK_E2 = 0");

0 commit comments

Comments
 (0)