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

Commit 4712042

Browse files
committed
fix
1 parent a2d22ff commit 4712042

3 files changed

Lines changed: 68 additions & 36 deletions

File tree

include/bbp/sonata/config.h

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#pragma once
1313

14-
#include <memory> // std::unique_ptr
1514
#include <set>
1615
#include <string>
1716
#include <unordered_map>
@@ -266,27 +265,34 @@ class SONATA_API SimulationConfig
266265
struct Run {
267266
enum class IntegrationMethod { invalid = -1, euler, nicholson, nicholson_ion };
268267

268+
static constexpr int DEFAULT_spikeThreshold = -30;
269+
static constexpr IntegrationMethod DEFAULT_IntegrationMethod = IntegrationMethod::euler;
270+
static constexpr int DEFAULT_stimulusSeed = 0;
271+
static constexpr int DEFAULT_ionchannelSeed = 0;
272+
static constexpr int DEFAULT_minisSeed = 0;
273+
static constexpr int DEFAULT_synapseSeed = 0;
274+
269275
/// Biological simulation end time in milliseconds
270276
double tstop{};
271277
/// Integration step duration in milliseconds
272278
double dt{};
273279
/// Random seed
274280
int randomSeed{};
275281
/// The spike detection threshold. Default is -30mV
276-
int spikeThreshold;
282+
int spikeThreshold = DEFAULT_spikeThreshold;
277283
/// Selects the NEURON/CoreNEURON integration method. This parameter sets the NEURON
278284
/// global variable h.secondorder. Default 0 ('euler')
279-
IntegrationMethod integrationMethod;
285+
IntegrationMethod integrationMethod = DEFAULT_IntegrationMethod;
280286
/// A non-negative integer used for seeding noise stimuli and any other future stochastic
281287
/// stimuli, default is 0.
282-
int stimulusSeed;
288+
int stimulusSeed = DEFAULT_stimulusSeed;
283289
/// A non-negative integer used for seeding stochastic ion channels, default is 0.
284-
int ionchannelSeed;
290+
int ionchannelSeed = DEFAULT_ionchannelSeed;
285291
/// A non-negative integer used for seeding the Poisson processes that drives the minis,
286292
/// default is 0.
287-
int minisSeed;
293+
int minisSeed = DEFAULT_minisSeed;
288294
/// A non-negative integer used for seeding stochastic synapses, default is 0.
289-
int synapseSeed;
295+
int synapseSeed = DEFAULT_synapseSeed;
290296
/// Filename that contains the weights for the LFP calculation.
291297
std::string electrodesFile;
292298
};
@@ -296,14 +302,19 @@ class SONATA_API SimulationConfig
296302
struct Output {
297303
enum class SpikesSortOrder { invalid = -1, none, by_id, by_time };
298304

305+
static constexpr char DEFAULT_outputDir[] = "output";
306+
static constexpr char DEFAULT_logFile[] = "";
307+
static constexpr char DEFAULT_spikesFile[] = "out.h5";
308+
static constexpr SpikesSortOrder DEFAULT_sortOrder = SpikesSortOrder::by_time;
309+
299310
/// Spike report file output directory. Default is "output"
300-
std::string outputDir;
311+
std::string outputDir = DEFAULT_outputDir;
301312
/// Filename where console output is written. Default is STDOUT.
302-
std::string logFile;
313+
std::string logFile = DEFAULT_logFile;
303314
/// Spike report file name. Default is "out.h5"
304-
std::string spikesFile;
315+
std::string spikesFile = DEFAULT_spikesFile;
305316
/// The sorting order of the spike report. Default is "by_time"
306-
SpikesSortOrder sortOrder;
317+
SpikesSortOrder sortOrder = DEFAULT_sortOrder;
307318
};
308319

