[med-svn] [cnrun] 01/05: implement NML export
andrei zavada
hmmr-guest at moszumanska.debian.org
Wed Dec 28 17:57:00 UTC 2016
This is an automated email from the git hooks/post-receive script.
hmmr-guest pushed a commit to branch WIP
in repository cnrun.
commit b2837ebc10cd07be444f729982ac45d8c9d45939
Author: Andrei Zavada <johnhommer at gmail.com>
Date: Tue Dec 27 05:57:59 2016 +0200
implement NML export
---
upstream/ChangeLog | 4 +
upstream/Makefile.am | 1 +
upstream/configure.ac | 8 +-
upstream/doc/examples/example1.lua | 117 ++++++++++--
upstream/doc/lua-api/cnrun-lua-api.texi | 2 +-
upstream/src/libcnrun/model/cycle.cc | 5 +-
upstream/src/libcnrun/model/model.hh | 19 +-
upstream/src/libcnrun/model/nmlio.cc | 211 ++++++++++++++++------
upstream/src/libcnrun/model/struct.cc | 57 +++---
upstream/src/libcnrun/units/base-neuron.hh | 10 +-
upstream/src/libcnrun/units/base-synapse.hh | 3 +-
upstream/src/libcnrun/units/base-unit.cc | 102 +++++++++--
upstream/src/libcnrun/units/base-unit.hh | 47 +++--
upstream/src/libcnrun/units/hosted-neurons.cc | 8 +-
upstream/src/libcnrun/units/hosted-neurons.hh | 84 ++++-----
upstream/src/libcnrun/units/standalone-neurons.cc | 20 +-
upstream/src/libcnrun/units/standalone-neurons.hh | 53 +++---
upstream/src/lua-cnrun/commands.cc | 4 +-
upstream/src/tools/hh-latency-estimator.cc | 18 +-
19 files changed, 507 insertions(+), 266 deletions(-)
diff --git a/upstream/ChangeLog b/upstream/ChangeLog
index 6f20a86..7f5fe8f 100644
--- a/upstream/ChangeLog
+++ b/upstream/ChangeLog
@@ -1,3 +1,7 @@
+2016-12-25 andrei zavada <johnhommer at gmail.com>
+ * Implement NML export.
+ * Release 2.1.
+
2016-01-12 andrei zavada <johnhommer at gmail.com>
* Fix decimate and putout.
* Release 2.0.3.
diff --git a/upstream/Makefile.am b/upstream/Makefile.am
index 98cfaed..4789435 100644
--- a/upstream/Makefile.am
+++ b/upstream/Makefile.am
@@ -33,6 +33,7 @@ unwanted_files = \
m4/ltsugar.m4 \
m4/ltversion.m4 \
aclocal.m4 \
+ compile \
config.sub \
ltmain.sh \
depcomp \
diff --git a/upstream/configure.ac b/upstream/configure.ac
index d945eb0..b335672 100644
--- a/upstream/configure.ac
+++ b/upstream/configure.ac
@@ -1,6 +1,6 @@
AC_COPYRIGHT([Copyright (c) 2008-15 Andrei Zavada <johnhommer at gmail.com>])
-AC_INIT([cnrun], [2.0.3], [johnhommer at gmail.com])
+AC_INIT([cnrun], [2.1.0], [johnhommer at gmail.com])
AC_CONFIG_SRCDIR([src/libcnrun/model/model.hh])
AC_CONFIG_MACRO_DIR([m4])
AC_PREREQ(2.61)
@@ -65,14 +65,12 @@ AX_LUA_HEADERS2014
dnl we cannot do strcmp in cpp, so here's bash to the rescue
if test x"$LUA_VERSION" = x"5.2"; then
AC_DEFINE([HAVE_LUA_52], [], ["Do we have lua 5.2?"])
-else
- AC_DEFINE([HAVE_LUA_51], [], ["Do we have lua 5.1?"])
fi
AC_ARG_ENABLE(
[tools],
- AS_HELP_STRING( [--enable-tools], [build spike2sdf, varfold & hh-latency-estimator (default = no)]),
- [do_tools=$enableval], [do_tools=no])
+ AS_HELP_STRING( [--enable-tools], [build spike2sdf, varfold & hh-latency-estimator (default = yes)]),
+ [do_tools=$enableval], [do_tools=yes])
AM_CONDITIONAL(DO_TOOLS, [test x"$do_tools" = xyes])
AC_ARG_ENABLE(
diff --git a/upstream/doc/examples/example1.lua b/upstream/doc/examples/example1.lua
index 3f91c82..bf4900c 100644
--- a/upstream/doc/examples/example1.lua
+++ b/upstream/doc/examples/example1.lua
@@ -35,6 +35,55 @@ if res == nil then
end
C = ult
+function print_units (model_name, ult, unit_regex)
+ print ("There are " .. #ult .. " unit(s) matching \"" .. unit_regex .. "\"")
+ local unit_list = ult
+ local fmt = " %-10s %-16s %-16s %-12s %-16s %-6s"
+ print (string.format(
+ fmt,
+ "label", "class", "family", "species", "has_sources", "is_altered"))
+ print (string.rep('-', 87))
+ for _, u in ipairs(unit_list) do
+ result = {M.get_unit_properties (C, model_name, u)}
+ res, ult = result[1], {effective_unpack(result, 2)}
+ local b = function (x) if x then return "yes" else return "no" end end
+ print (string.format(
+ fmt,
+ ult[1], ult[2], ult[3], ult[4], b(ult[5]), b(ult[6])))
+ end
+ print()
+end
+
+function compare_models (model_name1, model_name2)
+ local result1 = {M.get_units_matching(C, model_name1, ".*")}
+ local result2 = {M.get_units_matching(C, model_name2, ".*")}
+ res, ult1 = result[1], {effective_unpack(result1, 2)}
+ if res == nil then
+ print (ult1)
+ return
+ end
+ res, ult2 = result[1], {effective_unpack(result2, 2)}
+ if res == nil then
+ print (ult2)
+ return
+ end
+ local relevant_list1 = get_relevant_unit_params (model_name1, ult1)
+ local relevant_list2 = get_relevant_unit_params (model_name2, ult2)
+
+ return relevant_list1 == relevant_list2
+end
+
+function get_relevant_unit_params (model_name, unit_list)
+ local rup = {}
+ for _, u in ipairs(unit_list) do
+ result = {M.get_unit_properties (C, model_name, u)}
+ res, ult = result[1], {effective_unpack(result, 2)}
+ table.insert (rup, {ult[1], ult[2], ult[3], ult[4], ult[5], ult[6]})
+ end
+ return rup
+end
+
+
local mname = "FAFA"
res, ult = M.new_model (C, mname)
if res == nil then
@@ -44,8 +93,9 @@ end
model = ult
print ("Created model")
-print ("Setting verbosely to 4")
-M.set_model_parameter (C, mname, "verbosely", 4)
+local verbosely = 3
+print ("Setting verbosely to " .. verbosely)
+M.set_model_parameter (C, mname, "verbosely", verbosely)
result = {M.list_models (C)}
res, ult = result[1], {effective_unpack(result, 2)}
@@ -69,6 +119,46 @@ end
print ()
+print ("Testing NML export")
+local mname2 = "FAFA2"
+local f2 = "/tmp/m2.nml"
+
+print ("Exporting to " .. f2)
+res, ult = M.export_nml (C, mname, f2)
+if res == nil then
+ print (ult)
+ return
+end
+
+M.new_model (C, mname2)
+print ("Importing into new model from " .. f2)
+res, ult = M.import_nml (C, mname2, f2)
+if res == nil then
+ print (ult)
+ return
+end
+
+print ()
+print ("Comparing old and new models")
+if compare_models (mname, mname2) then
+ print ()
+ print ("Models appear to be different:")
+ print ("Original model:")
+ print_units (mname, ult1, ".*")
+ print ("Reimported model:")
+ print_units (mname2, ult2, ".*")
+ return
+end
+print ("Models are pretty much the same")
+print()
+
+M.delete_model (C, mname2)
+if res == nil then
+ print (ult)
+ return
+end
+
+
print ("Host parmeters:")
local parameters = {
"verbosely", "integration_dt_min",
@@ -96,23 +186,8 @@ if res == nil then
print (ult)
return
end
-print ()
-print ("There are " .. #ult .. " unit(s) matching L.*:")
-local unit_list = ult
-local fmt = " %-10s %-16s %-16s %-12s %-16s %-6s"
-print (string.format(
- fmt,
- "label", "class", "family", "species", "has_sources", "is_altered"))
-print (string.rep('-', 87))
-for _, u in ipairs(unit_list) do
- result = {M.get_unit_properties (C, mname, u)}
- res, ult = result[1], {effective_unpack(result, 2)}
- local b = function (x) if x then return "yes" else return "no" end end
- print (string.format(
- fmt,
- ult[1], ult[2], ult[3], ult[4], b(ult[5]), b(ult[6])))
-end
-print()
+
+print_units (mname, ult, "L.*")
print ("Advancing 10 sec:")
@@ -166,7 +241,9 @@ print()
local affected, remaining
print ("Putout:")
--- there is unit_list already:
+result = {M.get_units_matching(C, mname, ".*")}
+res, ult = result[1], {effective_unpack(result, 2)}
+local unit_list = ult
math.randomseed(os.time())
local deleting = unit_list[math.random(1, #unit_list)]
-- deleting, _ = string.gsub(deleting, ".", "\\.")
diff --git a/upstream/doc/lua-api/cnrun-lua-api.texi b/upstream/doc/lua-api/cnrun-lua-api.texi
index 6e76736..738c3a9 100644
--- a/upstream/doc/lua-api/cnrun-lua-api.texi
+++ b/upstream/doc/lua-api/cnrun-lua-api.texi
@@ -177,7 +177,7 @@ Models can be populated by constituent neurons and synapses in two ways:
@defun new_neuron (C, M, type, label)
Create a neuron of type @var{type}, with this @var{label}, in model
- @var{M}.
+ @var{M}. @var{label} must be of the form ``population.id''.
@end defun
@defun new_synapse (C, M, type, source, target)
diff --git a/upstream/src/libcnrun/model/cycle.cc b/upstream/src/libcnrun/model/cycle.cc
index 5247bae..ca5379a 100644
--- a/upstream/src/libcnrun/model/cycle.cc
+++ b/upstream/src/libcnrun/model/cycle.cc
@@ -280,10 +280,7 @@ prepare_advance()
N->n_spikes_in_last_dt() && \
options.log_spikers ) { \
(*_spike_logger) << model_time() << "\t"; \
- if ( options.log_spikers_use_serial_id ) \
- (*_spike_logger) << N->_serial_id << endl; \
- else \
- (*_spike_logger) << N->_label << endl; \
+ (*_spike_logger) << N->_label << endl; \
} \
}
diff --git a/upstream/src/libcnrun/model/model.hh b/upstream/src/libcnrun/model/model.hh
index 88c2c3f..6173bb2 100644
--- a/upstream/src/libcnrun/model/model.hh
+++ b/upstream/src/libcnrun/model/model.hh
@@ -118,7 +118,7 @@ class CModel : public cnrun::stilton::C_verprintf {
C_BaseUnit *unit_by_label( const string&) const;
C_BaseNeuron *neuron_by_label( const string&) const;
C_BaseSynapse *synapse_by_label( const string&) const;
- unsigned short longest_label() const
+ size_t longest_label() const
{ return _longest_label; }
// Unit tally
@@ -158,17 +158,17 @@ class CModel : public cnrun::stilton::C_verprintf {
int include_unit( C_StandaloneSynapse*);
C_BaseNeuron*
- add_neuron_species( TUnitType, const string& label,
+ add_neuron_species( TUnitType, const char *pop, const char* id,
TIncludeOption = TIncludeOption::is_last,
double x = 0., double y = 0., double z = 0.);
C_BaseNeuron*
- add_neuron_species( const string& type, const string& label,
+ add_neuron_species( const char *type, const char *pop, const char* id,
TIncludeOption = TIncludeOption::is_last,
double x = 0., double y = 0., double z = 0.);
enum class TSynapseCloningOption { yes, no, };
C_BaseSynapse*
- add_synapse_species( const string& type, const string& src, const string& tgt,
+ add_synapse_species( const char *type, const char *src, const char *tgt,
double g,
TSynapseCloningOption = TSynapseCloningOption::yes,
TIncludeOption = TIncludeOption::is_last);
@@ -187,6 +187,11 @@ class CModel : public cnrun::stilton::C_verprintf {
void delete_unit( C_BaseUnit* u)
{ exclude_unit( u, TExcludeOption::with_delete); }
+ void update_longest_label(size_t label_size)
+ {
+ _longest_label = max(_longest_label, label_size);
+ }
+
// 1. NeuroMl interface
enum class TNMLImportOption { merge, reset, };
enum TNMLIOResult {
@@ -448,9 +453,6 @@ class CModel : public cnrun::stilton::C_verprintf {
list<unsigned>
regular_periods_last_checked;
- unsigned long
- _global_unit_id_reservoir;
-
// the essential mechanical parts: ----
// hosted unit variables
vector<double> V, // contains catenated var vectors of all constituent neurons and synapses
@@ -477,8 +479,7 @@ class CModel : public cnrun::stilton::C_verprintf {
is_diskless:1,
have_ddtb_units:1;
- unsigned short
- _longest_label;
+ size_t _longest_label;
gsl_rng *_rng;
diff --git a/upstream/src/libcnrun/model/nmlio.cc b/upstream/src/libcnrun/model/nmlio.cc
index 9711377..8221a72 100644
--- a/upstream/src/libcnrun/model/nmlio.cc
+++ b/upstream/src/libcnrun/model/nmlio.cc
@@ -22,6 +22,7 @@
using namespace std;
+using cnrun::stilton::str::sasprintf;
int
cnrun::CModel::
@@ -188,19 +189,18 @@ _process_populations( xmlNode *n)
}
xmlNode *nin = n->children; // again, ->children means ->first
- if ( nin )
- for ( ; nin; nin = nin->next ) // deal with multiple <instances> nodes
- if ( nin->type == XML_ELEMENT_NODE && xmlStrEqual( nin->name, BAD_CAST "instances") ) {
- int subretval = _process_population_instances(
- nin->children,
- group_id_s, cell_type_s);
- if ( subretval < 0 )
- throw subretval;
-
- vp( 2, " %5d instance(s) of type \"%s\" in population \"%s\"\n",
- subretval, cell_type_s, group_id_s);
- ++pop_cnt;
- }
+ for ( ; nin; nin = nin->next ) // deal with multiple <instances> nodes
+ if ( nin->type == XML_ELEMENT_NODE && xmlStrEqual( nin->name, BAD_CAST "instances") ) {
+ int subretval = _process_population_instances(
+ nin->children,
+ group_id_s, cell_type_s);
+ if ( subretval < 0 )
+ throw subretval;
+
+ vp( 2, " %5d instance(s) of type \"%s\" in population \"%s\"\n",
+ subretval, cell_type_s, group_id_s);
+ ++pop_cnt;
+ }
xmlFree( cell_type_s), xmlFree( group_id_s);
}
@@ -305,17 +305,17 @@ int
cnrun::CModel::
_process_population_instances(
xmlNode *n,
- const xmlChar *group_prefix,
+ const xmlChar *population,
const xmlChar *type_s)
{
int retval = 0; // also keeps a count of added neurons
double x, y, z;
- char cell_id[C_BaseUnit::max_label_size];
+ string label;
xmlNode *nin;
- xmlChar *id_s = nullptr;
+ char *id_s = nullptr;
try {
for ( ; n; n = n->next ) {
if ( n->type != XML_ELEMENT_NODE || !xmlStrEqual( n->name, BAD_CAST "instance") )
@@ -323,29 +323,10 @@ _process_population_instances(
xmlChar *id_s = xmlGetProp( n, BAD_CAST "id");
if ( !id_s ) {
- // could be less strict here and allow empty ids, which will then be composed
- // from group_prefix + id (say, "LN0", "LN1" and so on); but then, as
- // individual <projection>s would have to reference both endpoints by explicit
- // ids, it is obviously prone to error to have <instance> ids depend solely on
- // their order of appearance.
- // So we bark at empty ids.
fprintf( stderr, "<instance> element without an \"id\" attribute near line %u\n", n->line);
return TNMLIOResult::badattr;
}
- size_t total_len = xmlStrlen( group_prefix) + xmlStrlen( id_s);
- if ( total_len >= C_BaseUnit::max_label_size ) {
- fprintf( stderr, "Combined label for an <instance> (\"%s%s\") exceeding %zu characters near line %d\n",
- group_prefix, id_s, C_BaseUnit::max_label_size, n->line);
- throw TNMLIOResult::biglabel;
- }
- _longest_label = max(
- _longest_label,
- (unsigned short)snprintf(
- cell_id, C_BaseUnit::max_label_size-1, "%s.%s",
- group_prefix, id_s)); // here, a new instance is given a name
- xmlFree( id_s);
-
if ( !(nin = n->children) )
return retval;
@@ -357,24 +338,27 @@ _process_population_instances(
xmlChar *x_s = xmlGetProp( nin, BAD_CAST "x"),
*y_s = xmlGetProp( nin, BAD_CAST "y"),
*z_s = xmlGetProp( nin, BAD_CAST "z");
- // here we do actually insert neurons into the model
+ // here we do actually insert neurons into the model
if ( !(x_s && y_s && z_s) )
vp( 1, stderr, "<location> element missing full set of coordinates near line %d\n", nin->line);
- // not an error
+ // not an error
x = strtod( (char*)x_s, nullptr), y = strtod( (char*)y_s, nullptr), z = strtod( (char*)z_s, nullptr);
- xmlFree( x_s), xmlFree( y_s), xmlFree( z_s);
+ auto maybe_free = [](decltype(x_s) X) { if ( X ) free((void*)X); };
+ maybe_free( x_s), maybe_free( y_s), maybe_free( z_s);
C_BaseNeuron *neu = add_neuron_species(
- (char*)type_s, cell_id,
- TIncludeOption::is_notlast);
+ (char*)type_s, (char*)population, (char*)id_s,
+ TIncludeOption::is_notlast,
+ x, y, z);
+
+ xmlFree( id_s);
if ( !neu || neu->_status & CN_UERROR ) {
if ( neu )
delete neu;
- fprintf( stderr, "Failed to add a neuron \"%s\" near line %u\n", cell_id, n->line);
+ fprintf( stderr, "Failed to add neuron of type %s, population:id \"%s:%s\" near line %u\n", type_s, population, id_s, n->line);
return TNMLIOResult::structerror;
} else {
- neu->_serial_id = _global_unit_id_reservoir++;
neu->pos = make_tuple( x, y, z);
++retval;
}
@@ -394,8 +378,8 @@ _process_population_instances(
int
cnrun::CModel::
_process_projection_connections(
- xmlNode *n,
- const xmlChar *synapse_name,
+ xmlNode *N,
+ const xmlChar *unused_synapse_name,
const xmlChar *type_s,
const xmlChar *src_grp_prefix,
const xmlChar *tgt_grp_prefix)
@@ -405,9 +389,7 @@ _process_projection_connections(
int retval = 0; // is also a counter of synapses
- char //synapse_id [C_BaseUnit::max_label_size],
- src_s[C_BaseUnit::max_label_size],
- tgt_s[C_BaseUnit::max_label_size];
+ string label_src, label_tgt;
double weight;
C_BaseSynapse *y;
@@ -416,31 +398,38 @@ _process_projection_connections(
*tgt_cell_id_s = nullptr,
*weight_s = nullptr;
try {
- for ( ; n; n = n->next ) {
- if ( n->type != XML_ELEMENT_NODE || !xmlStrEqual( n->name, BAD_CAST "connection") )
+ for ( ; N; N = N->next ) {
+ if ( N->type != XML_ELEMENT_NODE || !xmlStrEqual( N->name, BAD_CAST "connection") )
continue;
- src_cell_id_s = xmlGetProp( n, BAD_CAST "pre_cell_id"),
- tgt_cell_id_s = xmlGetProp( n, BAD_CAST "post_cell_id"),
- weight_s = xmlGetProp( n, BAD_CAST "weight");
+ src_cell_id_s = xmlGetProp( N, BAD_CAST "pre_cell_id"),
+ tgt_cell_id_s = xmlGetProp( N, BAD_CAST "post_cell_id"),
+ weight_s = xmlGetProp( N, BAD_CAST "weight");
if ( /*!synapse_id_s || */ !src_cell_id_s || !tgt_cell_id_s ) {
- fprintf( stderr, "A <connection> element without \"pre_cell_id\" and/or \"post_cell_id\" attribute near line %u\n", n->line);
+ fprintf( stderr, "A <connection> element without \"pre_cell_id\" and/or \"post_cell_id\" attribute near line %u\n", N->line);
throw TNMLIOResult::badattr;
}
- snprintf( src_s, C_BaseUnit::max_label_size-1, "%s.%s", src_grp_prefix, src_cell_id_s);
- snprintf( tgt_s, C_BaseUnit::max_label_size-1, "%s.%s", tgt_grp_prefix, tgt_cell_id_s);
+ label_src = C_BaseNeuron::make_nml_name( (char*)src_grp_prefix, (char*)src_cell_id_s);
+ label_tgt = C_BaseNeuron::make_nml_name( (char*)tgt_grp_prefix, (char*)tgt_cell_id_s);
+ if ( label_src.size() > C_BaseUnit::max_label_size ||
+ label_tgt.size() > C_BaseUnit::max_label_size ) {
+ fprintf( stderr, "Source or target label size (%zu) exceeds %zu chars near line %u\n",
+ max(label_tgt.size(), label_src.size()), C_BaseUnit::max_label_size, N->line);
+ return TNMLIOResult::biglabel;
+ }
if ( !weight_s ) {
vp( 3, stderr, "Assuming 0 for a synapse of \"%s.%s\" to \"%s%s\" without a \"weight\" attribute near line %u\n",
- src_grp_prefix, src_cell_id_s, tgt_grp_prefix, tgt_cell_id_s, n->line);
+ src_grp_prefix, src_cell_id_s, tgt_grp_prefix, tgt_cell_id_s, N->line);
weight = 0.;
}
/* xmlFree( synapse_id_s), */ xmlFree( src_cell_id_s), xmlFree( tgt_cell_id_s),
xmlFree( weight_s);
y = add_synapse_species(
- (char*)type_s, src_s, tgt_s,
+ (char*)type_s,
+ label_src.c_str(), label_tgt.c_str(),
weight,
TSynapseCloningOption::yes,
TIncludeOption::is_notlast);
@@ -449,7 +438,7 @@ _process_projection_connections(
if ( y )
delete y;
fprintf( stderr, "Failed to add an \"%s\" synapse from \"%s\" to \"%s\" near line %u\n",
- (char*)type_s, src_s, tgt_s, n->line);
+ (char*)type_s, label_src.c_str(), label_tgt.c_str(), N->line);
return TNMLIOResult::structerror;
} else
++retval;
@@ -472,9 +461,111 @@ export_NetworkML( const string& fname)
{
int retval = 0;
- LIBXML_TEST_VERSION;
+ xmlIndentTreeOutput = 1;
+
+ xmlDoc *doc = xmlNewDoc( BAD_CAST "1.0");
+
+ xmlNode *root_node = xmlNewDocNode( doc, NULL, BAD_CAST "networkml", NULL);
+ xmlDocSetRootElement( doc, root_node);
+ // This is from m.nml, originally generated by neuroConstruct ca 2009:
+ // <networkml xmlns="http://morphml.org/networkml/schema"
+ // xmlns:meta="http://morphml.org/metadata/schema"
+ // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ // xsi:schemaLocation="http://morphml.org/networkml/schema NetworkML_v1.7.xsd"
+ // lengthUnits="micron">
+ // The definitions below are from https://github.com/NeuroML/NeuroML2/blob/master/examples/NML2_FullNeuroML.nml:
+ xmlNs *ns = xmlNewNs( root_node, BAD_CAST "http://www.neuroml.org/schema/neuroml2", NULL);
+ xmlNewNsProp( root_node, ns, BAD_CAST "xmlns:meta", BAD_CAST "http://morphml.org/metadata/schema");
+ xmlNewNsProp( root_node, ns, BAD_CAST "xmlns:xsi", BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
+ xmlNewNsProp( root_node, ns, BAD_CAST "xsi:schemaLocation", BAD_CAST "http://www.neuroml.org/schema/neuroml2 ../Schemas/NeuroML2/NeuroML_v2beta4.xsd");
+
+ {
+ time_t t = time(NULL);
+ string manifest = sasprintf(
+ "Model %s\n"
+ "Created with CNRun2 v. " VERSION " on %s",
+ name.c_str(), asctime( localtime( &t)));
+ xmlNewTextChild( root_node, ns, BAD_CAST "meta:notes", BAD_CAST manifest.c_str());
+ }
- fprintf( stderr, "export_NetworkML() not implemented yet\n");
+ xmlNode *populations_node = xmlNewNode( NULL, BAD_CAST "populations"),
+ *projections_node = xmlNewNode( NULL, BAD_CAST "projections");
+ xmlAddChild( root_node, populations_node);
+ xmlAddChild( root_node, projections_node);
+
+ map<string, xmlNode*> PP;
+ auto get_or_create_population = [&] (const char *population,
+ const char *cell_type) -> xmlNode* {
+ auto found = PP.find(string(population));
+ if ( found == PP.end() ) {
+ xmlNode *N = xmlNewChild( populations_node, NULL, BAD_CAST "population", NULL);
+ xmlNewProp( N, BAD_CAST "name", BAD_CAST population);
+ xmlNewProp( N, BAD_CAST "cell_type", BAD_CAST cell_type);
+ return PP[population] = xmlNewChild( N, NULL, BAD_CAST "instances", NULL);
+ }
+ return found->second;
+ };
+ auto get_or_create_projection = [&] (const char *projection,
+ const char *source,
+ const char *target,
+ const char *synapse_type,
+ const char *weight) -> xmlNode* {
+ auto found = PP.find(string(projection));
+ if ( found == PP.end() ) { // is always true
+ xmlNode *N = xmlNewChild( projections_node, NULL, BAD_CAST "projection", NULL);
+ xmlNewProp( N, BAD_CAST "name", BAD_CAST projection);
+ xmlNewProp( N, BAD_CAST "source", BAD_CAST source);
+ xmlNewProp( N, BAD_CAST "target", BAD_CAST target);
+ xmlNode *Nsyn_props = xmlNewChild( N, NULL, BAD_CAST "synapse_props", NULL);
+ xmlNewProp( Nsyn_props, BAD_CAST "synapse_type", BAD_CAST synapse_type);
+ xmlNewProp( Nsyn_props, BAD_CAST "weight", BAD_CAST weight);
+ return PP[projection] = xmlNewChild( N, NULL, BAD_CAST "connections", NULL);
+ }
+ return found->second;
+ };
+ for ( const auto& U : units )
+ if ( U->is_neuron() ) {
+ const auto& N = reinterpret_cast<C_BaseNeuron*>(U);
+ xmlNode *instances_node =
+ get_or_create_population(
+ U->population(),
+ U->species());
+ xmlNode *instance_node = xmlNewChild( instances_node, NULL, BAD_CAST "instance", NULL);
+ xmlNewProp(instance_node, BAD_CAST "id", BAD_CAST U->id());
+ xmlNode *location_node = xmlNewChild( instance_node, NULL, BAD_CAST "location", NULL);
+ xmlNewProp(location_node, BAD_CAST "x", BAD_CAST sasprintf("%g", N->pos.x).c_str());
+ xmlNewProp(location_node, BAD_CAST "y", BAD_CAST sasprintf("%g", N->pos.y).c_str());
+ xmlNewProp(location_node, BAD_CAST "z", BAD_CAST sasprintf("%g", N->pos.z).c_str());
+ } else if ( U->is_synapse() ) {
+ const auto& Y = reinterpret_cast<C_BaseSynapse*>(U);
+ string src_pop, src_id,
+ tgt_pop, tgt_id;
+ C_BaseNeuron::extract_nml_parts(
+ Y->source()->label(),
+ &src_pop, &src_id);
+ for ( const auto T : Y->targets() ) {
+ C_BaseNeuron::extract_nml_parts(
+ T->label(),
+ &tgt_pop, &tgt_id);
+ xmlNode *projection_node =
+ get_or_create_projection(
+ (src_pop + "-" + tgt_pop).c_str(),
+ src_pop.c_str(), tgt_pop.c_str(),
+ Y->type_s(), "1.0");
+ xmlNode *connection_node = xmlNewChild( projection_node, NULL, BAD_CAST "connection", NULL);
+ xmlNewProp( connection_node, BAD_CAST "pre_cell_id", BAD_CAST src_id.c_str());
+ xmlNewProp( connection_node, BAD_CAST "post_cell_id", BAD_CAST tgt_id.c_str());
+ }
+ }
+ {
+ FILE* fout = fopen( fname.c_str(), "w");
+ if ( !fout )
+ return TNMLIOResult::nofile;
+ xmlDocFormatDump( fout, doc, 1);
+ fclose( fout);
+ }
+ xmlFreeDoc( doc);
+ xmlCleanupParser();
return retval;
}
diff --git a/upstream/src/libcnrun/model/struct.cc b/upstream/src/libcnrun/model/struct.cc
index 355e939..21bdace 100644
--- a/upstream/src/libcnrun/model/struct.cc
+++ b/upstream/src/libcnrun/model/struct.cc
@@ -35,7 +35,6 @@ CModel (const string& inname,
const SModelOptions& inoptions)
: name (inname),
options (inoptions),
- _global_unit_id_reservoir (0l),
V (1),
W (1),
_var_cnt (1), // reserve [0] for model_time
@@ -189,7 +188,6 @@ _include_base_unit( C_BaseUnit* u)
}
u->M = this;
- u->_serial_id = _global_unit_id_reservoir++;
}
@@ -443,71 +441,71 @@ unregister_unit_with_sources( C_BaseUnit *u)
cnrun::C_BaseNeuron*
cnrun::CModel::
-add_neuron_species( const string& type_s, const string& label,
+add_neuron_species( const char* type_s, const char* population, const char* id,
const TIncludeOption include_option,
const double x, const double y, const double z)
{
TUnitType t = unit_species_by_string( type_s);
if ( unlikely (t == NT_VOID || !unit_species_is_neuron(type_s)) ) {
- fprintf( stderr, "Unrecognised neuron species: \"%s\"\n", type_s.c_str());
+ fprintf( stderr, "Unrecognised neuron species: \"%s\"\n", type_s);
return nullptr;
} else
- return add_neuron_species( t, label, include_option, x, y, z);
+ return add_neuron_species( t, population, id, include_option, x, y, z);
}
cnrun::C_BaseNeuron*
cnrun::CModel::
-add_neuron_species( TUnitType type, const string& label,
+add_neuron_species( TUnitType type, const char* population, const char* id,
const TIncludeOption include_option,
double x, double y, double z)
{
C_BaseNeuron *n;
switch ( type ) {
case NT_HH_D:
- n = new CNeuronHH_d( label, x, y, z, this, CN_UOWNED, include_option);
+ n = new CNeuronHH_d( population, id, x, y, z, this, CN_UOWNED, include_option);
break;
case NT_HH_R:
- n = new CNeuronHH_r( label, x, y, z, this, CN_UOWNED);
+ n = new CNeuronHH_r( population, id, x, y, z, this, CN_UOWNED);
break;
case NT_HH2_D:
- n = new CNeuronHH2_d( label, x, y, z, this, CN_UOWNED, include_option);
+ n = new CNeuronHH2_d( population, id, x, y, z, this, CN_UOWNED, include_option);
break;
// case NT_HH2_R:
- // n = new CNeuronHH2_r( label, x, y, z, this, CN_UOWNED, include_option);
+ // n = new CNeuronHH2_r( population, id, x, y, z, this, CN_UOWNED, include_option);
// break;
//#ifdef CN_WANT_MORE_NEURONS
case NT_EC_D:
- n = new CNeuronEC_d( label, x, y, z, this, CN_UOWNED, include_option);
+ n = new CNeuronEC_d( population, id, x, y, z, this, CN_UOWNED, include_option);
break;
case NT_ECA_D:
- n = new CNeuronECA_d( label, x, y, z, this, CN_UOWNED, include_option);
+ n = new CNeuronECA_d( population, id, x, y, z, this, CN_UOWNED, include_option);
break;
/*
case NT_LV:
- n = new COscillatorLV( label, x, y, z, this, CN_UOWNED, include_option);
+ n = new COscillatorLV( population, id, x, y, z, this, CN_UOWNED, include_option);
break;
*/
case NT_COLPITTS:
- n = new COscillatorColpitts( label, x, y, z, this, CN_UOWNED, include_option);
+ n = new COscillatorColpitts( population, id, x, y, z, this, CN_UOWNED, include_option);
break;
case NT_VDPOL:
- n = new COscillatorVdPol( label, x, y, z, this, CN_UOWNED, include_option);
+ n = new COscillatorVdPol( population, id, x, y, z, this, CN_UOWNED, include_option);
break;
//#endif
case NT_DOTPOISSON:
- n = new COscillatorDotPoisson( label, x, y, z, this, CN_UOWNED);
+ n = new COscillatorDotPoisson( population, id, x, y, z, this, CN_UOWNED);
break;
case NT_POISSON:
- n = new COscillatorPoisson( label, x, y, z, this, CN_UOWNED);
+ n = new COscillatorPoisson( population, id, x, y, z, this, CN_UOWNED);
break;
case NT_DOTPULSE:
- n = new CNeuronDotPulse( label, x, y, z, this, CN_UOWNED);
+ n = new CNeuronDotPulse( population, id, x, y, z, this, CN_UOWNED);
break;
case NT_MAP:
- n = new CNeuronMap( label, x, y, z, this, CN_UOWNED);
+ n = new CNeuronMap( population, id, x, y, z, this, CN_UOWNED);
break;
default:
@@ -529,24 +527,25 @@ add_neuron_species( TUnitType type, const string& label,
cnrun::C_BaseSynapse*
cnrun::CModel::
-add_synapse_species( const string& type_s,
- const string& src_l, const string& tgt_l,
+add_synapse_species( const char *type_s,
+ const char *src_s, const char *tgt_s,
const double g,
const TSynapseCloningOption cloning_option,
const TIncludeOption include_option)
{
- TUnitType ytype = unit_species_by_string( type_s);
+ TUnitType
+ ytype = unit_species_by_string( type_s);
bool given_species = true;
if ( ytype == NT_VOID && (given_species = false, ytype = unit_family_by_string( type_s)) == NT_VOID ) {
- vp( 0, stderr, "Unrecognised synapse species or family: \"%s\"\n", type_s.c_str());
+ vp( 0, stderr, "Unrecognised synapse species or family: \"%s\"\n", type_s);
return nullptr;
}
C_BaseNeuron
- *src = neuron_by_label( src_l),
- *tgt = neuron_by_label( tgt_l);
+ *src = neuron_by_label( src_s),
+ *tgt = neuron_by_label( tgt_s);
if ( !src || !tgt ) {
- vp( 0, stderr, "Phony source (\"%s\") or target (\"%s\")\n", src_l.c_str(), tgt_l.c_str());
+ vp( 0, stderr, "Non-existent source (\"%s\") or target (\"%s\")\n", src_s, tgt_s);
return nullptr;
}
@@ -618,7 +617,7 @@ add_synapse_species( const string& type_s,
}
break;
default:
- vp( 0, stderr, "Bad synapse type: %s\n", type_s.c_str());
+ vp( 0, stderr, "Bad synapse type: %s\n", type_s);
return nullptr;
}
@@ -635,8 +634,8 @@ add_synapse_species( TUnitType ytype,
double g,
TSynapseCloningOption cloning_option, TIncludeOption include_option)
{
- vp( 5, "add_synapse_species( \"%s\", \"%s\", \"%s\", %g, %d, %d)\n",
- __CNUDT[ytype].species, src->_label, tgt->_label, g, (int)cloning_option, (int)include_option);
+ vp( 5, "add_synapse_species( type: \"%s\", src: \"%s\", tgt: \"%s\", g: %g)\n",
+ __CNUDT[ytype].species, src->_label, tgt->_label, g);
C_BaseSynapse *y = nullptr;
diff --git a/upstream/src/libcnrun/units/base-neuron.hh b/upstream/src/libcnrun/units/base-neuron.hh
index ad3f35e..332efbb 100644
--- a/upstream/src/libcnrun/units/base-neuron.hh
+++ b/upstream/src/libcnrun/units/base-neuron.hh
@@ -46,11 +46,11 @@ class C_BaseNeuron
friend class C_BaseSynapse;
protected:
- C_BaseNeuron (TUnitType intype, const string& inlabel,
- double inx, double iny, double inz,
- CModel* inM, int s_mask = 0)
- : C_BaseUnit (intype, inlabel, inM, s_mask),
- pos (inx, iny, inz),
+ C_BaseNeuron (TUnitType type_, const char* pop_, const char* id_,
+ double x_, double y_, double z_,
+ CModel* M_, int s_mask = 0)
+ : C_BaseUnit (type_, pop_, id_, M_, s_mask),
+ pos (x_, y_, z_),
_spikelogger_agent (nullptr)
{}
diff --git a/upstream/src/libcnrun/units/base-synapse.hh b/upstream/src/libcnrun/units/base-synapse.hh
index ebad567..d52536a 100644
--- a/upstream/src/libcnrun/units/base-synapse.hh
+++ b/upstream/src/libcnrun/units/base-synapse.hh
@@ -52,7 +52,8 @@ class C_BaseSynapse
return cnrun::alg::member(
const_cast<C_BaseNeuron*>(&tgt), _targets);
}
- C_BaseNeuron* source() { return _source; }
+ const C_BaseNeuron* source() const { return _source; }
+ const list<C_BaseNeuron*>& targets() { return _targets; }
double g_on_target( C_BaseNeuron&) const;
void set_g_on_target( C_BaseNeuron&, double);
diff --git a/upstream/src/libcnrun/units/base-unit.cc b/upstream/src/libcnrun/units/base-unit.cc
index 5d72777..521a0ee 100644
--- a/upstream/src/libcnrun/units/base-unit.cc
+++ b/upstream/src/libcnrun/units/base-unit.cc
@@ -34,29 +34,90 @@ using cnrun::alg::member;
unsigned short cnrun::global::precision = 4;
int cnrun::global::verbosely = 1;
+string
cnrun::C_BaseUnit::
-C_BaseUnit (TUnitType type_, const string& label_,
+make_nml_name( const char *population, const size_t id)
+{
+ return sasprintf("%s.%zu", population, id);
+}
+
+string
+cnrun::C_BaseUnit::
+make_nml_name( const char *population, const char *id)
+{
+ return sasprintf("%s.%s", population, id);
+}
+
+void
+cnrun::C_BaseUnit::
+extract_nml_parts( const char *label,
+ string* population, string* id)
+{
+ auto parts = cnrun::stilton::str::tokens(label, ".");
+ if ( population )
+ *population = *parts.begin();
+ if ( id )
+ *id = *next(parts.begin());
+}
+
+cnrun::C_BaseUnit::
+C_BaseUnit (TUnitType type_, const char* population_, const char* id_,
CModel* M_, int s_mask)
: precision (global::precision),
_type (type_), _status (0 |/* CN_UENABLED |*/ s_mask),
M (M_),
_binwrite_handle (-1), _listener_disk (nullptr), _listener_mem (nullptr)
{
- memset( _label, 0, max_label_size);
- if ( label_.size() )
- strncpy( _label, label_.c_str(), max_label_size);
- else
- snprintf( _label, max_label_size-1, "fafa%p", this);
-
- if ( M_ && M_->unit_by_label( label_) ) {
- fprintf( stderr, "Model %s already has a unit labelled \"%s\"\n", M_->name.c_str(), label_.c_str());
- throw "Duplicate unit label";
- }
-
+ set_population_id( population_, id_);
reset_params();
// don't have field idx to do reset_vars() safely
}
+void
+cnrun::C_BaseUnit::C_BaseUnit::
+set_population_id( const char* pop_, const char* id_)
+{
+ if ( !pop_ && !id_ )
+ return;
+
+ const char* id = id_ ? id_ : _id;
+ const char* pop = pop_ ? pop_ : _population;
+
+ if ( strlen(id) > max_id_size ) {
+ fprintf( stderr, "Unit id too long: \"%.*s\"", (int)max_id_size, id);
+ throw "Id too long";
+ }
+ if ( strlen(id) == 0 ) {
+ fprintf( stderr, "Empty unit id for unit in population \"%s\"", pop);
+ throw "Empty id";
+ }
+ if ( strlen(pop) == 0 ) {
+ fprintf( stderr, "Empty unit population (unit id \"%s\")", id);
+ throw "Empty population";
+ }
+ string prelabel = make_nml_name( pop, id);
+ if ( prelabel.size() > max_label_size ) {
+ fprintf( stderr, "Unit label too long: \"%.*s\"", (int)max_label_size, prelabel.c_str());
+ throw "Label too long";
+ }
+
+ if ( M && M->unit_by_label( prelabel) ) {
+ fprintf( stderr, "Model %s already has a unit labelled \"%s\"\n", M->name.c_str(), prelabel.c_str());
+ throw "Duplicate unit label";
+ }
+
+ memset( _label, 0, max_label_size);
+ memset( _population, 0, max_label_size);
+ memset( _id, 0, max_id_size);
+
+ strncpy( _label, prelabel.c_str(), max_label_size);
+ if ( pop == pop_ )
+ strncpy( _population, pop_, max_label_size);
+ if ( id == id_ )
+ strncpy( _id, id, max_id_size);
+
+ M -> update_longest_label( strlen(_label));
+}
void
@@ -244,7 +305,7 @@ void
cnrun::C_BaseUnit::
dump( bool with_params, FILE *strm) const
{
- fprintf( strm, "[%lu] (%s) \"%s\"\n", _serial_id, species(), _label);
+ fprintf( strm, "(%s) \"%s\"\n", species(), _label);
if ( with_params ) {
fprintf( strm, " Pp: ");
@@ -542,17 +603,17 @@ n_spikes_since( double since) const
// ----- CSynapse
cnrun::C_BaseSynapse::
-C_BaseSynapse( TUnitType intype,
- C_BaseNeuron *insource, C_BaseNeuron *intarget,
- double ing, CModel *inM, int s_mask)
- : C_BaseUnit (intype, "overwrite-me", inM, s_mask),
- _source (insource),
+C_BaseSynapse (const TUnitType type_,
+ C_BaseNeuron *source_, C_BaseNeuron *target_,
+ const double g_, CModel *M_, int s_mask)
+ : C_BaseUnit (type_, "overwrite me", "and me", M_, s_mask),
+ _source (source_),
t_last_release_started (-INFINITY)
{
if ( M )
M->vp( 5, "Creating a \"%s\" base synapse\n", species());
- _targets.push_back( intarget);
- intarget->_dendrites[this] = ing;
+ _targets.push_back( target_);
+ target_->_dendrites[this] = g_;
_source->_axonal_harbour.push_back( this);
snprintf( _label, max_label_size-1, "%s:1", _source->_label);
}
@@ -658,6 +719,7 @@ cnrun::C_BaseSynapse::
}
}
+
// Local Variables:
// Mode: c++
// indent-tabs-mode: nil
diff --git a/upstream/src/libcnrun/units/base-unit.hh b/upstream/src/libcnrun/units/base-unit.hh
index 569ce39..6b76013 100644
--- a/upstream/src/libcnrun/units/base-unit.hh
+++ b/upstream/src/libcnrun/units/base-unit.hh
@@ -63,16 +63,21 @@ extern int verbosely;
// * listening, i.e., keeping a history of vars along a timeline;
class C_BaseUnit {
- DELETE_DEFAULT_METHODS (C_BaseUnit)
-
- friend class CModel;
- friend class SSpikeloggerService;
-
public:
static const constexpr size_t max_label_size = 40;
+ static const constexpr size_t max_id_size = 10;
+
+ static string make_nml_name( const char* population, const size_t id);
+ static string make_nml_name( const char* population, const char *id);
+ static void extract_nml_parts( const char* label, string* population_p, string* id_p);
protected:
- C_BaseUnit (TUnitType, const string& label,
+ DELETE_DEFAULT_METHODS (C_BaseUnit);
+
+ friend class CModel;
+ friend class SSpikeloggerService;
+
+ C_BaseUnit (TUnitType, const char* pop, const char *id,
CModel*, int s_mask);
public:
virtual ~C_BaseUnit(); // surely virtual
@@ -85,6 +90,7 @@ class C_BaseUnit {
// classification
int traits() const { return __CNUDT[_type].traits; }
+ const char* type_s() const { return __CNUDT[_type].species; }
bool is_hostable() const { return __CNUDT[_type].traits & UT_HOSTED; }
bool is_ddtbound() const { return __CNUDT[_type].traits & UT_DDTSET; }
bool is_neuron() const { return _type >= NT_FIRST && _type <= NT_LAST; }
@@ -92,20 +98,21 @@ class C_BaseUnit {
bool is_oscillator() const { return __CNUDT[_type].traits & UT_OSCILLATOR; }
bool is_conscious() const { return is_oscillator(); }
- unsigned long serial() const
- { return _serial_id; }
- const char *label() const // for synapses, it is "%s:%d", src->label, targets.size()
+ const char* label() const // for synapses, it is "%s:%d", src->label, targets.size()
{ return _label; }
- void set_label( const string& new_label)
- { strncpy( _label, new_label.c_str(), max_label_size-1); }
+ const char* population() const
+ { return _population; }
+ const char* id() const
+ { return _id; }
+ void set_population_id( const char*, const char*);
- const char *class_name() const
+ const char* class_name() const
{ return is_neuron() ? "Neuron" : "Synapse"; }
- const char *species() const
+ const char* species() const
{ return __CNUDT[_type].species; }
- const char *family() const
+ const char* family() const
{ return __CNUDT[_type].family; }
- const char *type_description() const
+ const char* type_description() const
{ return __CNUDT[_type].description; }
// parent model
@@ -117,8 +124,8 @@ class C_BaseUnit {
bool is_owned() const { return _status & CN_UOWNED; }
// parameter & variable names and symbols
- const char *const param_name( size_t i) const { return __CNUDT[_type].stock_param_names[i]; }
- const char *const param_sym( size_t i) const { return __CNUDT[_type].stock_param_syms[i]; }
+ const char* const param_name( size_t i) const { return __CNUDT[_type].stock_param_names[i]; }
+ const char* const param_sym( size_t i) const { return __CNUDT[_type].stock_param_syms[i]; }
int param_idx_by_sym( const string&) const __attribute__ ((pure));
const char *const var_name( size_t i) const { return __CNUDT[_type].stock_var_names[i]; }
@@ -262,9 +269,9 @@ class C_BaseUnit {
_type; // will look up p, pno and vno from __CNUDT using _type as index
int _status;
- unsigned long
- _serial_id; // assigned incrementally as read by import_NetworkML
- char _label[max_label_size];
+ char _label [max_label_size],
+ _population[max_label_size],
+ _id [max_id_size];
CModel *M;
diff --git a/upstream/src/libcnrun/units/hosted-neurons.cc b/upstream/src/libcnrun/units/hosted-neurons.cc
index d9a6125..9e9fadb 100644
--- a/upstream/src/libcnrun/units/hosted-neurons.cc
+++ b/upstream/src/libcnrun/units/hosted-neurons.cc
@@ -25,11 +25,11 @@
cnrun::C_HostedNeuron::
-C_HostedNeuron (TUnitType intype, const string& inlabel,
- double inx, double iny, double inz,
- CModel* inM, int s_mask,
+C_HostedNeuron (const TUnitType type_, const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel* M_, int s_mask,
TIncludeOption include_option)
- : C_BaseNeuron (intype, inlabel, inx, iny, inz, inM, s_mask)
+ : C_BaseNeuron (type_, pop_, id_, x_, y_, z_, M_, s_mask)
{
if ( M )
M->include_unit( this, include_option);
diff --git a/upstream/src/libcnrun/units/hosted-neurons.hh b/upstream/src/libcnrun/units/hosted-neurons.hh
index cf86043..7bd11b4 100644
--- a/upstream/src/libcnrun/units/hosted-neurons.hh
+++ b/upstream/src/libcnrun/units/hosted-neurons.hh
@@ -34,10 +34,10 @@ class C_HostedNeuron
DELETE_DEFAULT_METHODS (C_HostedNeuron)
protected:
- C_HostedNeuron (TUnitType intype, const string& inlabel,
- double x, double y, double z,
+ C_HostedNeuron (TUnitType type_, const char* pop_, const char* id_,
+ double, double, double,
CModel*, int s_mask,
- TIncludeOption include_option);
+ TIncludeOption);
public:
void reset_vars();
double &var_value( size_t);
@@ -54,11 +54,11 @@ class C_HostedConductanceBasedNeuron
DELETE_DEFAULT_METHODS (C_HostedConductanceBasedNeuron)
protected:
- C_HostedConductanceBasedNeuron (TUnitType intype, const string& inlabel,
- double inx, double iny, double inz,
- CModel* inM, int s_mask,
+ C_HostedConductanceBasedNeuron (TUnitType type_, const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel* M_, int s_mask,
TIncludeOption include_option)
- : C_HostedNeuron (intype, inlabel, inx, iny, inz, inM, s_mask, include_option)
+ : C_HostedNeuron (type_, pop_, id_, x_, y_, z_, M_, s_mask, include_option)
{}
public:
@@ -82,11 +82,11 @@ class C_HostedRateBasedNeuron
DELETE_DEFAULT_METHODS (C_HostedRateBasedNeuron)
protected:
- C_HostedRateBasedNeuron (TUnitType intype, const string& inlabel,
- double inx, double iny, double inz,
- CModel* inM, int s_mask,
+ C_HostedRateBasedNeuron (TUnitType type_, const char *pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel* M_, int s_mask,
TIncludeOption include_option)
- : C_HostedNeuron (intype, inlabel, inx, iny, inz, inM, s_mask, include_option)
+ : C_HostedNeuron (type_, pop_, id_, x_, y_, z_, M_, s_mask, include_option)
{}
public:
@@ -110,20 +110,20 @@ class CNeuronHH_d
DELETE_DEFAULT_METHODS (CNeuronHH_d)
public:
- CNeuronHH_d (const string& inlabel,
- double x, double y, double z,
- CModel *inM, int s_mask = 0,
+ CNeuronHH_d (const char *pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask = 0,
TIncludeOption include_option = TIncludeOption::is_last)
- : C_HostedConductanceBasedNeuron (NT_HH_D, inlabel, x, y, z,
- inM, s_mask, include_option)
+ : C_HostedConductanceBasedNeuron (NT_HH_D, pop_, id_, x_, y_, z_,
+ M_, s_mask, include_option)
{}
// parameters (since gcc 4.4, accessible from within member functions defined outside class definition, gee!)
enum {
gNa, ENa, gK, EK, gl, El, Cmem,
- alpha_m_a, alpha_m_b, alpha_m_c, beta_m_a, beta_m_b, beta_m_c,
- alpha_h_a, alpha_h_b, alpha_h_c, beta_h_a, beta_h_b, beta_h_c,
- alpha_n_a, alpha_n_b, alpha_n_c, beta_n_a, beta_n_b, beta_n_c,
+ alpha_m_a, alpha_m_b, alpha_m_c, beta_m_a, beta_m_b, beta_m_c,
+ alpha_h_a, alpha_h_b, alpha_h_c, beta_h_a, beta_h_b, beta_h_c,
+ alpha_n_a, alpha_n_b, alpha_n_c, beta_n_a, beta_n_b, beta_n_c,
Idc,
};
@@ -152,12 +152,12 @@ class CNeuronHH2_d
DELETE_DEFAULT_METHODS (CNeuronHH2_d)
public:
- CNeuronHH2_d (const string& inlabel,
- double x, double y, double z,
- CModel *inM, int s_mask = 0,
+ CNeuronHH2_d (const char *pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask = 0,
TIncludeOption include_option = TIncludeOption::is_last)
- : C_HostedConductanceBasedNeuron( NT_HH2_D, inlabel, x, y, z,
- inM, s_mask, include_option)
+ : C_HostedConductanceBasedNeuron( NT_HH2_D, pop_, id_, x_, y_, z_,
+ M_, s_mask, include_option)
{}
double m( vector<double>& b) const { return b[idx+1]; }
@@ -182,11 +182,11 @@ class CNeuronEC_d
DELETE_DEFAULT_METHODS (CNeuronEC_d)
public:
- CNeuronEC_d( const string& inlabel,
- double x, double y, double z,
+ CNeuronEC_d( const char *pop_, const char* id_,
+ const double x, const double y, const double z,
CModel *inM, int s_mask = 0,
TIncludeOption include_option = TIncludeOption::is_last)
- : C_HostedConductanceBasedNeuron (NT_EC_D, inlabel, x, y, z,
+ : C_HostedConductanceBasedNeuron (NT_EC_D, pop_, id_, x, y, z,
inM, s_mask, include_option)
{}
@@ -216,12 +216,12 @@ class CNeuronECA_d
DELETE_DEFAULT_METHODS (CNeuronECA_d)
public:
- CNeuronECA_d( const string& inlabel,
- double x, double y, double z,
- CModel *inM, int s_mask = 0,
+ CNeuronECA_d( const char *pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask = 0,
TIncludeOption include_option = TIncludeOption::is_last)
- : C_HostedConductanceBasedNeuron( NT_ECA_D, inlabel, x, y, z,
- inM, s_mask, include_option)
+ : C_HostedConductanceBasedNeuron( NT_ECA_D, pop_, id_, x_, y_, z_,
+ M_, s_mask, include_option)
{}
double m( vector<double>& b) const { return b[idx+1]; }
@@ -258,12 +258,12 @@ class COscillatorColpitts
DELETE_DEFAULT_METHODS (COscillatorColpitts)
public:
- COscillatorColpitts( const string& inlabel,
- double x, double y, double z,
- CModel *inM, int s_mask = 0,
+ COscillatorColpitts( const char *pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask = 0,
TIncludeOption include_option = TIncludeOption::is_last)
- : C_HostedConductanceBasedNeuron (NT_COLPITTS, inlabel, x, y, z,
- inM, s_mask, include_option)
+ : C_HostedConductanceBasedNeuron (NT_COLPITTS, pop_, id_, x_, y_, z_,
+ M_, s_mask, include_option)
{}
double x0( vector<double>& b) const { return b[idx+0]; } // there's no E() for this one
@@ -321,12 +321,12 @@ class COscillatorVdPol
DELETE_DEFAULT_METHODS (COscillatorVdPol)
public:
- COscillatorVdPol (const string& inlabel,
- double x, double y, double z,
- CModel *inM, int s_mask = 0,
+ COscillatorVdPol (const char *pop_, const char* id_,
+ double x_, double y_, double z_,
+ CModel *M_, int s_mask = 0,
TIncludeOption include_option = TIncludeOption::is_last)
- : C_HostedConductanceBasedNeuron (NT_VDPOL, inlabel, x, y, z,
- inM, s_mask, include_option)
+ : C_HostedConductanceBasedNeuron (NT_VDPOL, pop_, id_, x_, y_, z_,
+ M_, s_mask, include_option)
{}
double amp( vector<double>& b) const { return b[idx+0]; }
diff --git a/upstream/src/libcnrun/units/standalone-neurons.cc b/upstream/src/libcnrun/units/standalone-neurons.cc
index 37f36fc..e92f14a 100644
--- a/upstream/src/libcnrun/units/standalone-neurons.cc
+++ b/upstream/src/libcnrun/units/standalone-neurons.cc
@@ -24,10 +24,10 @@
cnrun::C_StandaloneNeuron::
-C_StandaloneNeuron (TUnitType type_, const string& label_,
- double x, double y, double z,
- CModel *M_, int s_mask)
- : C_BaseNeuron( type_, label_, x, y, z, M_, s_mask),
+C_StandaloneNeuron (const TUnitType type_, const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, const int s_mask)
+ : C_BaseNeuron( type_, pop_, id_, x_, y_, z_, M_, s_mask),
C_StandaloneAttributes( __CNUDT[type_].vno)
{
reset_vars();
@@ -334,14 +334,16 @@ const char* const cnrun::CN_VarSyms_NeuronMap[] = {
cnrun::CNeuronMap::
-CNeuronMap (const string& inlabel, double x, double y, double z, CModel *inM, int s_mask)
- : C_StandaloneConductanceBasedNeuron( NT_MAP, inlabel, x, y, z, inM, s_mask)
+CNeuronMap (const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask)
+ : C_StandaloneConductanceBasedNeuron( NT_MAP, pop_, id_, x_, y_, z_, M_, s_mask)
{
- if ( inM ) {
- if ( isfinite( inM->_discrete_dt) && inM->_discrete_dt != fixed_dt )
+ if ( M_ ) {
+ if ( isfinite( M_->_discrete_dt) && M_->_discrete_dt != fixed_dt )
throw "Inappropriate discrete dt";
- inM -> _discrete_dt = fixed_dt;
+ M_ -> _discrete_dt = fixed_dt;
}
}
diff --git a/upstream/src/libcnrun/units/standalone-neurons.hh b/upstream/src/libcnrun/units/standalone-neurons.hh
index 7189059..a298f05 100644
--- a/upstream/src/libcnrun/units/standalone-neurons.hh
+++ b/upstream/src/libcnrun/units/standalone-neurons.hh
@@ -33,7 +33,7 @@ class C_StandaloneNeuron
DELETE_DEFAULT_METHODS (C_StandaloneNeuron)
protected:
- C_StandaloneNeuron (TUnitType intype, const string& inlabel,
+ C_StandaloneNeuron (TUnitType, const char* pop, const char* id,
double x, double y, double z,
CModel*, int s_mask);
@@ -57,10 +57,10 @@ class C_StandaloneConductanceBasedNeuron
DELETE_DEFAULT_METHODS (C_StandaloneConductanceBasedNeuron)
protected:
- C_StandaloneConductanceBasedNeuron (TUnitType intype, const string& inlabel,
- double inx, double iny, double inz,
- CModel *inM, int s_mask)
- : C_StandaloneNeuron (intype, inlabel, inx, iny, inz, inM, s_mask)
+ C_StandaloneConductanceBasedNeuron (const TUnitType type_, const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask)
+ : C_StandaloneNeuron (type_, pop_, id_, x_, y_, z_, M_, s_mask)
{}
public:
@@ -77,10 +77,10 @@ class C_StandaloneRateBasedNeuron
DELETE_DEFAULT_METHODS (C_StandaloneRateBasedNeuron)
protected:
- C_StandaloneRateBasedNeuron (TUnitType intype, const string& inlabel,
- double inx, double iny, double inz,
- CModel *inM, int s_mask)
- : C_StandaloneNeuron (intype, inlabel, inx, iny, inz, inM, s_mask)
+ C_StandaloneRateBasedNeuron (const TUnitType type_, const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask)
+ : C_StandaloneNeuron (type_, pop_, id_, x_, y_, z_, M_, s_mask)
{}
public:
@@ -100,10 +100,10 @@ class CNeuronHH_r
DELETE_DEFAULT_METHODS (CNeuronHH_r)
public:
- CNeuronHH_r( const string& inlabel,
- double x, double y, double z,
- CModel *inM, int s_mask = 0)
- : C_StandaloneRateBasedNeuron( NT_HH_R, inlabel, x, y, z, inM, s_mask)
+ CNeuronHH_r( const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask = 0)
+ : C_StandaloneRateBasedNeuron( NT_HH_R, pop_, id_, x_, y_, z_, M_, s_mask)
{}
enum {
@@ -128,10 +128,10 @@ class COscillatorPoisson
DELETE_DEFAULT_METHODS (COscillatorPoisson)
public:
- COscillatorPoisson( const string& inlabel,
- double x, double y, double z,
- CModel *inM, int s_mask = 0)
- : C_StandaloneConductanceBasedNeuron (NT_POISSON, inlabel, x, y, z, inM, s_mask)
+ COscillatorPoisson( const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask = 0)
+ : C_StandaloneConductanceBasedNeuron (NT_POISSON, pop_, id_, x_, y_, z_, M_, s_mask)
{
// need _spikelogger_agent's fields even when no spikelogging is done
_spikelogger_agent = new SSpikeloggerService(
@@ -163,10 +163,10 @@ class COscillatorDotPoisson
DELETE_DEFAULT_METHODS (COscillatorDotPoisson)
public:
- COscillatorDotPoisson (const string& inlabel,
- double x, double y, double z,
- CModel *inM, int s_mask = 0)
- : C_StandaloneConductanceBasedNeuron( NT_DOTPOISSON, inlabel, x, y, z, inM, s_mask)
+ COscillatorDotPoisson (const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask = 0)
+ : C_StandaloneConductanceBasedNeuron( NT_DOTPOISSON, pop_, id_, x_, y_, z_, M_, s_mask)
{
// need _spikelogger_agent's fields even when no spikelogging is done
_spikelogger_agent = new SSpikeloggerService(
@@ -197,10 +197,10 @@ class CNeuronDotPulse
DELETE_DEFAULT_METHODS (CNeuronDotPulse)
public:
- CNeuronDotPulse (const string& inlabel,
- double x, double y, double z,
- CModel *inM, int s_mask = 0)
- : C_StandaloneConductanceBasedNeuron (NT_DOTPULSE, inlabel, x, y, z, inM, s_mask)
+ CNeuronDotPulse (const char* pop_, const char* id_,
+ const double x_, const double y_, const double z_,
+ CModel *M_, int s_mask = 0)
+ : C_StandaloneConductanceBasedNeuron (NT_DOTPULSE, pop_, id_, x_, y_, z_, M_, s_mask)
{}
enum { _f_, _Vrst_, _Vfir_ };
@@ -229,7 +229,8 @@ class CNeuronMap
public:
static const constexpr double fixed_dt = 0.1;
- CNeuronMap (const string& inlabel, double x, double y, double z,
+ CNeuronMap (const char* pop_, const char* id_,
+ double x_, double y_, double z_,
CModel*, int s_mask = 0);
enum {
diff --git a/upstream/src/lua-cnrun/commands.cc b/upstream/src/lua-cnrun/commands.cc
index 3ffee50..c91386e 100644
--- a/upstream/src/lua-cnrun/commands.cc
+++ b/upstream/src/lua-cnrun/commands.cc
@@ -442,8 +442,10 @@ int new_neuron( lua_State *L)
*type = lua_tostring( L, 3),
*label = lua_tostring( L, 4);
+ string population, id;
+ C_BaseUnit::extract_nml_parts( label, &population, &id);
if ( !M.add_neuron_species(
- type, label,
+ type, population.c_str(), id.c_str(),
TIncludeOption::is_last) )
return make_error(
L, "%s(%s): error", __FUNCTION__, model_name);
diff --git a/upstream/src/tools/hh-latency-estimator.cc b/upstream/src/tools/hh-latency-estimator.cc
index ee63d50..4fad6ac 100644
--- a/upstream/src/tools/hh-latency-estimator.cc
+++ b/upstream/src/tools/hh-latency-estimator.cc
@@ -116,10 +116,10 @@ main( int argc, char *argv[])
Model->options.verbosely = 0;
// add our three units
- CNeuronHH_d *hh = new CNeuronHH_d( "HH", 0.2, 0.1, 0.3, Model, CN_UOWNED);
+ CNeuronHH_d *hh = new CNeuronHH_d( "HH", "0", 0.2, 0.1, 0.3, Model, CN_UOWNED);
C_BaseNeuron *pulse = (Options.src_type == S_PULSE)
- ? static_cast<C_BaseNeuron*>(new CNeuronDotPulse( "Pulse", 0.1, 0.2, 0.3, Model, CN_UOWNED))
- : static_cast<C_BaseNeuron*>(new COscillatorDotPoisson( "Pulse", 0.1, 0.2, 0.3, Model, CN_UOWNED));
+ ? static_cast<C_BaseNeuron*>(new CNeuronDotPulse( "Pulse", "0", 0.1, 0.2, 0.3, Model, CN_UOWNED))
+ : static_cast<C_BaseNeuron*>(new COscillatorDotPoisson( "Pulse", "1", 0.1, 0.2, 0.3, Model, CN_UOWNED));
CSynapseMxAB_dd *synapse = new CSynapseMxAB_dd( pulse, hh, Options.syn_g, Model, CN_UOWNED);
// enable_spikelogging_service
@@ -166,13 +166,11 @@ main( int argc, char *argv[])
for ( i = 0; i < n_steps; i++ ) {
if ( Options.enable_listening ) {
- char label[C_BaseUnit::max_label_size];
- snprintf( label, C_BaseUnit::max_label_size, "pulse-%06g", frequencies[i]);
- pulse->set_label( label);
- snprintf( label, C_BaseUnit::max_label_size, "hh-%06g", frequencies[i]);
- hh->set_label( label);
- snprintf( label, C_BaseUnit::max_label_size, "synapse-%06g", frequencies[i]);
- synapse->set_label( label);
+ auto set_pop = [&frequencies,&i](C_BaseUnit* U, const char* u_s)
+ { U->set_population_id( sasprintf( "%s-%06g", u_s, frequencies[i]).c_str(), nullptr); };
+ set_pop(hh, "hh");
+ set_pop(pulse, "pulse");
+ set_pop(synapse, "synapse");
}
Model->reset(); // will reset model_time, preserve params, and is a generally good thing
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/cnrun.git
More information about the debian-med-commit
mailing list