bmtool 0.5.4__py3-none-any.whl → 0.5.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
bmtool/singlecell.py CHANGED
@@ -136,22 +136,23 @@ class Passive(CurrentClamp):
136
136
  def __init__(self, template_name, inj_amp=-100., inj_delay=200., inj_dur=1000.,
137
137
  tstop=1200., method=None, **kwargs):
138
138
  """
139
- method: {'simple', 'exp2'}, optional.
139
+ method: {'simple', 'exp2', 'exp'}, optional.
140
140
  Method to estimate membrane time constant. Default is 'simple'
141
141
  that find the time to reach 0.632 of change. 'exp2' fits a double
142
- exponential curve to the membrane potential response.
142
+ exponential curve to the membrane potential response. 'exp' fits
143
+ a single exponential curve.
143
144
  """
144
145
  assert(inj_amp != 0)
145
146
  super().__init__(template_name=template_name, tstop=tstop,
146
147
  inj_amp=inj_amp, inj_delay=inj_delay, inj_dur=inj_dur, **kwargs)
147
148
  self.inj_stop = inj_delay + inj_dur
148
149
  self.method = method
149
- self.tau_methods = {'simple': self.tau_simple, 'exp2': self.tau_double_exponential}
150
+ self.tau_methods = {'simple': self.tau_simple, 'exp2': self.tau_double_exponential, 'exp': self.tau_single_exponential}
150
151
 
151
152
  def tau_simple(self):
152
153
  v_t_const = self.cell_v_final - self.v_diff / np.e
153
154
  index_v_tau = next(x for x, val in enumerate(self.v_vec_inj) if val <= v_t_const)
154
- self.tau = self.t_vec[self.index_v_rest + index_v_tau] - self.v_rest_time # ms
155
+ self.tau = self.t_vec[self.index_v_rest + index_v_tau] - self.v_rest_time # ms
155
156
 
156
157
  def print_calc():
157
158
  print()
@@ -163,6 +164,41 @@ class Passive(CurrentClamp):
163
164
  print()
164
165
  return print_calc
165
166
 
167
+ @staticmethod
168
+ def single_exponential(t, a0, a, tau):
169
+ return a0 + a * np.exp(-t / tau)
170
+
171
+ def tau_single_exponential(self):
172
+ index_v_peak = (np.sign(self.inj_amp) * self.v_vec_inj).argmax()
173
+ self.t_peak = self.t_vec_inj[index_v_peak]
174
+ self.v_peak = self.v_vec_inj[index_v_peak]
175
+ self.v_sag = self.v_peak - self.cell_v_final
176
+ self.v_max_diff = self.v_diff + self.v_sag
177
+ self.sag_norm = self.v_sag / self.v_max_diff
178
+
179
+ self.tau_simple()
180
+
181
+ p0 = (self.v_diff, self.tau) # initial estimate
182
+ v0 = self.v_rest
183
+ def fit_func(t, a, tau):
184
+ return self.single_exponential(t, a0=v0 - a, a=a, tau=tau)
185
+ bounds = ((-np.inf, 1e-3), np.inf)
186
+ popt, self.pcov = curve_fit(fit_func, self.t_vec_inj, self.v_vec_inj, p0=p0, bounds=bounds, maxfev=10000)
187
+ self.popt = np.insert(popt, 0, v0 - popt[0])
188
+ self.tau = self.popt[2]
189
+
190
+ def print_calc():
191
+ print()
192
+ print('Tau Calculation: Fit a single exponential curve to the membrane potential response')
193
+ print('f(t) = a0 + a*exp(-t/tau)')
194
+ print(f'Fit parameters: (a0, a, tau) = ({self.popt[0]:.2f}, {self.popt[1]:.2f}, {self.popt[2]:.2f})')
195
+ print(f'Membrane time constant is determined from the exponential term: {self.tau:.2f} (ms)')
196
+ print()
197
+ print('Sag potential: v_sag = v_peak - v_final = %.2f (mV)' % self.v_sag)
198
+ print('Normalized sag potential: v_sag / (v_peak - v_rest) = %.3f' % self.sag_norm)
199
+ print()
200
+ return print_calc
201
+
166
202
  @staticmethod
167
203
  def double_exponential(t, a0, a1, a2, tau1, tau2):
168
204
  return a0 + a1 * np.exp(-t / tau1) + a2 * np.exp(-t / tau2)
@@ -176,7 +212,7 @@ class Passive(CurrentClamp):
176
212
  self.sag_norm = self.v_sag / self.v_max_diff
177
213
 
178
214
  self.tau_simple()
179
- p0 = (self.v_sag, -self.v_max_diff, self.t_peak, self.tau) # intial estimate
215
+ p0 = (self.v_sag, -self.v_max_diff, self.t_peak, self.tau) # initial estimate
180
216
  v0 = self.v_rest
181
217
  def fit_func(t, a1, a2, tau1, tau2):
182
218
  return self.double_exponential(t, v0 - a1 - a2, a1, a2, tau1, tau2)
@@ -189,7 +225,7 @@ class Passive(CurrentClamp):
189
225
  print()
190
226
  print('Tau Calculation: Fit a double exponential curve to the membrane potential response')
191
227
  print('f(t) = a0 + a1*exp(-t/tau1) + a2*exp(-t/tau2)')
192
- print('Constained by initial value: f(0) = a0 + a1 + a2 = v_rest')
228
+ print('Constrained by initial value: f(0) = a0 + a1 + a2 = v_rest')
193
229
  print('Fit parameters: (a0, a1, a2, tau1, tau2) = (' + ', '.join(f'{x:.2f}' for x in self.popt) + ')')
194
230
  print(f'Membrane time constant is determined from the slowest exponential term: {self.tau:.2f} (ms)')
195
231
  print()
@@ -202,6 +238,11 @@ class Passive(CurrentClamp):
202
238
  t_vec = self.v_rest_time + self.t_vec_inj
203
239
  v_fit = self.double_exponential(self.t_vec_inj, *self.popt)
204
240
  return t_vec, v_fit
241
+
242
+ def single_exponential_fit(self):
243
+ t_vec = self.v_rest_time + self.t_vec_inj
244
+ v_fit = self.single_exponential(self.t_vec_inj, *self.popt)
245
+ return t_vec, v_fit
205
246
 
206
247
  def execute(self):
207
248
  print("Running simulation for passive properties...")
@@ -221,7 +262,7 @@ class Passive(CurrentClamp):
221
262
  self.t_vec_inj = np.array(self.t_vec)[t_idx] - self.v_rest_time
222
263
 
223
264
  self.v_diff = self.cell_v_final - self.v_rest
224
- self.r_in = self.v_diff / self.inj_amp # MegaOhms
265
+ self.r_in = self.v_diff / self.inj_amp # MegaOhms
225
266
 
226
267
  print_calc = self.tau_methods.get(self.method, self.tau_simple)()
227
268