309320
struct ModificationBase {
@@ -333,19 +344,23 @@ class SONATA_API SimulationConfig
333344
*/
334345
struct Conditions {
335346
enum class SpikeLocation { invalid = -1, soma, AIS };
347+
static constexpr double DEFAULT_celsius = 34.0;
348+
static constexpr double DEFAULT_vInit = -80.0;
349+
static constexpr SpikeLocation DEFAULT_spikeLocation = SpikeLocation::soma;
350+
static constexpr bool DEFAULT_randomizeGabaRiseTime = false;
336351

337352
/// Temperature of experiment. Default is 34.0
338-
double celsius;
353+
double celsius = DEFAULT_celsius;
339354
/// Initial membrane voltage in mV. Default is -80
340-
double vInit;
355+
double vInit = DEFAULT_vInit;
341356
/// The spike detection location. Can be either ‘soma’ or 'AIS'. Default is 'soma'
342-
SpikeLocation spikeLocation;
357+
SpikeLocation spikeLocation = DEFAULT_spikeLocation;
343358
/// Extracellular calcium concentration, being applied to the synapse uHill parameter in
344359
/// order to scale the U parameter of synapses. Default is None.
345360
nonstd::optional<double> extracellularCalcium{nonstd::nullopt};
346361
/// Enable legacy behavior to randomize the GABA_A rise time in the helper functions.
347362
/// Default is false
348-
bool randomizeGabaRiseTime;
363+
bool randomizeGabaRiseTime = DEFAULT_randomizeGabaRiseTime;
349364
/// Properties to assign values to variables in synapse MOD files.
350365
/// The format is a dictionary with keys being the SUFFIX names and values being
351366
/// dictionaries of variables' names and values.

python/tests/test_config.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -628,16 +628,14 @@ def test_empty_connection_overrides(self):
628628
def test_empty_conditions(self):
629629
contents = """
630630
{
631-
"manifest": {
632-
"$CIRCUIT_DIR": "./circuit"
633-
},
631+
"manifest": { "$CIRCUIT_DIR": "./circuit" },
634632
"network": "$CIRCUIT_DIR/circuit_config.json",
635633
"run": { "random_seed": 12345, "dt": 0.05, "tstop": 1000 },
636634
"connection_overrides": []
637635
}
638636
"""
639637
conf = SimulationConfig(contents, "./")
640-
self.assertEqual(conf.conditions.celsius, 35.0)
638+
self.assertEqual(conf.conditions.celsius, 34.0)
641639
self.assertEqual(conf.conditions.v_init, -80)
642640

643641
def test_run(self):

src/config.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,25 @@ NLOHMANN_JSON_SERIALIZE_ENUM(
132132
{SimulationConfig::ModificationBase::ModificationType::ConfigureAllSections,
133133
"ConfigureAllSections"}})
134134

135+
// { in C++14; one has to declare static constexpr members; this can go away in c++17
136+
#define D(name) decltype(SimulationConfig::name) constexpr SimulationConfig::name;
137+
D(Output::DEFAULT_outputDir)
138+
D(Conditions::DEFAULT_randomizeGabaRiseTime)
139+
D(Output::DEFAULT_logFile)
140+
D(Run::DEFAULT_stimulusSeed)
141+
D(Conditions::DEFAULT_spikeLocation)
142+
D(Run::DEFAULT_ionchannelSeed)
143+
D(Output::DEFAULT_sortOrder)
144+
D(Run::DEFAULT_IntegrationMethod)
145+
D(Conditions::DEFAULT_vInit)
146+
D(Run::DEFAULT_minisSeed)
147+
D(Output::DEFAULT_spikesFile)
148+
D(Conditions::DEFAULT_celsius)
149+
D(Run::DEFAULT_synapseSeed)
150+
D(Run::DEFAULT_spikeThreshold)
151+
#undef D
152+
// }
153+
135154
namespace {
136155
// to be replaced by std::filesystem once C++17 is used
137156
namespace fs = ghc::filesystem;
@@ -976,15 +995,15 @@ class SimulationConfig::Parser
976995
parseMandatory(*runIt, "tstop", "run", result.tstop);
977996
parseMandatory(*runIt, "dt", "run", result.dt);
978997
parseMandatory(*runIt, "random_seed", "run", result.randomSeed);
979-
parseOptional(*runIt, "spike_threshold", result.spikeThreshold, {-30});
998+
parseOptional(*runIt, "spike_threshold", result.spikeThreshold, {Run::DEFAULT_spikeThreshold});
980999
parseOptional(*runIt,
9811000
"integration_method",
9821001
result.integrationMethod,
983-
{Run::IntegrationMethod::euler});
984-
parseOptional(*runIt, "stimulus_seed", result.stimulusSeed, {0});
985-
parseOptional(*runIt, "ionchannel_seed", result.ionchannelSeed, {0});
986-
parseOptional(*runIt, "minis_seed", result.minisSeed, {0});
987-
parseOptional(*runIt, "synapse_seed", result.synapseSeed, {0});
1002+
{Run::DEFAULT_IntegrationMethod});
1003+
parseOptional(*runIt, "stimulus_seed", result.stimulusSeed, {Run::DEFAULT_stimulusSeed});
1004+
parseOptional(*runIt, "ionchannel_seed", result.ionchannelSeed, {Run::DEFAULT_ionchannelSeed});
1005+
parseOptional(*runIt, "minis_seed", result.minisSeed, {Run::DEFAULT_minisSeed});
1006+
parseOptional(*runIt, "synapse_seed", result.synapseSeed, {Run::DEFAULT_synapseSeed});
9881007
parseOptional(*runIt, "electrodes_file", result.electrodesFile, {""});
9891008

9901009
if (!result.electrodesFile.empty()) {
@@ -1001,37 +1020,37 @@ class SimulationConfig::Parser
10011020
if (outputIt == _json.end()) {
10021021
return result;
10031022
}
1004-
parseOptional(*outputIt, "output_dir", result.outputDir, {"output"});
1005-
parseOptional(*outputIt, "log_file", result.logFile, {""});
1006-
parseOptional(*outputIt, "spikes_file", result.spikesFile, {"out.h5"});
1023+
parseOptional(*outputIt, "output_dir", result.outputDir, {Output::DEFAULT_outputDir});
1024+
parseOptional(*outputIt, "log_file", result.logFile, {Output::DEFAULT_logFile});
1025+
parseOptional(*outputIt, "spikes_file", result.spikesFile, {Output::DEFAULT_spikesFile});
10071026
parseOptional(*outputIt,
10081027
"spikes_sort_order",
10091028
result.sortOrder,
1010-
{Output::SpikesSortOrder::by_time});
1029+
{Output::DEFAULT_sortOrder});
10111030

10121031
result.outputDir = toAbsolute(_basePath, result.outputDir);
10131032

10141033
return result;
10151034
}
10161035

