Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 93 additions & 87 deletions src/coreneuron/io/reports/nrnreport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,44 @@ struct SummationReport {
std::unordered_map<int, std::vector<size_t>> gid_segments_;
};

/// @brief Print to ostream the SummationReport
inline std::ostream& operator<<(std::ostream& os, const SummationReport& report) {
os << "SummationReport:\n";

os << "summation_ (" << report.summation_.size() << "): [";
for (size_t i = 0; i < report.summation_.size(); ++i) {
os << report.summation_[i];
if (i + 1 < report.summation_.size())
os << ", ";
}
os << "]\n";

os << "currents_ (" << report.currents_.size() << "):\n";
for (const auto& [seg_id, vec]: report.currents_) {
os << " " << seg_id << ": [";
for (size_t i = 0; i < vec.size(); ++i) {
const auto& [ptr, scale] = vec[i];
os << "(ptr=" << ptr << ", val=" << (ptr ? *ptr : 0.0) << ", scale=" << scale << ")";
if (i + 1 < vec.size())
os << ", ";
}
os << "]\n";
}

os << "gid_segments_ (" << report.gid_segments_.size() << "):\n";
for (const auto& [gid, segs]: report.gid_segments_) {
os << " " << gid << ": [";
for (size_t i = 0; i < segs.size(); ++i) {
os << segs[i];
if (i + 1 < segs.size())
os << ", ";
}
os << "]\n";
}

return os;
}

