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 
22 
23 namespace coreneuron {
24 
25 /** @brief Section to segment mapping
26  *
27  * For a section list (of a particulat type), store mapping
28  * of section to compartments
29  * a section is a arbitrary user classification to recognize some compartments (ex: api, soma,
30  * dend, axon)
31  *
32  */
33 struct SecMapping {
34  /** name of section list */
36 
37  /** map of section and associated compartments */
38  std::unordered_map<int, std::vector<int>> secmap;
39 
40  SecMapping() = default;
41 
43  : type(t) {}
44 
45  /** @brief return total number of sections in section list */
46  size_t num_sections() const noexcept {
47  return secmap.size();
48  }
49 
50  /** @brief return number of compartments in section list */
51  size_t num_compartments() const {
52  return std::accumulate(secmap.begin(), secmap.end(), 0, [](int psum, const auto& item) {
53  return psum + item.second.size();
54  });
55  }
56 
57  /** @brief add section to associated segment */
58  void add_segment(int sec, int seg) {
59  secmap[sec].push_back(seg);
60  }
61 };
62 
63 /** @brief Compartment mapping information for a cell
64  *
65  * A cell can have multiple section list types like
66  * soma, axon, apic, dend etc. User will add these
67  * section lists using HOC interface.
68  */
69 struct CellMapping {
70  /** gid of a cell */
71  int gid;
72 
73  /** list of section lists (like soma, axon, apic) */
74  std::vector<std::shared_ptr<SecMapping>> sec_mappings;
75 
76  /** map containing segment ids an its respective lfp factors */
77  std::unordered_map<int, std::vector<double>> lfp_factors;
78 
79  CellMapping(int g)
80  : gid(g) {}
81 
82  /** @brief total number of sections in a cell */
83  int num_sections() const {
84  return std::accumulate(sec_mappings.begin(),
85  sec_mappings.end(),
86  0,
87  [](int psum, const auto& secmap) {
88  return psum + secmap->num_sections();
89  });
90  }
91 
92  /** @brief return number of compartments in a cell */
93  int num_compartments() const {
94  return std::accumulate(sec_mappings.begin(),
95  sec_mappings.end(),
96  0,
97  [](int psum, const auto& secmap) {
98  return psum + secmap->num_compartments();
99  });
100  }
101 
102  /** @brief return the number of electrodes in the lfp_factors map **/
103  int num_electrodes() const {
104  int num_electrodes = 0;
105  if (!lfp_factors.empty()) {
106  num_electrodes = lfp_factors.begin()->second.size();
107  }
108  return num_electrodes;
109  }
110 
111  /** @brief number of section lists */
112  size_t size() const noexcept {
113  return sec_mappings.size();
114  }
115 
116  /** @brief add new SecMapping */
117  void add_sec_map(std::shared_ptr<SecMapping> s) {
118  sec_mappings.push_back(s);
119  }
120 
121  /** @brief return section list mapping with given type */
122  std::shared_ptr<SecMapping> get_seclist_mapping(const SectionType type) const {
123  for (auto& secmap: sec_mappings) {
124  if (type == secmap->type) {
125  return secmap;
126  }
127  }
128 
129  std::cout << "Warning: Section mapping list " << to_string(type) << " doesn't exist! \n";
130  return nullptr;
131  }
132 
133  /** @brief return compartment count for specific section list with given type */
135  auto s = get_seclist_mapping(type);
136  if (!s) {
137  return 0;
138  }
139  return s->num_compartments();
140  }
141  /** @brief return segment count for specific section list with given type */
143  auto s = get_seclist_mapping(type);
144  if (!s) {
145  return 0;
146  }
147  return s->num_sections();
148  }
149 
150  /** @brief add the lfp electrode factors of a segment_id */
151  void add_segment_lfp_factor(const int segment_id, std::vector<double>& factors) {
152  lfp_factors.insert({segment_id, factors});
153  }
154 };
155 
156 /** @brief Compartment mapping information for NrnThread
157  *
158  * NrnThread could have more than one cell in cellgroup
159  * and we store this in vector.
160  */
162  /** list of cells mapping */
163  std::unordered_map<int, std::shared_ptr<CellMapping>> cell_mappings;
164 
165  /** list of segment ids */
166  std::vector<int> segment_ids;
167 
168  std::vector<double> _lfp;
169 
170  /** @brief number of cells */
171  size_t size() const {
172  return cell_mappings.size();
173  }
174 
175  /** @brief get cell mapping information for given gid
176  * if exist otherwise return nullptr.
177  */
178  std::shared_ptr<CellMapping> get_cell_mapping(int gid) const {
179  auto it = cell_mappings.find(gid);
180  if (it != cell_mappings.end()) {
181  return it->second;
182  }
183  return nullptr;
184  }
185 
186  /** @brief add mapping information of new cell */
187  void add_cell_mapping(std::shared_ptr<CellMapping> c) {
188  auto [it, inserted] = cell_mappings.insert({c->gid, c});
189  if (!inserted) {
190  std::cerr << "CellMapping for gid " << std::to_string(c->gid) << " already exists!\n";
191  nrn_abort(1);
192  }
193  }
194 
195  /** @brief add a new segment */
196  void add_segment_id(const int segment_id) {
197  segment_ids.push_back(segment_id);
198  }
199 
200  /** @brief Resize the lfp vector */
201  void prepare_lfp() {
202  size_t lfp_size = std::accumulate(cell_mappings.begin(),
203  cell_mappings.end(),
204  0,
205  [](size_t total, const auto& mapping) {
206  return total + mapping.second->num_electrodes();
207  });
208  _lfp.resize(lfp_size);
209  }
210 };
211 } // 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
s
Definition: multisend.cpp:521
short type
Definition: cabvars.h:10
Compartment mapping information for a cell.
void add_segment_lfp_factor(const int segment_id, std::vector< double > &factors)
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
std::unordered_map< int, std::vector< double > > lfp_factors
map containing segment ids an its respective lfp factors
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
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
int num_electrodes() const
return the number of electrodes in the lfp_factors map
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