bmtool 0.7.4.1__py3-none-any.whl → 0.7.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/synapses.py CHANGED
@@ -113,12 +113,20 @@ class SynapseTuner:
113
113
  else:
114
114
  # Merge defaults with user-provided
115
115
  self.general_settings = {**DEFAULT_GENERAL_SETTINGS, **general_settings}
116
+
117
+ # Store the initial connection name and set up connection
118
+ self.current_connection = connection
116
119
  self.conn = self.conn_type_settings[connection]
120
+ self._current_cell_type = self.conn["spec_settings"]["post_cell"]
117
121
  self.synaptic_props = self.conn["spec_syn_param"]
118
122
  self.vclamp = self.general_settings["vclamp"]
119
123
  self.current_name = current_name
120
124
  self.other_vars_to_record = other_vars_to_record or []
121
125
  self.ispk = None
126
+ self.input_mode = False # Add input_mode attribute
127
+
128
+ # Store original slider_vars for connection switching
129
+ self.original_slider_vars = slider_vars or list(self.synaptic_props.keys())
122
130
 
123
131
  if slider_vars:
124
132
  # Start by filtering based on keys in slider_vars
@@ -174,6 +182,90 @@ class SynapseTuner:
174
182
 
175
183
  self._set_up_recorders()
176
184
 
185
+ def _switch_connection(self, new_connection: str) -> None:
186
+ """
187
+ Switch to a different connection type and update all related properties.
188
+
189
+ Parameters:
190
+ -----------
191
+ new_connection : str
192
+ Name of the new connection type to switch to.
193
+ """
194
+ if new_connection not in self.conn_type_settings:
195
+ raise ValueError(f"Connection '{new_connection}' not found in conn_type_settings.")
196
+
197
+ # Update current connection
198
+ self.current_connection = new_connection
199
+ self.conn = self.conn_type_settings[new_connection]
200
+ self.synaptic_props = self.conn["spec_syn_param"]
201
+
202
+ # Update slider vars for new connection
203
+ if hasattr(self, 'original_slider_vars'):
204
+ # Filter slider vars based on new connection's parameters
205
+ self.slider_vars = {
206
+ key: value for key, value in self.synaptic_props.items()
207
+ if key in self.original_slider_vars
208
+ }
209
+
210
+ # Check for missing keys and try to get them from the synapse
211
+ for key in self.original_slider_vars:
212
+ if key not in self.synaptic_props:
213
+ try:
214
+ # We'll get this after recreating the synapse
215
+ pass
216
+ except AttributeError as e:
217
+ print(f"Warning: Could not access '{key}' for connection '{new_connection}': {e}")
218
+ else:
219
+ self.slider_vars = self.synaptic_props
220
+
221
+ # Need to recreate the cell if it's different
222
+ if self.hoc_cell is None:
223
+ # Check if we need a different cell type
224
+ new_cell_type = self.conn["spec_settings"]["post_cell"]
225
+ if not hasattr(self, '_current_cell_type') or self._current_cell_type != new_cell_type:
226
+ self._current_cell_type = new_cell_type
227
+ self._set_up_cell()
228
+
229
+ # Recreate synapse for new connection
230
+ self._set_up_synapse()
231
+
232
+ # Update any missing slider vars from the new synapse
233
+ if hasattr(self, 'original_slider_vars'):
234
+ for key in self.original_slider_vars:
235
+ if key not in self.synaptic_props:
236
+ try:
237
+ value = getattr(self.syn, key)
238
+ self.slider_vars[key] = value
239
+ except AttributeError as e:
240
+ print(f"Warning: Could not access '{key}' for connection '{new_connection}': {e}")
241
+
242
+ # Recreate NetCon connections with new synapse
243
+ self.nc = h.NetCon(
244
+ self.nstim,
245
+ self.syn,
246
+ self.general_settings["threshold"],
247
+ self.general_settings["delay"],
248
+ self.general_settings["weight"],
249
+ )
250
+ self.nc2 = h.NetCon(
251
+ self.nstim2,
252
+ self.syn,
253
+ self.general_settings["threshold"],
254
+ self.general_settings["delay"],
255
+ self.general_settings["weight"],
256
+ )
257
+
258
+ # Recreate voltage clamp with potentially new cell
259
+ self.vcl = h.VClamp(self.cell.soma[0](0.5))
260
+
261
+ # Recreate recorders for new synapse
262
+ self._set_up_recorders()
263
+
264
+ # Reset NEURON state
265
+ h.finitialize()
266
+
267
+ print(f"Successfully switched to connection: {new_connection}")
268
+
177
269
  def _update_spec_syn_param(self, json_folder_path: str) -> None:
