NEURON
fstim.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /* /local/src/master/nrn/src/nrnoc/fstim.cpp,v 1.2 1997/08/15 13:04:11 hines Exp */
3 /* copy of synapse.cpp modified to simulate current stimulus pulses */
4 /* 4/9/2002 modified to conform to new treeset.cpp */
5 
6 /*
7 fstim(maxnum)
8  allocates space for maxnum synapses. Space for
9  previously existing synapses is released. All synapses initialized to
10  0 maximum conductance.
11 
12 fstim(i, loc, delay, duration, stim)
13  The ith current stimulus is injected at parameter `loc'
14  different current stimuli do not concatenate but can ride on top of
15  each other. delay refers to onset of stimulus relative to t=0
16  delay and duration are in msec.
17  stim in namps.
18 
19 fstimi(i)
20  returns stimulus current for ith stimulus at the value of the
21  global time t.
22 
23 */
24 
25 #include <stdlib.h>
26 #include "neuron.h"
27 #include "section.h"
28 #include "nrniv_mf.h"
29 
30 
31 typedef struct Stimulus {
32  double loc; /* parameter location (0--1) */
33  double delay; /* value of t in msec for onset */
34  double duration;/* turns off at t = delay + duration */
35  double mag; /* magnitude in namps */
36  double mag_seg; /* value added to rhs, depends on area of seg*/
37  Node *pnd; /* segment location */
39 } Stimulus;
40 
41 static int maxstim = 0; /* size of stimulus array */
42 static Stimulus *pstim; /* pointer to stimulus array */
43 static void free_stim(void);
44 
45 static void stim_record(int);
46 
47 #define nt_t nrn_threads->_t
48 
49 void print_stim() {
50  int i;
51 
52  if (maxstim == 0) return;
53  /*SUPPRESS 440*/
54  Printf("fstim(%d)\n/* section fstim( #, loc, delay(ms), duration(ms), magnitude(namp)) */\n", maxstim);
55  for (i = 0; i < maxstim; i++) {
56  Printf("%-15s fstim(%2d,%4g,%10g,%13g,%16g)\n",
57  secname(pstim[i].sec), i,
58  pstim[i].loc, pstim[i].delay, pstim[i].duration, pstim[i].mag);
59  }
60 }
61 
62 static double stimulus(int i) {
63 #if CVODE
64  at_time(nrn_threads, pstim[i].delay);
65  at_time(nrn_threads, pstim[i].delay + pstim[i].duration);
66 #endif
67  if (nt_t < pstim[i].delay - 1e-9
68  || nt_t > pstim[i].delay + pstim[i].duration - 1e-9) {
69  return 0.0;
70  }
71  return pstim[i].mag_seg;
72 }
73 
74 void fstimi(void) {
75  int i;
76  double cur;
77 
78  i = chkarg(1, 0., (double) (maxstim - 1));
79  if ((cur = stimulus(i)) != 0.) {
80  cur = pstim[i].mag;
81  }
82  hoc_retpushx(cur);
83 }
84 
85 void fstim(void) {
86  int i;
87 
88  if (nrn_nthread > 1) {
89  hoc_execerror("fstim does not allow threads", "");
90  }
91  i = chkarg(1, 0., 10000.);
92  if (ifarg(2)) {
93  if (i >= maxstim) {
94  hoc_execerror("index out of range", (char *) 0);
95  }
96  pstim[i].loc = chkarg(2, 0., 1.);
97  pstim[i].delay = chkarg(3, 0., 1e21);
98  pstim[i].duration = chkarg(4, 0., 1e21);
99  pstim[i].mag = *getarg(5);
100  pstim[i].sec = chk_access();
101  section_ref(pstim[i].sec);
102  stim_record(i);
103  } else {
104  free_stim();
105  maxstim = i;
106  if (maxstim) {
107  pstim = (Stimulus *) emalloc((unsigned) (maxstim * sizeof(Stimulus)));
108  }
109  for (i = 0; i < maxstim; i++) {
110  pstim[i].loc = 0;
111  pstim[i].mag = 0.;
112  pstim[i].delay = 1e20;
113  pstim[i].duration = 0.;
114  pstim[i].sec = 0;
115  stim_record(i);
116  }
117  }
118  hoc_retpushx(0.);
119 }
120 
121 static void free_stim(void) {
122  int i;
123  if (maxstim) {
124  for (i = 0; i < maxstim; ++i) {
125  if (pstim[i].sec) {
126  section_unref(pstim[i].sec);
127  }
128  }
129  free((char *) pstim);
130  maxstim = 0;
131  }
132 }
133 
134 static void stim_record(int i) /*fill in the section info*/
135 {
136  double area;
137  Section *sec;
138 
139  sec = pstim[i].sec;
140  if (sec) {
141  if (sec->prop) {
142  pstim[i].pnd = node_ptr(sec, pstim[i].loc, &area);
143  pstim[i].mag_seg = 1.e2 * pstim[i].mag / area;
144  } else {
145  section_unref(sec);
146  pstim[i].sec = 0;
147  }
148  }
149 }
150 
151 void stim_prepare(void) {
152  int i;
153 
154  for (i = 0; i < maxstim; i++) {
155  stim_record(i);
156  }
157 }
158 
159 void activstim_rhs(void) {
160  int i;
161 
162  for (i = 0; i < maxstim; i++) {
163  if (pstim[i].sec) {
164  NODERHS(pstim[i].pnd) += stimulus(i);
165  }
166  }
167 }
168 
#define area
Definition: md1redef.h:5
#define Printf
Definition: model.h:252
double duration
Definition: fstim.cpp:34
struct Prop * prop
Definition: section.h:62
static void stim_record(int)
Definition: fstim.cpp:134
double delay
Definition: fstim.cpp:33
double mag_seg
Definition: fstim.cpp:36
void activstim_rhs(void)
Definition: fstim.cpp:159
double loc
Definition: fstim.cpp:32
#define cur
Definition: eion.cpp:338
#define e
Definition: passive0.cpp:24
void stim_prepare(void)
Definition: fstim.cpp:151
static void free_stim(void)
Definition: fstim.cpp:121
int nrn_nthread
Definition: multicore.cpp:44
struct Stimulus Stimulus
void print_stim()
Definition: fstim.cpp:49
NrnThread * nrn_threads
Definition: multicore.cpp:45
static Stimulus * pstim
Definition: fstim.cpp:42
const char * secname(Section *sec)
Definition: cabcode.cpp:1787
Node * pnd
Definition: fstim.cpp:37
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
at_time
Definition: extargs.h:1
hoc_retpushx(1.0)
Section * sec
Definition: fstim.cpp:38
double mag
Definition: fstim.cpp:35
char * emalloc(unsigned n)
Definition: list.cpp:189
int ifarg(int)
Definition: code.cpp:1562
void section_ref(Section *)
Definition: solve.cpp:563
#define NODERHS(n)
Definition: section.h:104
static double stimulus(int i)
Definition: fstim.cpp:62
void fstim(void)
Definition: fstim.cpp:85
#define getarg
Definition: hocdec.h:15
#define i
Definition: md1redef.h:12
void fstimi(void)
Definition: fstim.cpp:74
static int maxstim
Definition: fstim.cpp:41
Node * node_ptr(Section *sec, double x, double *parea)
Definition: cabcode.cpp:2003
void section_unref(Section *)
Definition: solve.cpp:552
Definition: section.h:132
Section * chk_access(void)
Definition: cabcode.cpp:437
double chkarg(int, double low, double high)
Definition: code2.cpp:608
#define nt_t
Definition: fstim.cpp:47