10171036
SimulationConfig::Conditions parseConditions() const {
1018-
SimulationConfig::Conditions result{};
1037+
SimulationConfig::Conditions result;
10191038

10201039
const auto conditionsIt = _json.find("conditions");
10211040
if (conditionsIt == _json.end()) {
10221041
return result;
10231042
}
1024-
parseOptional(*conditionsIt, "celsius", result.celsius, {34.0});
1025-
parseOptional(*conditionsIt, "v_init", result.vInit, {-80});
1043+
parseOptional(*conditionsIt, "celsius", result.celsius, {Conditions::DEFAULT_celsius});
1044+
parseOptional(*conditionsIt, "v_init", result.vInit, {Conditions::DEFAULT_vInit});
10261045
parseOptional(*conditionsIt,
10271046
"spike_location",
10281047
result.spikeLocation,
1029-
{Conditions::SpikeLocation::soma});
1048+
{Conditions::DEFAULT_spikeLocation});
10301049
parseOptional(*conditionsIt, "extracellular_calcium", result.extracellularCalcium);
10311050
parseOptional(*conditionsIt,
10321051
"randomize_gaba_rise_time",
10331052
result.randomizeGabaRiseTime,
1034-
{false});
1053+
{Conditions::DEFAULT_randomizeGabaRiseTime});
10351054
parseConditionsMechanisms(*conditionsIt, result.mechanisms);
10361055
parseConditionsModifications(*conditionsIt, result.modifications);
10371056
return result;
@@ -1093,7 +1112,7 @@ class SimulationConfig::Parser
10931112
}
10941113

10951114
SimulationConfig::SimulatorType parseTargetSimulator() const {
1096-
SimulationConfig::SimulatorType val;
1115+
SimulationConfig::SimulatorType val = SimulationConfig::SimulatorType::NEURON;
10971116
parseOptional(_json, "target_simulator", val, {SimulationConfig::SimulatorType::NEURON});
10981117
return val;
10991118
}
@@ -1135,7 +1154,7 @@ class SimulationConfig::Parser
11351154
const auto& valueIt = it.value();
11361155
const auto debugStr = fmt::format("input {}", it.key());
11371156

1138-
InputBase::Module module;
1157+
InputBase::Module module = InputBase::Module::invalid;
11391158
parseMandatory(valueIt, "module", debugStr, module);
11401159

11411160
const auto input = parseInputModule(valueIt, module, _basePath, debugStr);

0 commit comments

Comments
 (0)