178
270
  """
179
271
  Update specific synaptic parameters using JSON files located in the specified folder.
@@ -741,6 +833,7 @@ class SynapseTuner:
741
833
  Sets up interactive sliders for tuning short-term plasticity (STP) parameters in a Jupyter Notebook.
742
834
 
743
835
  This method creates an interactive UI with sliders for:
836
+ - Connection type selection dropdown
744
837
  - Input frequency
745
838
  - Delay between pulse trains
746
839
  - Duration of stimulation (for continuous input mode)
@@ -766,6 +859,15 @@ class SynapseTuner:
766
859
  duration0 = 300
767
860
  vlamp_status = self.vclamp
768
861
 
862
+ # Connection dropdown
863
+ connection_options = list(self.conn_type_settings.keys())
864
+ w_connection = widgets.Dropdown(
865
+ options=connection_options,
866
+ value=self.current_connection,
867
+ description="Connection:",
868
+ style={'description_width': 'initial'}
869
+ )
870
+
769
871
  w_run = widgets.Button(description="Run Train", icon="history", button_style="primary")
770
872
  w_single = widgets.Button(description="Single Event", icon="check", button_style="success")
771
873
  w_vclamp = widgets.ToggleButton(
@@ -785,28 +887,33 @@ class SynapseTuner:
785
887
  options=durations, value=duration0, description="Duration"
786
888
  )
787
889
 
890
+ def create_dynamic_sliders():
891
+ """Create sliders based on current connection's parameters"""
892
+ sliders = {}
893
+ for key, value in self.slider_vars.items():
894
+ if isinstance(value, (int, float)): # Only create sliders for numeric values
895
+ if hasattr(self.syn, key):
896
+ if value == 0:
897
+ print(
898
+ f"{key} was set to zero, going to try to set a range of values, try settings the {key} to a nonzero value if you dont like the range!"
899
+ )
900
+ slider = widgets.FloatSlider(
901
+ value=value, min=0, max=1000, step=1, description=key
902
+ )
903
+ else:
904
+ slider = widgets.FloatSlider(
905
+ value=value, min=0, max=value * 20, step=value / 5, description=key
906
+ )
907
+ sliders[key] = slider
908
+ else:
909
+ print(f"skipping slider for {key} due to not being a synaptic variable")
910
+ return sliders
911
+
788
912
  # Generate sliders dynamically based on valid numeric entries in self.slider_vars
789
- self.dynamic_sliders = {}
913
+ self.dynamic_sliders = create_dynamic_sliders()
790
914
  print(
791
915
  "Setting up slider! The sliders ranges are set by their init value so try changing that if you dont like the slider range!"
792
916
  )
793
- for key, value in self.slider_vars.items():
794
- if isinstance(value, (int, float)): # Only create sliders for numeric values
795
- if hasattr(self.syn, key):
796
- if value == 0:
797
- print(
798
- f"{key} was set to zero, going to try to set a range of values, try settings the {key} to a nonzero value if you dont like the range!"
799
- )
800
- slider = widgets.FloatSlider(
801
- value=value, min=0, max=1000, step=1, description=key
802
- )
803
- else:
804
- slider = widgets.FloatSlider(
805
- value=value, min=0, max=value * 20, step=value / 5, description=key
806
- )
807
- self.dynamic_sliders[key] = slider
808
- else:
809
- print(f"skipping slider for {key} due to not being a synaptic variable")
810
917
 
811
918
  def run_single_event(*args):
812
919
  clear_output()
@@ -816,6 +923,46 @@ class SynapseTuner:
816
923
  self.ispk = None
817
924
  self.SingleEvent()
818
925
 
926
+ def on_connection_change(*args):
927
+ """Handle connection dropdown change"""
928
+ try:
929
+ new_connection = w_connection.value
930
+ if new_connection != self.current_connection:
931
+ # Switch to new connection
932
+ self._switch_connection(new_connection)
933
+
934
+ # Recreate dynamic sliders for new connection
935
+ self.dynamic_sliders = create_dynamic_sliders()
936
+
937
+ # Update UI
938
+ update_ui_layout()
939
+ update_ui()
940
+
941
+ except Exception as e:
942
+ print(f"Error switching connection: {e}")
943
+
944
+ def update_ui_layout():
945
+ """Update the UI layout with new sliders"""
946
+ nonlocal ui, slider_columns
947
+
948
+ # Add the dynamic sliders to the UI
949
+ slider_widgets = [slider for slider in self.dynamic_sliders.values()]
950
+
951
+ if slider_widgets:
952
+ half = len(slider_widgets) // 2
953
+ col1 = VBox(slider_widgets[:half])
954
+ col2 = VBox(slider_widgets[half:])
955
+ slider_columns = HBox([col1, col2])
956
+ else:
957
+ slider_columns = VBox([])
958
+
959
+ # Reconstruct the UI
960
+ connection_row = HBox([w_connection])
961
+ button_row = HBox([w_run, w_single, w_vclamp, w_input_mode])
962
+ slider_row = HBox([w_input_freq, self.w_delay, self.w_duration])
963
+
964
+ ui = VBox([connection_row, button_row, slider_row, slider_columns])
965
+
819
966
  # Function to update UI based on input mode
820
967
  def update_ui(*args):
821
968
  clear_output()
@@ -843,7 +990,8 @@ class SynapseTuner:
843
990
  self.w_delay.layout.display = "" # Show delay slider
844
991
  self.w_duration.layout.display = "none" # Hide duration slider
845
992
 
