OSCR

Clustered inputs engage dendritic nonlinearities and calcium signaling to support efficient place-field formation in CA1 pyramidal neurons.

Code ↔ Paper

22 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 22 matches
  1. [1] § STAR★METHODS › METHOD DETAILS › Inhibitory inputs ↔ Code_data_generation/Cluster_cells_validation_protocols.py, lines 769–832 · score 0.85 · hippocampal network, PVbasket, Ivy cells, 2.8 Hz, transmission, neurogliaform
  2. [2] § STAR★METHODS › METHOD DETAILS › Inhibitory inputs ↔ Code_data_generation/Cluster_make_connectivity.py, lines 393–435 · score 0.80 · hippocampal network, PVbasket, Ivy cells, neurogliaform, parvalbumin, NGF
  3. [3] § STAR★METHODS › METHOD DETAILS › Grid-like and place-like inputs structure ↔ Make_input/Cluster_make_grid_like_inputs.py, lines 148–233 · score 0.79 · 30–40 Hz, place field location, theta phase, tref, CA3, EC
  4. [4] § STAR★METHODS › METHOD DETAILS › Pyramidal neuron model validation ↔ Code_data_generation/Cluster_cells_validation_protocols.py, lines 317–398 · score 0.79 · voltage attenuation, passive properties, pyramidal neurons, Rin, validated, curve
  5. [5] § STAR★METHODS › METHOD DETAILS › Input distribution ↔ Code_data_generation/Cluster_make_connectivity_higher_w_infield.py, lines 130–253 · score 0.77 · chosen place field, probability distribution, clustered synapses, bias, place tuned, cumulative
  6. [6] § STAR★METHODS › METHOD DETAILS › Inhibitory inputs ↔ Make_input/poisson_input.py, lines 417–522 · score 0.76 · filtered Poisson distributed, theta cycle, theta modulated, spike trains, firing rates, phase
  7. [7] § STAR★METHODS › QUANTIFICATION AND STATISTICAL ANALYSIS › Multivariate random forest ↔ Code_data_generation/Code_data_analysis/Analysis_synapse_distribution_ML.py, lines 462–545 · score 0.76 · Min Max Scaler, Random Forest regression, predict, trained, model, protocols
  8. [8] § STAR★METHODS › METHOD DETAILS › Inhibitory inputs ↔ Make_input/poisson_input_interneurons.py, lines 41–124 · score 0.75 · theta cycle, theta modulated, Poisson distributed, spike trains, firing rates, interneuron
  9. [9] § RESULTS › Functional role of input clustering in place cell computation ↔ Figure_6.py, lines 65–106 · score 0.74 · pairwise Mann Whitney, Benjamini Hochberg, Kruskal Wallis, FDR, Figure 6
  10. [10] § RESULTS › Synaptic clustering amplifies dendritic gain and sustains calcium influx under noisy input regimes ↔ Figure_4.py, lines 383–398 · score 0.72 · dendritic firing rates, dendritic spiking, somatic spiking, dendritic activity, activated synapses, Figure 4
  11. [11] § RESULTS › From reconstruction of synaptic distribution to modeling of neuronal functional properties ↔ Code_data_generation/Cluster_cells_validation_protocols.py, lines 769–832 · score 0.69 · PVbasket, Ivy cells, neurogliaform, parvalbumin, NGF, Bistratified
  12. [12] § STAR★METHODS › QUANTIFICATION AND STATISTICAL ANALYSIS › Place cell quantification ↔ Code_data_generation/Code_data_analysis/place_cell_metrics.py, lines 225–294 · score 0.69 · linear track, firing rate maps, field Firing, Place Field, metric, peak
  13. [13] § STAR★METHODS › METHOD DETAILS › Somato-dendritic parameter distributions ↔ Code_data_generation/Cluster_cells_validation_protocols.py, lines 317–398 · score 0.68 · CA1 pyramidal neurons, passive properties, integration properties, uniformly, apical, location
  14. [14] § RESULTS › From reconstruction of synaptic distribution to modeling of neuronal functional properties ↔ Code_data_generation/Cluster_make_connectivity.py, lines 393–435 · score 0.67 · PVbasket, Ivy cells, neurogliaform, parvalbumin, NGF, Bistratified
  15. [15] § STAR★METHODS › METHOD DETAILS › Inputs design ↔ Make_input/poisson_input.py, lines 417–522 · score 0.64 · Gaussian filtered Poisson, Poisson distributed, spike trains, firing rate, peak, noise
  16. [16] § RESULTS › Dendritic subdomain-specific strategies differentially shape spatial tuning ↔ Code_data_generation/Code_data_analysis/Analysis_synapse_distribution_ML.py, lines 462–545 · score 0.62 · squared error, random forest, RF, MSE, regression, predict
  17. [17] § RESULTS › Dendritic subdomain-specific strategies differentially shape spatial tuning ↔ Figure_7.py, lines 39–124 · score 0.59 · squared error, random forest, RF, MSE, variable, Figure 7
  18. [18] § STAR★METHODS › METHOD DETAILS › Input distribution ↔ Figure_5.py, lines 317–340 · score 0.55 · PV basket, CCK, Bistratified, Bezaire, apical, probabilities
  19. [19] § RESULTS › Synaptic clustering amplifies dendritic gain and sustains calcium influx under noisy input regimes ↔ Figure_4.py, lines 419–434 · score 0.52 · NMDA charge, NMDA spike, activated synapses, CI, Figure 4, shuffled
  20. [20] § RESULTS › From reconstruction of synaptic distribution to modeling of neuronal functional properties ↔ Figure_3.py, lines 285–332 · score 0.52 · Passive properties, sag ratio, resistance, models, Figure 3
  21. [21] § RESULTS › Domain-specific analysis of synaptic organization in CA1 PNs ↔ Code_data_generation/Code_data_analysis/Analysis_synapse_distribution_ML.py, lines 230–319 · score 0.51 · density distribution, co tuned, uniformly, subdomains, shuffling, volume
  22. [22] § RESULTS › From reconstruction of synaptic distribution to modeling of neuronal functional properties ↔ Figure_5.py, lines 224–272 · score 0.50 · excitatory theta oscillation, spike trains, interneuron, activity, Figure 5

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 1,224 lines · 51 KB · GPL-3.0 · 4 matches

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Tue Apr 23 11:39:07 2024
  4. @author: simon
  5. """
  6. from neuron import h
  7. from neuron.units import mV, ms
  8. from Class_CA1_Pyr_standardized import Cell
  9. import numpy as np
  10. import pickle
  11. import pandas as pd
  12. import os, sys
  13. import random
  14. from functools import wraps
  15. import pathlib
  16. # Get the path of the current script
  17. base_path = pathlib.Path().resolve().parent
  18. h.load_file("stdgui.hoc")
  19. h.load_file('stdlib.hoc') #mknrndll on anaconda prompt to compile the mod files
  20. h.load_file("stdrun.hoc")
  21. h.load_file('import3d.hoc')
  22. protocols = ['negative_current_soma', 'negative_current_dend',
  23. 'negative_current_cesium_bath_soma', 'negative_current_cesium_bath_dend',
  24. 'positive_current_soma', 'positive_current_dend', 'excitatory_synaptic_validation',
  25. 'NMDA_AMPA_ratio', 'inhibitory_synaptic_validation']
  26. protocol = protocols[0] #protocols[int(sys.argv[1])] #Use sys.argv to input parameters externally and loop through all protocols
  27. high_segmentation = True
  28. path = str(base_path / "Morphologies\\SWCs")+"\\"
  29. names = ["E_6_15_", "E_6_14_", "E_3_6_", "E_3_7_", "E_9_11_"]
  30. name = names[0] #names[int(sys.argv[2])] #Use sys.argv to input parameters externally and loop through all cells
  31. if protocol == 'dendritic_nonlinearity':
  32. hh_switch = False
  33. else:
  34. hh_switch = True
  35. ###################################################################################################################
  36. # F U N C T I O N D E F I N I T I O N
  37. ###################################################################################################################
  38. def find_closest_values(pd_serie, target_value):
  39. """
  40. pd_serie: pd.Series or a column of a dataframe.
  41. target_value: int or float that you want to find in the pd.Series/column.
  42. """
  43. idx = (pd_serie - target_value).abs().idxmin()
  44. return pd_serie.loc[idx]
  45. def input_resistance_calculation(voltage, time, stim_onset, stim_duration, inj_current):
  46. """
  47. voltage: np.array of the voltage trace
  48. time: np.array of the simulation time
  49. stim_onset: int when the stimulation starts
  50. stim_duration: int the duration of the current injection stim
  51. inj_current: amplitude of the injected current in nA
  52. """
  53. indx_v0 = np.abs(time - (stim_onset)).argmin()
  54. v0 = voltage[indx_v0]
  55. indx_v_max = np.abs(time - (stim_onset + stim_duration)).argmin()
  56. v_max= voltage[indx_v_max]
  57. R_Input= (np.abs((v_max-v0)))/np.abs(inj_current)
  58. return R_Input
  59. def sag_ratio_and_tau_calc(voltage, time, stim_onset, stim_duration, after_stim_duration, inj_current):
  60. """
  61. voltage: np.array of the voltage trace
  62. time: np.array of the simulation time
  63. stim_onset: int when the stimulation starts
  64. stim_duration: int the duration of the current injection stim
  65. after_stim_duration: int the duration of the simulation after the stimulus ends
  66. inj_current: amplitude of the injected current in nA
  67. """
  68. indx_v0 = np.abs(time - (stim_onset)).argmin()
  69. v0 = voltage[indx_v0]
  70. indx_v_max = np.abs(time - (stim_onset + stim_duration)).argmin()
  71. v_max= voltage[indx_v_max]
  72. v_peak = np.amax(np.abs(voltage))
  73. sag_ratio = (v_peak-np.abs(v_max))/(v_peak-np.abs(v0))
  74. v_decrease = abs(voltage[indx_v_max:])
  75. Diff_v = v_decrease-abs(voltage[np.abs(time - (stim_onset + stim_duration +
  76. after_stim_duration-1)).argmin()])
  77. Normalized_v = Diff_v/max(Diff_v)
  78. Calc_tau= time[indx_v_max + np.argmin(abs(Normalized_v-(1/np.e)))] - time[indx_v_max]
  79. return sag_ratio, Calc_tau
  80. def tau_rise_decay_calc(voltage, time, spike_onset, delay):
  81. """
  82. voltage: np.array of the voltage trace
  83. time: np.array of the simulation time
  84. stim_onset: int when the stimulation starts
  85. delay: delay of synaptic current from actual spiketime in ms
  86. """
  87. indx_v0 = np.abs(time - (spike_onset + delay)).argmin()
  88. v_psp = np.abs(voltage[indx_v0:] - voltage[indx_v0])
  89. time_psp = np.abs(time[indx_v0:] - time[indx_v0])
  90. indx_psp_peak = np.abs(v_psp).argmax()
  91. v_peak = v_psp[indx_psp_peak]
  92. v_decrease = v_psp[indx_psp_peak:]
  93. t_decrease = time_psp[indx_psp_peak:]
  94. Normalized_v_decrease = v_decrease/v_peak
  95. tau_decay = t_decrease[np.argmin(abs(Normalized_v_decrease-(1/np.e)))] - t_decrease[0]
  96. v_increase = v_psp[:indx_psp_peak]
  97. t_increase = time_psp[:indx_psp_peak]
  98. Normalized_v_increase = v_increase/v_peak
  99. tau_rise = t_increase[np.argmin(abs(Normalized_v_increase-0.9))] - t_increase[
  100. np.argmin(abs(Normalized_v_increase-0.1))]
  101. return tau_rise, tau_decay
  102. def timeit(func):
  103. @wraps(func)
  104. def wrapper(*args, **kwargs):
  105. start = time.perf_counter()
  106. func(*args, **kwargs)
  107. end = time.perf_counter()
  108. print(f"Time {start - end} sec")
  109. return wrapper
  110. # @timeit
  111. # def func1():
  112. # time.sleep(1)
  113. def calculate_segment_indexes(num_segments):
  114. if num_segments == 1:
  115. return [0.5]
  116. initial_segs = []
  117. final_segs = []
  118. segment_length = 1 / (num_segments)
  119. for i in range(int((num_segments-1)/2)):
  120. ind = i+1
  121. initial_segs.append(0.5-(segment_length*ind))
  122. final_segs.append(0.5+(segment_length*ind))
  123. inverted_initial_segs = initial_segs[::-1]
  124. indexes = inverted_initial_segs + [0.5] + final_segs
  125. return indexes
  126. ###################################################################################################################
  127. # C E L L S E T U P
  128. ###################################################################################################################
  129. if high_segmentation:
  130. segmentation = 0.001
  131. else:
  132. segmentation = 0.1
  133. c = Cell(path, name + "smooth_smaller_diam",'swc', 0,
  134. d_lambda = segmentation)
  135. if 'cesium_bath' in protocol:
  136. c.cesium_bath_present = 0.2
  137. cesium_protocol = 'cesium'
  138. else:
  139. c.cesium_bath_present = 1
  140. cesium_protocol = 'control'
  141. axon_group = c.axon
  142. trunk_group = c.apic
  143. oblique_group = c.dend
  144. tuft_group = c.dend_5
  145. basal_group = c.dend_7
  146. if protocol == 'NMDA_AMPA_ratio':
  147. # Channels inhibition (switch to false relevant channels) #################################
  148. for segment in c.soma:
  149. c.channel_setup('soma', segment, c.soma[0](1), hha2=False, pas=True, h=False,
  150. kap=False, km=False, cal=False, kca=False, mykca=False, cat=False,
  151. somacar=False)
  152. for segment in axon_group:
  153. c.channel_setup('axon', segment, c.soma[0](0), hha2=False, pas=True,
  154. km=False)
  155. for segment in trunk_group:
  156. c.channel_setup('trunk', segment, c.soma[0](1), hha_old=False, pas=True,
  157. h=False, kap=False, kad=False, km=False, cal=False, calH=False,
  158. car=False, kca=False, mykca=False, cat=False)
  159. for segment in oblique_group:
  160. c.channel_setup('oblique', segment, c.soma[0](1), hha_old=False, pas=True,
  161. h=False, kap=False, kad=False, km=False, calH=False, car=False, kca=False,
  162. mykca=False, cat=False, nap=False)
  163. for segment in tuft_group:
  164. c.channel_setup('tuft', segment, c.soma[0](1), hha_old=False, pas=True,
  165. h=False, kap=False, kad=False, km=False, calH=False, car=False, kca=False,
  166. mykca=False, cat=False, nap=False)
  167. for segment in basal_group:
  168. c.channel_setup('basal', segment, c.soma[0](1), hha2=False, pas=True,
  169. h=False, kap=False, kad=False)
  170. cyt, ca, cad = c.setup_molecules(c.all, cainf=5e-5, tau_ca=200, dCa=0.6)
  171. else:
  172. for segment in c.soma:
  173. c.channel_setup('soma', segment, c.soma[0](1), hha2=hh_switch, pas=True, h=True,
  174. kap=True, km=True, cal=True, kca=True, mykca=True, cat=True,
  175. somacar=True)
  176. for segment in axon_group:
  177. c.channel_setup('axon', segment, c.soma[0](0), hha2=hh_switch, pas=True,
  178. km=True)
  179. for segment in trunk_group:
  180. c.channel_setup('trunk', segment, c.soma[0](1), hha_old=True, pas=True,
  181. h=True, kap=True, kad=True, km=True, cal=True, calH=True,
  182. car=True, kca=True, mykca=True, cat=True)
  183. for segment in oblique_group:
  184. c.channel_setup('oblique', segment, c.soma[0](1), hha_old=True, pas=True,
  185. h=True, kap=True, kad=True, km=True, calH=True, car=True, kca=True,
  186. mykca=True, cat=True, nap=True)
  187. for segment in tuft_group:
  188. c.channel_setup('tuft', segment, c.soma[0](1), hha_old=True, pas=True,
  189. h=True, kap=True, kad=True, km=True, calH=True, car=True, kca=True,
  190. mykca=True, cat=True, nap=True)
  191. for segment in basal_group:
  192. c.channel_setup('basal', segment, c.soma[0](1), hha2=True, pas=True,
  193. h=True, kap=True, kad=True)
  194. cyt, ca, cad = c.setup_molecules(c.all, cainf=5e-5, tau_ca=200, dCa=0.6)
  195. ###################################################################################################################
  196. # M O N I T O R S
  197. ###################################################################################################################
  198. number_of_segments = 0
  199. cell_segment_names = {}
  200. for pp in c.all:
  201. cell_segment_names[f"{pp}"] = pp
  202. for segment_b in pp:
  203. number_of_segments += 1
  204. compartments = {}
  205. compartments_list = []
  206. comp_distances = np.zeros(len(c.all))
  207. for i, sec in enumerate(c.all):
  208. compartments[f"volt_{i}"] = h.Vector().record(sec(0.5)._ref_v)
  209. compartments[f"compartment_{i}"] = str(sec)
  210. compartments_list.append(sec)
  211. comp_distances[i] = c.fromtodistance(c.soma[0](1), sec(0.5))
  212. domain_list = [
  213. 'Trunk' if 'apic' in str(sec)
  214. else 'Basal' if 'dend_7' in str(sec)
  215. else 'Oblique' if 'dend[' in str(sec)
  216. else 'Tuft' if 'dend_5' in str(sec)
  217. else 'Soma' if 'soma' in str(sec)
  218. else 'Axon'
  219. for sec in c.all
  220. ]
  221. comp_df = pd.DataFrame(comp_distances, columns=['comp_distances'])
  222. comp_df['domain_list'] = domain_list
  223. apic_distances = np.zeros(len(c.apic))
  224. for i, el in enumerate(c.apic):
  225. distance = c.fromtodistance(c.soma[0](1), el(0.5))
  226. apic_distances[i] = distance
  227. index_238_apic = np.argmin(np.abs(apic_distances-238))
  228. voltage_238_apic = h.Vector().record(c.apic[index_238_apic](0.5)._ref_v)
  229. index_169_apic = np.argmin(np.abs(apic_distances-169))
  230. voltage_169_apic = h.Vector().record(c.apic[index_169_apic](0.5)._ref_v)
  231. index_30_apic = np.argmin(np.abs(apic_distances-30))
  232. voltage_soma = h.Vector().record(c.soma[0](0.5)._ref_v)
  233. time_ = h.Vector().record(h._ref_t)
  234. ###################################################################################################################
  235. # P R O T O C O L S
  236. ###################################################################################################################
  237. stim_onset = 300*ms
  238. stim_duration = 1000*ms
  239. after_stim_duration = 300*ms
  240. exp_R_input = 60 #Mohm From Magee (1998)
  241. ########################### NEGATIVE CURRENT ####################################################################
  242. if 'negative_current' in protocol:
  243. '''
  244. Postsynaptic integrative properties of dorsal CA1 pyramidal neuron subpopulations. Masurkar JNphys 2020.
  245. - Resting membrane potential was measured on break-in. The remaining measurements
  246. - were made after 2–5 min following break-in while the cell was maintained at −70 mV.
  247. - Input resistance Rin was measured by [...] −10-pA current injection.
  248. Arithmetic of Subthreshold Synaptic Summation in a Model CA1 Pyramidal Cell. Poirazi Neuron 2003
  249. - somatic and dendritic current injections, under control conditions (−200 pA,
  250. - solid curves) and with bath application of 3 mM Cs+ (−100 pA, dashed curves),
  251. - which we assumed blocked 80% of Ih. [...] current injections either at the
  252. - soma or 325 μm away in the main apical trunk.
  253. Factors mediating powerful voltage attenuation along CA1 pyramidal neuron dendrites. Golding J Physiol 2005
  254. -Figure 2, around 50% of attenuation at 238um distance from the soma.
  255. -The parameters that contribute to the high attenuation are: internal resistivity (high); non-uniform
  256. membrane resistivity (high in the soma, low in distal dendrites); non-uniform h conductance
  257. (low in the soma, high in distal dendrites).
  258. To verify the passive properties, run the simulations with the four combinations of
  259. stimulus location (comment/uncomment below) and cesium_bath presence (Ture/False above).
  260. After producing the four files, run the visualization code.
  261. '''
  262. if '_soma' in protocol:
  263. stim_location = 'Somatic_injection'
  264. I_negative_range = [-0.01, -0.2]
  265. elif '_dend' in protocol:
  266. stim_location = 'Dendritic_injection'
  267. I_negative_range = [-0.2]
  268. DATA = {}
  269. iclamps = []
  270. for i, I_negative in enumerate (I_negative_range):
  271. #Current injection
  272. if stim_location == 'Dendritic_injection':
  273. iclamps.append(h.IClamp(c.apic[index_238_apic](0.5)))
  274. else:
  275. iclamps.append(h.IClamp(c.soma[0](0.5)))
  276. iclamps[-1].delay = stim_onset
  277. iclamps[-1].dur = stim_duration
  278. iclamps[-1].amp = I_negative
  279. h.finitialize(c.v_init)
  280. h.fcurrent()
  281. h.continuerun(stim_onset + stim_duration + after_stim_duration)
  282. v_soma = np.array(voltage_soma)
  283. v_apic_238 = np.array(voltage_238_apic)
  284. time = np.array(time_)
  285. DATA[f'Voltage_soma_{I_negative}_{stim_location}'] = v_soma
  286. DATA[f'Voltage_apical_{I_negative}_{stim_location}'] = v_apic_238
  287. DATA[f'Time_{I_negative}_{stim_location}'] = time
  288. DATA[f'Compartments_{I_negative}_{stim_location}'] = compartments
  289. DATA["Inj_current_range"] = I_negative_range
  290. DATA["stim_onset"] = stim_onset
  291. DATA["stim_duration"] = stim_duration
  292. DATA["after_stim_duration"] = after_stim_duration
  293. DATA["comp_df"] = comp_df
  294. saving_path = str(base_path / f"Protocol_results\\Cell_validation\\{name}validation")
  295. if not os.path.exists(saving_path):
  296. os.makedirs(saving_path)
  297. with open(f"{saving_path}/{name}negative_current_{stim_location}_{cesium_protocol}.pkl", "wb") as file:
  298. pickle.dump(DATA, file, protocol=pickle.HIGHEST_PROTOCOL)
  299. comp_df.to_csv(r''+saving_path+'/'+name+'comp_df.txt', header=None, index=None, sep=' ', mode='a')
  300. ########################### POSITIVE CURRENT ####################################################################
  301. if 'positive_current' in protocol:
  302. '''
  303. Postsynaptic integrative properties of dorsal CA1 pyramidal neuron subpopulations. Masurkar JNphys 2020.
  304. - Firing frequency-input current (F-I) curves for each of these neurons [...] were produced
  305. by giving a range of current injections from 100 to 350 pA.
  306. '''
  307. DATA = {}
  308. if '_soma' in protocol:
  309. stim_location = 'Somatic_injection'
  310. I_positive_range = [0.02, 0.04, 0.06, 0.08, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5]
  311. elif '_dend' in protocol:
  312. stim_location = 'Dendritic_injection'
  313. I_positive_range = [-0.2, 0.2, 0.3, 0.4, 0.5, 0.8]
  314. for I_positive in I_positive_range:
  315. if stim_location == 'Somatic_injection':
  316. iclamps = h.IClamp(c.soma[0](0.5))
  317. else:
  318. iclamps = h.IClamp(c.apic[index_169_apic](0.5))
  319. iclamps.delay = stim_onset
  320. iclamps.dur = stim_duration
  321. iclamps.amp = I_positive
  322. h.finitialize(c.v_init)
  323. h.fcurrent()
  324. h.continuerun(stim_onset + stim_duration + after_stim_duration)
  325. v_soma = np.array(voltage_soma)
  326. v_apic_169 = np.array(voltage_169_apic)
  327. time = np.array(time_)
  328. DATA[f'Voltage_soma_{I_positive}'] = v_soma
  329. DATA[f'Voltage_apical_{I_positive}'] = v_apic_169
  330. DATA[f'Time_{I_positive}'] = time
  331. DATA[f'Compartments_{I_positive}'] = compartments
  332. DATA["Inj_current_range"] = I_positive_range
  333. DATA["stim_onset"] = stim_onset
  334. DATA["stim_duration"] = stim_duration
  335. DATA["after_stim_duration"] = after_stim_duration
  336. saving_path = str(base_path / f"Protocol_results/Cell_validation/{name}validation")
  337. if not os.path.exists(saving_path):
  338. os.makedirs(saving_path)
  339. with open(f"{saving_path}/{name}positive_current_{stim_location}.pkl", "wb") as file:
  340. pickle.dump(DATA, file, protocol=pickle.HIGHEST_PROTOCOL)
  341. ########################### EXCITATORY SYNAPSES VALIDATION ####################################################################
  342. if 'excitatory_synaptic_validation' in protocol:
  343. '''
  344. For apical inputs (Trunk, Schaffer collaterals), from "Somatic EPSP amplitude is independent of synapse
  345. location in hippocampal pyramidal neurons", Magee Narure Neuro 2000.
  346. - "EPSPs recorded simultaneously at the soma exhibited an average amplitude that was virtually independent of
  347. synapse location (Fig. 1e; ∼0.2 mV from 50 to 325 μm [...])"
  348. - "Somatic EPSP rise times show a more pronounced location dependence than do somatic EPSP decay times".
  349. Rise time goes from around 1ms from 100um syn activation to 2.5ms from 300um.
  350. Decay time goes from 20ms to 25ms in the same distance range.
  351. Basal inputs are inferred to have similar properties.
  352. '''
  353. compartments = {} #to remove not needed recordings for this validation protocol
  354. stim_duration = 0
  355. DATA = {}
  356. domains = ["Trunk_stimulation", "Basal_stimulation"] #
  357. input_distances = np.arange(50, 301, 25)
  358. # Synapse details
  359. volume_scaling = 1 #(synapse_list['Spine_Volume'][i]/e_syn_volume_average) * 0.6 + 0.4
  360. for stim_domain in domains:
  361. for distance in input_distances:
  362. # Create empty list for preallocation.
  363. syns, netcons = [], []
  364. inputs, vecstims = [], []
  365. if stim_domain == 'Trunk_stimulation':
  366. domain = c.apic
  367. elif stim_domain == 'Basal_stimulation':
  368. domain = c.dend_7
  369. if distance >= 200:
  370. # print('Skip distance for basal')
  371. continue
  372. sec_distances = []
  373. sections = []
  374. for i, el in enumerate(domain):
  375. for selected_section in el:
  376. distance_section = c.fromtodistance(c.soma[0](1), selected_section)
  377. sec_distances.append(distance_section)
  378. sections.append(selected_section)
  379. index_section = np.argmin(np.abs(np.array(sec_distances)-int(np.random.choice(
  380. np.arange(distance-5,distance+5),1))))
  381. # print('Synapse section', sections[index_section], 'distant', c.fromtodistance(
  382. # c.soma[0](1), sections[index_section]),'um from the soma')
  383. voltage_section = h.Vector().record(sections[index_section]._ref_v)
  384. syns.append(h.AmpaNmda(sections[index_section])) # add a synapse to the closest segment to the node that holds the synapse
  385. syns[-1].gamma_mg = 0.12
  386. syns[-1].eta_mg = 0.28011
  387. syns[-1].mg2o = 1.2
  388. syns[-1].half_mg =2.5 #4
  389. if stim_domain == 'Trunk_stimulation':
  390. #Setting AMPA conductance
  391. syns[-1].tau1_ampa = 0.61 # rise time
  392. syns[-1].tau2_ampa = 4.5 # decay time #??? Increasing AMPA with the distance causes a shortening of the decay time with the distance. Not biologically relevant!
  393. syns[-1].eampa = 0.0 # reversal potential NMDA
  394. syns[-1].gbar_ampa = (0.17e-3 * volume_scaling) + (distance * 3e-7)
  395. #Setting NMDA conductance
  396. syns[-1].tau1_nmda = 0.4 # rise time
  397. syns[-1].tau2_nmda = 43.0 # decay time
  398. syns[-1].enmda = 0.0 # reversal potential NMDA
  399. syns[-1].gbar_nmda = (0.50e-3 + (distance * 1.0e-6))
  400. elif stim_domain == 'Basal_stimulation':
  401. #Setting AMPA conductance
  402. syns[-1].tau1_ampa = 0.61 # rise time
  403. syns[-1].tau2_ampa = 4.5 # decay time
  404. syns[-1].eampa = 0.0 # reversal potential NMDA
  405. syns[-1].gbar_ampa = (0.14e-3 * volume_scaling) + (distance * 1.2e-7)
  406. #Setting NMDA conductance
  407. syns[-1].tau1_nmda = 14 # rise time
  408. syns[-1].tau2_nmda = 43.0 # decay time
  409. syns[-1].enmda = 0.0 # reversal potential NMDA
  410. syns[-1].gbar_nmda = (0.36e-3 + (distance * 1.0e-6))
  411. spiketimes = [stim_onset]
  412. inputs.append(h.Vector(spiketimes))
  413. vecstims.append(h.VecStim())
  414. vecstims[-1].play(inputs[-1]) # add the last created inputs to the last created VecStim
  415. pre_synaptic_input = vecstims[-1]
  416. netcons.append(h.NetCon(pre_synaptic_input, syns[-1]))
  417. netcons[-1].delay = 2.0 # delay in ms
  418. ampa_current = h.Vector().record(syns[-1]._ref_iampa)
  419. nmda_current = h.Vector().record(syns[-1]._ref_inmda)
  420. h.finitialize(c.v_init)
  421. h.fcurrent()
  422. h.continuerun(stim_onset + stim_duration + after_stim_duration)
  423. time = np.array(time_)
  424. v_soma = np.array(voltage_soma)
  425. v_section = np.array(voltage_section)
  426. DATA[f'Voltage_soma_{stim_domain}_{distance}um'] = v_soma
  427. DATA[f'Voltage_section_{stim_domain}_{distance}um'] = v_section
  428. DATA[f'Time_{stim_domain}_{distance}um'] = time
  429. DATA[f'Real_distance_{stim_domain}_{distance}um'] = c.fromtodistance(c.soma[0](1), sections[index_section])
  430. DATA["input_distances"] = input_distances
  431. DATA["domains"] = domains
  432. DATA["stim_onset"] = stim_onset
  433. DATA["stim_duration"] = stim_duration
  434. DATA["after_stim_duration"] = after_stim_duration
  435. saving_path = str(base_path / f"Protocol_results/Cell_validation/{name}validation")
  436. if not os.path.exists(saving_path):
  437. os.makedirs(saving_path)
  438. with open(f"{saving_path}/{name}syn_validation_amplitude_kinetic.pkl", "wb") as file:
  439. pickle.dump(DATA, file, protocol=pickle.HIGHEST_PROTOCOL)
  440. ########################### NMDA/AMPA RATIO ####################################################################
  441. if 'NMDA_AMPA_ratio' in protocol:
  442. '''
  443. NMDA/AMPA for Perforant Pathway synapses (on tuft) and Shaffer collaterals (on trunk)
  444. from "Pathway-Specific Properties of AMPA and NMDA-Mediated Transmission in CA1
  445. Hippocampal Pyramidal Cells", Otmakhova et al., 2002 J Neurosci.
  446. - The intracellular solution contained Cs+ to block most K+ channels and QX-314 to
  447. block Na+ channels, Ih channels, G-protein-coupled K+ (GABAB) channels and Ca2+
  448. currents (partially). Voltage clamp at -20 mV.
  449. - The NMDA/AMPA ratio was determined as the control area minus APV (NMDA antagonist)
  450. area, all divided by APV area (Fig. 4C, PP (8.6 +/- 0.8), SC input (5.3 +/- 0.9;)).
  451. - Basals inferred to be the same as the trunk.
  452. '''
  453. compartments = {} #to remove not needed recordings for this validation protocol
  454. stim_duration = 0
  455. DATA = {}
  456. domains = ["Trunk_stimulation", "Tuft_stimulation", "Basal_stimulation"]
  457. samples_n = 5
  458. nmda_inhibition = [True, False]
  459. # Synapse details
  460. volume_scaling = 1 #(synapse_list['Spine_Volume'][i]/e_syn_volume_average) * 0.6 + 0.4
  461. for stim_domain in domains:
  462. for samples in range(samples_n):
  463. if stim_domain == 'Trunk_stimulation':
  464. domain = c.apic
  465. elif stim_domain == 'Tuft_stimulation':
  466. domain = c.dend_5
  467. elif stim_domain == 'Basal_stimulation':
  468. domain = c.dend_7
  469. stimulated_branch = random.choice([branch for branch in domain])
  470. voltage_section = h.Vector().record(stimulated_branch(0.5)._ref_v)
  471. for nmda_inh in nmda_inhibition:
  472. if nmda_inh:
  473. APV = 0
  474. else:
  475. APV = 1
  476. # Create empty list for preallocation.
  477. syns, netcons = [], []
  478. inputs, vecstims = [], []
  479. syns.append(h.AmpaNmda(stimulated_branch(0.5)))
  480. syn_distance = c.fromtodistance(c.soma[0](1), stimulated_branch(0.5))
  481. if stim_domain == 'Trunk_stimulation':
  482. #Setting AMPA conductance
  483. syns[-1].tau1_ampa = 0.61 # rise time
  484. syns[-1].tau2_ampa = 4.5 # decay time
  485. syns[-1].eampa = 0.0 # reversal potential NMDA
  486. syns[-1].gbar_ampa = (0.17e-3 * volume_scaling) + (distance * 3e-7)
  487. #Setting NMDA conductance
  488. syns[-1].tau1_nmda = 14 # rise time
  489. syns[-1].tau2_nmda = 43.0 # decay time
  490. syns[-1].enmda = 0.0 # reversal potential NMDA
  491. syns[-1].gbar_nmda = APV * (0.50e-3 + (distance * 1.0e-6))
  492. elif stim_domain == 'Tuft_stimulation':
  493. #Setting AMPA conductance
  494. syns[-1].tau1_ampa = 0.61 # rise time
  495. syns[-1].tau2_ampa = 4.5 # decay time
  496. syns[-1].eampa = 0.0 # reversal potential NMDA
  497. syns[-1].gbar_ampa = 0.17e-3 * volume_scaling
  498. #Setting NMDA conductance
  499. syns[-1].tau1_nmda = 14 # rise time
  500. syns[-1].tau2_nmda = 43.0 # decay time
  501. syns[-1].enmda = 0.0 # reversal potential NMDA
  502. syns[-1].gbar_nmda = APV * 0.75e-3
  503. elif stim_domain == 'Basal_stimulation':
  504. #Setting AMPA conductance
  505. syns[-1].tau1_ampa = 0.61 # rise time
  506. syns[-1].tau2_ampa = 4.5 # decay time
  507. syns[-1].eampa = 0.0 # reversal potential NMDA
  508. syns[-1].gbar_ampa = (0.18e-3 * volume_scaling) + (distance * 1.2e-7)
  509. #Setting NMDA conductance
  510. syns[-1].tau1_nmda = 14 # rise time
  511. syns[-1].tau2_nmda = 43.0 # decay time
  512. syns[-1].enmda = 0.0 # reversal potential NMDA
  513. syns[-1].gbar_nmda = APV * (0.44e-3 + (distance * 1.0e-6))
  514. # Voltage clamp at -20 to reproduce experimental condition
  515. clampobj = h.SEClamp(c.soma[0](0.5))
  516. clampobj.dur1 = stim_onset + stim_duration + after_stim_duration
  517. clampobj.amp1 = -20
  518. clampobj.rs = 5
  519. clamp_current = h.Vector().record(clampobj._ref_i)
  520. spiketimes = [stim_onset]
  521. inputs.append(h.Vector(spiketimes))
  522. vecstims.append(h.VecStim())
  523. vecstims[-1].play(inputs[-1]) # add the last created inputs to the last created VecStim
  524. pre_synaptic_input = vecstims[-1]
  525. netcons.append(h.NetCon(pre_synaptic_input, syns[-1]))
  526. netcons[-1].delay = 2.0 # delay in ms
  527. ampa_current = h.Vector().record(syns[-1]._ref_iampa)
  528. nmda_current = h.Vector().record(syns[-1]._ref_inmda)
  529. h.finitialize(c.v_init)
  530. h.fcurrent()
  531. h.continuerun(stim_onset + stim_duration + after_stim_duration)
  532. time = np.array(time_)
  533. v_soma = np.array(voltage_soma)
  534. v_section = np.array(voltage_section)
  535. DATA[f'Voltage_soma_{stim_domain}_sample{samples}_{APV}'] = v_soma
  536. DATA[f'Voltage_section_{stim_domain}_sample{samples}_{APV}'] = v_section
  537. DATA[f'Time_{stim_domain}_sample{samples}_{APV}'] = time
  538. DATA["nmda_inhibition"] = nmda_inhibition
  539. DATA["domains"] = domains
  540. DATA["samples_n"] = samples_n
  541. DATA["stim_onset"] = stim_onset
  542. DATA["stim_duration"] = stim_duration
  543. DATA["after_stim_duration"] = after_stim_duration
  544. saving_path = str(base_path / f"Protocol_results/Cell_validation/{name}validation")
  545. if not os.path.exists(saving_path):
  546. os.makedirs(saving_path)
  547. with open(f"{saving_path}/{name}syn_validation_NMDA_AMPA_ratio.pkl", "wb") as file:
  548. pickle.dump(DATA, file, protocol=pickle.HIGHEST_PROTOCOL)
  549. ########################### INHIBITORY SYNAPSES VALIDATION ####################################################################
  550. if 'inhibitory_synaptic_validation' in protocol:
  551. '''
  552. - NGF: uIPSC average 4.9 pA current recorded in the soma after clamping at -50mV from
  553. "GABAB Receptor Modulation of Feedforward Inhibition through Hippocampal Neurogliaform
  554. Cells" T. Price 2008 JoN. (Voltage clamped at -62mV in model to stay below threshold,
  555. validated to ≈ half amplitude) Decay includes the GABAb component. Kinetics (rise time:
  556. 4.17 ± 0.24 ms; decay time: 36.5 ± 1.3 ms) from "Different transmitter transients
  557. underlie presynaptic cell type specificity of GABAA,slow and GABAA,fast" Szabadics
  558. et al 2007 PNAS
  559. - OLM: uIPSC average 2.6 pA current recorded in the soma after clamping at -70mV and
  560. kinetics (rise time: 6.2 ± 0.6 ms; decay time: 20.8 ± 1.7 ms) from "Cell surface
  561. domain specific postsynaptic currents evoked by identified GABAergic neurones in
  562. rat hippocampus in vitro" Maccaferri et al 2000 J. Physiol
  563. The actual amplitude in the paper is 26 pA but it would not make sense. The paper
  564. has been corrected but such correction is not available. Moreover, in "Dendritic
  565. inhibition mediated by O-LM and bistratified interneurons in the hippocampus"
  566. Müller et al Frontiers 2014 they cite Maccaferri claiming IPSC = 2.6 pA.
  567. - PVbasket: average 32.4 pA current (for superficialPC) recorded in the soma after
  568. clamping at -70mV with reversal at -26.3 from "Parvalbumin-Positive Basket
  569. Cells Differentiate Among Hippocampal Pyramidal Cells" Lee 2014 Neuron
  570. Kinetics (rise times: 0.53 ± 0.02 ms; decay time: 6.4 ± 0.33 ms, for fast
  571. spiking BC) from "Different transmitter transients underlie presynaptic cell
  572. type specificity of GABAA,slow and GABAA,fast" Szabadics et al 2007 PNAS
  573. - CCKbasket: average 42.9 pA current recorded in the soma after clamping at -70mV with
  574. reversal at -26.3 from "Parvalbumin-Positive Basket Cells Differentiate Among
  575. Hippocampal Pyramidal Cells" Lee 2014 Neuron
  576. Kinetics (rise times: 2.0 ± 0.8 ms; decay time: 8.15 ± 0.75 ms, average from
  577. two cases in TableS5) from "Ivy Cells: A Population of Nitric-Oxide-Producing,
  578. Slow-Spiking GABAergic Neurons and Their Involvement in Hippocampal Network
  579. Activity" P. Fuentealba 2008 Neuron
  580. - bistratified: average 0.8 mV current recorded in the soma after clamping at -50mV. Kinetics
  581. (rise times: 8.4 ± 3.2 ms; decay time: 42.1 ± 17.0 ms, average from two cases in
  582. Table2) from "Ivy Cells: A Population of Nitric-Oxide-Producing, Slow-Spiking
  583. GABAergic Neurons and Their Involvement in Hippocampal Network Activity" P. Fuentealba
  584. 2008 Neuron (Voltage clamped at -62mV in model to stay below threshold, validated to ≈
  585. half amplitude).
  586. - Ivy: average 8.0 pA current recorded in the soma after clamping at -50mV. Kinetics
  587. (rise times: 2.8 ± 0.2 ms; decay time: 16.05 ± 2.45 ms, average from two cases in
  588. TableS5) from "Ivy Cells: A Population of Nitric-Oxide-Producing, Slow-Spiking
  589. GABAergic Neurons and Their Involvement in Hippocampal Network Activity" P. Fuentealba
  590. 2008 Neuron (Voltage clamped at -62mV in model to stay below threshold, validated to
  591. ≈ half amplitude).
  592. '''
  593. stim_duration = 0
  594. DATA = {}
  595. presynaptic_interneurons = ["NGF", "OLM", "PVbasket", "CCKbasket", "bistratified", "Bistratified", "Ivy"]
  596. n_repetitions = 5
  597. for intern in presynaptic_interneurons:
  598. for n in range(n_repetitions):
  599. # Create empty list for preallocation.
  600. syns, netcons = [], []
  601. inputs, vecstims = [], []
  602. clampobj = []
  603. if intern == 'NGF':
  604. compartment_idx = random.choice(comp_df.loc[(comp_df['domain_list'] == 'Tuft')
  605. ].index)
  606. elif intern == 'OLM':
  607. compartment_idx = random.choice(comp_df.loc[(comp_df['domain_list'] == 'Tuft')
  608. ].index)
  609. elif intern == 'PVbasket':
  610. compartment_idx = random.choice(comp_df.loc[(comp_df['domain_list'] == 'Trunk') & (
  611. comp_df['comp_distances'] >= 80) & (comp_df['comp_distances'] <= 90)
  612. ].index)
  613. elif intern == 'CCKbasket':
  614. compartment_idx = random.choice(comp_df.loc[(comp_df['domain_list'] == 'Trunk') & (
  615. comp_df['comp_distances'] >= 150) & (comp_df['comp_distances'] <= 160)
  616. ].index)
  617. elif intern == 'bistratified':
  618. compartment_idx = random.choice(comp_df.loc[(comp_df['domain_list'] == 'Trunk') & (
  619. comp_df['comp_distances'] >= 95) & (comp_df['comp_distances'] <= 105)
  620. ].index)
  621. elif intern == 'Bistratified':
  622. compartment_idx = random.choice(comp_df.loc[(comp_df['domain_list'] == 'Trunk') & (
  623. comp_df['comp_distances'] >= 95) & (comp_df['comp_distances'] <= 105)
  624. ].index)
  625. elif intern == 'Ivy':
  626. compartment_idx = random.choice(comp_df.loc[(comp_df['domain_list'] == 'Basal') & (
  627. comp_df['comp_distances'] >= 85) & (comp_df['comp_distances'] <= 110)
  628. ].index)
  629. else:
  630. compartment_idx = random.choice(comp_df.loc[(comp_df['domain_list'] == 'Trunk') & (
  631. comp_df['comp_distances'] >= 95) & (comp_df['comp_distances'] <= 105)
  632. ].index)
  633. # print("Not a valid interneuron, using bistratified cells")
  634. stimulated_branch = compartments_list[compartment_idx]
  635. voltage_section = h.Vector().record(stimulated_branch(0.5)._ref_v)
  636. syn_distance = c.fromtodistance(c.soma[0](1), stimulated_branch(0.5))
  637. # print('Synapse section', stimulated_branch, 'distant', syn_distance,
  638. # 'um from the soma')
  639. syns.append(h.Exp2Syn(stimulated_branch(0.5)))
  640. if intern == 'NGF':
  641. syns[-1].tau1 = 1.17 # rise time
  642. syns[-1].tau2 = 36.5 # decay time #decay includes the GABAb component.
  643. syns[-1].e = -80 # reversal potential GABA #??? reverse potential should be -72mV for GABAa and -87mV for GABAb component. Since I cannot reproduce both components, I will set it in between the two.
  644. syn_weight = 0.6e-3
  645. clampobj.append(h.SEClamp(c.soma[0](0.5)))
  646. clampobj[-1].dur1 = stim_onset + stim_duration + after_stim_duration
  647. clampobj[-1].amp1 = -62
  648. clampobj[-1].rs = 5
  649. clamp_current = h.Vector().record(clampobj[-1]._ref_i)
  650. clamp_on = True
  651. elif intern == 'OLM':
  652. syns[-1].tau1 = 1. # rise time
  653. syns[-1].tau2 = 16. # decay time
  654. syns[-1].e = -80 # reversal potential GABA
  655. syn_weight = 0.62e-3
  656. clampobj.append(h.SEClamp(c.soma[0](0.5)))
  657. clampobj[-1].dur1 = stim_onset + stim_duration + after_stim_duration
  658. clampobj[-1].amp1 = -70
  659. clampobj[-1].rs = 5
  660. clamp_current = h.Vector().record(clampobj[-1]._ref_i)
  661. clamp_on = True
  662. elif intern == 'PVbasket':
  663. syns[-1].tau1 = 0.1 # rise time
  664. syns[-1].tau2 = 3.1 # decay time
  665. syns[-1].e = -26.3 # reversal potential GABA #??? high cloride in the pipet, they calculate this reversal
  666. syn_weight = 2.1e-3
  667. clampobj.append(h.SEClamp(c.soma[0](0.5)))
  668. clampobj[-1].dur1 = stim_onset + stim_duration + after_stim_duration
  669. clampobj[-1].amp1 = -70
  670. clampobj[-1].rs = 5
  671. clamp_current = h.Vector().record(clampobj[-1]._ref_i)
  672. clamp_on = True
  673. elif intern == 'CCKbasket':
  674. syns[-1].tau1 = 0.5 # rise time
  675. syns[-1].tau2 = 3. # decay time
  676. syns[-1].e = -26.3 # reversal potential GABA #??? high cloride in the pipet, they calculate this reversal
  677. syn_weight = 3.3e-3
  678. clampobj.append(h.SEClamp(c.soma[0](0.5)))
  679. clampobj[-1].dur1 = stim_onset + stim_duration + after_stim_duration
  680. clampobj[-1].amp1 = -70
  681. clampobj[-1].rs = 5
  682. clamp_current = h.Vector().record(clampobj[-1]._ref_i)
  683. clamp_on = True
  684. elif intern == 'bistratified':
  685. syns[-1].tau1 = 0.5 # rise time
  686. syns[-1].tau2 = 23.4 # decay time
  687. syns[-1].e = -80 # reversal potential GABA
  688. syn_weight = 3.5e-3 # Tuned in order to produce average 0.86 mV depolarization in the soma from "Dendritic inhibition mediated by O-LM and bistratified interneurons in the hippocampus" Muller 2014 FSN
  689. clamp_on = False
  690. elif intern == 'Bistratified':
  691. syns[-1].tau1 = 0.5 # rise time
  692. syns[-1].tau2 = 23.4 # decay time
  693. syns[-1].e = -80 # reversal potential GABA
  694. syn_weight = 3.5e-3 # Tuned in order to produce average 0.86 mV depolarization in the soma from "Dendritic inhibition mediated by O-LM and bistratified interneurons in the hippocampus" Muller 2014 FSN
  695. clampobj.append(h.SEClamp(c.soma[0](0.5)))
  696. clampobj[-1].dur1 = stim_onset + stim_duration + after_stim_duration
  697. clampobj[-1].amp1 = -70
  698. clampobj[-1].rs = 5
  699. clamp_current = h.Vector().record(clampobj[-1]._ref_i)
  700. clamp_on = True
  701. elif intern == 'Ivy':
  702. syns[-1].tau1 = 0.4 # rise time
  703. syns[-1].tau2 = 10.8 # decay time
  704. syns[-1].e = -80 # reversal potential GABA
  705. syn_weight = 0.8e-3
  706. clampobj.append(h.SEClamp(c.soma[0](0.5)))
  707. clampobj[-1].dur1 = stim_onset + stim_duration + after_stim_duration
  708. clampobj[-1].amp1 = -62
  709. clampobj[-1].rs = 5
  710. clamp_current = h.Vector().record(clampobj[-1]._ref_i)
  711. clamp_on = True
  712. else:
  713. syns[-1].tau1 = 0.5 # rise time
  714. syns[-1].tau2 = 23.4 # decay time
  715. syns[-1].e = -80 # reversal potential GABA
  716. syn_weight = 3.5e-3 # Tuned in order to produce average 0.86 mV depolarization in the soma from "Dendritic inhibition mediated by O-LM and bistratified interneurons in the hippocampus" Muller 2014 FSN
  717. clamp_on = False
  718. # print("Not a valid interneuron, using bistratified cells")
  719. spiketimes = [stim_onset]
  720. inputs.append(h.Vector(spiketimes))
  721. vecstims.append(h.VecStim())
  722. vecstims[-1].play(inputs[-1]) # add the last created inputs to the last created VecStim
  723. pre_synaptic_input = vecstims[-1]
  724. netcons.append(h.NetCon(pre_synaptic_input, syns[-1]))
  725. netcons[-1].delay = 2.0 # delay in ms
  726. netcons[-1].weight[0] = syn_weight
  727. current = h.Vector().record(syns[-1]._ref_i)
  728. h.finitialize(c.v_init)
  729. h.fcurrent()
  730. h.continuerun(stim_onset + stim_duration + after_stim_duration)
  731. time = np.array(time_)
  732. v_soma = np.array(voltage_soma)
  733. v_section = np.array(voltage_section)
  734. I_syn = np.array(current)
  735. if clamp_on == True:
  736. DATA[f'Clamp_current_{intern}_syn_{n}'] = np.array(clamp_current)
  737. DATA[f'Clamp_on_{intern}_{n}'] = clamp_on
  738. DATA[f'Voltage_soma_{intern}_syn_{n}'] = v_soma
  739. DATA[f'Voltage_section_{intern}_syn_{n}'] = v_section
  740. DATA[f'Time_{intern}_syn_{n}'] = time
  741. DATA[f'Synaptic_current_{intern}_syn_{n}'] = I_syn
  742. DATA["interneurons"] = presynaptic_interneurons
  743. DATA["n_repetitions"] = n_repetitions
  744. DATA["stim_onset"] = stim_onset
  745. DATA["stim_duration"] = stim_duration
  746. DATA["after_stim_duration"] = after_stim_duration
  747. saving_path = str(base_path / f"Protocol_results/Cell_validation/{name}validation")
  748. if not os.path.exists(saving_path):
  749. os.makedirs(saving_path)
  750. with open(f"{saving_path}/{name}interneurons_validation_amplitude.pkl", "wb") as file:
  751. pickle.dump(DATA, file, protocol=pickle.HIGHEST_PROTOCOL)
  752. ########################### DENDRITIC NONLINEARITY PROTOCOL ####################################################################
  753. if 'dendritic_nonlinearity' in protocol:
  754. '''
  755. Tuning the NMDA and the dendritic sodium to validate dendritic non-linearity from
  756. "Integrative Properties of Radial Oblique Dendrites in Hippocampal CA1 Pyramidal Neurons",
  757. Attila Losonczy, Jeffrey C. Magee, 2006 Neuron.
  758. E_6_14:
  759. Oblique 51, measured EPSP supralinear with 25 synapses to about 8 mV, dV/dt up to 3.5 mV/ms.
  760. '''
  761. stimulated_domain = 'Oblique'
  762. ind_section = 6
  763. synapse_number = [1, 4, 8, 12, 15, 18, 22, 25, 28, 30, 32, 35]
  764. NMDA_switch = 1
  765. if stimulated_domain == 'Tuft':
  766. selected_branch = tuft_group[ind_section]
  767. elif stimulated_domain == 'Trunk':
  768. selected_branch = trunk_group[ind_section]
  769. elif stimulated_domain == 'Oblique':
  770. selected_branch = oblique_group[ind_section]
  771. elif stimulated_domain == 'Basal':
  772. selected_branch = basal_group[ind_section]
  773. selected_branch_apic = c.apic[np.argmax(apic_distances)] #index_169_apic] # selected_branch #
  774. ICa_apic = h.Vector().record(selected_branch_apic(0.5)._ref_ica)
  775. ICa_apic_car = h.Vector().record(selected_branch_apic(0.5)._ref_ica_car)
  776. ICa_apic_calh = h.Vector().record(selected_branch_apic(0.5)._ref_ica_calH)
  777. Ikad_apic = h.Vector().record(selected_branch_apic(0.5)._ref_ik_kad) #c.apic[index_238_apic]
  778. Ikap_apic = h.Vector().record(selected_branch_apic(0.5)._ref_ik_kap)
  779. Ikm_apic = h.Vector().record(selected_branch_apic(0.5)._ref_ik_km)
  780. Ikca_apic = h.Vector().record(selected_branch_apic(0.5)._ref_ik_kca)
  781. Imykca_apic = h.Vector().record(selected_branch_apic(0.5)._ref_ik_mykca)
  782. IK_apic = h.Vector().record(selected_branch_apic(0.5)._ref_ik_kvs)
  783. INa_apic = h.Vector().record(selected_branch_apic(0.5)._ref_ina_nas)
  784. act_Na_par = h.Vector().record(selected_branch_apic(0.5)._ref_m_nas)
  785. inact_Na_par = h.Vector().record(selected_branch_apic(0.5)._ref_h_nas)
  786. act_K_par = h.Vector().record(selected_branch_apic(0.5)._ref_n_kvs)
  787. DATA = {}
  788. distances = []
  789. DATA['time'] = []
  790. DATA['v_soma'] = []
  791. DATA['v_section'] = []
  792. DATA['derivative_soma'] = []
  793. DATA['depol_soma'] = []
  794. stim_onset = 150*ms
  795. stim_duration = 10*ms
  796. after_stim_duration = 100*ms
  797. for n_syns in synapse_number:
  798. selected_branch.nseg = 201
  799. seg_id = calculate_segment_indexes(201)[101:]
  800. segs_with_syns = seg_id[:n_syns]
  801. # Create empty list for preallocation.
  802. syns, netcons = [], []
  803. inputs, vecstims = [], []
  804. diameter = selected_branch.diam
  805. length = selected_branch.L
  806. voltage_section = h.Vector().record(selected_branch(0.5)._ref_v)
  807. for i_s, segs in enumerate(segs_with_syns):
  808. stim_dend = selected_branch(segs)
  809. distances.append(c.fromtodistance(c.soma[0](1), stim_dend))
  810. distance = distances[-1]
  811. syns.append(h.AmpaNmda(stim_dend))
  812. syns[-1].gamma_mg = 0.12
  813. syns[-1].eta_mg = 0.28011
  814. syns[-1].mg2o = 1.2
  815. syns[-1].half_mg =2.5 #4
  816. if stimulated_domain == 'Trunk' or stimulated_domain == 'Oblique':
  817. #Setting AMPA conductance
  818. syns[-1].tau1_ampa = 0.61 # rise time
  819. syns[-1].tau2_ampa = 4.5 # decay time #??? Increasing AMPA with the distance causes a shortening of the decay time with the distance. Not biologically relevant!
  820. syns[-1].eampa = 0.0 # reversal potential NMDA
  821. syns[-1].gbar_ampa = 0.17e-3 + (distance * 3e-7)
  822. #Setting NMDA conductance
  823. syns[-1].tau1_nmda = 2.4 # rise time
  824. syns[-1].tau2_nmda = 43.0 # decay time
  825. syns[-1].enmda = 0.0 # reversal potential NMDA
  826. syns[-1].gbar_nmda = (0.50e-3 + (distance * 1e-6)) * NMDA_switch
  827. elif stimulated_domain == 'Tuft':
  828. #Setting AMPA conductance
  829. syns[-1].tau1_ampa = 0.61 # rise time
  830. syns[-1].tau2_ampa = 4.5 # decay time
  831. syns[-1].eampa = 0.0 # reversal potential AMPA/NMDA
  832. syns[-1].gbar_ampa = 0.06e-3
  833. #Setting NMDA conductance
  834. syns[-1].tau1_nmda = 2.4 # rise time
  835. syns[-1].tau2_nmda = 43. # decay time
  836. syns[-1].enmda = 0.0 # reversal potential AMPA/NMDA
  837. syns[-1].gbar_nmda = (0.6e-3) * NMDA_switch
  838. elif stimulated_domain == 'Basal':
  839. #Setting AMPA conductance
  840. syns[-1].tau1_ampa = 0.61 # rise time
  841. syns[-1].tau2_ampa = 4.5 # decay time
  842. syns[-1].eampa = 0.0 # reversal potential NMDA
  843. syns[-1].gbar_ampa = (0.14e-3 + (distance * 1.2e-7))
  844. #Setting NMDA conductance
  845. syns[-1].tau1_nmda = 2.4 # rise time
  846. syns[-1].tau2_nmda = 43.0 # decay time
  847. syns[-1].enmda = 0.0 # reversal potential NMDA
  848. syns[-1].gbar_nmda = (0.36e-3 + (distance * 1e-6)) * NMDA_switch
  849. spiketimes = [stim_onset + 0.1*i_s]
  850. inputs.append(h.Vector(spiketimes))
  851. vecstims.append(h.VecStim())
  852. vecstims[-1].play(inputs[-1]) # add the last created inputs to the last created VecStim
  853. pre_synaptic_input = vecstims[-1]
  854. netcons.append(h.NetCon(pre_synaptic_input, syns[-1]))
  855. netcons[-1].delay = 2.0 # delay in ms
  856. ampa_current = h.Vector().record(syns[-1]._ref_iampa)
  857. nmda_current = h.Vector().record(syns[-1]._ref_inmda)
  858. h.finitialize(c.v_init)
  859. h.fcurrent()
  860. h.continuerun(stim_onset + stim_duration + after_stim_duration)
  861. time = np.array(time_)
  862. v_soma = np.array(voltage_soma)
  863. v_section = np.array(voltage_section)
  864. dist = distances[0]
  865. DATA['time'].append(time)
  866. DATA['v_soma'].append(v_soma)
  867. DATA['v_section'].append(v_section)
  868. DATA['derivative_soma'].append(max(np.gradient(v_soma, time)))
  869. indx_v0 = np.abs(time - (stim_onset)).argmin()
  870. DATA['depol_soma'].append(max(np.abs(v_soma[indx_v0:]-v_soma[indx_v0-1])))
  871. saving_path = str(base_path / f"Protocol_results/Cell_validation/{name}validation")
  872. if not os.path.exists(saving_path):
  873. os.makedirs(saving_path)
  874. with open(f"{saving_path}/{name}dendritic_nonlinearity.pkl", "wb") as file:
  875. pickle.dump(DATA, file, protocol=pickle.HIGHEST_PROTOCOL)

Cluster_cells_validation_protocols.py at commit 77cf670, under GPL-3.0 · at the source

Overview

Authors: Simone Tasciotti1,2, Daniel Maxim Iascone3,4, Spyridon Chavlis2, Luke A Hammond3,5, Yardena Katz3, Attila Losonczy3,6,7, Franck Polleux3,6, Panayiota Poirazi2,8
  1. Department of Biology, University of Crete, Heraklion, Greece
  2. Institute of Molecular Biology and Biotechnology, Foundation for Research and Technology-Hellas, Heraklion, Greece
  3. Mortimer B. Zuckerman Mind Brain Behavior Institute, Columbia University, New York, NY, USA
  4. Present address: Department of Biological Sciences, Rensselaer Polytechnic Institute, Troy, NY, USA
  5. Present address: Department of Neurology, The Ohio State University, Wexner Medical School, Columbus, Ohio, USA
  6. Department of Neuroscience, Columbia University, New York, NY, USA
  7. Present address: O’Donnell Brain Institute at UT Southwestern Medical Center, Harry Hines Blvd. Dallas, Texas, USA
  8. Lead contact
Journal: Cell reports, volume 45, issue 8, article 117793
Dates: published online 5 August 2026; in print August 2026
Type: Research article · Language: English
License: CC BY-NC
Identifiers: DOI 10.1016/j.celrep.2026.117793 · PMID 42560818 · PMCID PMC13586326 · OpenAlex W7172502162
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: computational modeling (no new data) (modality), none (in silico) (organism), cellular / molecular (subfield)
Methods: Connectivity, Statistics, Machine learning, Preprocessing, Evoked potentials, Graphs, Single-unit activity, calcium imaging, Smoothing, state filtering, decompositions
Keywords: Morphology, CA1, Pyramidal Neuron, Computational Efficiency, Biophysical Model, Dendritic Computation, Synaptic Clustering, Dendritic Nonlinearity, Cp: Neuroscience, Dendritic Domains
Topic: Neuroscience and Neuropharmacology Research (Cellular and Molecular Neuroscience, Neuroscience), according to OpenAlex
Funding: NINDS NIH HHS (R01 NS121106, R01 NS133381, F31 NS101820, R01 NS131728, R35 NS127232, U01 NS115530, RF1 NS133381); National Institute of Neurological Disorders and Stroke (R01NS131728, U01NS115530, R01NS121106, R35 NS127232); Stavros Niarchos Foundation; NIDDK NIH HHS (K99 DK142063); Horizon 2020 Framework Programme; NIMH NIH HHS (R01 MH124867, F32 MH125600, R01 MH124047); NIA NIH HHS (RF1 AG080818); Hellenic Foundation for Research and Innovation (28056, COFLEX 14941 HFRI P.N. 80147/17.1.24); National Institutes of Health Blueprint for Neuroscience Research (F31NS101820, R01MH124867); European Commission (014941); BRAIN Initiative (R01NS133381); National Institutes of Health (F32MH125600, K99DK142063); National Institute of Mental Health (R01MH124047); NOMIS Stiftung; EU Framework Programme for Research and Innovation Marie Skłodowska-Curie Actions (860949); National Institute on Aging (RF1AG080818); National Institute of Mental Health and Neurosciences
Citations: not cited yet (Europe PMC); 150 references in the paper
Research resources: Mouse: C57BL/6 RRID:IMSR_JAX:000664

Abstract

How the spatial arrangement of synaptic inputs shapes neuronal feature selectivity remains a fundamental question. Here, we map the three-dimensional distribution of excitatory and inhibitory synapses across the dendritic arbor of CA1 pyramidal neurons in vivo and build biophysical models to probe their impact on place-cell emergence. Excitatory synapses are non-uniformly distributed, forming structural clusters preferentially on terminal apical and basal dendrites, whereas inhibitory synapses are uniformly arranged. Relative to dispersed configurations, clustered inputs generate higher-quality, stable place fields while recruiting ~13% fewer active synapses for equivalent somatic output, and cause elevated voltage-gated calcium influx and NMDA-receptor activation. Notably, disrupting clustering permits recovery of somatic excitability but not dendritic calcium dynamics, implicating clustering in calcium-dependent plasticity. Synaptic organization further determines integration strategy: clustered inputs preferentially engage apical dendritic nonlinearities, whereas distributed inputs rely on basal summation. These results establish synaptic clustering as a core mechanism for efficient, compartmentalized spatial computation.

Reproduced under the paper's license (CC BY-NC), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 22 matches between paragraphs and lines of code.

Zenodo 20738191

License: GPL-3.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: the resources table
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NEURON (36 files), NumPy (31 files), pandas (24 files), SciPy (19 files), Matplotlib (16 files), seaborn (11 files), Pingouin (4 files), Brian 2 (2 files), SHAP (2 files), scikit-learn (1 file), statannotations (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
64 files
At the source:

zenodo.com

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: the link answers
Software Heritage: not checked
Found in: the text, “Footnotes”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
At the source: Zenodo.com

poirazi-lab/tasciotti_et_al_2026

License: GPL-3.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 77cf67010d0e6bce4e83a891fb6a49318b5b0ac4, 17 June 2026
Languages: Python (33), NEURON (29)
Size: 67 files, 62 scripts
Software Heritage: not archived
Found in: the Zenodo archive record
Holds: README, license file, environment (requirements.txt)
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: NEURON (36 files), NumPy (31 files), pandas (24 files), SciPy (19 files), Matplotlib (16 files), seaborn (11 files), Pingouin (4 files), Brian 2 (2 files), SHAP (2 files), scikit-learn (1 file), statannotations (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
64 files

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 3 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 124 scripts, each with its path and the digest of its content;
  • 22 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 3, 28 September 2026

  • Publisher: — → Cell Press

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 8 authors, 10 keywords, 17 funders, 148 references, 1 RRID.

Cite

This paper

Tasciotti, S., Iascone, D. M., Chavlis, S., Hammond, L. A., Katz, Y., Losonczy, A., Polleux, F., & Poirazi, P. (2026). Clustered inputs engage dendritic nonlinearities and calcium signaling to support efficient place-field formation in CA1 pyramidal neurons. Cell reports, 45(8), 117793. https://doi.org/10.1016/j.celrep.2026.117793

BibTeX

@article{tasciotti2026clustered,
author = {Tasciotti, Simone and Iascone, Daniel Maxim and Chavlis, Spyridon and Hammond, Luke A and Katz, Yardena and Losonczy, Attila and Polleux, Franck and Poirazi, Panayiota},
title = {{Clustered inputs engage dendritic nonlinearities and calcium signaling to support efficient place-field formation in CA1 pyramidal neurons}},
journal = {Cell reports},
year = {2026},
month = aug,
volume = {45},
number = {8},
pages = {117793},
publisher = {Cell Press},
issn = {2211-1247},
doi = {10.1016/j.celrep.2026.117793},
url = {https://doi.org/10.1016/j.celrep.2026.117793},
pmid = {42560818},
pmcid = {PMC13586326}
}

RIS

TY - JOUR
AU - Tasciotti, Simone
AU - Iascone, Daniel Maxim
AU - Chavlis, Spyridon
AU - Hammond, Luke A
AU - Katz, Yardena
AU - Losonczy, Attila
AU - Polleux, Franck
AU - Poirazi, Panayiota
TI - Clustered inputs engage dendritic nonlinearities and calcium signaling to support efficient place-field formation in CA1 pyramidal neurons
T2 - Cell reports
J2 - Cell Rep
PY - 2026
DA - 2026/08/05
VL - 45
IS - 8
SP - 117793
SN - 2211-1247
PB - Cell Press
DO - 10.1016/j.celrep.2026.117793
UR - https://doi.org/10.1016/j.celrep.2026.117793
LA - en
ER -

CSL-JSON

{
"id": "10.1016/j.celrep.2026.117793",
"type": "article-journal",
"title": "Clustered inputs engage dendritic nonlinearities and calcium signaling to support efficient place-field formation in CA1 pyramidal neurons",
"container-title": "Cell reports",
"author": [
{
"family": "Tasciotti",
"given": "Simone"
},
{
"family": "Iascone",
"given": "Daniel Maxim"
},
{
"family": "Chavlis",
"given": "Spyridon"
},
{
"family": "Hammond",
"given": "Luke A"
},
{
"family": "Katz",
"given": "Yardena"
},
{
"family": "Losonczy",
"given": "Attila"
},
{
"family": "Polleux",
"given": "Franck"
},
{
"family": "Poirazi",
"given": "Panayiota"
}
],
"container-title-short": "Cell Rep",
"volume": "45",
"issue": "8",
"page": "117793",
"DOI": "10.1016/j.celrep.2026.117793",
"PMID": "42560818",
"PMCID": "PMC13586326",
"ISSN": "2211-1247",
"publisher": "Cell Press",
"URL": "https://doi.org/10.1016/j.celrep.2026.117793",
"language": "en",
"issued": {
"date-parts": [
[
2026,
8,
5
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.7554/elife.108352 [code]
Analysis of dendritic input currents during place field dynamics.
Journal: eLife
In common: NEURON, pandas, Matplotlib, 1 other tool, 20 references
[2] doi:10.1126/sciadv.aec3961 [code]
Linking functional and structural dendritic spine remodeling during fear learning and extinction in vivo.
Journal: Science advances
In common: NEURON, pandas, SciPy, 2 other tools, 14 references
[3] doi:10.1016/j.isci.2026.117010 [code]
Deep learning-assisted mapping of dendritic spines using sequential 2D two-photon calcium imaging.
Journal: iScience
In common: seaborn, scikit-learn, pandas, 3 other tools, cellular / molecular, 11 references
[4] doi:10.1038/s41467-026-77800-w [code]
Learning reorganizes dendritic and stabilizes axon initial segment inhibitory synapses in CA1 pyramidal neurons.
Journal: Nature communications
In common: cellular / molecular, 13 references
[5] doi:10.1038/s41467-026-74834-y [code]
Voltage imaging of CA1 pyramidal cells and SST+ interneurons reveals stability and plasticity mechanisms of spatial firing.
Journal: Nature communications
In common: 11 references
[6] doi:10.7554/elife.89629 [code]
Active dendrites enable robust spiking computations despite timing jitter.
Journal: eLife
In common: NEURON, seaborn, pandas, 2 other tools, 7 references
[7] doi:10.1126/sciadv.adz4123 [code]
Highly attenuated dendritic propagation of isolated synaptic potentials in vivo.
Journal: Science advances
In common: cellular / molecular, 10 references
[8] doi:10.1016/j.celrep.2026.117388 [code]
An unsuspected physiological role for mGluRIII glutamate receptors in hippocampal area CA1.
Journal: Cell reports
In common: NEURON, pandas, Matplotlib, 1 other tool, cellular / molecular, 7 references
[9] doi:10.1523/jneurosci.1540-25.2026 [code]
Dendritic Inhibition Terminates Plateau Potentials in CA1 Pyramidal Neurons.
Journal: The Journal of neuroscience : the official journal of the Society for Neuroscience
In common: cellular / molecular, 10 references
[10] doi:10.1073/pnas.2533168123 [code]
Dendritic morphology and synaptic nonlinearities enhance functional complexity in human cortical neurons.
Journal: Proceedings of the National Academy of Sciences of the United States of America
In common: NEURON, scikit-learn, pandas, 3 other tools, cellular / molecular, 5 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.