OSCR

Fast reconstruction of degenerate populations of conductance-based neuron models from spike times.

Code ↔ Paper

14 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 14 matches
  1. [1] § Materials and methods › Conductance-based models ↔ FIGURES_GENERATION/figures_bg_bio/stg.py, lines 1141–1249 · score 0.85 · delayed rectifier potassium, stomatogastric ganglion, intracellular calcium, STG model, neuron model, sodium
  2. [2] § Materials and methods › Conductance-based models ↔ FIGURES_GENERATION/figures_methods/stg.py, lines 1141–1249 · score 0.85 · delayed rectifier potassium, stomatogastric ganglion, intracellular calcium, STG model, neuron model, sodium
  3. [3] § Materials and methods › Training procedure ↔ FIGURES_GENERATION/figures_methods/Alternative_Figure_APpendix.ipynb, lines 28–59 · score 0.70 · cosine annealing learning, rate schedule, restarts
  4. [4] § Results › DICs provide a structured and learnable representation of neuronal activity ↔ FIGURES_GENERATION/figures_bg_bio/stg.py, lines 1740–1848 · score 0.67 · calcium concentration, compensated conductances, sensitivity matrix, target DIC, linear, STG
  5. [5] § Results › DICs provide a structured and learnable representation of neuronal activity ↔ FIGURES_GENERATION/figures_methods/stg.py, lines 1740–1850 · score 0.67 · calcium concentration, compensated conductances, sensitivity matrix, target DIC, linear, STG
  6. [6] § Results › General problem statement ↔ FIGURES_GENERATION/figures_bg_bio/stg.py, lines 1141–1249 · score 0.63 · gating variables, membrane potential, reversal potential, capacitance, external, intracellular
  7. [7] § Results › General problem statement ↔ FIGURES_GENERATION/figures_methods/stg.py, lines 1141–1249 · score 0.63 · gating variables, membrane potential, reversal potential, capacitance, external, intracellular
  8. [8] § Materials and methods › Generating degenerate populations from DICs ↔ FIGURES_GENERATION/figures_bg_bio/stg.py, lines 1740–1848 · score 0.62 · calcium conductances, calcium dynamics, sensitivity matrix, linear, STG, iteratively
  9. [9] § Materials and methods › Generating degenerate populations from DICs ↔ FIGURES_GENERATION/figures_methods/stg.py, lines 1740–1850 · score 0.62 · calcium conductances, calcium dynamics, sensitivity matrix, linear, STG, iteratively
  10. [10] § Materials and methods › Transfer to the DA model ↔ FIGURES_GENERATION/figures_results/architecture_transfer_final_evaluate.py, lines 190–287 · score 0.60 · attention layers, LoRA, linear layers, adapters, network, Transfer
  11. [11] § Materials and methods › Transfer to the DA model ↔ FIGURES_GENERATION/figures_results/results_inference_da.ipynb, lines 203–300 · score 0.60 · attention layers, LoRA, linear layers, adapters, network
  12. [12] § Materials and methods › Architecture overview ↔ FIGURES_GENERATION/figures_results/poisson_process.ipynb, lines 122–210 · score 0.52 · positional encoding, ISIs, stack, embedding, layer, encoder
  13. [13] § Materials and methods › Architecture overview ↔ FIGURES_GENERATION/figures_results/architecture_final_evaluate.py, lines 18–106 · score 0.52 · positional encoding, ISIs, stack, embedding, layer, encoder
  14. [14] § Materials and methods › Evaluation metrics ↔ FIGURES_GENERATION/figures_results/results.ipynb, lines 326–413 · score 0.51 · primary metric, hyperparameter, validation, regression, head, activity

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,974 lines · 78 KB · no license · 4 matches

  1. import numpy as np
  2. from utils import gsigmoid
  3. from utils import get_w_factors, get_w_factors_constant_tau
  4. from utils import d_gsigmoid
  5. from utils import find_first_decreasing_zero_bisection
  6. from scipy.integrate import solve_ivp
  7. from utils import gamma_uniform_mean_std_matching
  8. # == simulation functions == #
  9. def simulate_individual(args):
  10. """
  11. Simulates the dynamics of a single STG neuron based on its conductance parameters.
  12. Parameters
  13. ----------
  14. args : tuple
  15. A tuple containing:
  16. - u0 : array-like
  17. Initial conditions for the state variables.
  18. - individual : array-like
  19. Conductance parameters for the neuron (e.g., maximal conductances for ion channels).
  20. - T_final : float
  21. Final time for the simulation.
  22. - dt : float
  23. Time step for evaluating the solution.
  24. - params : dict
  25. Dictionary of fixed neuron parameters (e.g., reversal potentials and calcium dynamics).
  26. Returns
  27. -------
  28. np.ndarray
  29. A 2D array where the first row contains the time points and the second row contains
  30. the voltage trace of the neuron during the simulation.
  31. """
  32. u0, individual, T_final, dt, params = args
  33. t_eval = np.arange(0, T_final, dt)
  34. return simulate_individual_t_eval((u0, individual, t_eval, params))
  35. def simulate_individual_t_eval(args):
  36. """
  37. Simulates the dynamics of a single STG neuron, evaluating the solution at specific time points.
  38. Parameters
  39. ----------
  40. args : tuple
  41. A tuple containing:
  42. - u0 : array-like
  43. Initial conditions for the state variables.
  44. - individual : array-like
  45. Conductance parameters for the neuron (e.g., maximal conductances for ion channels).
  46. - t_eval : array-like
  47. Time points at which to evaluate the solution.
  48. - params : dict
  49. Dictionary of fixed neuron parameters (e.g., reversal potentials and calcium dynamics).
  50. Returns
  51. -------
  52. np.ndarray
  53. A 2D array where the first row contains the specified time points and the second row contains
  54. the voltage trace of the neuron during the simulation.
  55. """
  56. u0, individual, t_eval, params = args
  57. sol = solve_ivp(
  58. ODEs,
  59. [0, t_eval[-1]],
  60. u0,
  61. t_eval=t_eval,
  62. args=(
  63. individual[0], individual[1], individual[2], individual[3],
  64. individual[4], individual[5], individual[6], individual[7],
  65. params['E_Na'], params['E_K'], params['E_H'], params['E_leak'],
  66. params['E_Ca'], params['alpha_Ca'], params['beta_Ca'], params['tau_Ca']
  67. ),
  68. method='BDF',
  69. dense_output=False,
  70. jac=jacobian
  71. )
  72. return np.array((sol.t, sol.y[0]))
  73. def get_u0(V0, Ca0):
  74. """
  75. Generates the initial conditions for the state variables of the STG neuron.
  76. Parameters
  77. ----------
  78. V0 : float
  79. Initial membrane voltage.
  80. Ca0 : float
  81. Initial intracellular calcium concentration.
  82. Returns
  83. -------
  84. np.ndarray
  85. An array of initial values for the state variables, including the gating variables and calcium concentration.
  86. """
  87. u0 = np.zeros(13)
  88. u0[0] = V0
  89. u0[1] = m_inf_Na(V0)
  90. u0[2] = h_inf_Na(V0)
  91. u0[3] = m_inf_Kd(V0)
  92. u0[4] = m_inf_CaT(V0)
  93. u0[5] = h_inf_CaT(V0)
  94. u0[6] = m_inf_CaS(V0)
  95. u0[7] = h_inf_CaS(V0)
  96. u0[8] = m_inf_KCa(V0, Ca0)
  97. u0[9] = m_inf_A(V0)
  98. u0[10] = h_inf_A(V0)
  99. u0[11] = m_inf_H(V0)
  100. u0[12] = Ca0
  101. return u0
  102. def get_default_parameters():
  103. """
  104. Provides the default neuron parameters for the STG model.
  105. Returns
  106. -------
  107. dict
  108. A dictionary containing the reversal potentials and calcium dynamics parameters.
  109. """
  110. params = {}
  111. params['E_leak'] = -50 # Leak reversal potential
  112. params['E_Na'] = 50 # Sodium reversal potential
  113. params['E_K'] = -80 # Potassium reversal potential
  114. params['E_H'] = -20 # H-current reversal potential
  115. params['E_Ca'] = 80 # Calcium reversal potential
  116. params['tau_Ca'] = 20 # Calcium decay time constant
  117. params['alpha_Ca'] = 0.94
  118. params['beta_Ca'] = 0.05
  119. return params
  120. def get_default_u0():
  121. """
  122. Provides default initial conditions for the STG neuron state variables.
  123. The default values are for a resting neuron with a membrane potential of -70 mV and a calcium concentration of 0.5 µM.
  124. Returns
  125. -------
  126. np.ndarray
  127. Default initial state variables, including resting membrane potential and calcium concentration.
  128. """
  129. V0 = -70 # Resting membrane potential
  130. Ca0 = 0.5 # Initial calcium concentration
  131. u0 = get_u0(V0, Ca0)
  132. return u0
  133. def get_best_set(g_s, g_u):
  134. """
  135. Determines the best set of conductances to neuromulate based on the slow and ultra-slow DIC conductance parameters.
  136. Derived from the reachability analysis of the STG model.
  137. Parameters
  138. ----------
  139. g_s : float
  140. Slow DIC conductance parameter.
  141. g_u : float
  142. Ultra-slow DIC conductance parameter.
  143. Returns
  144. -------
  145. list
  146. A list of strings identifying the best conductances ('A', 'H', or 'CaS').
  147. Notes
  148. -----
  149. - If `g_u` is negative, a warning is printed and the function returns ['CaS', 'A'].
  150. - If `g_s` is positive, the function returns ['A', 'H'].
  151. - If `g_s` is negative, the function returns ['CaS', 'H'].
  152. """
  153. if g_u < 0:
  154. print('Cautious, g_u is negative!')
  155. return ['CaS', 'A']
  156. if g_s >= 0:
  157. return ['A', 'H']
  158. if g_s < 0:
  159. return ['CaS', 'H']
  160. # == Gating variables functions == #
  161. def m_inf_Na(V):
  162. """
  163. Computes the steady-state activation variable (m) for sodium (Na) channels as a function of membrane potential.
  164. Parameters
  165. ----------
  166. V : float
  167. Membrane potential.
  168. Returns
  169. -------
  170. float
  171. The steady-state value of the m variable for Na channels.
  172. Reference
  173. ---------
  174. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  175. """
  176. return gsigmoid(V, A=0, B=1, C=-5.29, D=25.5)
  177. def h_inf_Na(V):
  178. """
  179. Computes the steady-state inactivation variable (h) for sodium (Na) channels as a function of membrane potential.
  180. Parameters
  181. ----------
  182. V : float
  183. Membrane potential.
  184. Returns
  185. -------
  186. float
  187. The steady-state value of the h variable for Na channels.
  188. Reference
  189. ---------
  190. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  191. """
  192. return gsigmoid(V, A=0, B=1, C=5.18, D=48.9)
  193. def tau_m_Na(V):
  194. """
  195. Computes the time constant for the activation variable (m) for sodium (Na) channels as a function of membrane potential.
  196. Parameters
  197. ----------
  198. V : float
  199. Membrane potential.
  200. Returns
  201. -------
  202. float
  203. The time constant of the m variable for Na channels.
  204. Reference
  205. ---------
  206. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  207. """
  208. return gsigmoid(V, A=1.32, B=-1.26, C=-25, D=120)
  209. def tau_h_Na(V):
  210. """
  211. Computes the time constant for the inactivation variable (h) for sodium (Na) channels as a function of membrane potential.
  212. Parameters
  213. ----------
  214. V : float
  215. Membrane potential.
  216. Returns
  217. -------
  218. float
  219. The time constant of the h variable for Na channels.
  220. Reference
  221. ---------
  222. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  223. """
  224. return gsigmoid(V, A=0, B=0.67, C=-10, D=62.9) * gsigmoid(V, A=1.5, B=1, C=3.6, D=34.9)
  225. def m_inf_Kd(V):
  226. """
  227. Computes the steady-state activation variable (m) for delayed rectifier potassium (Kd) channels as a function of membrane potential.
  228. Parameters
  229. ----------
  230. V : float
  231. Membrane potential.
  232. Returns
  233. -------
  234. float
  235. The steady-state value of the m variable for Kd channels.
  236. Reference
  237. ---------
  238. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  239. """
  240. return gsigmoid(V, A=0, B=1, C=-11.8, D=12.3)
  241. def tau_m_Kd(V):
  242. """
  243. Computes the time constant for the activation variable (m) for delayed rectifier potassium (Kd) channels as a function of membrane potential.
  244. Parameters
  245. ----------
  246. V : float
  247. Membrane potential.
  248. Returns
  249. -------
  250. float
  251. The time constant of the m variable for Kd channels.
  252. Reference
  253. ---------
  254. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  255. """
  256. return gsigmoid(V, A=7.2, B=-6.4, C=-19.2, D=28.3)
  257. def m_inf_CaT(V):
  258. """
  259. Computes the steady-state activation variable (m) for T-type calcium (CaT) channels as a function of membrane potential.
  260. Parameters
  261. ----------
  262. V : float
  263. Membrane potential.
  264. Returns
  265. -------
  266. float
  267. The steady-state value of the m variable for CaT channels.
  268. Reference
  269. ---------
  270. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  271. """
  272. return gsigmoid(V, A=0, B=1, C=-7.2, D=27.1)
  273. def h_inf_CaT(V):
  274. """
  275. Computes the steady-state inactivation variable (h) for T-type calcium (CaT) channels as a function of membrane potential.
  276. Parameters
  277. ----------
  278. V : float
  279. Membrane potential.
  280. Returns
  281. -------
  282. float
  283. The steady-state value of the h variable for CaT channels.
  284. Reference
  285. ---------
  286. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  287. """
  288. return gsigmoid(V, A=0, B=1, C=5.5, D=32.1)
  289. def tau_m_CaT(V):
  290. """
  291. Computes the time constant for the activation variable (m) for T-type calcium (CaT) channels as a function of membrane potential.
  292. Parameters
  293. ----------
  294. V : float
  295. Membrane potential.
  296. Returns
  297. -------
  298. float
  299. The time constant of the m variable for CaT channels.
  300. Reference
  301. ---------
  302. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  303. """
  304. return gsigmoid(V, A=21.7, B=-21.3, C=-20.5, D=68.1)
  305. def tau_h_CaT(V):
  306. """
  307. Computes the time constant for the inactivation variable (h) for T-type calcium (CaT) channels as a function of membrane potential.
  308. Parameters
  309. ----------
  310. V : float
  311. Membrane potential.
  312. Returns
  313. -------
  314. float
  315. The time constant of the h variable for CaT channels.
  316. Reference
  317. ---------
  318. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  319. """
  320. return gsigmoid(V, A=105, B=-89.8, C=-16.9, D=55)
  321. def m_inf_CaS(V):
  322. """
  323. Computes the steady-state activation variable (m) for S-type calcium (CaS) channels as a function of membrane potential.
  324. Parameters
  325. ----------
  326. V : float
  327. Membrane potential.
  328. Returns
  329. -------
  330. float
  331. The steady-state value of the m variable for CaS channels.
  332. Reference
  333. ---------
  334. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  335. """
  336. return gsigmoid(V, A=0, B=1, C=-8.1, D=33)
  337. def h_inf_CaS(V):
  338. """
  339. Computes the steady-state inactivation variable (h) for S-type calcium (CaS) channels as a function of membrane potential.
  340. Parameters
  341. ----------
  342. V : float
  343. Membrane potential.
  344. Returns
  345. -------
  346. float
  347. The steady-state value of the h variable for CaS channels.
  348. Reference
  349. ---------
  350. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  351. """
  352. return gsigmoid(V, A=0, B=1, C=6.2, D=60)
  353. def tau_m_CaS(V):
  354. """
  355. Computes the time constant for the activation variable (m) for S-type calcium (CaS) channels as a function of membrane potential.
  356. Parameters
  357. ----------
  358. V : float
  359. Membrane potential.
  360. Returns
  361. -------
  362. float
  363. The time constant of the m variable for CaS channels.
  364. Reference
  365. ---------
  366. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  367. """
  368. return 1.4 + 7/(np.exp((V+27)/10) + np.exp((V+70)/-13))
  369. def tau_h_CaS(V):
  370. """
  371. Computes the time constant for the inactivation variable (h) for S-type calcium (CaS) channels as a function of membrane potential.
  372. Parameters
  373. ----------
  374. V : float
  375. Membrane potential.
  376. Returns
  377. -------
  378. float
  379. The time constant of the h variable for CaS channels.
  380. Reference
  381. ---------
  382. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  383. """
  384. return 60 + 150/(np.exp((V+55)/9) + np.exp((V+65)/-16))
  385. def m_inf_KCa(V, Ca):
  386. """
  387. Computes the steady-state activation variable (m) for calcium-dependent potassium (KCa) channels as a function of membrane potential and calcium concentration.
  388. Parameters
  389. ----------
  390. V : float
  391. Membrane potential.
  392. Ca : float
  393. Calcium concentration.
  394. Returns
  395. -------
  396. float
  397. The steady-state value of the m variable for KCa channels.
  398. Reference
  399. ---------
  400. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  401. """
  402. return Ca/(Ca + 3) * gsigmoid(V, A=0, B=1, C=-12.6, D=28.3)
  403. def tau_m_KCa(V):
  404. """
  405. Computes the time constant for the activation variable (m) for calcium-dependent potassium (KCa) channels as a function of membrane potential.
  406. Parameters
  407. ----------
  408. V : float
  409. Membrane potential.
  410. Returns
  411. -------
  412. float
  413. The time constant of the m variable for KCa channels.
  414. Reference
  415. ---------
  416. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  417. """
  418. return gsigmoid(V, A=90.3, B=-75.1, C=-22.7, D=46)
  419. def m_inf_A(V):
  420. """
  421. Computes the steady-state activation variable (m) for A-type potassium (A) channels as a function of membrane potential.
  422. Parameters
  423. ----------
  424. V : float
  425. Membrane potential.
  426. Returns
  427. -------
  428. float
  429. The steady-state value of the m variable for A-type K channels.
  430. Reference
  431. ---------
  432. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  433. """
  434. return gsigmoid(V, A=0, B=1, C=-8.7, D=27.2)
  435. def h_inf_A(V):
  436. """
  437. Computes the steady-state inactivation variable (h) for A-type potassium (A) channels as a function of membrane potential.
  438. Parameters
  439. ----------
  440. V : float
  441. Membrane potential.
  442. Returns
  443. -------
  444. float
  445. The steady-state value of the h variable for A-type K channels.
  446. Reference
  447. ---------
  448. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  449. """
  450. return gsigmoid(V, A=0, B=1, C=4.9, D=56.9)
  451. def tau_m_A(V):
  452. """
  453. Computes the time constant for the activation variable (m) for A-type potassium (A) channels as a function of membrane potential.
  454. Parameters
  455. ----------
  456. V : float
  457. Membrane potential.
  458. Returns
  459. -------
  460. float
  461. The time constant of the m variable for A-type K channels.
  462. Reference
  463. ---------
  464. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  465. """
  466. return gsigmoid(V, A=11.6, B=-10.4, C=-15.2, D=32.9)
  467. def tau_h_A(V):
  468. """
  469. Computes the time constant for the inactivation variable (h) for A-type potassium (A) channels as a function of membrane potential.
  470. Parameters
  471. ----------
  472. V : float
  473. Membrane potential.
  474. Returns
  475. -------
  476. float
  477. The time constant of the h variable for A-type K channels.
  478. Reference
  479. ---------
  480. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  481. """
  482. return gsigmoid(V, A=38.6, B=-29.2, C=-26.5, D=38.9)
  483. def m_inf_H(V):
  484. """
  485. Computes the steady-state activation variable (m) for H-type potassium (H) channels as a function of membrane potential.
  486. Parameters
  487. ----------
  488. V : float
  489. Membrane potential.
  490. Returns
  491. -------
  492. float
  493. The steady-state value of the m variable for H-type K channels.
  494. Reference
  495. ---------
  496. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  497. """
  498. return gsigmoid(V, A=0, B=1, C=6, D=70)
  499. def tau_m_H(V):
  500. """
  501. Computes the time constant for the activation variable (m) for H-type potassium (H) channels as a function of membrane potential.
  502. Parameters
  503. ----------
  504. V : float
  505. Membrane potential.
  506. Returns
  507. -------
  508. float
  509. The time constant of the m variable for H-type K channels.
  510. Reference
  511. ---------
  512. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  513. """
  514. return gsigmoid(V, A=272, B=1499, C=-8.73, D=42.2)
  515. def tau_Ca_constant_function(V, tau=20):
  516. """
  517. Returns a constant time constant for calcium decay.
  518. Parameters
  519. ----------
  520. V : float
  521. Membrane potential (not used in this function, but kept for consistency with other functions).
  522. tau : float
  523. The constant time constant value.
  524. Returns
  525. -------
  526. float
  527. The constant time constant.
  528. Reference
  529. ---------
  530. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  531. """
  532. if np.isscalar(V):
  533. return tau
  534. return np.full_like(V, tau)
  535. # == Derivatives == #
  536. def d_m_inf_Na(V):
  537. """
  538. Compute the derivative of the Na activation gating variable, m_inf, with respect to membrane potential (V).
  539. Parameters
  540. ----------
  541. V : float or array
  542. Membrane potential in mV.
  543. Returns
  544. -------
  545. float or array
  546. Derivative of m_inf with respect to V.
  547. """
  548. return d_gsigmoid(V, A = 0, B = 1, C = -5.29, D = 25.5)
  549. def d_h_inf_Na(V):
  550. """
  551. Compute the derivative of the Na inactivation gating variable, h_inf, with respect to membrane potential (V).
  552. Parameters
  553. ----------
  554. V : float or array
  555. Membrane potential in mV.
  556. Returns
  557. -------
  558. float or array
  559. Derivative of h_inf with respect to V.
  560. """
  561. return d_gsigmoid(V, A = 0, B = 1, C = 5.18, D = 48.9)
  562. def d_m_inf_Kd(V):
  563. """
  564. Compute the derivative of the K delayed rectifier activation gating variable, m_inf, with respect to membrane potential (V).
  565. Parameters
  566. ----------
  567. V : float or array
  568. Membrane potential in mV.
  569. Returns
  570. -------
  571. float or array
  572. Derivative of m_inf with respect to V.
  573. """
  574. return d_gsigmoid(V, A = 0, B = 1, C = -11.8, D = 12.3)
  575. def d_m_inf_CaT(V):
  576. """
  577. Compute the derivative of the Ca T-type activation gating variable, m_inf, with respect to membrane potential (V).
  578. Parameters
  579. ----------
  580. V : float or array
  581. Membrane potential in mV.
  582. Returns
  583. -------
  584. float or array
  585. Derivative of m_inf with respect to V.
  586. """
  587. return d_gsigmoid(V, A = 0, B = 1, C = -7.2, D = 27.1)
  588. def d_h_inf_CaT(V):
  589. """
  590. Compute the derivative of the Ca T-type inactivation gating variable, h_inf, with respect to membrane potential (V).
  591. Parameters
  592. ----------
  593. V : float or array
  594. Membrane potential in mV.
  595. Returns
  596. -------
  597. float or array
  598. Derivative of h_inf with respect to V.
  599. """
  600. return d_gsigmoid(V, A = 0, B = 1, C = 5.5, D = 32.1)
  601. def d_m_inf_CaS(V):
  602. """
  603. Compute the derivative of the Ca S-type activation gating variable, m_inf, with respect to membrane potential (V).
  604. Parameters
  605. ----------
  606. V : float or array
  607. Membrane potential in mV.
  608. Returns
  609. -------
  610. float or array
  611. Derivative of m_inf with respect to V.
  612. """
  613. return d_gsigmoid(V, A = 0, B = 1, C = -8.1, D = 33)
  614. def d_h_inf_CaS(V):
  615. """
  616. Compute the derivative of the Ca S-type inactivation gating variable, h_inf, with respect to membrane potential (V).
  617. Parameters
  618. ----------
  619. V : float or array
  620. Membrane potential in mV.
  621. Returns
  622. -------
  623. float or array
  624. Derivative of h_inf with respect to V.
  625. """
  626. return d_gsigmoid(V, A = 0, B = 1, C = 6.2, D = 60)
  627. def d_m_inf_KCa_dV(V, Ca):
  628. """
  629. Compute the derivative of the K Ca-dependent activation gating variable, m_inf, with respect to membrane potential (V).
  630. Parameters
  631. ----------
  632. V : float or array
  633. Membrane potential in mV.
  634. Ca : float
  635. Intracellular calcium concentration in µM.
  636. Returns
  637. -------
  638. float or array
  639. Derivative of m_inf with respect to V.
  640. """
  641. return Ca/(Ca + 3) * d_gsigmoid(V, A = 0, B = 1, C = -12.6, D = 28.3)
  642. def d_m_inf_KCa_dCa(V, Ca):
  643. """
  644. Compute the derivative of the K Ca-dependent activation gating variable, m_inf, with respect to calcium concentration (Ca).
  645. Parameters
  646. ----------
  647. V : float or array
  648. Membrane potential in mV.
  649. Ca : float
  650. Intracellular calcium concentration in µM.
  651. Returns
  652. -------
  653. float or array
  654. Derivative of m_inf with respect to Ca.
  655. """
  656. return 3 * gsigmoid(V, A = 0, B = 1, C = -12.6, D = 28.3) / (Ca + 3)**2
  657. def d_Ca_inf_dV(V, alpha, E_Ca, g_CaT, g_CaS, m_inf_CaT_values, m_inf_CaS_values, h_inf_CaT_values, h_inf_CaS_values, d_m_inf_CaT_values, d_m_inf_CaS_values, d_h_inf_CaT_values, d_h_inf_CaS_values):
  658. """
  659. Compute the derivative of the intracellular calcium concentration with respect to membrane potential (V).
  660. Parameters
  661. ----------
  662. V : float or array
  663. Membrane potential in mV.
  664. alpha : float
  665. Constant for scaling the calcium concentration change.
  666. E_Ca : float
  667. Calcium reversal potential in mV.
  668. g_CaT : float
  669. Maximal conductance for Ca T-type channels.
  670. g_CaS : float
  671. Maximal conductance for Ca S-type channels.
  672. m_inf_CaT_values : array
  673. m_inf values for the Ca T-type channel.
  674. m_inf_CaS_values : array
  675. m_inf values for the Ca S-type channel.
  676. h_inf_CaT_values : array
  677. h_inf values for the Ca T-type channel.
  678. h_inf_CaS_values : array
  679. h_inf values for the Ca S-type channel.
  680. d_m_inf_CaT_values : array
  681. Derivative of m_inf values for Ca T-type.
  682. d_m_inf_CaS_values : array
  683. Derivative of m_inf values for Ca S-type.
  684. d_h_inf_CaT_values : array
  685. Derivative of h_inf values for Ca T-type.
  686. d_h_inf_CaS_values : array
  687. Derivative of h_inf values for Ca S-type.
  688. Returns
  689. -------
  690. float or array
  691. Derivative of calcium concentration with respect to V.
  692. Notes
  693. -----
  694. The equation is derived from the chain rule of differentiation. The original equation can be found in the STG model ODEs.
  695. """
  696. d = np.zeros_like(V)
  697. d = g_CaT * 3 * m_inf_CaT_values**2 * h_inf_CaT_values * d_m_inf_CaT_values * (V - E_Ca) +\
  698. g_CaT * m_inf_CaT_values**3 * d_h_inf_CaT_values * (V - E_Ca) +\
  699. g_CaT * m_inf_CaT_values**3 * h_inf_CaT_values +\
  700. g_CaS * 3 * m_inf_CaS_values**2 * h_inf_CaS_values * d_m_inf_CaS_values * (V - E_Ca) +\
  701. g_CaS * m_inf_CaS_values**3 * d_h_inf_CaS_values * (V - E_Ca) +\
  702. g_CaS * m_inf_CaS_values**3 * h_inf_CaS_values
  703. return - alpha * d
  704. def d_m_inf_A(V):
  705. """
  706. Compute the derivative of the A-type K activation gating variable, m_inf, with respect to membrane potential (V).
  707. Parameters
  708. ----------
  709. V : float or array
  710. Membrane potential in mV.
  711. Returns
  712. -------
  713. float or array
  714. Derivative of m_inf with respect to V.
  715. """
  716. return d_gsigmoid(V, A = 0, B = 1, C = -8.7, D = 27.2)
  717. def d_h_inf_A(V):
  718. """
  719. Compute the derivative of the A-type K inactivation gating variable, h_inf, with respect to membrane potential (V).
  720. Parameters
  721. ----------
  722. V : float or array
  723. Membrane potential in mV.
  724. Returns
  725. -------
  726. float or array
  727. Derivative of h_inf with respect to V.
  728. """
  729. return d_gsigmoid(V, A = 0, B = 1, C = 4.9, D = 56.9)
  730. def d_m_inf_H(V):
  731. """
  732. Compute the derivative of the H-type K activation gating variable, m_inf, with respect to membrane potential (V).
  733. Parameters
  734. ----------
  735. V : float or array
  736. Membrane potential in mV.
  737. Returns
  738. -------
  739. float or array
  740. Derivative of m_inf with respect to V.
  741. """
  742. return d_gsigmoid(V, A = 0, B = 1, C = 6, D = 70)
  743. # == UTILS == #
  744. def compute_equilibrium_Ca(alpha, I_Ca, beta):
  745. """
  746. Compute the equilibrium calcium concentration based on the calcium current (I_Ca),
  747. the scaling constant (alpha), and the calcium influx rate (beta).
  748. The equilibrium condition is given by:
  749. dCa/dt = 0 = -alpha * I_Ca - Ca + beta
  750. Parameters
  751. ----------
  752. alpha : float
  753. A constant scaling factor representing the effect of the calcium current (I_Ca) on calcium concentration.
  754. I_Ca : float
  755. The calcium current (typically in µA or similar units).
  756. beta : float
  757. The calcium influx rate (or leakage rate) in the system.
  758. Returns
  759. -------
  760. float
  761. The equilibrium calcium concentration at the steady-state (Ca).
  762. """
  763. return -alpha * I_Ca + beta
  764. def find_V_th_DICs(V, g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak,
  765. E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca,
  766. tau_f_stg = tau_m_Na, tau_s_stg = tau_m_Kd, tau_u_stg = tau_m_H, get_I_static = False, normalize = True, y_tol = 1e-6, x_tol=1e-6, max_iter = 1000, verbose=True):
  767. """
  768. Find the threshold voltage (V_th) for dynamic input conductances (DICs).
  769. This function uses a bisection method to find the first voltage where the total conductance
  770. (g_t) decreases to zero. It also returns the values of the DICs at this threshold voltage.
  771. Parameters
  772. ----------
  773. V : array-like
  774. Array of membrane potentials (in mV) to search for the threshold voltage.
  775. g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak : float
  776. Maximum conductances (in mS/cm²) for the respective ion channels.
  777. E_Na, E_K, E_H, E_leak, E_Ca : float
  778. Reversal potentials (in mV) for the respective ion channels.
  779. alpha_Ca : float
  780. Scaling factor for calcium influx.
  781. beta_Ca : float
  782. Rate constant for calcium extrusion.
  783. tau_Ca : float
  784. Time constant for calcium concentration dynamics.
  785. tau_f_stg, tau_s_stg, tau_u_stg : callable, optional
  786. Functions to compute the time constants for fast, slow, and ultra-slow dynamics.
  787. get_I_static : bool, optional
  788. If True, also compute the static current.
  789. normalize : bool, optional
  790. If True, normalize the sensitivity matrix by the leak conductance.
  791. y_tol : float, optional
  792. Tolerance for the y-axis (conductance) in the bisection method.
  793. x_tol : float, optional
  794. Tolerance for the x-axis (voltage) in the bisection method.
  795. max_iter : int, optional
  796. Maximum number of iterations for the bisection method.
  797. verbose : bool, optional
  798. If True, print additional information during the bisection process.
  799. Returns
  800. -------
  801. V_th : float
  802. The threshold voltage where the total conductance decreases to zero.
  803. values : tuple
  804. A tuple containing the values of the DICs (g_f, g_s, g_u, g_t) at the threshold voltage.
  805. References
  806. ----------
  807. Fyon, A., Franci, A., Sacré, P., & Drion, G. (2024). Dimensionality reduction of neuronal degeneracy reveals two interfering physiological mechanisms. PNAS Nexus, 3(10), pgae415. https://doi.org/10.1093/pnasnexus/pgae415
  808. """
  809. g_t = lambda V_scalar : DICs(np.asarray([V_scalar,]), g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak, E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca, tau_f_stg, tau_s_stg, tau_u_stg, False, normalize)[3]
  810. V_th = find_first_decreasing_zero_bisection(V, g_t, y_tol = y_tol, x_tol=x_tol, max_iter = max_iter, verbose=verbose)
  811. V_th = np.asarray([V_th,], dtype=np.float64)
  812. if V_th is None or np.isnan(V_th):
  813. return V_th, (np.atleast_1d(np.nan), np.atleast_1d(np.nan), np.atleast_1d(np.nan), np.atleast_1d(np.nan))
  814. values = DICs(V_th, g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak, E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca, tau_f_stg, tau_s_stg, tau_u_stg, get_I_static, normalize)
  815. return V_th, values
  816. # == ODEs == #
  817. def jacobian(t, u, g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak, E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca):
  818. """
  819. Compute the Jacobian matrix for the STG model.
  820. Parameters
  821. ----------
  822. t : float
  823. Time variable (not used in this function, but kept for consistency with other functions).
  824. u : array-like, shape (13,)
  825. State vector containing the following variables:
  826. - u[0]: V (membrane potential, mV)
  827. - u[1]: m_Na (activation of sodium channel)
  828. - u[2]: h_Na (inactivation of sodium channel)
  829. - u[3]: m_Kd (activation of delayed rectifier potassium channel)
  830. - u[4]: m_CaT (activation of T-type calcium channel)
  831. - u[5]: h_CaT (inactivation of T-type calcium channel)
  832. - u[6]: m_CaS (activation of S-type calcium channel)
  833. - u[7]: h_CaS (inactivation of S-type calcium channel)
  834. - u[8]: m_KCa (activation of calcium-activated potassium channel)
  835. - u[9]: m_A (activation of A-type potassium channel)
  836. - u[10]: h_A (inactivation of A-type potassium channel)
  837. - u[11]: m_H (activation of H-current channel)
  838. - u[12]: Ca (intracellular calcium concentration, μM)
  839. g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak : float
  840. Maximum conductances (mS/cm²) of the respective ion channels.
  841. E_Na, E_K, E_H, E_leak, E_Ca : float
  842. Reversal potentials (mV) of the respective ion channels.
  843. alpha_Ca : float
  844. Scaling factor for the calcium current.
  845. beta_Ca : float
  846. Calcium influx rate (or leakage rate).
  847. tau_Ca : float
  848. Time constant for calcium decay.
  849. Returns
  850. -------
  851. J : ndarray, shape (13, 13)
  852. The Jacobian matrix of the system, where J[i, j] is the partial derivative
  853. of the i-th state variable's time derivative with respect to the j-th state variable.
  854. The rows and columns of J correspond to the variables in `u`.
  855. """
  856. # Initialize Jacobian matrix (13x13 for your system)
  857. J = np.zeros((13, 13))
  858. # Unpack variables (for clarity)
  859. V = u[0]
  860. m_Na, h_Na = u[1], u[2]
  861. m_Kd = u[3]
  862. m_CaT, h_CaT = u[4], u[5]
  863. m_CaS, h_CaS = u[6], u[7]
  864. m_KCa = u[8]
  865. m_A, h_A = u[9], u[10]
  866. m_H = u[11]
  867. Ca = u[12]
  868. # 1. Compute partial derivatives for V equation (voltage dynamics)
  869. J[0, 0] = -(
  870. g_Na * m_Na**3 * h_Na + g_Kd * m_Kd**4 + g_CaT * m_CaT**3 * h_CaT +
  871. g_CaS * m_CaS**3 * h_CaS + g_KCa * m_KCa**4 + g_A * m_A**3 * h_A +
  872. g_H * m_H + g_leak
  873. ) # ∂V_dot/∂V
  874. J[0, 1] = -3 * g_Na * m_Na**2 * h_Na * (V - E_Na) # ∂V_dot/∂m_Na
  875. J[0, 2] = -g_Na * m_Na**3 * (V - E_Na) # ∂V_dot/∂h_Na
  876. J[0, 3] = -4 * g_Kd * m_Kd**3 * (V - E_K) # ∂V_dot/∂m_Kd
  877. J[0, 4] = -3 * g_CaT * m_CaT**2 * h_CaT * (V - E_Ca) # ∂V_dot/∂m_CaT
  878. J[0, 5] = -g_CaT * m_CaT**3 * (V - E_Ca) # ∂V_dot/∂h_CaT
  879. J[0, 6] = -3 * g_CaS * m_CaS**2 * h_CaS * (V - E_Ca) # ∂V_dot/∂m_CaS
  880. J[0, 7] = -g_CaS * m_CaS**3 * (V - E_Ca) # ∂V_dot/∂h_CaS
  881. J[0, 8] = -4 * g_KCa * m_KCa**3 * (V - E_K) # ∂V_dot/∂m_KCa
  882. J[0, 9] = -3 * g_A * m_A**2 * h_A * (V - E_K) # ∂V_dot/∂m_A
  883. J[0, 10] = -g_A * m_A**3 * (V - E_K) # ∂V_dot/∂h_A
  884. J[0, 11] = -g_H * (V - E_H) # ∂V_dot/∂m_H
  885. # 2. Compute partial derivatives for calcium concentration dynamics
  886. J[12, 0] = -(alpha_Ca * (g_CaT * m_CaT**3 * h_CaT + g_CaS * m_CaS**3 * h_CaS)) / tau_Ca # ∂Ca_dot/∂V
  887. J[12, 4] = -(alpha_Ca * 3 * g_CaT * m_CaT**2 * h_CaT * (V - E_Ca)) / tau_Ca # ∂Ca_dot/∂m_CaT
  888. J[12, 5] = -(alpha_Ca * g_CaT * m_CaT**3 * (V - E_Ca)) / tau_Ca # ∂Ca_dot/∂h_CaT
  889. J[12, 6] = -(alpha_Ca * 3 * g_CaS * m_CaS**2 * h_CaS * (V - E_Ca)) / tau_Ca # ∂Ca_dot/∂m_CaS
  890. J[12, 7] = -(alpha_Ca * g_CaS * m_CaS**3 * (V - E_Ca)) / tau_Ca # ∂Ca_dot/∂h_CaS
  891. J[12, 12] = -1 / tau_Ca # ∂Ca_dot/∂Ca
  892. # 3. Partial derivatives for gating variables
  893. # m_Na and h_Na dynamics
  894. J[1, 0] = d_m_inf_Na(V) / tau_m_Na(V) # ∂m_Na_dot/∂V
  895. J[1, 1] = -1 / tau_m_Na(V) # ∂m_Na_dot/∂m_Na
  896. J[2, 0] = d_h_inf_Na(V) / tau_h_Na(V) # ∂h_Na_dot/∂V
  897. J[2, 2] = -1 / tau_h_Na(V) # ∂h_Na_dot/∂h_Na
  898. # m_Kd dynamics
  899. J[3, 0] = d_m_inf_Kd(V) / tau_m_Kd(V) # ∂m_Kd_dot/∂V
  900. J[3, 3] = -1 / tau_m_Kd(V) # ∂m_Kd_dot/∂m_Kd
  901. # m_CaT and h_CaT dynamics
  902. J[4, 0] = d_m_inf_CaT(V) / tau_m_CaT(V) # ∂m_CaT_dot/∂V
  903. J[4, 4] = -1 / tau_m_CaT(V) # ∂m_CaT_dot/∂m_CaT
  904. J[5, 0] = d_h_inf_CaT(V) / tau_h_CaT(V) # ∂h_CaT_dot/∂V
  905. J[5, 5] = -1 / tau_h_CaT(V) # ∂h_CaT_dot/∂h_CaT
  906. # m_CaS and h_CaS dynamics
  907. J[6, 0] = d_m_inf_CaS(V) / tau_m_CaS(V) # ∂m_CaS_dot/∂V
  908. J[6, 6] = -1 / tau_m_CaS(V) # ∂m_CaS_dot/∂m_CaS
  909. J[7, 0] = d_h_inf_CaS(V) / tau_h_CaS(V) # ∂h_CaS_dot/∂V
  910. J[7, 7] = -1 / tau_h_CaS(V) # ∂h_CaS_dot/∂h_CaS
  911. # m_KCa dynamics
  912. J[8, 0] = d_m_inf_KCa_dV(V, Ca) / tau_m_KCa(V) # ∂m_KCa_dot/∂V
  913. J[8, 8] = -1 / tau_m_KCa(V) # ∂m_KCa_dot/∂m_KCa
  914. # m_A and h_A dynamics
  915. J[9, 0] = d_m_inf_A(V) / tau_m_A(V) # ∂m_A_dot/∂V
  916. J[9, 9] = -1 / tau_m_A(V) # ∂m_A_dot/∂m_A
  917. J[10, 0] = d_h_inf_A(V) / tau_h_A(V) # ∂h_A_dot/∂V
  918. J[10, 10] = -1 / tau_h_A(V) # ∂h_A_dot/∂h_A
  919. # m_H dynamics
  920. J[11, 0] = d_m_inf_H(V) / tau_m_H(V) # ∂m_H_dot/∂V
  921. J[11, 11] = -1 / tau_m_H(V) # ∂m_H_dot/∂m_H
  922. return J
  923. def ODEs(t, u, g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak, E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca):
  924. """
  925. Compute the time derivatives of the state variables in the STG model.
  926. This function implements the system of ordinary differential equations (ODEs) governing
  927. the dynamics of the membrane potential, gating variables, and intracellular calcium concentration
  928. in a neuron modeled after the stomatogastric ganglion (STG).
  929. Parameters
  930. ----------
  931. t : float
  932. Time variable (included for compatibility with ODE solvers, but not explicitly used in the equations).
  933. u : array-like, shape (13,)
  934. State vector containing the following variables in order:
  935. - u[0] : V (membrane potential, mV)
  936. - u[1] : m_Na (activation variable for sodium channel)
  937. - u[2] : h_Na (inactivation variable for sodium channel)
  938. - u[3] : m_Kd (activation variable for delayed rectifier potassium channel)
  939. - u[4] : m_CaT (activation variable for T-type calcium channel)
  940. - u[5] : h_CaT (inactivation variable for T-type calcium channel)
  941. - u[6] : m_CaS (activation variable for S-type calcium channel)
  942. - u[7] : h_CaS (inactivation variable for S-type calcium channel)
  943. - u[8] : m_KCa (activation variable for calcium-activated potassium channel)
  944. - u[9] : m_A (activation variable for A-type potassium channel)
  945. - u[10]: h_A (inactivation variable for A-type potassium channel)
  946. - u[11]: m_H (activation variable for H-current channel)
  947. - u[12]: Ca (intracellular calcium concentration, μM)
  948. g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak : float
  949. Maximum conductances (μS/nF) of the respective ion channels.
  950. E_Na, E_K, E_H, E_leak, E_Ca : float
  951. Reversal potentials (mV) for sodium, potassium, leak, and calcium currents.
  952. alpha_Ca : float
  953. Proportionality constant for calcium influx (μM·cm²·ms⁻¹).
  954. beta_Ca : float
  955. Rate constant for calcium extrusion (ms⁻¹).
  956. tau_Ca : float
  957. Time constant for calcium concentration dynamics (ms).
  958. Returns
  959. -------
  960. du : ndarray, shape (13,)
  961. Time derivatives of the state variables. The output contains:
  962. - du[0] : dV/dt (rate of change of membrane potential)
  963. - du[1] : dm_Na/dt (rate of change of sodium channel activation)
  964. - du[2] : dh_Na/dt (rate of change of sodium channel inactivation)
  965. - du[3] : dm_Kd/dt (rate of change of delayed rectifier potassium activation)
  966. - du[4] : dm_CaT/dt (rate of change of T-type calcium activation)
  967. - du[5] : dh_CaT/dt (rate of change of T-type calcium inactivation)
  968. - du[6] : dm_CaS/dt (rate of change of S-type calcium activation)
  969. - du[7] : dh_CaS/dt (rate of change of S-type calcium inactivation)
  970. - du[8] : dm_KCa/dt (rate of change of calcium-activated potassium activation)
  971. - du[9] : dm_A/dt (rate of change of A-type potassium activation)
  972. - du[10]: dh_A/dt (rate of change of A-type potassium inactivation)
  973. - du[11]: dm_H/dt (rate of change of H-current activation)
  974. - du[12]: dCa/dt (rate of change of intracellular calcium concentration)
  975. References
  976. ----------
  977. The STG model is based on the following paper:
  978. Liu, Z., Golowasch, J., Marder, E., & Abbott, L. F. (1998). A model neuron with activity-dependent conductances regulated by multiple calcium sensors. The Journal of neuroscience: the official journal of the Society for Neuroscience, 18(7), 2309–2320. https://doi.org/10.1523/JNEUROSCI.18-07-02309.1998
  979. - But the equations are adapted and the g_bar dynamics is not considered in this implementation.
  980. - The capacitance should be considered in the conductances directly.
  981. - No external input current is considered in this implementation.
  982. """
  983. # Preallocate du (the vector of derivatives)
  984. du = np.zeros_like(u)
  985. # Extract variables (u is treated as a vector)
  986. V = u[0]
  987. m_Na, h_Na = u[1], u[2]
  988. m_Kd = u[3]
  989. m_CaT, h_CaT = u[4], u[5]
  990. m_CaS, h_CaS = u[6], u[7]
  991. m_KCa = u[8]
  992. m_A, h_A = u[9], u[10]
  993. m_H = u[11]
  994. Ca = u[12]
  995. # Compute currents using vectorized operations
  996. I_Na = g_Na * m_Na**3 * h_Na * (V - E_Na)
  997. I_Kd = g_Kd * m_Kd**4 * (V - E_K)
  998. I_CaT = g_CaT * m_CaT**3 * h_CaT * (V - E_Ca)
  999. I_CaS = g_CaS * m_CaS**3 * h_CaS * (V - E_Ca)
  1000. I_KCa = g_KCa * m_KCa**4 * (V - E_K)
  1001. I_A = g_A * m_A**3 * h_A * (V - E_K)
  1002. I_H = g_H * m_H * (V - E_H)
  1003. I_leak = g_leak * (V - E_leak)
  1004. # Compute the voltage derivative
  1005. du[0] = -(I_Na + I_Kd + I_CaT + I_CaS + I_KCa + I_A + I_H + I_leak)
  1006. # Calcium concentration derivative
  1007. I_Ca = I_CaT + I_CaS
  1008. du[12] = (-alpha_Ca * I_Ca - Ca + beta_Ca) / tau_Ca
  1009. # Gating variables (vectorized)
  1010. du[1] = (m_inf_Na(V) - m_Na) / tau_m_Na(V)
  1011. du[2] = (h_inf_Na(V) - h_Na) / tau_h_Na(V)
  1012. du[3] = (m_inf_Kd(V) - m_Kd) / tau_m_Kd(V)
  1013. du[4] = (m_inf_CaT(V) - m_CaT) / tau_m_CaT(V)
  1014. du[5] = (h_inf_CaT(V) - h_CaT) / tau_h_CaT(V)
  1015. du[6] = (m_inf_CaS(V) - m_CaS) / tau_m_CaS(V)
  1016. du[7] = (h_inf_CaS(V) - h_CaS) / tau_h_CaS(V)
  1017. du[8] = (m_inf_KCa(V, Ca) - m_KCa) / tau_m_KCa(V)
  1018. du[9] = (m_inf_A(V) - m_A) / tau_m_A(V)
  1019. du[10] = (h_inf_A(V) - h_A) / tau_h_A(V)
  1020. du[11] = (m_inf_H(V) - m_H) / tau_m_H(V)
  1021. return du
  1022. # == DICs related functions == #
  1023. def DICs(V, g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak,
  1024. E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca,
  1025. tau_f_stg=tau_m_Na, tau_s_stg=tau_m_Kd, tau_u_stg=tau_m_H, get_I_static=False, normalize=True):
  1026. """
  1027. Computes the dynamic input conductances (DICs) for a given set of membrane potentials and conductances.
  1028. Parameters
  1029. ----------
  1030. V : array-like
  1031. Membrane potentials at which to compute the DICs. Can be a scalar or a 1D array.
  1032. g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak : array-like
  1033. Maximum conductances for the respective ion channels. Each can be a scalar or a 1D array.
  1034. E_Na, E_K, E_H, E_leak, E_Ca : float
  1035. Reversal potentials for the respective ion channels.
  1036. alpha_Ca : float
  1037. Proportionality constant for calcium influx.
  1038. beta_Ca : float
  1039. Rate constant for calcium extrusion.
  1040. tau_Ca : float
  1041. Time constant for calcium concentration dynamics.
  1042. tau_f_stg, tau_s_stg, tau_u_stg : callable, optional
  1043. Functions to compute the time constants for fast, slow, and ultra-slow dynamics.
  1044. get_I_static : bool, optional
  1045. If True, also compute the static current.
  1046. normalize : bool, optional
  1047. If True, normalize the sensitivity matrix by the leak conductance.
  1048. Returns
  1049. -------
  1050. g_f, g_s, g_u, g_t : array-like
  1051. The fast, slow, ultra-slow, and total conductances. Each can be a scalar, a 1D array, or a 2D array.
  1052. I_static : array-like, optional
  1053. The static current, returned only if `get_I_static` is True.
  1054. Notes
  1055. -----
  1056. - The dimensions of the inputs can vary:
  1057. - If all inputs are scalars, the outputs will be scalars.
  1058. - If `V` is a 1D array and the conductances are scalars, the outputs will be 1D arrays of length N (N,).
  1059. - If `V` is a scalar and the conductances are 1D arrays of length M, the outputs will be 1D arrays of length M (M,).
  1060. - If both `V` and the conductances are 1D arrays of length N and M respectively, the outputs will be 2D arrays of shape (M, N).
  1061. References
  1062. ----------
  1063. Drion, G., Franci, A., Dethier, J., & Sepulchre, R. (2015). Dynamic Input Conductances Shape Neuronal Spiking. eNeuro, 2(1), ENEURO.0031-14.2015. https://doi.org/10.1523/ENEURO.0031-14.2015
  1064. """
  1065. # get the S matrix
  1066. if not get_I_static:
  1067. S = sensitivity_matrix(V, g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak,
  1068. E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca,
  1069. tau_f_stg, tau_s_stg, tau_u_stg, normalize, get_I_static)
  1070. else:
  1071. S, S_static = sensitivity_matrix(V, g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak,
  1072. E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca,
  1073. tau_f_stg, tau_s_stg, tau_u_stg, normalize, get_I_static)
  1074. if S.ndim == 3:
  1075. S = S[np.newaxis, :, :, :]
  1076. m = S.shape[0]
  1077. g_vec = np.array([g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak]).T
  1078. g_vec = np.atleast_2d(g_vec)
  1079. g_vec = g_vec[:, :, np.newaxis, np.newaxis].transpose(0, 2, 1, 3)
  1080. S_mul = np.sum(S * g_vec, axis=2)
  1081. g_f = S_mul[:, 0, :]
  1082. g_s = S_mul[:, 1, :]
  1083. g_u = S_mul[:, 2, :]
  1084. g_t = g_f + g_s + g_u
  1085. if get_I_static:
  1086. V_Na = V - E_Na
  1087. V_K = V - E_K
  1088. V_Ca = V - E_Ca
  1089. V_H = V - E_H
  1090. V_leak = V - E_leak
  1091. V_vec = np.array([V_Na, V_K, V_Ca, V_Ca, V_K, V_K, V_H, V_leak])
  1092. g_vec = g_vec[:, 0, :, 0][:, :, np.newaxis]
  1093. I_static = np.sum(S_static * g_vec * V_vec, axis=1)
  1094. if m == 1:
  1095. I_static = I_static[0]
  1096. g_f = g_f[0]
  1097. g_s = g_s[0]
  1098. g_u = g_u[0]
  1099. g_t = g_t[0]
  1100. return g_f, g_s, g_u, g_t, I_static
  1101. if m == 1:
  1102. g_f = g_f[0]
  1103. g_s = g_s[0]
  1104. g_u = g_u[0]
  1105. g_t = g_t[0]
  1106. return g_f, g_s, g_u, g_t
  1107. def sensitivity_matrix(V, g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak,
  1108. E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca,
  1109. tau_f_stg = tau_m_Na, tau_s_stg = tau_m_Kd, tau_u_stg = tau_m_H, normalize = True, get_I_static = False):
  1110. """
  1111. Computes the sensitivity matrix for the dynamic input conductances (DICs) of a neuron model.
  1112. Parameters
  1113. ----------
  1114. V : array-like
  1115. Membrane potentials at which to compute the sensitivity matrix. Can be a scalar or a 1D array.
  1116. g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, g_leak : array-like
  1117. Maximum conductances for the respective ion channels. Each can be a scalar or a 1D array.
  1118. E_Na, E_K, E_H, E_leak, E_Ca : float
  1119. Reversal potentials for the respective ion channels.
  1120. alpha_Ca : float
  1121. Proportionality constant for calcium influx.
  1122. beta_Ca : float
  1123. Rate constant for calcium extrusion.
  1124. tau_Ca : float
  1125. Time constant for calcium concentration dynamics.
  1126. tau_f_stg, tau_s_stg, tau_u_stg : callable, optional
  1127. Functions to compute the time constants for fast, slow, and ultra-slow dynamics.
  1128. normalize : bool, optional
  1129. If True, normalize the sensitivity matrix by the leak conductance.
  1130. get_I_static : bool, optional
  1131. If True, also compute the static current.
  1132. Returns
  1133. -------
  1134. S : ndarray
  1135. The sensitivity matrix of shape (m, 3, 8, n) where n is the length of V and m is the number of conductances.
  1136. S_static : ndarray, optional
  1137. The static current sensitivity matrix, returned only if `get_I_static` is True.
  1138. Notes
  1139. -----
  1140. - The dimensions of the inputs can vary:
  1141. - If all inputs are scalars, the outputs will be 3D arrays of shape (3, 8, 1).
  1142. - If `V` is a 1D array and the conductances are scalars, the outputs will be 3D arrays of shape (3, 8, N).
  1143. - If `V` is a scalar and the conductances are 1D arrays of length M, the outputs will be 3D arrays of shape (M, 3, 8, 1).
  1144. - If both `V` and the conductances are 1D arrays of length N and M respectively, the outputs will be 4D arrays of shape (M, 3, 8, N).
  1145. References
  1146. ----------
  1147. Drion, G., Franci, A., Dethier, J., & Sepulchre, R. (2015). Dynamic Input Conductances Shape Neuronal Spiking. eNeuro, 2(1), ENEURO.0031-14.2015. https://doi.org/10.1523/ENEURO.0031-14.2015
  1148. """
  1149. V = np.atleast_1d(V)
  1150. g_Na = np.atleast_1d(g_Na)
  1151. g_Kd = np.atleast_1d(g_Kd)
  1152. g_CaT = np.atleast_1d(g_CaT)
  1153. g_CaS = np.atleast_1d(g_CaS)
  1154. g_KCa = np.atleast_1d(g_KCa)
  1155. g_A = np.atleast_1d(g_A)
  1156. g_H = np.atleast_1d(g_H)
  1157. g_leak = np.atleast_1d(g_leak)
  1158. # m represents the number of conductances, it will be 1 for scalars, or match the size of arrays
  1159. m = g_Na.size # we assume all conductances have the same size ... should be the case with a proper call to the function !
  1160. n = V.size # n is the size of V
  1161. # S will be a 3xN matrix with N = 7+1. Each row will correspond to a different variable (f, s, u) and each column to a different channel.
  1162. S_Na = np.zeros((m, 3, n))
  1163. S_Kd = np.zeros((m, 3, n))
  1164. S_CaT = np.zeros((m, 3, n))
  1165. S_CaS = np.zeros((m, 3, n))
  1166. S_KCa = np.zeros((m, 3, n))
  1167. S_A = np.zeros((m, 3, n))
  1168. S_H = np.zeros((m, 3, n))
  1169. S_leak = np.zeros((m, 3, n))
  1170. V = np.atleast_2d(V).T
  1171. m_inf_Na_values = m_inf_Na(V)
  1172. h_inf_Na_values = h_inf_Na(V)
  1173. m_inf_Kd_values = m_inf_Kd(V)
  1174. m_inf_CaT_values = m_inf_CaT(V)
  1175. h_inf_CaT_values = h_inf_CaT(V)
  1176. m_inf_CaS_values = m_inf_CaS(V)
  1177. h_inf_CaS_values = h_inf_CaS(V)
  1178. I_CaT = g_CaT * m_inf_CaT_values**3 * h_inf_CaT_values * (V - E_Ca)
  1179. I_CaS = g_CaS * m_inf_CaS_values**3 * h_inf_CaS_values * (V - E_Ca)
  1180. I_Ca = I_CaT + I_CaS
  1181. Ca = compute_equilibrium_Ca(alpha_Ca, I_Ca, beta_Ca)
  1182. m_inf_KCa_values = m_inf_KCa(V, Ca)
  1183. m_inf_A_values = m_inf_A(V)
  1184. h_inf_A_values = h_inf_A(V)
  1185. m_inf_H_values = m_inf_H(V)
  1186. d_m_inf_Na_values = d_m_inf_Na(V)
  1187. d_h_inf_Na_values = d_h_inf_Na(V)
  1188. d_m_inf_Kd_values = d_m_inf_Kd(V)
  1189. d_m_inf_CaT_values = d_m_inf_CaT(V)
  1190. d_h_inf_CaT_values = d_h_inf_CaT(V)
  1191. d_m_inf_CaS_values = d_m_inf_CaS(V)
  1192. d_h_inf_CaS_values = d_h_inf_CaS(V)
  1193. d_m_inf_A_values = d_m_inf_A(V)
  1194. d_h_inf_A_values = d_h_inf_A(V)
  1195. d_m_inf_H_values = d_m_inf_H(V)
  1196. d_m_inf_KCa_dCa_values = d_m_inf_KCa_dCa(V, Ca)
  1197. d_m_inf_KCa_dV_values = d_m_inf_KCa_dV(V, Ca)
  1198. d_Ca_inf_dV_values = d_Ca_inf_dV(V, alpha_Ca, E_Ca, g_CaT, g_CaS, m_inf_CaT_values, m_inf_CaS_values, h_inf_CaT_values, h_inf_CaS_values, d_m_inf_CaT_values, d_m_inf_CaS_values, d_h_inf_CaT_values, d_h_inf_CaS_values)
  1199. S_Na[:, 0, :] += (m_inf_Na_values**3 * h_inf_Na_values).T
  1200. S_Kd[:,0,:] += (m_inf_Kd_values**4).T
  1201. S_CaT[:,0,:] += (m_inf_CaT_values**3 * h_inf_CaT_values).T
  1202. S_CaS[:,0,:] += (m_inf_CaS_values**3 * h_inf_CaS_values).T
  1203. S_KCa[:,0,:] += (m_inf_KCa_values**4).T
  1204. S_A[:,0,:] += (m_inf_A_values**3 * h_inf_A_values).T
  1205. S_H[:,0,:] += (m_inf_H_values).T
  1206. S_leak[:,0,:] += 1.0
  1207. if get_I_static:
  1208. S_Na_static = S_Na[:, 0, :].copy()
  1209. S_Kd_static = S_Kd[:, 0, :].copy()
  1210. S_CaT_static = S_CaT[:, 0, :].copy()
  1211. S_CaS_static = S_CaS[:, 0, :].copy()
  1212. S_KCa_static = S_KCa[:, 0, :].copy()
  1213. S_A_static = S_A[:, 0, :].copy()
  1214. S_H_static = S_H[:, 0, :].copy()
  1215. S_leak_static = S_leak[:, 0, :].copy()
  1216. dV_dot_dm_Na = - 3 * m_inf_Na_values**2 * h_inf_Na_values * d_m_inf_Na_values * (V - E_Na)
  1217. dV_dot_dh_Na = - m_inf_Na_values**3 * d_h_inf_Na_values * (V - E_Na)
  1218. dV_dot_dm_Kd = - 4 * m_inf_Kd_values**3 * d_m_inf_Kd_values * (V - E_K)
  1219. dV_dot_dm_CaT = - 3 * m_inf_CaT_values**2 * h_inf_CaT_values * d_m_inf_CaT_values * (V - E_Ca)
  1220. dV_dot_dh_CaT = - m_inf_CaT_values**3 * d_h_inf_CaT_values * (V - E_Ca)
  1221. dV_dot_dm_CaS = - 3 * m_inf_CaS_values**2 * h_inf_CaS_values * d_m_inf_CaS_values * (V - E_Ca)
  1222. dV_dot_dh_CaS = - m_inf_CaS_values**3 * d_h_inf_CaS_values * (V - E_Ca)
  1223. dV_dot_dm_KCa = - 4 * m_inf_KCa_values**3 * d_m_inf_KCa_dV_values * (V - E_K)
  1224. dV_dot_dCa_KCa = - 4 * m_inf_KCa_values**3 * d_m_inf_KCa_dCa_values * (V - E_K) * d_Ca_inf_dV_values
  1225. dV_dot_dm_A = - 3 * m_inf_A_values**2 * h_inf_A_values * d_m_inf_A_values * (V - E_K)
  1226. dV_dot_dh_A = - m_inf_A_values**3 * d_h_inf_A_values * (V - E_K)
  1227. dV_dot_dm_H = - d_m_inf_H_values * (V - E_H)
  1228. w_fs_m_Na, w_su_m_Na = get_w_factors(V, tau_m_Na, tau_f_stg, tau_s_stg, tau_u_stg)
  1229. w_fs_h_Na, w_su_h_Na = get_w_factors(V, tau_h_Na, tau_f_stg, tau_s_stg, tau_u_stg)
  1230. w_fs_m_Kd, w_su_m_Kd = get_w_factors(V, tau_m_Kd, tau_f_stg, tau_s_stg, tau_u_stg)
  1231. w_fs_m_CaT, w_su_m_CaT = get_w_factors(V, tau_m_CaT, tau_f_stg, tau_s_stg, tau_u_stg)
  1232. w_fs_h_CaT, w_su_h_CaT = get_w_factors(V, tau_h_CaT, tau_f_stg, tau_s_stg, tau_u_stg)
  1233. w_fs_m_CaS, w_su_m_CaS = get_w_factors(V, tau_m_CaS, tau_f_stg, tau_s_stg, tau_u_stg)
  1234. w_fs_h_CaS, w_su_h_CaS = get_w_factors(V, tau_h_CaS, tau_f_stg, tau_s_stg, tau_u_stg)
  1235. w_fs_m_KCa, w_su_m_KCa = get_w_factors(V, tau_m_KCa, tau_f_stg, tau_s_stg, tau_u_stg)
  1236. w_fs_m_KCa2, w_su_m_KCa2 = get_w_factors_constant_tau(V, tau_Ca, tau_f_stg, tau_s_stg, tau_u_stg) # TO BE CHANGED
  1237. w_fs_m_A, w_su_m_A = get_w_factors(V, tau_m_A, tau_f_stg, tau_s_stg, tau_u_stg)
  1238. w_fs_h_A, w_su_h_A = get_w_factors(V, tau_h_A, tau_f_stg, tau_s_stg, tau_u_stg)
  1239. w_fs_m_H, w_su_m_H = get_w_factors(V, tau_m_H, tau_f_stg, tau_s_stg, tau_u_stg)
  1240. S_Na[:,0,:] += (- w_fs_m_Na * dV_dot_dm_Na - w_fs_h_Na * dV_dot_dh_Na).T
  1241. S_Kd[:,0,:] += (- w_fs_m_Kd * dV_dot_dm_Kd).T
  1242. S_CaT[:,0,:] += (- w_fs_m_CaT * dV_dot_dm_CaT - w_fs_h_CaT * dV_dot_dh_CaT).T
  1243. S_CaS[:,0,:] += (- w_fs_m_CaS * dV_dot_dm_CaS - w_fs_h_CaS * dV_dot_dh_CaS).T
  1244. S_KCa[:,0,:] += (- w_fs_m_KCa * dV_dot_dm_KCa - w_fs_m_KCa2 * dV_dot_dCa_KCa).T
  1245. S_A[:,0,:] += (- w_fs_m_A * dV_dot_dm_A - w_fs_h_A * dV_dot_dh_A).T
  1246. S_H[:,0,:] += (- w_fs_m_H * dV_dot_dm_H).T
  1247. S_Na[:,1,:] += (- (w_su_m_Na - w_fs_m_Na) * dV_dot_dm_Na - (w_su_h_Na - w_fs_h_Na) * dV_dot_dh_Na).T
  1248. S_Kd[:,1,:] += (- (w_su_m_Kd - w_fs_m_Kd) * dV_dot_dm_Kd).T
  1249. S_CaT[:,1,:] += (- (w_su_m_CaT - w_fs_m_CaT) * dV_dot_dm_CaT - (w_su_h_CaT - w_fs_h_CaT) * dV_dot_dh_CaT).T
  1250. S_CaS[:,1,:] += (- (w_su_m_CaS - w_fs_m_CaS) * dV_dot_dm_CaS - (w_su_h_CaS - w_fs_h_CaS) * dV_dot_dh_CaS).T
  1251. S_KCa[:,1,:] += (- (w_su_m_KCa - w_fs_m_KCa) * dV_dot_dm_KCa - (w_su_m_KCa2 - w_fs_m_KCa2) * dV_dot_dCa_KCa).T
  1252. S_A[:,1,:] += (- (w_su_m_A - w_fs_m_A) * dV_dot_dm_A - (w_su_h_A - w_fs_h_A) * dV_dot_dh_A).T
  1253. S_H[:,1,:] += (- (w_su_m_H - w_fs_m_H) * dV_dot_dm_H).T
  1254. S_Na[:,2,:] += (- (1 - w_su_m_Na) * dV_dot_dm_Na - (1 - w_su_h_Na) * dV_dot_dh_Na).T
  1255. S_Kd[:,2,:] += (- (1 - w_su_m_Kd) * dV_dot_dm_Kd).T
  1256. S_CaT[:,2,:] += (- (1 - w_su_m_CaT) * dV_dot_dm_CaT - (1 - w_su_h_CaT) * dV_dot_dh_CaT).T
  1257. S_CaS[:,2,:] += (- (1 - w_su_m_CaS) * dV_dot_dm_CaS - (1 - w_su_h_CaS) * dV_dot_dh_CaS).T
  1258. S_KCa[:,2,:] += (- (1 - w_su_m_KCa) * dV_dot_dm_KCa - (1 - w_su_m_KCa2) * dV_dot_dCa_KCa).T
  1259. S_A[:,2,:] += (- (1 - w_su_m_A) * dV_dot_dm_A - (1 - w_su_h_A) * dV_dot_dh_A).T
  1260. S_H[:,2,:] += (- (1 - w_su_m_H) * dV_dot_dm_H).T
  1261. if normalize:
  1262. S_Na /= g_leak[:, np.newaxis, np.newaxis]
  1263. S_Kd /= g_leak[:, np.newaxis, np.newaxis]
  1264. S_CaT /= g_leak[:, np.newaxis, np.newaxis]
  1265. S_CaS /= g_leak[:, np.newaxis, np.newaxis]
  1266. S_KCa /= g_leak[:, np.newaxis, np.newaxis]
  1267. S_A /= g_leak[:, np.newaxis, np.newaxis]
  1268. S_H /= g_leak[:, np.newaxis, np.newaxis]
  1269. S_leak /= g_leak[:, np.newaxis, np.newaxis]
  1270. S_Na = S_Na[:, :, np.newaxis, :]
  1271. S_Kd = S_Kd[:, :, np.newaxis, :]
  1272. S_CaT = S_CaT[:, :, np.newaxis, :]
  1273. S_CaS = S_CaS[:, :, np.newaxis, :]
  1274. S_KCa = S_KCa[:, :, np.newaxis, :]
  1275. S_A = S_A[:, :, np.newaxis, :]
  1276. S_H = S_H[:, :, np.newaxis, :]
  1277. S_leak = S_leak[:, :, np.newaxis, :]
  1278. if not get_I_static:
  1279. if m == 1:
  1280. return np.concatenate((S_Na[0], S_Kd[0], S_CaT[0], S_CaS[0], S_KCa[0], S_A[0], S_H[0], S_leak[0]), axis=1)
  1281. else:
  1282. return np.concatenate((S_Na, S_Kd, S_CaT, S_CaS, S_KCa, S_A, S_H, S_leak), axis=2)
  1283. else:
  1284. if m == 1:
  1285. return np.concatenate((S_Na[0], S_Kd[0], S_CaT[0], S_CaS[0], S_KCa[0], S_A[0], S_H[0], S_leak[0]), axis=1), np.stack((S_Na_static, S_Kd_static, S_CaT_static, S_CaS_static, S_KCa_static, S_A_static, S_H_static, S_leak_static), axis=1)
  1286. else:
  1287. return np.concatenate((S_Na, S_Kd, S_CaT, S_CaS, S_KCa, S_A, S_H, S_leak), axis=2), np.stack((S_Na_static, S_Kd_static, S_CaT_static, S_CaS_static, S_KCa_static, S_A_static, S_H_static, S_leak_static), axis=1)
  1288. # == Compensation algorithms and generation functions == #
  1289. def generate_population(n_cells, V_th, g_f_target, g_s_target, g_u_target, g_bar_range_leak, g_bar_range_Na, g_bar_range_Kd, g_bar_range_CaT, g_bar_range_CaS, g_bar_range_KCa, g_bar_range_A, g_bar_range_H, params, default_g_CaS_for_Ca = 10., default_g_CaT_for_Ca = 6.0, distribution='uniform', normalize_by_leak=True):
  1290. """
  1291. Generates a population of neurons with specified dynamic input conductances (DICs).
  1292. Parameters
  1293. ----------
  1294. n_cells : int
  1295. Number of neurons to generate.
  1296. V_th : float
  1297. Threshold voltage for dynamic input conductances (DICs).
  1298. g_f_target : float
  1299. Target fast DIC.
  1300. g_s_target : float
  1301. Target slow DIC.
  1302. g_u_target : float
  1303. Target ultra-slow DIC.
  1304. g_bar_range_leak : list
  1305. Range of leak conductances.
  1306. g_bar_range_Na : list
  1307. Range of sodium conductances.
  1308. g_bar_range_Kd : list
  1309. Range of delayed rectifier potassium conductances.
  1310. g_bar_range_CaT : list
  1311. Range of T-type calcium conductances.
  1312. g_bar_range_CaS : list
  1313. Range of S-type calcium conductances.
  1314. g_bar_range_KCa : list
  1315. Range of calcium-activated potassium conductances.
  1316. g_bar_range_A : list
  1317. Range of A-type potassium conductances.
  1318. g_bar_range_H : list
  1319. Range of H-current conductances.
  1320. params : dict
  1321. Dictionary of fixed neuron parameters (e.g., reversal potentials and calcium dynamics).
  1322. default_g_CaS_for_Ca : float, optional
  1323. Default S-type calcium conductance for calcium dynamics.
  1324. default_g_CaT_for_Ca : float, optional
  1325. Default T-type calcium conductance for calcium dynamics.
  1326. distribution : str, optional
  1327. Distribution type for generating conductances ('uniform' or 'gamma').
  1328. normalize_by_leak : bool, optional
  1329. If True, normalize the conductances by the leak conductance.
  1330. Returns
  1331. -------
  1332. np.ndarray
  1333. Array of generated neuron conductances.
  1334. Notes
  1335. -----
  1336. - The population generation from this method can fail. In practice, the method using neuromodulation introduced by A. Fyon et al. (2015) and improved by this work can be used to generate a population of neurons with specified DICs.
  1337. - The method using neuromodulation is implemented in the `generate_neuromodulated_population` function and using the `get_best_set` function ensure reachability from a spiking population.
  1338. - The method is based on the work of Drion et al. (2015) and the compensation algorithm for DICs.
  1339. - If g_CaS and g_CaT are among the conductances to be compensated, the system is non-linear and providing a default value for the conductances is necessary. The compensation is, in this case, approximate and the reached DICs may not be exactly the target DICs.
  1340. References
  1341. ----------
  1342. For the compensation algorithm:
  1343. - Drion, G., Franci, A., Dethier, J., & Sepulchre, R. (2015). Dynamic Input Conductances Shape Neuronal Spiking. eNeuro, 2(1), ENEURO.0031-14.2015. https://doi.org/10.1523/ENEURO.0031-14.2015
  1344. For the population generation:
  1345. - Fyon, A., Franci, A., Sacré, P., & Drion, G. (2024). Dimensionality reduction of neuronal degeneracy reveals two interfering physiological mechanisms. PNAS Nexus, 3(10), pgae415. https://doi.org/10.1093/pnasnexus/pgae415
  1346. """
  1347. g_Na = np.random.uniform(g_bar_range_Na[0], g_bar_range_Na[1], n_cells) if g_bar_range_Na is not None else np.full(n_cells, np.nan)
  1348. g_Kd = np.random.uniform(g_bar_range_Kd[0], g_bar_range_Kd[1], n_cells) if g_bar_range_Kd is not None else np.full(n_cells, np.nan)
  1349. g_CaT = np.random.uniform(g_bar_range_CaT[0], g_bar_range_CaT[1], n_cells) if g_bar_range_CaT is not None else np.full(n_cells, np.nan)
  1350. g_CaS = np.random.uniform(g_bar_range_CaS[0], g_bar_range_CaS[1], n_cells) if g_bar_range_CaS is not None else np.full(n_cells, np.nan)
  1351. g_KCa = np.random.uniform(g_bar_range_KCa[0], g_bar_range_KCa[1], n_cells) if g_bar_range_KCa is not None else np.full(n_cells, np.nan)
  1352. g_A = np.random.uniform(g_bar_range_A[0], g_bar_range_A[1], n_cells) if g_bar_range_A is not None else np.full(n_cells, np.nan)
  1353. g_H = np.random.uniform(g_bar_range_H[0], g_bar_range_H[1], n_cells) if g_bar_range_H is not None else np.full(n_cells, np.nan)
  1354. if distribution == 'uniform':
  1355. # here we assume that the ranges are the min and max values for the uniform distribution
  1356. mean_leak = (g_bar_range_leak[0] + g_bar_range_leak[1]) / 2
  1357. g_leak = np.random.uniform(g_bar_range_leak[0], g_bar_range_leak[1], n_cells)
  1358. elif distribution == 'gamma':
  1359. g_bar_range_leak = gamma_uniform_mean_std_matching(*g_bar_range_leak)
  1360. mean_leak = g_bar_range_leak[0] * g_bar_range_leak[1]
  1361. g_leak = np.random.gamma(g_bar_range_leak[0], g_bar_range_leak[1], n_cells)
  1362. else:
  1363. raise ValueError('Invalid distribution type ! Please use either "uniform" or "gamma".')
  1364. if normalize_by_leak:
  1365. f = g_leak/mean_leak
  1366. g_Na *= f
  1367. g_Kd *= f
  1368. g_CaT *= f
  1369. g_CaS *= f
  1370. g_KCa *= f
  1371. g_A *= f
  1372. g_H *= f
  1373. x = general_compensation_algorithm(V_th, [g_f_target, g_s_target, g_u_target], g_leak, g_Na, g_Kd, g_CaT, g_CaS, g_KCa, g_A, g_H, params['E_Na'], params['E_K'], params['E_H'], params['E_leak'], params['E_Ca'], params['alpha_Ca'], params['beta_Ca'], params['tau_Ca'], default_g_CaS_for_Ca=default_g_CaS_for_Ca, default_g_CaT_for_Ca=default_g_CaT_for_Ca)
  1374. return x
  1375. def modulate_population(population, V_th, g_f_target, g_s_target, g_u_target, params, set_to_compensate, default_g_CaS_for_Ca = 10., default_g_CaT_for_Ca = 6.0, iterations=0):
  1376. """
  1377. Modulates a population of neurons to achieve specified dynamic input conductances (DICs).
  1378. Parameters
  1379. ----------
  1380. population : array-like
  1381. Array of neuron conductances to be modulated.
  1382. V_th : float
  1383. Threshold voltage for dynamic input conductances (DICs).
  1384. g_f_target : float or None
  1385. Target fast DIC. If None, it will be compensated.
  1386. g_s_target : float or None
  1387. Target slow DIC. If None, it will be compensated.
  1388. g_u_target : float or None
  1389. Target ultra-slow DIC. If None, it will be compensated.
  1390. params : dict
  1391. Dictionary of fixed neuron parameters (e.g., reversal potentials and calcium dynamics).
  1392. set_to_compensate : list
  1393. List of conductances to be compensated (e.g., ['Na', 'Kd', 'CaT']).
  1394. default_g_CaS_for_Ca : float or array-like, optional
  1395. Default S-type calcium conductance for calcium dynamics.
  1396. default_g_CaT_for_Ca : float or array-like, optional
  1397. Default T-type calcium conductance for calcium dynamics.
  1398. iterations : int, optional
  1399. Number of iterations for the compensation algorithm. Useless if g_CaS and g_CaT are not among the conductances to compensate.
  1400. Returns
  1401. -------
  1402. np.ndarray
  1403. Array of modulated neuron conductances.
  1404. Notes
  1405. -----
  1406. - The function uses a compensation algorithm to adjust the conductances of the neurons to achieve the specified DICs.
  1407. - The number of conductances to compensate should be equal to the number of target DICs that are None or NaN.
  1408. - If g_CaS and g_CaT are among the conductances to be compensated, the system is non-linear and providing a default value for the conductances is necessary. The compensation is, in this case, approximate and the reached DICs may not be exactly the target DICs. Iterations can be used to refine the compensation.
  1409. References
  1410. ----------
  1411. Drion, G., Franci, A., Dethier, J., & Sepulchre, R. (2015). Dynamic Input Conductances Shape Neuronal Spiking. eNeuro, 2(1), ENEURO.0031-14.2015. https://doi.org/10.1523/ENEURO.0031-14.2015
  1412. """
  1413. population = np.asarray(population)
  1414. number_none_dics = 0
  1415. if g_f_target is None or np.isnan(g_f_target):
  1416. number_none_dics += 1
  1417. if g_s_target is None or np.isnan(g_s_target):
  1418. number_none_dics += 1
  1419. if g_u_target is None or np.isnan(g_u_target):
  1420. number_none_dics += 1
  1421. if 3 - number_none_dics != len(set_to_compensate):
  1422. raise ValueError('Number of conductances to compensate should be equal to the number of target DICS')
  1423. while iterations >= 0:
  1424. if 'Na' in set_to_compensate:
  1425. population[:, 0] = np.nan
  1426. if 'Kd' in set_to_compensate:
  1427. population[:, 1] = np.nan
  1428. if 'CaT' in set_to_compensate:
  1429. population[:, 2] = np.nan
  1430. if 'CaS' in set_to_compensate:
  1431. population[:, 3] = np.nan
  1432. if 'KCa' in set_to_compensate:
  1433. population[:, 4] = np.nan
  1434. if 'A' in set_to_compensate:
  1435. population[:, 5] = np.nan
  1436. if 'H' in set_to_compensate:
  1437. population[:, 6] = np.nan
  1438. if 'CaS' not in set_to_compensate and 'CaT' not in set_to_compensate:
  1439. iterations = 0
  1440. population = general_compensation_algorithm(V_th, [g_f_target, g_s_target, g_u_target], population[:, 7], population[:, 0], population[:, 1], population[:, 2], population[:, 3], population[:, 4], population[:, 5], population[:, 6], params['E_Na'], params['E_K'], params['E_H'], params['E_leak'], params['E_Ca'], params['alpha_Ca'], params['beta_Ca'], params['tau_Ca'], default_g_CaS_for_Ca=default_g_CaS_for_Ca, default_g_CaT_for_Ca=default_g_CaT_for_Ca)
  1441. iterations -= 1
  1442. default_g_CaT_for_Ca = population[:, 2].copy()
  1443. default_g_CaS_for_Ca = population[:, 3].copy()
  1444. return population
  1445. def general_compensation_algorithm(V_th, target_DICs, new_g_leak, new_g_Na, new_g_Kd, new_g_CaT, new_g_CaS, new_g_KCa, new_g_A, new_g_H, E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca, tau_f_stg = tau_m_Na, tau_s_stg = tau_m_Kd, tau_u_stg = tau_m_H, default_g_CaS_for_Ca = 10., default_g_CaT_for_Ca = 6.0):
  1446. """
  1447. General compensation algorithm to adjust conductances to achieve target dynamic input conductances (DICs).
  1448. Parameters
  1449. ----------
  1450. V_th : float or array-like
  1451. Threshold voltage for dynamic input conductances (DICs).
  1452. target_DICs : list of float
  1453. List containing the target fast, slow, and ultra-slow DICs. Use None or NaN for the DICs to be compensated.
  1454. new_g_leak, new_g_Na, new_g_Kd, new_g_CaT, new_g_CaS, new_g_KCa, new_g_A, new_g_H : array-like or float
  1455. Initial conductances for the respective ion channels. Use None or NaN for the conductances to be compensated.
  1456. E_Na, E_K, E_H, E_leak, E_Ca : float
  1457. Reversal potentials for the respective ion channels.
  1458. alpha_Ca : float
  1459. Proportionality constant for calcium influx.
  1460. beta_Ca : float
  1461. Rate constant for calcium extrusion.
  1462. tau_Ca : float
  1463. Time constant for calcium concentration dynamics.
  1464. tau_f_stg, tau_s_stg, tau_u_stg : callable, optional
  1465. Functions to compute the time constants for fast, slow, and ultra-slow dynamics.
  1466. default_g_CaS_for_Ca : float or array-like, optional
  1467. Default S-type calcium conductance for calcium dynamics.
  1468. default_g_CaT_for_Ca : float or array-like, optional
  1469. Default T-type calcium conductance for calcium dynamics.
  1470. Returns
  1471. -------
  1472. np.ndarray
  1473. Array of compensated conductances.
  1474. Notes
  1475. -----
  1476. - The number of conductances to compensate should be equal to the number of target DICs that are None or NaN.
  1477. - If g_CaS and g_CaT are among the conductances to be compensated, the system is non-linear and providing a default value for the conductances is necessary. The compensation is, in this case, approximate and the reached DICs may not be exactly the target DICs. Iterative compensation can be used to refine the compensation.
  1478. References
  1479. ----------
  1480. Drion, G., Franci, A., Dethier, J., & Sepulchre, R. (2015). Dynamic Input Conductances Shape Neuronal Spiking. eNeuro, 2(1), ENEURO.0031-14.2015. https://doi.org/10.1523/ENEURO.0031-14.2015
  1481. """
  1482. none_index = []
  1483. new_g_dict = {
  1484. 'Na': new_g_Na,
  1485. 'Kd': new_g_Kd,
  1486. 'CaT': new_g_CaT,
  1487. 'CaS': new_g_CaS,
  1488. 'KCa': new_g_KCa,
  1489. 'A': new_g_A,
  1490. 'H': new_g_H,
  1491. 'leak': new_g_leak
  1492. }
  1493. # Handle None and NaN values
  1494. for idx, (key, g_value) in enumerate(new_g_dict.items()):
  1495. g_value = np.atleast_1d(g_value)
  1496. if g_value is None or np.isnan(g_value).all():
  1497. none_index.append(idx)
  1498. new_g_dict[key] = np.zeros_like(g_value) if key not in ['CaT', 'CaS'] else np.full_like(g_value, default_g_CaT_for_Ca if key == 'CaT' else default_g_CaS_for_Ca)
  1499. if len(none_index) == 0 or len(none_index) > 3:
  1500. raise ValueError('Number of conductances to compensate should be between 1 and 3')
  1501. target_DICs = np.array(target_DICs, dtype=np.float64)
  1502. not_none_index_target = np.where(~np.isnan(target_DICs))[0]
  1503. target_DICs = target_DICs[not_none_index_target]
  1504. # verify if the number of none index is equal to the number of none in target_DICs
  1505. if len(none_index) != len(not_none_index_target):
  1506. raise ValueError('Number of None in target_DICs should be equal to the number of None in the conductances')
  1507. new_gs = np.asarray([new_g_dict[key] for key in new_g_dict.keys()])
  1508. copy_new_gs = new_gs.copy().T
  1509. if not isinstance(V_th, np.ndarray):
  1510. V_th = np.array([V_th,])
  1511. S_full = sensitivity_matrix(V_th, *new_gs, E_Na, E_K, E_H, E_leak, E_Ca, alpha_Ca, beta_Ca, tau_Ca, tau_f_stg, tau_s_stg, tau_u_stg)
  1512. S_full = S_full.squeeze()
  1513. if S_full.ndim == 2:
  1514. S_full = S_full[np.newaxis, :, :]
  1515. not_none_index = [i for i in range(len(new_g_dict)) if i not in none_index]
  1516. S_random = S_full[:, not_none_index_target, :][:, :, not_none_index]
  1517. S_compensated = S_full[:, not_none_index_target, :][:, :, none_index]
  1518. new_gs = new_gs[not_none_index]
  1519. new_gs = new_gs.T[:, np.newaxis, :]
  1520. A = S_compensated
  1521. result_dot_product = np.sum(S_random * new_gs, axis=2)
  1522. b = target_DICs[np.newaxis, :] - result_dot_product
  1523. # add a dimension to b - I have to introduce this because of the new version of numpy ...
  1524. b = b[:, :, np.newaxis]
  1525. try:
  1526. x = np.linalg.solve(A, b)
  1527. except np.linalg.LinAlgError:
  1528. x = np.full((1, len(none_index)), -np.inf)
  1529. x = x.squeeze()
  1530. # refill new_gs with the new values
  1531. copy_new_gs[:, none_index] = x
  1532. return copy_new_gs
  1533. def generate_spiking_population(n_cells, V_th=-51.0):
  1534. """
  1535. Generates a population of spiking neurons (corresponding to g_f = -6.2, g_s = 4.0, g_u = 5.0).
  1536. Parameters
  1537. ----------
  1538. n_cells : int
  1539. Number of neurons to generate.
  1540. V_th : float, optional
  1541. Threshold voltage for dynamic input conductances (DICs). Default is -51.0 mV.
  1542. Returns
  1543. -------
  1544. np.ndarray
  1545. Array of generated spiking neuron conductances, shape (n_cells, 8).
  1546. Notes
  1547. -----
  1548. - The population is generated with the following conductance ranges:
  1549. - Leak: [0.007, 0.014]
  1550. - (Na: [2500, 4500]) [compensated]
  1551. - Kd: [70, 140]
  1552. - CaT: [3, 7]
  1553. - CaS: [6, 22]
  1554. - KCa: [140, 180]
  1555. - (A: [200, 400]) [compensated]
  1556. - (H: [0.25, 0.5]) [compensated]
  1557. - Fyon et al. (2024) used a uniform distribution to generate the conductances. We use a gamma distribution to generate the conductances in this work. Results are similar.
  1558. References
  1559. ----------
  1560. Fyon, A., Franci, A., Sacré, P., & Drion, G. (2024). Dimensionality reduction of neuronal degeneracy reveals two interfering physiological mechanisms. PNAS Nexus, 3(10), pgae415. https://doi.org/10.1093/pnasnexus/pgae415
  1561. """
  1562. # FROM Fyon et al. 2024
  1563. g_bar_range_Kd2 = [70, 140]
  1564. g_bar_range_CaT2 = [3, 7]
  1565. g_bar_range_CaS2 = [6, 22]
  1566. g_bar_range_KCa2 = [140, 180]
  1567. g_bar_range_leak2 = [0.007, 0.014]
  1568. # g_Na is compensated
  1569. g_bar_range_Kd = [g_bar_range_Kd2[0], g_bar_range_Kd2[1]]
  1570. g_bar_range_CaT = [g_bar_range_CaT2[0], g_bar_range_CaT2[1]]
  1571. g_bar_range_CaS = [g_bar_range_CaS2[0], g_bar_range_CaS2[1]]
  1572. g_bar_range_KCa = [g_bar_range_KCa2[0], g_bar_range_KCa2[1]]
  1573. # g_A is compensated
  1574. # g_H is compensated
  1575. g_bar_range_leak = [g_bar_range_leak2[0], g_bar_range_leak2[1]]
  1576. g_s_spiking = 4.
  1577. g_u_spiking = 5.
  1578. g_f_spiking = -g_s_spiking - 2.2
  1579. PARAMS = get_default_parameters()
  1580. spiking_population = generate_population(n_cells, V_th, g_f_spiking, g_s_spiking, g_u_spiking, g_bar_range_leak, None, g_bar_range_Kd, g_bar_range_CaT, g_bar_range_CaS, g_bar_range_KCa, None, None, params=PARAMS, distribution="gamma")
  1581. return spiking_population
  1582. def generate_neuromodulated_population(n_cells, V_th_target, g_s_target, g_u_target, set_to_compensate=None, clean=True, use_fitted_gCaS = lambda g_s, g_u : 34.12021074772369 -2.3296612301271464*g_s, use_fitted_gCaT = lambda g_s, g_u : 24.6 - 5.14 * g_s, iterations=0):
  1583. """
  1584. Generates a population of neurons with specified dynamic input conductances (DICs) using neuromodulation from a spiking population.
  1585. Parameters
  1586. ----------
  1587. n_cells : int
  1588. Number of neurons to generate.
  1589. V_th_target : float
  1590. Target threshold voltage for dynamic input conductances (DICs).
  1591. g_s_target : float
  1592. Target slow DIC.
  1593. g_u_target : float
  1594. Target ultra-slow DIC.
  1595. set_to_compensate : list, optional
  1596. List of conductances to be compensated (e.g., ['A', 'H']). If None, the best set will be determined automatically from the target DICs and the reachability from a spiking population.
  1597. clean : bool, optional
  1598. If True, remove any neuron with negative conductances.
  1599. use_fitted_gCaS : callable, optional
  1600. Function to determine the default S-type calcium conductance for calcium dynamics based on the target DICs.
  1601. The default function is a linear fit performed in this work and is associated with the best set of conductances to compensate.
  1602. use_fitted_gCaT : callable, optional
  1603. Function to determine the default T-type calcium conductance for calcium dynamics based on the target DICs.
  1604. The default function is a linear fit performed in this work and is associated with the best set of conductances to compensate.
  1605. iterations : int, optional
  1606. Number of iterations for the compensation algorithm. Useless if g_CaS and g_CaT are not among the conductances to compensate.
  1607. Returns
  1608. -------
  1609. np.ndarray
  1610. Array of generated neuromodulated neuron conductances.
  1611. Notes
  1612. -----
  1613. - The function first generates a population of spiking neurons and then modulates them to achieve the specified DICs.
  1614. - The number of conductances to compensate should be equal to the number of target DICs that are None or NaN.
  1615. - If g_CaS and g_CaT are among the conductances to be compensated, the system is non-linear and providing a default value for the conductances is necessary. The compensation is, in this case, approximate and the reached DICs may not be exactly the target DICs. Iterative compensation can be used to refine the compensation.
  1616. - In practice, the method using neuromodulation introduced by A. Fyon et al. (2015) and improved by this work can be used to generate a population of neurons with specified DICs without the failure of the direct population generation method.
  1617. References
  1618. ----------
  1619. - Fyon, A., Franci, A., Sacré, P., & Drion, G. (2024). Dimensionality reduction of neuronal degeneracy reveals two interfering physiological mechanisms. PNAS Nexus, 3(10), pgae415. https://doi.org/10.1093/pnasnexus/pgae415
  1620. """
  1621. g_f_target = None
  1622. spiking_population = generate_spiking_population(n_cells, V_th_target)
  1623. if set_to_compensate is None:
  1624. set_to_compensate = get_best_set(g_s_target, g_u_target)
  1625. if use_fitted_gCaS:
  1626. d_gCaS = use_fitted_gCaS(g_s_target, g_u_target)
  1627. else:
  1628. d_gCaS = 10.
  1629. if use_fitted_gCaT:
  1630. d_gCaT = use_fitted_gCaT(g_s_target, g_u_target)
  1631. else:
  1632. d_gCaT = 6.0
  1633. neuromodulated_population = modulate_population(spiking_population, V_th_target, g_f_target, g_s_target, g_u_target, get_default_parameters(), set_to_compensate, default_g_CaS_for_Ca=d_gCaS, default_g_CaT_for_Ca=d_gCaT, iterations=iterations)
  1634. if clean:
  1635. # remove any neuron with < 0 conductances
  1636. neuromodulated_population = neuromodulated_population[np.all(neuromodulated_population >= 0, axis=1)]
  1637. return neuromodulated_population

