bmtool 0.6.6.1__py3-none-any.whl → 0.6.6.3__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/synapses.py CHANGED
@@ -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._set_up_cell()
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
- syn_prop = self._get_syn_prop(short=True)
215
- current = (current - syn_prop['baseline']) * 1000 # Convert to pA
225
+ syn_props = self._get_syn_prop(rise_interval=self.general_settings['rise_interval'])
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
- self._plot_model([self.general_settings['tstart'] - 5, self.general_settings['tstart'] + self.general_settings['tdur']])
219
- syn_props = self._get_syn_prop(rise_interval=self.general_settings['rise_interval'])
220
- for prop in syn_props.items():
221
- print(prop)
222
- print(f'Current Integral in pA: {current_integral:.2f}')
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):
@@ -687,8 +701,9 @@ class SynapseTuner:
687
701
  display(ui)
688
702
  update_ui()
689
703
 
690
- def analyze_frequency_response(self, freqs=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 35, 50, 100, 200],
691
- delay=250, plot=True):
704
+
705
+ def stp_frequency_response(self, freqs=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 35, 50, 100, 200],
706
+ delay=250, plot=True,log_plot=True):
692
707
  """
693
708
  Analyze synaptic response across different stimulation frequencies.
694
709
 
@@ -729,11 +744,12 @@ class SynapseTuner:
729
744
  self.ispk = original_ispk
730
745
 
731
746
  if plot:
732
- self._plot_frequency_analysis(results)
747
+ self._plot_frequency_analysis(results,log_plot=log_plot)
733
748
 
734
749
  return results
735
750
 
736
- def _plot_frequency_analysis(self, results):
751
+
752
+ def _plot_frequency_analysis(self, results,log_plot):
737
753
  """
738
754
  Plot the frequency-dependent synaptic properties.
739
755
 
