Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit 9dfaabb

Browse files
sergiorg-hpcpramodkalexsavulescu
authored
Adds support for Section target reports (#419)
* Adds support for Axon, Dendrite, and Apical sections in reports * Prevents to generate an empty list when the section is empty * Adds support for Section in a Compartment * Introduces suggestions by code review in PR * Updates description of the enum Co-authored-by: Pramod Kumbhar <[email protected]> * Adds an error when the Section type is unknown Co-authored-by: Alexandru Săvulescu <[email protected]> * Adds ref to the section_type_str Co-authored-by: Alexandru Săvulescu <[email protected]> * Adds an error when the target type is unknown * Switches abort() for nrn_abort() in the configuration parser Co-authored-by: Alexandru Săvulescu <[email protected]> * Switched assert() to nrn_assert() Co-authored-by: Alexandru Săvulescu <[email protected]> * Extends the previous commit NEURON_BRANCH=master Co-authored-by: Pramod Kumbhar <[email protected]> Co-authored-by: Pramod Kumbhar <[email protected]> Co-authored-by: Alexandru Săvulescu <[email protected]> Co-authored-by: Alexandru Săvulescu <[email protected]>
1 parent daabf11 commit 9dfaabb

File tree

4 files changed

+157
-13
lines changed

4 files changed

+157
-13
lines changed

coreneuron/io/reports/nrnreport.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ namespace coreneuron {
5151
/// name of the variable in mod file used for setting synapse id
5252
#define SYNAPSE_ID_MOD_NAME "synapseID"
5353

54-
enum ReportType { SomaReport, CompartmentReport, SynapseReport, IMembraneReport };
54+
// enumerate that defines the type of target report requested
55+
enum ReportType { SomaReport, CompartmentReport, SynapseReport,
56+
IMembraneReport, SectionReport };
57+
58+
// enumerate that defines the section type for a Section report
59+
enum SectionType { Axon, Dendrite, Apical };
5560

5661
struct ReportConfiguration {
5762
char name[REPORT_MAX_NAME_LEN]; // name of the report
@@ -64,6 +69,8 @@ struct ReportConfiguration {
6469
char type_str[REPORT_MAX_NAME_LEN]; // type of report string
6570
char population_name[REPORT_MAX_NAME_LEN]; // population name of the report
6671
ReportType type; // type of the report
72+
SectionType section_type; // type of section report
73+
bool section_all_compartments; // flag for section report (all values)
6774
int mech_id; // mechanism
6875
double report_dt; // reporting timestep
6976
double start; // start time of report

coreneuron/io/reports/report_configuration_parser.cpp

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,37 @@
3939

4040
namespace coreneuron {
4141

42+
/*
43+
* Defines the type of target, as per the following syntax:
44+
* 0=Compartment, 1=Cell/Soma, Section { 2=Axon, 3=Dendrite, 4=Apical }
45+
* The "Comp" variations are compartment-based (all segments, not middle only)
46+
*/
47+
enum class TargetType
48+
{
49+
Compartment = 0,
50+
Soma = 1,
51+
Axon = 2,
52+
Dendrite = 3,
53+
Apical = 4,
54+
AxonComp = 5,
55+
DendriteComp = 6,
56+
ApicalComp = 7,
57+
};
58+
4259
/*
4360
* Split filter string ("mech.var_name") into mech_id and var_name
4461
*/
4562
void parse_filter_string(char* filter, ReportConfiguration& config) {
4663
char* token = strtok(filter, ".");
4764
if (!token) {
4865
std::cerr << "Error : Invalid report variable, should be mch_name.var_name" << std::endl;
49-
abort();
66+
nrn_abort(1);
5067
}
5168
strcpy(config.mech_name, token);
5269
token = strtok(nullptr, "\n");
5370
if (!token) {
5471
std::cerr << "Error : Invalid report variable, should be mch_name.var_name" << std::endl;
55-
abort();
72+
nrn_abort(1);
5673
}
5774
strcpy(config.var_name, token);
5875
}
@@ -65,14 +82,14 @@ std::vector<ReportConfiguration> create_report_configurations(const char* conf_f
6582
char report_on[REPORT_MAX_NAME_LEN] = "";
6683
char raw_line[REPORT_MAX_FILEPATH_LEN] = "";
6784
char spikes_population[REPORT_MAX_NAME_LEN] = "";
68-
int is_soma;
85+
TargetType target_type;
6986
int* gids;
7087

7188
FILE* fp = fopen(conf_file, "r");
7289
if (!fp) {
7390
std::cerr << "Cannot open configuration file: " << conf_file << ", aborting execution"
7491
<< std::endl;
75-
abort();
92+
nrn_abort(1);
7693
}
7794

7895
fgets(raw_line, REPORT_MAX_FILEPATH_LEN, fp);
@@ -85,7 +102,7 @@ std::vector<ReportConfiguration> create_report_configurations(const char* conf_f
85102
report.buffer_size = 4; // default size to 4 Mb
86103
fgets(raw_line, REPORT_MAX_FILEPATH_LEN, fp);
87104
sscanf(raw_line, "\n%s %s %s %s %s %s %d %lf %lf %lf %d %d %s\n", report.name,
88-
report.target_name, report.type_str, report_on, report.unit, report.format, &is_soma,
105+
report.target_name, report.type_str, report_on, report.unit, report.format, &target_type,
89106
&report.report_dt, &report.start, &report.stop, &report.num_gids,
90107
&report.buffer_size, report.population_name);
91108
for (int i = 0; i < REPORT_MAX_NAME_LEN; i++) {
@@ -96,15 +113,54 @@ std::vector<ReportConfiguration> create_report_configurations(const char* conf_f
96113
if (strcmp(report_on, "i_membrane") == 0) {
97114
nrn_use_fast_imem = true;
98115
report.type = IMembraneReport;
99-
} else if (is_soma)
100-
report.type = SomaReport;
101-
else
102-
report.type = CompartmentReport;
116+
} else {
117+
switch (target_type) {
118+
case TargetType::Soma:
119+
report.type = SomaReport;
120+
break;
121+
case TargetType::Compartment:
122+
report.type = CompartmentReport;
123+
break;
124+
case TargetType::Axon:
125+
report.type = SectionReport;
126+
report.section_type = Axon;
127+
report.section_all_compartments = false;
128+
break;
129+
case TargetType::AxonComp:
130+
report.type = SectionReport;
131+
report.section_type = Axon;
132+
report.section_all_compartments = true;
133+
break;
134+
case TargetType::Dendrite:
135+
report.type = SectionReport;
136+
report.section_type = Dendrite;
137+
report.section_all_compartments = false;
138+
break;
139+
case TargetType::DendriteComp:
140+
report.type = SectionReport;
141+
report.section_type = Dendrite;
142+
report.section_all_compartments = true;
143+
break;
144+
case TargetType::Apical:
145+
report.type = SectionReport;
146+
report.section_type = Apical;
147+
report.section_all_compartments = false;
148+
break;
149+
case TargetType::ApicalComp:
150+
report.type = SectionReport;
151+
report.section_type = Apical;
152+
report.section_all_compartments = true;
153+
break;
154+
default:
155+
std::cerr << "Report error: unsupported target type" << std::endl;
156+
nrn_abort(1);
157+
}
158+
}
103159
} else if (strcmp(report.type_str, "synapse") == 0) {
104160
report.type = SynapseReport;
105161
} else {
106-
std::cerr << "Report error: unsupported type " << report.type_str << "\n";
107-
abort();
162+
std::cerr << "Report error: unsupported type " << report.type_str << std::endl;
163+
nrn_abort(1);
108164
}
109165

110166
if (report.type == SynapseReport)

coreneuron/io/reports/report_handler.cpp

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ void ReportHandler::create_report(double dt, double tstop, double delay) {
3939
nt.nrn_fast_imem->nrn_sav_rhs);
4040
register_compartment_report(nt, m_report_config, vars_to_report);
4141
break;
42+
case SectionReport:
43+
vars_to_report = get_section_vars_to_report(nt, m_report_config.target, nt._actual_v,
44+
m_report_config.section_type,
45+
m_report_config.section_all_compartments);
46+
register_compartment_report(nt, m_report_config, vars_to_report);
47+
break;
4248
default:
4349
vars_to_report = get_custom_vars_to_report(nt, m_report_config, nodes_to_gid);
4450
register_custom_report(nt, m_report_config, vars_to_report);
@@ -155,6 +161,76 @@ VarsToReport ReportHandler::get_compartment_vars_to_report(const NrnThread& nt,
155161
return vars_to_report;
156162
}
157163

164+
std::string getSectionTypeStr(SectionType type) {
165+
switch (type) {
166+
case Axon:
167+
return "axon";
168+
case Dendrite:
169+
return "dend";
170+
case Apical:
171+
return "apic";
172+
default:
173+
std::cerr << "SectionType not handled in getSectionTypeStr" << std::endl;
174+
nrn_abort(1);
175+
}
176+
}
177+
178+
VarsToReport ReportHandler::get_section_vars_to_report(const NrnThread& nt,
179+
const std::set<int>& target,
180+
double* report_variable,
181+
SectionType section_type,
182+
bool all_compartments) const {
183+
VarsToReport vars_to_report;
184+
const auto& section_type_str = getSectionTypeStr(section_type);
185+
const auto* mapinfo = static_cast<NrnThreadMappingInfo*>(nt.mapping);
186+
if (!mapinfo) {
187+
std::cerr << "[COMPARTMENTS] Error : mapping information is missing for a Cell group "
188+
<< nt.ncell << '\n';
189+
nrn_abort(1);
190+
}
191+
192+
for (int i = 0; i < nt.ncell; i++) {
193+
int gid = nt.presyns[i].gid_;
194+
if (target.find(gid) != target.end()) {
195+
CellMapping* cell_mapping = mapinfo->get_cell_mapping(gid);
196+
if (cell_mapping == nullptr) {
197+
std::cerr
198+
<< "[COMPARTMENTS] Error : Compartment mapping information is missing for gid "
199+
<< gid << '\n';
200+
nrn_abort(1);
201+
}
202+
std::vector<VarWithMapping> to_report;
203+
to_report.reserve(cell_mapping->size());
204+
205+
/** get section list mapping for the type, if available */
206+
if (cell_mapping->get_seclist_section_count(section_type_str) > 0) {
207+
SecMapping* s = cell_mapping->get_seclist_mapping(section_type_str);
208+
for (const auto& sm : s->secmap) {
209+
int compartment_id = sm.first;
210+
const auto& vec = sm.second;
211+
212+
/** get all compartment values (otherwise, just middle point) */
213+
if (all_compartments) {
214+
for (const auto& idx : vec) {
215+
/** corresponding voltage in coreneuron voltage array */
216+
double* variable = report_variable + idx;
217+
to_report.push_back(VarWithMapping(compartment_id, variable));
218+
}
219+
} else {
220+
nrn_assert(vec.size() % 2);
221+
/** corresponding voltage in coreneuron voltage array */
222+
const auto idx = vec[vec.size() / 2];
223+
double* variable = report_variable + idx;
224+
to_report.push_back(VarWithMapping(compartment_id, variable));
225+
}
226+
}
227+
vars_to_report[gid] = to_report;
228+
}
229+
}
230+
}
231+
return vars_to_report;
232+
}
233+
158234
VarsToReport ReportHandler::get_custom_vars_to_report(const NrnThread& nt,
159235
ReportConfiguration& report,
160236
const std::vector<int>& nodes_to_gids) const {
@@ -188,7 +264,7 @@ VarsToReport ReportHandler::get_custom_vars_to_report(const NrnThread& nt,
188264
get_var_location_from_var_name(report.mech_id, report.var_name, ml, j);
189265
const auto synapse_id = static_cast<int>(
190266
*get_var_location_from_var_name(report.mech_id, SYNAPSE_ID_MOD_NAME, ml, j));
191-
assert(synapse_id && var_value);
267+
nrn_assert(synapse_id && var_value);
192268
to_report.emplace_back(synapse_id, var_value);
193269
}
194270
}

coreneuron/io/reports/report_handler.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ class ReportHandler {
3232
VarsToReport get_compartment_vars_to_report(const NrnThread& nt,
3333
const std::set<int>& target,
3434
double* report_variable) const;
35+
VarsToReport get_section_vars_to_report(const NrnThread& nt,
36+
const std::set<int>& target,
37+
double* report_variable,
38+
SectionType section_type,
39+
bool all_compartments) const;
3540
VarsToReport get_custom_vars_to_report(const NrnThread& nt,
3641
ReportConfiguration& report,
3742
const std::vector<int>& nodes_to_gids) const;

0 commit comments

Comments
 (0)