stg.py at commit 42c572c, no license · at the source

Overview

Authors: Julien Brandoit1, Damien Ernst1,2, Guillaume Drion1, Arthur Fyon1
  1. Department of Electrical Engineering and Computer Science, University of Liège, Liège, Belgium
  2. LTCI, Telecom Paris, Institut Polytechnique de Paris, Palaiseau, France
Journal: PLoS computational biology, volume 22, issue 5, article e1014337
Dates: received 17 September 2025; accepted 15 May 2026; published online 21 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1371/journal.pcbi.1014337 · PMID 42166500 · PMCID PMC13241015 · OpenAlex W4415316636
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: computational modeling (no new data) (modality), human (organism), computational (subfield)
Methods: Source localization, Machine learning, Single-unit activity, calcium imaging
MeSH: Action Potentials*, Models, Neurological*, Neurons*, Algorithms, Animals, Computational Biology, Computer Simulation, Deep Learning, Humans, Ion Channels, Neural Networks, Computer (* major topic)
Topic: Neural dynamics and brain function (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: Belgian Federal Science Policy Office (NEMODEI2); Fonds De La Recherche Scientifique - FNRS (ASP-REN40024838); Fonds pour la Formation à la Recherche dans l’Industrie et dans l’Agriculture (FRIA40038025)
Citations: cited by 2 papers (Europe PMC); 58 references in the paper

Abstract

Inferring the biophysical parameters of conductance-based models (CBMs) from experimentally accessible recordings remains a central challenge in computational neuroscience. Spike times are the most widely available data, yet they reveal little about which combinations of ion channel conductances generate the observed activity. This inverse problem is further complicated by neuronal degeneracy, where multiple distinct conductance sets yield similar spiking patterns. We introduce a method that addresses this challenge by combining deep learning with Dynamic Input Conductances (DICs), a theoretical framework that reduces complex CBMs to three interpretable feedback components governing excitability and firing patterns. Our approach first maps spike times directly to DIC densities at threshold using a lightweight neural network that learns a low-dimensional representation of neuronal activity. The predicted DIC values are then used to generate degenerate CBM populations via an iterative compensation algorithm, ensuring compatibility with the intermediate target DICs, and thereby reproducing the corresponding firing patterns, even in high-dimensional models. Applied to two neuronal models, this algorithmic pipeline reconstructs spiking, bursting, and irregular regimes with high accuracy and robustness to variability, including spike trains generated under noisy current injection mimicking physiological stochasticity. It produces diverse degenerate populations within milliseconds on standard hardware, enabling scalable and efficient inference from spike recordings alone. Beyond methodological advances, we provide an open-source software package with a graphical interface that allows experimentalists to generate and explore CBM populations directly from spike trains without requiring programming expertise. Together, this work positions DICs as a practical and interpretable link between experimentally observed activity and mechanistic models. By enabling fast and scalable reconstruction of degenerate populations directly from spike times, our approach provides a powerful way to investigate how neurons exploit conductance variability to achieve reliable computation and provides the foundation for experimental applications that span from neuromodulation studies to real-time model-guided interventions.

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

Repositories

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

Zenodo 16912160

License: CC-BY-4.0
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: “Data Availability”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 28 September 2026: the link answers (HTTP 200)
  • 28 September 2026: the link answers (HTTP 200)

julienbrandoit/automatic-degenerate-cbm

License: none: the authors keep all their rights
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 42c572c9f0ca4abbdef15b6201468c9fd0323ed6, 16 September 2025
Languages: Jupyter (23), Python (18)
Size: 247 files, 41 scripts
Software Heritage: not archived
Found in: “Data Availability”
Holds: README, 23 notebooks
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (40 files), pandas (26 files), Matplotlib (23 files), seaborn (20 files), PyTorch (13 files), SciPy (12 files), scikit-learn (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
42 files

julienbrandoit/Spike2Pop---Bridging-Experimental-Neuroscience-and-Computational-Modeling

License: MIT
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: a2400d09a1b9ff1528ebdd6b2d8c47d2380fce0e, 22 August 2025
Languages: Python (9)
Size: 27 files, 9 scripts
Software Heritage: not archived
Found in: “Data Availability”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (7 files), pandas (5 files), PyTorch (3 files), SciPy (2 files), Matplotlib (1 file), Pillow (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
11 files

The paper's code and data availability statement is in the Data section.

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;
  • 50 scripts, each with its path and the digest of its content;
  • 14 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.

Data Availability

All training and testing datasets are available on Zenodo at link https://doi.org/10.5281/zenodo.16912160 All code used for running experiments, model fitting, and plotting is available on a GitHub repository at https://github.com/julienbrandoit/automatic-degenerate-cbm The GUI software package is available on a GitHub repository at https://github.com/julienbrandoit/Spike2Pop---Bridging-Experimental-Neuroscience-and-Computational-Modeling.

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

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 1, 28 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 4 authors, 11 MeSH terms, 3 funders, 53 references.

Cite

This paper

Brandoit, J., Ernst, D., Drion, G., & Fyon, A. (2026). Fast reconstruction of degenerate populations of conductance-based neuron models from spike times. PLoS computational biology, 22(5), e1014337. https://doi.org/10.1371/journal.pcbi.1014337

BibTeX

@article{brandoit2026fast,
author = {Brandoit, Julien and Ernst, Damien and Drion, Guillaume and Fyon, Arthur},
title = {{Fast reconstruction of degenerate populations of conductance-based neuron models from spike times}},
journal = {PLoS computational biology},
year = {2026},
month = may,
volume = {22},
number = {5},
pages = {e1014337},
publisher = {PLOS},
issn = {1553-734X},
doi = {10.1371/journal.pcbi.1014337},
url = {https://doi.org/10.1371/journal.pcbi.1014337},
pmid = {42166500},
pmcid = {PMC13241015}
}

RIS

TY - JOUR
AU - Brandoit, Julien
AU - Ernst, Damien
AU - Drion, Guillaume
AU - Fyon, Arthur
TI - Fast reconstruction of degenerate populations of conductance-based neuron models from spike times
T2 - PLoS computational biology
J2 - PLoS Comput Biol
PY - 2026
DA - 2026/05/21
VL - 22
IS - 5
SP - e1014337
SN - 1553-734X
PB - PLOS
DO - 10.1371/journal.pcbi.1014337
UR - https://doi.org/10.1371/journal.pcbi.1014337
LA - en
ER -

CSL-JSON

{
"id": "10.1371/journal.pcbi.1014337",
"type": "article-journal",
"title": "Fast reconstruction of degenerate populations of conductance-based neuron models from spike times",
"container-title": "PLoS computational biology",
"author": [
{
"family": "Brandoit",
"given": "Julien"
},
{
"family": "Ernst",
"given": "Damien"
},
{
"family": "Drion",
"given": "Guillaume"
},
{
"family": "Fyon",
"given": "Arthur"
}
],
"container-title-short": "PLoS Comput Biol",
"volume": "22",
"issue": "5",
"page": "e1014337",
"DOI": "10.1371/journal.pcbi.1014337",
"PMID": "42166500",
"PMCID": "PMC13241015",
"ISSN": "1553-734X",
"publisher": "PLOS",
"URL": "https://doi.org/10.1371/journal.pcbi.1014337",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
21
]
]
}
}

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.1371/journal.pcbi.1014177 [code]
Activity-dependent neuromodulation and calcium homeostasis cooperate to produce robust and modulable neuronal function.
Journal: PLoS computational biology
In common: computational modeling (no new data), 13 references, author Arthur Fyon
[2] doi:10.1371/journal.pcbi.1014458 [code]
Neuronal excitability and parameter variability in the Hodgkin-Huxley model.
Journal: PLoS computational biology
In common: pandas, SciPy, Matplotlib, 1 other tool, computational, computational modeling (no new data), 7 references
[3] doi:10.1007/s10827-026-00936-7 [code]
When can neuronal activity-dependent homeostatic plasticity maintain circuit-level properties?
Journal: Journal of computational neuroscience
In common: Matplotlib, NumPy, computational modeling (no new data), 6 references
[4] doi:10.1016/j.isci.2026.115488 [code]
An integrated &lt;i&gt;i&lt;/i&gt; &lt;i&gt;n vitro&lt;/i&gt; platform and biophysical modeling approach for studying synaptic transmission in isolated neuronal pairs.
Journal: iScience
In common: Pillow, PyTorch, seaborn, 5 other tools, 2 references
[5] doi:10.1126/sciadv.aee9425 [code]
Probabilistic inference of homonymous and heteronymous recurrent inhibition in human muscles from large-scale motor neuron recordings.
Journal: Science advances
In common: PyTorch, seaborn, scikit-learn, 4 other tools, 3 references
[6] doi:10.3389/frai.2026.1771088 [code]
Few-shot deployment of pretrained MRI transformers in brain imaging tasks.
Journal: Frontiers in artificial intelligence
In common: Pillow, PyTorch, seaborn, 5 other tools, 2 references
[7] doi:10.1016/j.patter.2026.101538 [code]
A multi-modal foundation model for brain disease diagnosis and medical imaging.
Journal: Patterns (New York, N.Y.)
In common: Pillow, PyTorch, scikit-learn, 4 other tools, 2 references
[8] doi:10.1093/bioinformatics/btag652 [code]
mmVelo: a deep generative model for estimating cell state-dependent dynamics across multiple modalities.
Journal: Bioinformatics (Oxford, England)
In common: Pillow, PyTorch, seaborn, 5 other tools, 1 reference
[9] doi:10.1162/imag.a.1164 [code]
Bias and generalizability of brain age prediction models: A multi-cohort evaluation with anatomical and interpretability insights.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Pillow, PyTorch, seaborn, 5 other tools, 1 reference
[10] doi:10.1098/rstb.2024.0461 [code]
Shallow recurrent decoders for neural and behavioural dynamics.
Journal: Philosophical transactions of the Royal Society of London. Series B, Biological sciences
In common: Pillow, PyTorch, scikit-learn, 4 other tools, computational, 1 reference

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.