NEURON
nrnsection_mapping.hpp
Go to the documentation of this file.
1 /*
2 # =============================================================================
3 # Copyright (c) 2016 - 2021 Blue Brain Project/EPFL
4 #
5 # See top-level LICENSE file for details.
6 # =============================================================================
7 */
8 
9 #pragma once
10 
11 #include <iostream>
12 #include <map>
13 #include <memory>
14 #include <numeric>
15 #include <string>
16 #include <utility>
17 #include <unordered_map>
18 #include <vector>
19 
23 
24 namespace coreneuron {
25 
26 /** @brief Section to segment mapping
27  *
28  * For a section list (of a particulat type), store mapping
29  * of section to compartments
30  * a section is a arbitrary user classification to recognize some compartments (ex: api, soma,
31  * dend, axon)
32  *
33  */
34 struct SecMapping {
35  /** name of section list */
37 
38  /** map of section and associated compartments */
39  std::unordered_map<int, std::vector<int>> secmap;
40 
41  SecMapping() = default;
42 
44  : type(t) {}
45 
46  /** @brief return total number of sections in section list */
47  size_t num_sections() const noexcept {
48  return secmap.size();
49  }
50 
51  /** @brief return number of compartments in section list */
52  size_t num_compartments() const {
53  return std::accumulate(secmap.begin(), secmap.end(), 0, [](int psum, const auto& item) {
54  return psum + item.second.size();
55  });
56  }
57 
58  /** @brief add section to associated segment */
59  void add_segment(int sec, int seg) {
60  secmap[sec].push_back(seg);
61  }
62 };
63 
64 /** @brief Compartment mapping information for a cell
65  *
66  * A cell can have multiple section list types like
67  * soma, axon, apic, dend etc. User will add these
68  * section lists using HOC interface.
69  */
70 struct CellMapping {
71  /** gid of a cell */
72  int gid;
73 
74  /** list of section lists (like soma, axon, apic) */
75  std::vector<std::shared_ptr<SecMapping>> sec_mappings;
76 
77  /** segment ids for lfp factors (one per compartment with LFP data) */
78  std::vector<int> lfp_segment_ids;
79 
80  /** flat array of lfp factors: stride = num_electrodes, indexed as [i * stride + e] */
81  std::vector<double> lfp_factors_flat;
82 
83  /** Electrode offsets per LFP report (CSR-style, size = num_reports + 1).
84  * offsets[i]..offsets[i+1] gives the electrode range for report i. */
85  std::vector<size_t> electrode_offsets;
86 
87  CellMapping(int g)
88  : gid(g) {}
89 
90  /** @brief total number of sections in a cell */
91  int num_sections() const {
92  return std::accumulate(sec_mappings.begin(),
93  sec_mappings.end(),
94  0,
95  [](int psum, const auto& secmap) {
96  return psum + secmap->num_sections();
97  });
98  }
99 
100  /** @brief return number of compartments in a cell */
101  int num_compartments() const {
102  return std::accumulate(sec_mappings.begin(),
103  sec_mappings.end(),
104  0,
105  [](int psum, const auto& secmap) {
106  return psum + secmap->num_compartments();
107  });
108  }
109 
110  /** @brief return the total number of electrodes **/
111  size_t num_electrodes() const {
112  return electrode_offsets.empty() ? 0 : electrode_offsets.back();
113  }
114 
115  /** @brief number of section lists */
116  size_t size() const noexcept {
117  return sec_mappings.size();
118  }
119 
120  /** @brief add new SecMapping */
121  void add_sec_map(std::shared_ptr<SecMapping> s) {
122  sec_mappings.push_back(s);
123  }
124 
125  /** @brief return section list mapping with given type */
126  std::shared_ptr<SecMapping> get_seclist_mapping(const SectionType type) const {
127  for (auto& secmap: sec_mappings) {
128  if (type == secmap->type) {
129  return secmap;
130  }
131  }
132 
133  std::cout << "Warning: Section mapping list " << to_string(type) << " doesn't exist! \n";
134  return nullptr;
135  }
136 
137  /** @brief return compartment count for specific section list with given type */
139  auto s = get_seclist_mapping(type);
140  if (!s) {
141  return 0;
142  }
143  return s->num_compartments();
144  }
145  /** @brief return segment count for specific section list with given type */
147  auto s = get_seclist_mapping(type);
148  if (!s) {
149  return 0;
150  }
151  return s->num_sections();
152  }
153 
154  /** @brief add the lfp electrode factors of a segment_id */
155  void add_segment_lfp_factor(const int segment_id,
156  std::vector<double>::const_iterator begin,
157  std::vector<double>::const_iterator end) {
158  const size_t n = std::distance(begin, end);
159  if (n == 0) {
160  return;
161  }
162  const auto curr_n_electrodes = num_electrodes();
163  // All segments must have the same number of electrode factors
164  nrn_assert(curr_n_electrodes == 0 || n == curr_n_electrodes);
165  lfp_segment_ids.push_back(segment_id);
166  lfp_factors_flat.insert(lfp_factors_flat.end(), begin, end);
167  }
168 };
169 
170 /** @brief Compartment mapping information for NrnThread
171  *
172  * NrnThread could have more than one cell in cellgroup
173  * and we store this in vector.
174  */
176  /** list of cells mapping */
177  std::unordered_map<int, std::shared_ptr<CellMapping>> cell_mappings;
178 
179  /** list of segment ids */
180  std::vector<int> segment_ids;
181 
182  std::vector<double> _lfp;
183 
184  /** @brief number of cells */
185  size_t size() const {
186  return cell_mappings.size();
187  }
188 
189  /** @brief get cell mapping information for given gid
190  * if exist otherwise return nullptr.
191  */
192  std::shared_ptr<CellMapping> get_cell_mapping(int gid) const {
193  auto it = cell_mappings.find(gid);
194  if (it != cell_mappings.end()) {
195  return it->second;
196  }
197  return nullptr;
198  }
199 
200  /** @brief add mapping information of new cell */
201  void add_cell_mapping(std::shared_ptr<CellMapping> c) {
202  auto [it, inserted] = cell_mappings.insert({c->gid, c});
203  if (!inserted) {
204  std::cerr << "CellMapping for gid " << std::to_string(c->gid) << " already exists!\n";
205  nrn_abort(1);
206  }
207  }
208 
209  /** @brief add a new segment */
210  void add_segment_id(const int segment_id) {
211  segment_ids.push_back(segment_id);
212  }
213 
214  /** @brief Resize the lfp vector */
215  void prepare_lfp() {
216  size_t lfp_size = std::accumulate(cell_mappings.begin(),
217  cell_mappings.end(),
218  0,
219  [](size_t total, const auto& mapping) {
220  return total + mapping.second->num_electrodes();
221  });
222  _lfp.resize(lfp_size);
223  }
224 };
225 } // namespace coreneuron
#define sec
Definition: md1redef.h:20
static int c
Definition: hoc.cpp:169
THIS FILE IS AUTO GENERATED DONT MODIFY IT.
void nrn_abort(int errcode)
Definition: utils.cpp:13
std::string to_string(EnumT e, const std::array< std::pair< EnumT, std::string_view >, N > &mapping, const std::string_view enum_name)
Converts an enum value to its corresponding string representation.
Definition: nrnreport.hpp:102
void distance()
Definition: solve.cpp:226
#define nrn_assert(x)
assert()-like macro, independent of NDEBUG status
Definition: nrn_assert.h:33
int const size_t const size_t n
Definition: nrngsl.h:10
s
Definition: multisend.cpp:521
short type
Definition: cabvars.h:10
Compartment mapping information for a cell.
std::vector< size_t > electrode_offsets
Electrode offsets per LFP report (CSR-style, size = num_reports + 1).
std::vector< double > lfp_factors_flat
flat array of lfp factors: stride = num_electrodes, indexed as [i * stride + e]
void add_segment_lfp_factor(const int segment_id, std::vector< double >::const_iterator begin, std::vector< double >::const_iterator end)
add the lfp electrode factors of a segment_id
int num_compartments() const
return number of compartments in a cell
std::shared_ptr< SecMapping > get_seclist_mapping(const SectionType type) const
return section list mapping with given type
size_t num_electrodes() const
return the total number of electrodes
size_t get_seclist_compartment_count(const SectionType type) const
return compartment count for specific section list with given type
size_t get_seclist_section_count(const SectionType type) const
return segment count for specific section list with given type
int num_sections() const
total number of sections in a cell
std::vector< int > lfp_segment_ids
segment ids for lfp factors (one per compartment with LFP data)
void add_sec_map(std::shared_ptr< SecMapping > s)
add new SecMapping
std::vector< std::shared_ptr< SecMapping > > sec_mappings
list of section lists (like soma, axon, apic)
size_t size() const noexcept
number of section lists
Compartment mapping information for NrnThread.
void add_cell_mapping(std::shared_ptr< CellMapping > c)
add mapping information of new cell
size_t size() const
number of cells
std::unordered_map< int, std::shared_ptr< CellMapping > > cell_mappings
list of cells mapping
std::shared_ptr< CellMapping > get_cell_mapping(int gid) const
get cell mapping information for given gid if exist otherwise return nullptr.
std::vector< int > segment_ids
list of segment ids
void add_segment_id(const int segment_id)
add a new segment
void prepare_lfp()
Resize the lfp vector.
Section to segment mapping.
std::unordered_map< int, std::vector< int > > secmap
map of section and associated compartments
void add_segment(int sec, int seg)
add section to associated segment
size_t num_sections() const noexcept
return total number of sections in section list
SectionType type
name of section list
size_t num_compartments() const
return number of compartments in section list