bmtool 0.6.6.2__tar.gz → 0.6.6.4__tar.gz
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-0.6.6.2 → bmtool-0.6.6.4}/PKG-INFO +1 -1
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/synapses.py +77 -31
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool.egg-info/PKG-INFO +1 -1
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/setup.py +1 -1
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/LICENSE +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/README.md +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/SLURM.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/__init__.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/__main__.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/bmplot.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/connectors.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/debug/__init__.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/debug/commands.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/debug/debug.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/graphs.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/manage.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/plot_commands.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/singlecell.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/util/__init__.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/util/commands.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/util/neuron/__init__.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/util/neuron/celltuner.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool/util/util.py +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool.egg-info/SOURCES.txt +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool.egg-info/dependency_links.txt +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool.egg-info/entry_points.txt +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool.egg-info/requires.txt +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/bmtool.egg-info/top_level.txt +0 -0
- {bmtool-0.6.6.2 → bmtool-0.6.6.4}/setup.cfg +0 -0
@@ -84,6 +84,20 @@ class SynapseTuner:
|
|
84
84
|
h.dt = general_settings['dt'] # Time step (resolution) of the simulation in ms
|
85
85
|
h.steps_per_ms = 1 / h.dt
|
86
86
|
h.celsius = general_settings['celsius']
|
87
|
+
|
88
|
+
# get some stuff set up we need for both SingleEvent and Interactive Tuner
|
89
|
+
self._set_up_cell()
|
90
|
+
self._set_up_synapse()
|
91
|
+
|
92
|
+
self.nstim = h.NetStim()
|
93
|
+
self.nstim2 = h.NetStim()
|
94
|
+
|
95
|
+
self.vcl = h.VClamp(self.cell.soma[0](0.5))
|
96
|
+
|
97
|
+
self.nc = h.NetCon(self.nstim, self.syn, self.general_settings['threshold'], self.general_settings['delay'], self.general_settings['weight'])
|
98
|
+
self.nc2 = h.NetCon(self.nstim2, self.syn, self.general_settings['threshold'], self.general_settings['delay'], self.general_settings['weight'])
|
99
|
+
|
100
|
+
self._set_up_recorders()
|
87
101
|
|
88
102
|
def _update_spec_syn_param(self, json_folder_path):
|
89
103
|
"""
|
@@ -168,7 +182,7 @@ class SynapseTuner:
|
|
168
182
|
self.ivcl.record(self.vcl._ref_i)
|
169
183
|
|
170
184
|
|
171
|
-
def SingleEvent(self):
|
185
|
+
def SingleEvent(self,plot_and_print=True):
|
172
186
|
"""
|
173
187
|
Simulate a single synaptic event by delivering an input stimulus to the synapse.
|
174
188
|
|
@@ -176,33 +190,30 @@ class SynapseTuner:
|
|
176
190
|
and then runs the NEURON simulation for a single event. The single synaptic event will occur at general_settings['tstart']
|
177
191
|
Will display graphs and synaptic properies works best with a jupyter notebook
|
178
192
|
"""
|
179
|
-
self.
|
180
|
-
self._set_up_synapse()
|
193
|
+
self.ispk = None
|
181
194
|
|
182
195
|
# user slider values if the sliders are set up
|
183
196
|
if hasattr(self, 'dynamic_sliders'):
|
184
197
|
syn_props = {var: slider.value for var, slider in self.dynamic_sliders.items()}
|
185
198
|
self._set_syn_prop(**syn_props)
|
199
|
+
|
200
|
+
# sets values based off optimizer
|
201
|
+
if hasattr(self,'using_optimizer'):
|
202
|
+
for name, value in zip(self.param_names, self.params):
|
203
|
+
setattr(self.syn, name, value)
|
186
204
|
|
187
205
|
# Set up the stimulus
|
188
|
-
self.nstim = h.NetStim()
|
189
206
|
self.nstim.start = self.general_settings['tstart']
|
190
207
|
self.nstim.noise = 0
|
191
|
-
self.nstim2 = h.NetStim()
|
192
208
|
self.nstim2.start = h.tstop
|
193
209
|
self.nstim2.noise = 0
|
194
|
-
self.nc = h.NetCon(self.nstim, self.syn, self.general_settings['threshold'], self.general_settings['delay'], self.general_settings['weight'])
|
195
|
-
self.nc2 = h.NetCon(self.nstim2, self.syn, self.general_settings['threshold'], self.general_settings['delay'], self.general_settings['weight'])
|
196
210
|
|
197
211
|
# Set up voltage clamp
|
198
|
-
self.vcl = h.VClamp(self.cell.soma[0](0.5))
|
199
212
|
vcldur = [[0, 0, 0], [self.general_settings['tstart'], h.tstop, 1e9]]
|
200
213
|
for i in range(3):
|
201
214
|
self.vcl.amp[i] = self.conn['spec_settings']['vclamp_amp']
|
202
215
|
self.vcl.dur[i] = vcldur[1][i]
|
203
216
|
|
204
|
-
self._set_up_recorders()
|
205
|
-
|
206
217
|
# Run simulation
|
207
218
|
h.tstop = self.general_settings['tstart'] + self.general_settings['tdur']
|
208
219
|
self.nstim.interval = self.general_settings['tdur']
|
@@ -211,15 +222,18 @@ class SynapseTuner:
|
|
211
222
|
h.run()
|
212
223
|
|
213
224
|
current = np.array(self.rec_vectors[self.current_name])
|
214
|
-
|
215
|
-
current = (current -
|
225
|
+
syn_props = self._get_syn_prop(rise_interval=self.general_settings['rise_interval'],dt=h.dt)
|
226
|
+
current = (current - syn_props['baseline']) * 1000 # Convert to pA
|
216
227
|
current_integral = np.trapz(current, dx=h.dt) # pA·ms
|
217
228
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
229
|
+
if plot_and_print:
|
230
|
+
self._plot_model([self.general_settings['tstart'] - 5, self.general_settings['tstart'] + self.general_settings['tdur']])
|
231
|
+
for prop in syn_props.items():
|
232
|
+
print(prop)
|
233
|
+
print(f'Current Integral in pA*ms: {current_integral:.2f}')
|
234
|
+
|
235
|
+
self.rise_time = syn_props['rise_time']
|
236
|
+
self.decay_time = syn_props['decay_time']
|
223
237
|
|
224
238
|
|
225
239
|
def _find_first(self, x):
|
@@ -263,7 +277,7 @@ class SynapseTuner:
|
|
263
277
|
if self.vclamp:
|
264
278
|
isyn = self.ivcl
|
265
279
|
else:
|
266
|
-
isyn = self.rec_vectors[
|
280
|
+
isyn = self.rec_vectors[self.current_name]
|
267
281
|
isyn = np.asarray(isyn)
|
268
282
|
tspk = np.asarray(self.tspk)
|
269
283
|
if tspk.size:
|
@@ -336,7 +350,7 @@ class SynapseTuner:
|
|
336
350
|
|
337
351
|
# Plot synaptic current (always included)
|
338
352
|
current = self.rec_vectors[self.current_name]
|
339
|
-
syn_prop = self._get_syn_prop(short=True)
|
353
|
+
syn_prop = self._get_syn_prop(short=True,dt=h.dt)
|
340
354
|
current = (current - syn_prop['baseline'])
|
341
355
|
current = current * 1000
|
342
356
|
|
@@ -433,13 +447,12 @@ class SynapseTuner:
|
|
433
447
|
"""
|
434
448
|
isyn = np.array(self.rec_vectors[self.current_name].to_python())
|
435
449
|
tspk = np.append(np.asarray(self.tspk), h.tstop)
|
436
|
-
syn_prop = self._get_syn_prop(short=True)
|
450
|
+
syn_prop = self._get_syn_prop(short=True,dt=h.dt)
|
437
451
|
# print("syn_prp[sign] = " + str(syn_prop['sign']))
|
438
452
|
isyn = (isyn - syn_prop['baseline'])
|
439
453
|
isyn *= syn_prop['sign']
|
440
454
|
ispk = np.floor((tspk + self.general_settings['delay']) / h.dt).astype(int)
|
441
455
|
|
442
|
-
|
443
456
|
try:
|
444
457
|
amp = [isyn[ispk[i]:ispk[i + 1]].max() for i in range(ispk.size - 1)]
|
445
458
|
# indexs of where the max of the synaptic current is at. This is then plotted
|
@@ -687,6 +700,7 @@ class SynapseTuner:
|
|
687
700
|
display(ui)
|
688
701
|
update_ui()
|
689
702
|
|
703
|
+
|
690
704
|
def stp_frequency_response(self, freqs=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 35, 50, 100, 200],
|
691
705
|
delay=250, plot=True,log_plot=True):
|
692
706
|
"""
|
@@ -733,6 +747,7 @@ class SynapseTuner:
|
|
733
747
|
|
734
748
|
return results
|
735
749
|
|
750
|
+
|
736
751
|
def _plot_frequency_analysis(self, results,log_plot):
|
737
752
|
"""
|
738
753
|
Plot the frequency-dependent synaptic properties.
|
@@ -928,15 +943,33 @@ class SynapseOptimizer:
|
|
928
943
|
|
929
944
|
def _calculate_metrics(self) -> Dict[str, float]:
|
930
945
|
"""Calculate standard metrics from the current simulation using specified frequency"""
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
946
|
+
|
947
|
+
# Set these to 0 for when we return the dict
|
948
|
+
induction = 0
|
949
|
+
ppr = 0
|
950
|
+
recovery = 0
|
951
|
+
amp = 0
|
952
|
+
rise_time = 0
|
953
|
+
decay_time = 0
|
954
|
+
|
955
|
+
if self.run_single_event:
|
956
|
+
self.tuner.SingleEvent(plot_and_print=False)
|
957
|
+
rise_time = self.tuner.rise_time
|
958
|
+
decay_time = self.tuner.decay_time
|
959
|
+
|
960
|
+
if self.run_train_input:
|
961
|
+
self.tuner._simulate_model(self.train_frequency, self.train_delay)
|
962
|
+
amp = self.tuner._response_amplitude()
|
963
|
+
ppr, induction, recovery = self.tuner._calc_ppr_induction_recovery(amp, print_math=False)
|
964
|
+
amp = self.tuner._find_max_amp(amp)
|
965
|
+
|
935
966
|
return {
|
936
967
|
'induction': float(induction),
|
937
968
|
'ppr': float(ppr),
|
938
969
|
'recovery': float(recovery),
|
939
|
-
'max_amplitude': float(amp)
|
970
|
+
'max_amplitude': float(amp),
|
971
|
+
'rise_time': float(rise_time),
|
972
|
+
'decay_time': float(decay_time)
|
940
973
|
}
|
941
974
|
|
942
975
|
def _default_cost_function(self, metrics: Dict[str, float], target_metrics: Dict[str, float]) -> float:
|
@@ -957,7 +990,13 @@ class SynapseOptimizer:
|
|
957
990
|
# Set parameters
|
958
991
|
for name, value in zip(param_names, params):
|
959
992
|
setattr(self.tuner.syn, name, value)
|
960
|
-
|
993
|
+
|
994
|
+
# just do this and have the SingleEvent handle it
|
995
|
+
if self.run_single_event:
|
996
|
+
self.tuner.using_optimizer = True
|
997
|
+
self.tuner.param_names = param_names
|
998
|
+
self.tuner.params = params
|
999
|
+
|
961
1000
|
# Calculate metrics and error
|
962
1001
|
metrics = self._calculate_metrics()
|
963
1002
|
error = float(cost_function(metrics, target_metrics)) # Ensure error is scalar
|
@@ -974,6 +1013,7 @@ class SynapseOptimizer:
|
|
974
1013
|
|
975
1014
|
def optimize_parameters(self, target_metrics: Dict[str, float],
|
976
1015
|
param_bounds: Dict[str, Tuple[float, float]],
|
1016
|
+
run_single_event:bool = False, run_train_input:bool = True,
|
977
1017
|
train_frequency: float = 50,train_delay: float = 250,
|
978
1018
|
cost_function: Optional[Callable] = None,
|
979
1019
|
method: str = 'SLSQP',init_guess='random') -> SynapseOptimizationResult:
|
@@ -1005,6 +1045,8 @@ class SynapseOptimizer:
|
|
1005
1045
|
self.optimization_history = []
|
1006
1046
|
self.train_frequency = train_frequency
|
1007
1047
|
self.train_delay = train_delay
|
1048
|
+
self.run_single_event = run_single_event
|
1049
|
+
self.run_train_input = run_train_input
|
1008
1050
|
|
1009
1051
|
param_names = list(param_bounds.keys())
|
1010
1052
|
bounds = [param_bounds[name] for name in param_names]
|
@@ -1107,10 +1149,14 @@ class SynapseOptimizer:
|
|
1107
1149
|
print(f"{param}: {float(value):.3f}")
|
1108
1150
|
|
1109
1151
|
# Plot final model response
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1152
|
+
if self.run_train_input:
|
1153
|
+
self.tuner._plot_model([self.tuner.general_settings['tstart'] - self.tuner.nstim.interval / 3, self.tuner.tstop])
|
1154
|
+
amp = self.tuner._response_amplitude()
|
1155
|
+
self.tuner._calc_ppr_induction_recovery(amp)
|
1156
|
+
if self.run_single_event:
|
1157
|
+
self.tuner.ispk=None
|
1158
|
+
self.tuner.SingleEvent(plot_and_print=True)
|
1159
|
+
|
1114
1160
|
|
1115
1161
|
# dataclass means just init the typehints as self.typehint. looks a bit cleaner
|
1116
1162
|
@dataclass
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|