NEURON
prcellstate.cpp
Go to the documentation of this file.
1 #include "../../nrnconf.h"
2 #include "section.h"
3 #include "membfunc.h"
4 #include "nrniv_mf.h"
5 #include "netcon.h"
6 #include <map>
7 #include "neuron.h"
8 #include "utils/enumerate.h"
9 
10 #define precision 15
11 
12 void nrn_prcellstate(int gid, const char* filesuffix);
13 
14 static void pr_memb(int type,
15  Memb_list* ml,
16  int* cellnodes,
17  NrnThread& nt,
18  FILE* f,
19  std::map<void*, int>& pnt2index) {
20  int header_printed = 0;
21  int size = nrn_prop_param_size_[type];
22  int receives_events = pnt_receive[type] ? 1 : 0;
23  for (int i = 0; i < ml->nodecount; ++i) {
24  int inode = ml->nodeindices[i];
25  if (cellnodes[inode] >= 0) {
26  if (!header_printed) {
27  header_printed = 1;
28  fprintf(f, "type=%d %s size=%d\n", type, memb_func[type].sym->name, size);
29  }
30  if (receives_events) {
31  fprintf(f, "%d nri %lu\n", cellnodes[inode], pnt2index.size());
32  auto* pp = ml->pdata[i][1].get<Point_process*>();
33  pnt2index.emplace(pp, pnt2index.size());
34  }
35  for (int j = 0; j < size; ++j) {
36  fprintf(f, " %d %d %.*g\n", cellnodes[inode], j, precision, ml->data(i, j));
37  }
38  }
39  }
40 }
41 
42 static void pr_netcon(NrnThread& nt, FILE* f, const std::map<void*, int>& pnt2index) {
43  if (pnt2index.empty()) {
44  return;
45  }
46  // pnt2index table has been filled
47 
48  // List of NetCon for each of the NET_RECEIVE point process instances
49  // ... all NetCon list in the hoc NetCon cTemplate
50  std::vector<std::vector<NetCon*>> nclist(pnt2index.size());
51  int nc_cnt = 0;
52  Symbol* ncsym = hoc_lookup("NetCon");
53  hoc_Item* q;
54  ITERATE(q, ncsym->u.ctemplate->olist) {
55  Object* obj = OBJ(q);
56  NetCon* nc = (NetCon*) obj->u.this_pointer;
57  Point_process* pp = nc->target_;
58  const auto& it = pnt2index.find(pp);
59  if (it != pnt2index.end()) {
60  nclist[it->second].push_back(nc);
61  ++nc_cnt;
62  }
63  }
64  fprintf(f, "netcons %d\n", nc_cnt);
65  fprintf(f, " pntindex srcgid active delay weights\n");
66  for (const auto&& [i, ncl]: enumerate(nclist)) {
67  for (const auto& nc: ncl) {
68  int srcgid = (nc->src_) ? nc->src_->gid_ : -3;
69  if (srcgid < 0 && nc->src_ && nc->src_->osrc_) {
70  const char* name = nc->src_->osrc_->ctemplate->sym->name;
71  fprintf(f, "%zd %s %d %.*g", i, name, nc->active_ ? 1 : 0, precision, nc->delay_);
72  } else if (srcgid < 0 && nc->src_ && nc->src_->ssrc_) {
73  fprintf(f, "%zd %s %d %.*g", i, "v", nc->active_ ? 1 : 0, precision, nc->delay_);
74  } else {
75  fprintf(f, "%zd %d %d %.*g", i, srcgid, nc->active_ ? 1 : 0, precision, nc->delay_);
76  }
77  int wcnt = pnt_receive_size[nc->target_->prop->_type];
78  for (int k = 0; k < wcnt; ++k) {
79  fprintf(f, " %.*g", precision, nc->weight_[k]);
80  }
81  fprintf(f, "\n");
82  }
83  }
84 }
85 
86 static void pr_realcell(PreSyn& ps, NrnThread& nt, FILE* f) {
87  assert(ps.thvar_);
88  // threshold variable is a voltage
89 
90  // If the "modern" data is "sorted" then the order should match the "legacy"
91  // data structures that still live alongside it
92  auto const cache_token = nrn_ensure_model_data_are_sorted();
93  assert(
95  int const inode = ps.thvar_.current_row() - cache_token.thread_cache(nt.id).node_data_offset;
96  // hoc_execerror("gid not associated with a voltage", 0);
97 
98  // and the root node is ...
99  int rnode = inode;
100  while (rnode >= nt.ncell) {
101  rnode = nt._v_parent_index[rnode];
102  }
103 
104  // count the number of nodes in the cell
105  // do not assume all cell nodes except the root are contiguous
106  int* cellnodes = new int[nt.end];
107  for (int i = 0; i < nt.end; ++i) {
108  cellnodes[i] = -1;
109  }
110  int cnt = 0;
111  cellnodes[rnode] = cnt++;
112  for (int i = nt.ncell; i < nt.end; ++i) {
113  if (cellnodes[nt._v_parent_index[i]] >= 0) {
114  cellnodes[i] = cnt++;
115  }
116  }
117  fprintf(f, "%d nodes %d is the threshold node\n", cnt, cellnodes[inode] - 1);
118  fprintf(f, " threshold %.*g\n", precision, ps.threshold_);
119  fprintf(f, "inode parent area a b\n");
120  for (int i = 0; i < nt.end; ++i)
121  if (cellnodes[i] >= 0) {
122  Node* nd = nt._v_node[i];
123  fprintf(f,
124  "%d %d %.*g %.*g %.*g\n",
125  cellnodes[i],
126  i < nt.ncell ? -1 : cellnodes[nt._v_parent_index[i]],
127  precision,
128  NODEAREA(nd),
129  precision,
130  nd->a(),
131  precision,
132  nd->b());
133  }
134  fprintf(f, "inode v\n");
135  for (int i = 0; i < nt.end; ++i)
136  if (cellnodes[i] >= 0) {
137  Node* nd = nt._v_node[i]; // if not cach_efficient then _actual_v=NULL
138  fprintf(f, "%d %.*g\n", cellnodes[i], precision, NODEV(nd));
139  }
140 
141  {
142  std::map<void*, int> pnt2index;
143  // each mechanism
144  for (NrnThreadMembList* tml = nt.tml; tml; tml = tml->next) {
145  pr_memb(tml->index, tml->ml, cellnodes, nt, f, pnt2index);
146  }
147 
148  // the NetCon info
149  pr_netcon(nt, f, pnt2index);
150  }
151  delete[] cellnodes;
152 }
153 
154 void nrn_prcellstate(int gid, const char* suffix) {
155  PreSyn* ps = nrn_gid2outputpresyn(gid);
156  if (!ps) {
157  return;
158  }
159  // found it so create a <gid>_<suffix>.nrn file
160  char buf[200];
161  Sprintf(buf, "%d_%s.nrndat", gid, suffix);
162  FILE* f = fopen(buf, "w");
163  assert(f);
164  NrnThread& nt = *ps->nt_;
165  fprintf(f, "gid = %d\n", gid);
166  fprintf(f, "t = %.*g\n", precision, nt._t);
167  fprintf(f, "celsius = %.*g\n", precision, celsius);
168  if (ps->thvar_) {
169  pr_realcell(*ps, nt, f);
170  }
171  fclose(f);
172 }
ReceiveFunc * pnt_receive
Definition: init.cpp:155
Definition: netcon.h:87
Point_process * target_
Definition: netcon.h:115
Definition: netcon.h:258
NrnThread * nt_
Definition: netcon.h:303
double threshold_
Definition: netcon.h:295
neuron::container::data_handle< double > thvar_
Definition: netcon.h:297
#define cnt
Definition: tqueue.hpp:44
#define i
Definition: md1redef.h:19
constexpr auto enumerate(T &&iterable)
Definition: enumerate.h:90
static RNG::key_type k
Definition: nrnran123.cpp:9
char buf[512]
Definition: init.cpp:13
Symbol * hoc_lookup(const char *)
Definition: symbol.cpp:59
#define assert(ex)
Definition: hocassrt.h:24
#define OBJ(q)
Definition: hoclist.h:88
#define ITERATE(itm, lst)
Definition: model.h:18
const char * name
Definition: init.cpp:16
double celsius
static std::map< Point_process *, int > pnt2index
Definition: prcellstate.cpp:23
Model & model()
Access the global Model instance.
Definition: model_data.hpp:206
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
Definition: wrap_sprintf.h:14
if(ncell==0)
Definition: cellorder.cpp:785
PreSyn * nrn_gid2outputpresyn(int gid)
Definition: netpar.cpp:1556
static char suffix[256]
Definition: nocpout.cpp:135
neuron::model_sorted_token nrn_ensure_model_data_are_sorted()
Ensure neuron::container::* data are sorted.
Definition: treeset.cpp:2182
size_t q
size_t j
int * nrn_prop_param_size_
Definition: init.cpp:162
#define precision
Definition: prcellstate.cpp:10
static void pr_netcon(NrnThread &nt, FILE *f, const std::map< void *, int > &pnt2index)
Definition: prcellstate.cpp:42
static void pr_realcell(PreSyn &ps, NrnThread &nt, FILE *f)
Definition: prcellstate.cpp:86
void nrn_prcellstate(int gid, const char *filesuffix)
static void pr_memb(int type, Memb_list *ml, int *cellnodes, NrnThread &nt, FILE *f, std::map< void *, int > &pnt2index)
Definition: prcellstate.cpp:14
std::vector< Memb_func > memb_func
Definition: init.cpp:145
short type
Definition: cabvars.h:10
short * pnt_receive_size
Definition: init.cpp:157
#define NODEAREA(n)
Definition: section.h:101
#define NODEV(n)
Definition: section_fwd.hpp:60
A view into a set of mechanism instances.
Definition: nrnoc_ml.h:34
int nodecount
Definition: nrnoc_ml.h:78
int * nodeindices
Definition: nrnoc_ml.h:74
Datum ** pdata
Definition: nrnoc_ml.h:75
std::vector< double * > data()
Get a vector of double* representing the model data.
Definition: memblist.cpp:64
Definition: section.h:105
auto & b()
Definition: section.h:129
auto & a()
Definition: section.h:114
Represent main neuron object computed by single thread.
Definition: multicore.h:58
int * _v_parent_index
Definition: multicore.h:89
NrnThreadMembList * tml
Definition: multicore.h:62
int ncell
Definition: multicore.h:64
int id
Definition: multicore.h:66
int end
Definition: multicore.h:65
Node ** _v_node
Definition: multicore.h:90
double _t
Definition: multicore.h:59
struct NrnThreadMembList * next
Definition: multicore.h:34
Definition: hocdec.h:173
void * this_pointer
Definition: hocdec.h:178
union Object::@47 u
A point process is computed just like regular mechanisms.
Definition: section_fwd.hpp:77
Definition: model.h:47
union Symbol::@28 u
cTemplate * ctemplate
Definition: hocdec.h:126
hoc_List * olist
Definition: hocdec.h:155
container::Node::storage & node_data()
Access the structure containing the data of all Nodes.
Definition: model_data.hpp:24
bool refers_to(Container const &container) const
Query whether this generic handle points to a value from the Tag field of the given container.
std::size_t current_row() const
Get the current logical row number.
T get() const
Explicit conversion to any T.