struct SummationReportMapping {
// Map containing a SummationReport object per report
std::unordered_map<std::string, SummationReport> summation_reports_;
Expand All @@ -48,13 +86,6 @@ struct SpikesInfo {
std::vector<std::pair<std::string, int>> population_info;
};

// name of the variable in mod file that is used to indicate which synapse
// is enabled or disable for reporting
#define SELECTED_VAR_MOD_NAME "selected_for_report"

/// name of the variable in mod file used for setting synapse id
#define SYNAPSE_ID_MOD_NAME "synapseID"

/**
* @brief Converts an enum value to its corresponding string representation.
*
Expand Down Expand Up @@ -125,80 +156,40 @@ EnumT from_string(std::string_view str,
}

// ReportType
enum class ReportType { Compartment, Summation, Synapse, LFP };
constexpr std::array<std::pair<ReportType, std::string_view>, 4> report_type_map{
{{ReportType::Compartment, "Compartment"},
{ReportType::Summation, "Summation"},
{ReportType::Synapse, "Synapse"},
{ReportType::LFP, "LFP"}}};
enum class ReportType { Compartment, CompartmentSet, Summation, Synapse, LFP };
constexpr std::array<std::pair<ReportType, std::string_view>, 5> report_type_map{
{{ReportType::Compartment, "compartment"},
{ReportType::CompartmentSet, "compartment_set"},
{ReportType::Summation, "summation"},
{ReportType::Synapse, "synapse"},
{ReportType::LFP, "lfp"}}};
inline std::string to_string(ReportType t) {
return to_string(t, report_type_map, "ReportType");
}
inline ReportType report_type_from_string(const std::string& s) {
return from_string<ReportType>(s, report_type_map, "ReportType");
}

// TargetType
enum class TargetType {
Compartment = 0,
Cell = 1,
SectionSoma = 2,
SectionAxon = 3,
SectionDendrite = 4,
SectionApical = 5,
SectionSomaAll = 6,
SectionAxonAll = 7,
SectionDendriteAll = 8,
SectionApicalAll = 9,
};

constexpr std::array<std::pair<TargetType, std::string_view>, 10> target_type_map{
{{TargetType::Compartment, "Compartment"},
{TargetType::Cell, "Cell"},
{TargetType::SectionSoma, "SectionSoma"},
{TargetType::SectionAxon, "SectionAxon"},
{TargetType::SectionDendrite, "SectionDendrite"},
{TargetType::SectionApical, "SectionApical"},
{TargetType::SectionSomaAll, "SectionSomaAll"},
{TargetType::SectionAxonAll, "SectionAxonAll"},
{TargetType::SectionDendriteAll, "SectionDendriteAll"},
{TargetType::SectionApicalAll, "SectionApicalAll"}}};

inline std::string to_string(TargetType t) {
return to_string(t, target_type_map, "TargetType");
}
inline TargetType target_type_from_string(const std::string& s) {
return from_string<TargetType>(s, target_type_map, "TargetType");
}

// SectionType
enum class SectionType { Cell, Soma, Axon, Dendrite, Apical, Custom, All };

constexpr std::array<std::pair<SectionType, std::string_view>, 7> section_type_map{{
{SectionType::Cell, "Cell"},
{SectionType::Soma, "Soma"},
{SectionType::Axon, "Axon"},
{SectionType::Dendrite, "Dendrite"},
{SectionType::Apical, "Apical"},
{SectionType::Custom, "Custom"},
{SectionType::All, "All"},
}};
enum class SectionType { Cell, Soma, Axon, Dendrite, Apical, Ais, Node, Myelin, All, Invalid };

constexpr std::array<std::pair<SectionType, std::string_view>, 11> section_type_map{
{{SectionType::Cell, "Cell"},
{SectionType::Soma, "Soma"},
{SectionType::Axon, "Axon"},
{SectionType::Dendrite, "Dend"},
{SectionType::Apical, "Apic"},
{SectionType::Ais, "Ais"},
{SectionType::Node, "Node"},
{SectionType::Myelin, "Myelin"},
{SectionType::All, "All"},
{SectionType::Invalid, "Invalid"}}};

inline std::string to_string(SectionType t) {
return to_string(t, section_type_map, "SectionType");
}
inline SectionType section_type_from_string(std::string_view str) {
auto it =
std::find_if(section_type_map.begin(), section_type_map.end(), [&str](const auto& pair) {
return equals_case_insensitive(str, pair.second);
});

if (it != section_type_map.end()) {
return it->first;
}

// Default to Custom instead of aborting
return SectionType::Custom;
return from_string<SectionType>(str, section_type_map, "SectionType");
}

// Scaling
Expand All @@ -214,26 +205,41 @@ inline Scaling scaling_from_string(const std::string& str) {
return from_string<Scaling>(str, scaling_map, "Scaling");
}

enum class Compartments { All, Center, Invalid };
constexpr std::array<std::pair<Compartments, std::string_view>, 3> compartments_map{
{{Compartments::All, "All"},
{Compartments::Center, "Center"},
{Compartments::Invalid, "Invalid"}}};

inline std::string to_string(Compartments s) {
return to_string(s, compartments_map, "Compartments");
}
inline Compartments compartments_from_string(const std::string& str) {
return from_string<Compartments>(str, compartments_map, "Compartments");
}

struct ReportConfiguration {
std::string name; // name of the report
std::string output_path; // full path of the report
std::string target_name; // target of the report
std::vector<std::string> mech_names; // mechanism names
std::vector<std::string> var_names; // variable names
std::vector<int> mech_ids; // mechanisms
std::string unit; // unit of the report
std::string format; // format of the report (SONATA)
std::string type_str; // type of report string
TargetType target_type; // type of the target
ReportType type; // type of the report
SectionType section_type; // type of section report
bool section_all_compartments; // flag for section report (all values)
double report_dt; // reporting timestep
double start; // start time of report
double stop; // stop time of report
int num_gids; // total number of gids
int buffer_size; // hint on buffer size used for this report
std::vector<int> target; // list of gids for this report
std::string name; // name of the report
std::string output_path; // full path of the report
std::string target_name; // target of the report
std::vector<std::string> mech_names; // mechanism names
std::vector<std::string> var_names; // variable names
std::vector<int> mech_ids; // mechanisms
std::string unit; // unit of the report
std::string format; // format of the report (SONATA)
ReportType type; // type of the report
SectionType sections; // type of section report
Compartments compartments; // flag for section report (all values)
double report_dt; // reporting timestep
double start; // start time of report
double stop; // stop time of report
int num_gids; // total number of gids
int buffer_size; // hint on buffer size used for this report
std::vector<int> target; // list of gids for this report
std::vector<int> point_section_ids; // list of section_ids for this compartment set report
// (empty otherwise)
std::vector<int> point_compartment_ids; // list of compartment_ids for this compartment set
// report (empty otherwise)
Scaling scaling;
};

Expand Down
123 changes: 43 additions & 80 deletions src/coreneuron/io/reports/report_configuration_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,106 +54,69 @@ void parse_filter_string(const std::string& filter, ReportConfiguration& config)
}
}

void register_target_type(ReportConfiguration& report, ReportType report_type) {
report.type = report_type;
switch (report.target_type) {
case TargetType::Compartment:
report.section_type = SectionType::All;
report.section_all_compartments = true;
break;
case TargetType::Cell:
report.section_type = SectionType::Cell;
report.section_all_compartments = false;
break;
case TargetType::SectionSoma:
report.section_type = SectionType::Soma;
report.section_all_compartments = false;
break;
case TargetType::SectionSomaAll:
report.section_type = SectionType::Soma;
report.section_all_compartments = true;
break;
case TargetType::SectionAxon:
report.section_type = SectionType::Axon;
report.section_all_compartments = false;
break;
case TargetType::SectionAxonAll:
report.section_type = SectionType::Axon;
report.section_all_compartments = true;
break;
case TargetType::SectionDendrite:
report.section_type = SectionType::Dendrite;
report.section_all_compartments = false;
break;
case TargetType::SectionDendriteAll:
report.section_type = SectionType::Dendrite;
report.section_all_compartments = true;
break;
case TargetType::SectionApical:
report.section_type = SectionType::Apical;
report.section_all_compartments = false;
break;
case TargetType::SectionApicalAll:
report.section_type = SectionType::Apical;
report.section_all_compartments = true;
break;
default:
std::cerr << "Report error: unsupported target type" << std::endl;
nrn_abort(1);
}
void fill_vec_int(std::ifstream& ss, std::vector<int>& v, const int n) {
v.resize(n);
ss.read(reinterpret_cast<char*>(v.data()), n * sizeof(int));
// extra new line: skip
ss.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

std::vector<ReportConfiguration> create_report_configurations(const std::string& conf_file,
const std::string& output_dir,
SpikesInfo& spikes_info) {
std::string report_on;
std::string token;
int target;
std::ifstream report_conf(conf_file);

int num_reports = 0;
report_conf >> num_reports;
std::vector<ReportConfiguration> reports(num_reports);
for (auto& report: reports) {
report.buffer_size = 4; // default size to 4 Mb
report_conf >> report.name >> report.target_name;
report.output_path = output_dir + "/" + report.name;
// type
report_conf >> token;
report.type = report_type_from_string(token);
// report_on
report_conf >> token;
if (report.type == ReportType::Synapse || report.type == ReportType::Summation ||
report.type == ReportType::Compartment || report.type == ReportType::CompartmentSet) {
parse_filter_string(token, report);
}
report_conf >> report.unit >> report.format;
// sections
report_conf >> token;
report.sections = section_type_from_string(token);
// compartments
report_conf >> token;
report.compartments = compartments_from_string(token);

std::string scaling;
report_conf >> report.name >> report.target_name >> report.type_str >> report_on >>
report.unit >> report.format >> target >> report.report_dt >> report.start >>
report.stop >> report.num_gids >> report.buffer_size >> scaling;
// doubles
report_conf >> report.report_dt >> report.start >> report.stop >> report.num_gids >>
report.buffer_size;
// scaling
report_conf >> token;
report.scaling = scaling_from_string(token);

report.scaling = scaling_from_string(scaling);
report.target_type = static_cast<TargetType>(target);
std::transform(report.type_str.begin(),
report.type_str.end(),
report.type_str.begin(),
[](unsigned char c) { return std::tolower(c); });
report.output_path = output_dir + "/" + report.name;
ReportType report_type = report_type_from_string(report.type_str);
if (report_type == ReportType::LFP) {
if (report.type == ReportType::LFP) {
nrn_use_fast_imem = true;
}
register_target_type(report, report_type);
if (report.type == ReportType::Synapse || report.type == ReportType::Summation ||
report.type == ReportType::Compartment) {
parse_filter_string(report_on, report);
}

// checks
if (report.type == ReportType::Compartment) {
if (report.mech_names.size() != 1) {
std::cerr << "Report error: Compartment report requires exactly one variable name, "
"but got "
<< report.mech_names.size() << std::endl;
nrn_abort(1);
}
if (report.type == ReportType::Compartment || report.type == ReportType::CompartmentSet) {
nrn_assert(report.mech_ids.empty());
nrn_assert(report.mech_names.size() == 1);
nrn_assert(report.var_names.size() == 1);
}

report_conf.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// gids
if (report.num_gids) {
report.target.resize(report.num_gids);
report_conf.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
report_conf.read(reinterpret_cast<char*>(report.target.data()),
report.num_gids * sizeof(int));
// extra new line: skip
report_conf.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
fill_vec_int(report_conf, report.target, report.num_gids);
if (report.type == ReportType::CompartmentSet) {
fill_vec_int(report_conf, report.point_section_ids, report.num_gids);
fill_vec_int(report_conf, report.point_compartment_ids, report.num_gids);
}
}
}
// read population information for spike report
Expand Down
Loading
Loading