846
- # Link input mode to slider switch
993
+ # Link widgets to their callback functions
994
+ w_connection.observe(on_connection_change, names="value")
847
995
  w_input_mode.observe(switch_slider, names="value")
848
996
 
849
997
  # Hide the duration slider initially until the user selects it
@@ -852,18 +1000,10 @@ class SynapseTuner:
852
1000
  w_single.on_click(run_single_event)
853
1001
  w_run.on_click(update_ui)
854
1002
 
855
- # Add the dynamic sliders to the UI
856
- slider_widgets = [slider for slider in self.dynamic_sliders.values()]
857
-
858
- button_row = HBox([w_run, w_single, w_vclamp, w_input_mode])
859
- slider_row = HBox([w_input_freq, self.w_delay, self.w_duration])
860
-
861
- half = len(slider_widgets) // 2
862
- col1 = VBox(slider_widgets[:half])
863
- col2 = VBox(slider_widgets[half:])
864
- slider_columns = HBox([col1, col2])
865
-
866
- ui = VBox([button_row, slider_row, slider_columns])
1003
+ # Initial UI setup
1004
+ slider_columns = VBox([])
1005
+ ui = VBox([])
1006
+ update_ui_layout()
867
1007
 
868
1008
  display(ui)
869
1009
  update_ui()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bmtool
3
- Version: 0.7.4.1
3
+ Version: 0.7.5
4
4
  Summary: BMTool
5
5
  Home-page: https://github.com/cyneuro/bmtool
6
6
  Download-URL:
@@ -6,7 +6,7 @@ bmtool/graphs.py,sha256=gBTzI6c2BBK49dWGcfWh9c56TAooyn-KaiEy0Im1HcI,6717
6
6
  bmtool/manage.py,sha256=lsgRejp02P-x6QpA7SXcyXdalPhRmypoviIA2uAitQs,608
7
7
  bmtool/plot_commands.py,sha256=Dxm_RaT4CtHnfsltTtUopJ4KVbfhxtktEB_b7bFEXII,12716
8
8
  bmtool/singlecell.py,sha256=I2yolbAnNC8qpnRkNdnDCLidNW7CktmBuRrcowMZJ3A,45041
9
- bmtool/synapses.py,sha256=Ayz4swAx0gNG-KtsCDJn3XJ7vw-qDuvSHy6xeIzd9ok,69697
9
+ bmtool/synapses.py,sha256=Yg0JOXT7zUvvoeAOkEvA4RBcwRkIvoROsUTvRkP00fw,75453
10
10
  bmtool/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  bmtool/analysis/entrainment.py,sha256=NQloQtVpEWjDzmkZwMWVcm3hSjErHBZfQl1mrBVoIE8,25321
12
12
  bmtool/analysis/lfp.py,sha256=S2JvxkjcK3-EH93wCrhqNSFY6cX7fOq74pz64ibHKrc,26556
@@ -26,9 +26,9 @@ bmtool/util/commands.py,sha256=Nn-R-4e9g8ZhSPZvTkr38xeKRPfEMANB9Lugppj82UI,68564
26
26
  bmtool/util/util.py,sha256=TAWdGd0tDuouS-JiusMs8WwP7kQpWHPr1nu0XG01TBQ,75056
27
27
  bmtool/util/neuron/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  bmtool/util/neuron/celltuner.py,sha256=lokRLUM1rsdSYBYrNbLBBo39j14mm8TBNVNRnSlhHCk,94868
29
- bmtool-0.7.4.1.dist-info/licenses/LICENSE,sha256=qrXg2jj6kz5d0EnN11hllcQt2fcWVNumx0xNbV05nyM,1068
30
- bmtool-0.7.4.1.dist-info/METADATA,sha256=TKDtODjH25ZRw2vYbHZWER_RuoAkIOEA3G2Hhpz6PHc,3597
31
- bmtool-0.7.4.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
32
- bmtool-0.7.4.1.dist-info/entry_points.txt,sha256=0-BHZ6nUnh0twWw9SXNTiRmKjDnb1VO2DfG_-oprhAc,45
33
- bmtool-0.7.4.1.dist-info/top_level.txt,sha256=gpd2Sj-L9tWbuJEd5E8C8S8XkNm5yUE76klUYcM-eWM,7
34
- bmtool-0.7.4.1.dist-info/RECORD,,
29
+ bmtool-0.7.5.dist-info/licenses/LICENSE,sha256=qrXg2jj6kz5d0EnN11hllcQt2fcWVNumx0xNbV05nyM,1068
30
+ bmtool-0.7.5.dist-info/METADATA,sha256=2KlbH04Q4LTGqmoMHqPFRPRHXPhfVBypKt4LIjGRUQ0,3595
31
+ bmtool-0.7.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
32
+ bmtool-0.7.5.dist-info/entry_points.txt,sha256=0-BHZ6nUnh0twWw9SXNTiRmKjDnb1VO2DfG_-oprhAc,45
33
+ bmtool-0.7.5.dist-info/top_level.txt,sha256=gpd2Sj-L9tWbuJEd5E8C8S8XkNm5yUE76klUYcM-eWM,7
34
+ bmtool-0.7.5.dist-info/RECORD,,