@@ -744,11 +760,12 @@ class SynapseTuner:
744
760
  """
745
761
  fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
746
762
 
747
- # Convert frequencies to log scale for better visualization
748
- frequencies = np.array(results['frequencies'])
749
763
 
750
764
  # Plot PPR
751
- ax1.semilogx(frequencies, results['ppr'], 'o-')
765
+ if log_plot:
766
+ ax1.semilogx(results['frequencies'], results['ppr'], 'o-')
767
+ else:
768
+ ax1.plot(results['frequencies'], results['ppr'], 'o-')
752
769
  ax1.axhline(y=1, color='gray', linestyle='--', alpha=0.5)
753
770
  ax1.set_xlabel('Frequency (Hz)')
754
771
  ax1.set_ylabel('Paired Pulse Ratio')
@@ -756,7 +773,10 @@ class SynapseTuner:
756
773
  ax1.grid(True)
757
774
 
758
775
  # Plot Induction
759
- ax2.semilogx(frequencies, results['induction'], 'o-')
776
+ if log_plot:
777
+ ax2.semilogx(results['frequencies'], results['induction'], 'o-')
778
+ else:
779
+ ax2.plot(results['frequencies'], results['induction'], 'o-')
760
780
  ax2.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
761
781
  ax2.set_xlabel('Frequency (Hz)')
762
782
  ax2.set_ylabel('Induction')
@@ -764,7 +784,10 @@ class SynapseTuner:
764
784
  ax2.grid(True)
765
785
 
766
786
  # Plot Recovery
767
- ax3.semilogx(frequencies, results['recovery'], 'o-')
787
+ if log_plot:
788
+ ax3.semilogx(results['frequencies'], results['recovery'], 'o-')
789
+ else:
790
+ ax3.plot(results['frequencies'], results['recovery'], 'o-')
768
791
  ax3.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
769
792
  ax3.set_xlabel('Frequency (Hz)')
770
793
  ax3.set_ylabel('Recovery')
@@ -921,15 +944,33 @@ class SynapseOptimizer:
921
944
 
922
945
  def _calculate_metrics(self) -> Dict[str, float]:
923
946
  """Calculate standard metrics from the current simulation using specified frequency"""
924
- self.tuner._simulate_model(self.train_frequency, self.train_delay)
925
- amp = self.tuner._response_amplitude()
926
- ppr, induction, recovery = self.tuner._calc_ppr_induction_recovery(amp, print_math=False)
927
- amp = self.tuner._find_max_amp(amp)
947
+
948
+ # Set these to 0 for when we return the dict
949
+ induction = 0
950
+ ppr = 0
951
+ recovery = 0
952
+ amp = 0
953
+ rise_time = 0
954
+ decay_time = 0
955
+
956
+ if self.run_single_event:
957
+ self.tuner.SingleEvent(plot_and_print=False)
958
+ rise_time = self.tuner.rise_time
959
+ decay_time = self.tuner.decay_time
960
+
961
+ if self.run_train_input:
962
+ self.tuner._simulate_model(self.train_frequency, self.train_delay)
963
+ amp = self.tuner._response_amplitude()
964
+ ppr, induction, recovery = self.tuner._calc_ppr_induction_recovery(amp, print_math=False)
965
+ amp = self.tuner._find_max_amp(amp)
966
+
928
967
  return {
929
968
  'induction': float(induction),
930
969
  'ppr': float(ppr),
931
970
  'recovery': float(recovery),
932
- 'max_amplitude': float(amp)
971
+ 'max_amplitude': float(amp),
972
+ 'rise_time': float(rise_time),
973
+ 'decay_time': float(decay_time)
933
974
  }
934
975
 
935
976
  def _default_cost_function(self, metrics: Dict[str, float], target_metrics: Dict[str, float]) -> float:
@@ -950,7 +991,13 @@ class SynapseOptimizer:
950
991
  # Set parameters
951
992
  for name, value in zip(param_names, params):
952
993
  setattr(self.tuner.syn, name, value)
953
-
994
+
995
+ # just do this and have the SingleEvent handle it
996
+ if self.run_single_event:
997
+ self.tuner.using_optimizer = True
998
+ self.tuner.param_names = param_names
999
+ self.tuner.params = params
1000
+
954
1001
  # Calculate metrics and error
955
1002
  metrics = self._calculate_metrics()
956
1003
  error = float(cost_function(metrics, target_metrics)) # Ensure error is scalar
@@ -967,6 +1014,7 @@ class SynapseOptimizer:
967
1014
 
968
1015
  def optimize_parameters(self, target_metrics: Dict[str, float],
969
1016
  param_bounds: Dict[str, Tuple[float, float]],
1017
+ run_single_event:bool = False, run_train_input:bool = True,
970
1018
  train_frequency: float = 50,train_delay: float = 250,
971
1019
  cost_function: Optional[Callable] = None,
972
1020
  method: str = 'SLSQP',init_guess='random') -> SynapseOptimizationResult:
@@ -998,6 +1046,8 @@ class SynapseOptimizer:
998
1046
  self.optimization_history = []
999
1047
  self.train_frequency = train_frequency
1000
1048
  self.train_delay = train_delay
1049
+ self.run_single_event = run_single_event
1050
+ self.run_train_input = run_train_input
1001
1051
 
1002
1052
  param_names = list(param_bounds.keys())
1003
1053
  bounds = [param_bounds[name] for name in param_names]
@@ -1100,9 +1150,14 @@ class SynapseOptimizer:
1100
1150
  print(f"{param}: {float(value):.3f}")
1101
1151
 
1102
1152
  # Plot final model response
1103
- self.tuner._plot_model([self.tuner.general_settings['tstart'] - self.tuner.nstim.interval / 3, self.tuner.tstop])
1104
- amp = self.tuner._response_amplitude()
1105
- self.tuner._calc_ppr_induction_recovery(amp)
1153
+ if self.run_train_input:
1154
+ self.tuner._plot_model([self.tuner.general_settings['tstart'] - self.tuner.nstim.interval / 3, self.tuner.tstop])
1155
+ amp = self.tuner._response_amplitude()
1156
+ self.tuner._calc_ppr_induction_recovery(amp)
1157
+ if self.run_single_event:
1158
+ self.tuner.ispk=None
1159
+ self.tuner.SingleEvent(plot_and_print=True)
1160
+
1106
1161
 
1107
1162
 
1108
1163
  # dataclass means just init the typehints as self.typehint. looks a bit cleaner
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: bmtool
3
- Version: 0.6.6.1
3
+ Version: 0.6.6.3
4
4
  Summary: BMTool
5
5
  Home-page: https://github.com/cyneuro/bmtool
6
6
  Download-URL:
@@ -7,7 +7,7 @@ bmtool/graphs.py,sha256=K8BiughRUeXFVvAgo8UzrwpSClIVg7UfmIcvtEsEsk0,6020
7
7
  bmtool/manage.py,sha256=_lCU0qBQZ4jSxjzAJUd09JEetb--cud7KZgxQFbLGSY,657
8
8
  bmtool/plot_commands.py,sha256=Tqujyf0c0u8olhiHOMwgUSJXIIE1hgjv6otb25G9cA0,12298
9
9
  bmtool/singlecell.py,sha256=MQiLucsI6OBIjtcJra3Z9PTFQOE-Zn5ST-R9SmFvrbQ,27049
10
- bmtool/synapses.py,sha256=HlAKDlXTDkth6sb8pvgX2k8kOOm9wNXiaCC80RCyOdE,52600
10
+ bmtool/synapses.py,sha256=qxUMeFIUJZweWhYsb24DL5cra9pbzCG61ZL0Rqc3B-8,54535
11
11
  bmtool/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  bmtool/debug/commands.py,sha256=AwtcR7BUUheM0NxvU1Nu234zCdpobhJv5noX8x5K2vY,583
13
13
  bmtool/debug/debug.py,sha256=xqnkzLiH3s-tS26Y5lZZL62qR2evJdi46Gud-HzxEN4,207
@@ -16,9 +16,9 @@ bmtool/util/commands.py,sha256=zJF-fiLk0b8LyzHDfvewUyS7iumOxVnj33IkJDzux4M,64396
16
16
  bmtool/util/util.py,sha256=00vOAwTVIifCqouBoFoT0lBashl4fCalrk8fhg_Uq4c,56654
17
17
  bmtool/util/neuron/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  bmtool/util/neuron/celltuner.py,sha256=xSRpRN6DhPFz4q5buq_W8UmsD7BbUrkzYBEbKVloYss,87194
19
- bmtool-0.6.6.1.dist-info/LICENSE,sha256=qrXg2jj6kz5d0EnN11hllcQt2fcWVNumx0xNbV05nyM,1068
20
- bmtool-0.6.6.1.dist-info/METADATA,sha256=f0-Qyi2oYMIthCUzvo0b2uiMsF9kUISI10p84dthBa0,20226
21
- bmtool-0.6.6.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
22
- bmtool-0.6.6.1.dist-info/entry_points.txt,sha256=0-BHZ6nUnh0twWw9SXNTiRmKjDnb1VO2DfG_-oprhAc,45
23
- bmtool-0.6.6.1.dist-info/top_level.txt,sha256=gpd2Sj-L9tWbuJEd5E8C8S8XkNm5yUE76klUYcM-eWM,7
24
- bmtool-0.6.6.1.dist-info/RECORD,,
19
+ bmtool-0.6.6.3.dist-info/LICENSE,sha256=qrXg2jj6kz5d0EnN11hllcQt2fcWVNumx0xNbV05nyM,1068
20
+ bmtool-0.6.6.3.dist-info/METADATA,sha256=a4htvjbNJxU3YSs5pGZxezk-v6kDgHnyPODs2H3l8V4,20226
21
+ bmtool-0.6.6.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
22
+ bmtool-0.6.6.3.dist-info/entry_points.txt,sha256=0-BHZ6nUnh0twWw9SXNTiRmKjDnb1VO2DfG_-oprhAc,45
23
+ bmtool-0.6.6.3.dist-info/top_level.txt,sha256=gpd2Sj-L9tWbuJEd5E8C8S8XkNm5yUE76klUYcM-eWM,7
24
+ bmtool-0.6.6.3.dist-info/RECORD,,