from __future__ import print_function import numpy as np from neuron import h from .psd import PSD class GlyPSD(PSD): """Glycinergic PSD This creates postsynaptoc glycinergic receptors. Receptors are connected to the XMTR range variable of the terminal release mechanisms. Parameters ---------- section : Section The postsynaptic section in which to insert the receptor mechanism. terminal : Terminal The presynaptic Terminal instance params : dict, default=None Dictionary of kinetic parameters to override {'KV', 'KU', 'XMax'} gmax : float, default=1000. maximal conductance unless overridden by values used in psdType psdType : str, default='glyfast' Kinetic model of receptors: possiblities are: glyfast, glyslow, glyGC, glya5, or glyexp, as defined in the mechanisms. message : str, default: None placeholder for a message to be printed out when testing. debug: bool, default=False enable printing of internal debugging messages. gvar : float, default=0 coefficient of variation of the amplitudes for each of the release zones. eRev : float, default=-70 "Reversal" potential, or Nernst potential for ions through the receptor channel. loc : float, default=0.5 Position on the postsynaptic section to insert the mechanism, from [0..1]. """ def __init__( self, section, terminal, params=None, gmax=1000.0, psdType="glyfast", message=None, debug=False, gvar=0, eRev=-70, loc=0.5, ): PSD.__init__(self, section, terminal) pre_sec = terminal.section post_sec = section from .. import cells params = {} if params is None else params self.pre_cell = cells.cell_from_section(pre_sec) self.post_cell = cells.cell_from_section(post_sec) self.psdType = psdType self.gmax = gmax glyslowPoMax = ( 0.162297 ) # thse were measured from the kinetic models in Synapses.py, as peak open P for the glycine receptors glyfastPoMax = 0.038475 # also later verified, same numbers... if self.psdType == "glyfast": gmax /= ( glyfastPoMax ) # normalized to maximum open probability for this receptor if self.psdType == "glyslow": gmax /= glyslowPoMax # normalized to max open prob for the slow receptor. # print "Stochastic syn: j = %d of n_fibers = %d n_rzones = %d\n" % (j, n_fibers, n_rzones) relzone = terminal.relsite n_rzones = terminal.n_rzones # # Create cleft mechanisms # clefts = [] for k in range(0, n_rzones): cl = h.cleftXmtr(loc, sec=post_sec) clefts.append(cl) # and then make a set of postsynaptic receptor mechanisms if self.psdType == "glyslow": (psd, par) = self.template_Gly_PSD_State_Gly6S( nReceptors=n_rzones, psdtype=self.psdType ) elif self.psdType == "glyfast": (psd, par) = self.template_Gly_PSD_State_PL( nReceptors=n_rzones, psdtype=self.psdType ) elif self.psdType == "glyGC": (psd, par) = self.template_Gly_PSD_State_GC( nReceptors=n_rzones, psdtype=self.psdType ) elif self.psdType == "glya5": (psd, par) = self.template_Gly_PSD_State_Glya5( nReceptors=n_rzones, psdtype=self.psdType ) elif self.psdType == "glyexp": (psd, par) = self.template_Gly_PSD_exp( nReceptors=n_rzones, psdtype=self.psdType ) else: print("**PSDTYPE IS NOT RECOGNIZED: [%s]\n" % (self.psdType)) exit() if debug: print("pre_sec: ", pre_sec) # Connect terminal to psd (or cleft) self._cleft_netcons = [] for k in range(0, n_rzones): pre_sec.push() netcon = h.NetCon(relzone._ref_XMTR[k], clefts[k], 0.1, 0.0, 1.0) self._cleft_netcons.append(netcon) h.pop_section() # set cleft transmitter kinetic parameters for pname, pval in params.items(): setattr(clefts[k], pname, pval) h.setpointer( clefts[k]._ref_CXmtr, "XMTR", psd[k] ) # connect transmitter release to the PSD v = 1.0 + gvar * np.random.standard_normal() psd[k].gmax = ( gmax * v ) # add a little variability - gvar is CV of amplitudes # print 'GLY psd %s %d gmax=%f' % (self.psdType, k, gmax) psd[k].Erev = eRev # set the reversal potential par = list(par) if message is not None: print(message) self.all_psd = psd self.clefts = clefts self.par = par # the following templates are a bit more complicated. # The parameter names as defined in the model are returned # but also those that are involved in the forward binding reactions are # listed separately - this is to allow us to run curve fits that adjust # only a subset of the parameters a time - e.g., the rising phase, then # the falling phase with the rising phase fixed. # the dictionary selection is made by selectpars in glycine_fit.py. # def template_Gly_PSD_exp( self, debug=False, nReceptors=2, cellname=None, message=None, loc=0.5 ): """ Template to build simple glycinergic exp-style PSD Parameters ---------- nReceptors : int, default=2 number of sites to implement loc : float, default=0.5 Position on the postsynaptic section to insert the mechanism, from [0..1]. Unused parameters: cellname, debug, message. """ sec = self.section psd = [] sec.push() for k in range(0, nReceptors): psd.append(h.GLY2(loc, sec)) h.pop_section() par = ["alpha", "beta"] p = [] for n in par: p.append(eval("psd[0]." + n)) # get default values from the mod file return (psd, par, p) def template_Gly_PSD_State_Glya5( self, debug=False, nReceptors=2, psdtype=None, message=None, loc=0.5 ): """ Template to build PSD using state model of glycine receptors, model glya5.mod Parameters ---------- nReceptors : int, default=2 number of sites to implement loc : float, default=0.5 Position on the postsynaptic section to insert the mechanism, from [0..1]. Unused parameters: cellname, debug, message, psdtype. """ sec = self.section psd = [] sec.push() for k in range(0, nReceptors): psd.append(h.GLYa5(loc, sec)) h.pop_section() par = { "kf1": ("r", psd[0].kf1), # retreive values in the MOD file "kf2": ("r", psd[0].kf2), "kb1": ("r", psd[0].kb1), "kb2": ("r", psd[0].kb2), "a1": ("f", psd[0].a1), "b1": ("f", psd[0].b1), "a2": ("f", psd[0].a2), "b2": ("f", psd[0].b2), } return (psd, par) def template_Gly_PSD_State_Gly6S( self, debug=False, nReceptors=2, psdtype=None, message=None, loc=0.5 ): """ Template to build PSD using state model of glycine receptors, model gly6s.mod Parameters ---------- nReceptors : int, default=2 number of sites to implement loc : float, default=0.5 Position on the postsynaptic section to insert the mechanism, from [0..1]. psdtype : str, default=None resets the psd type to have slow kinetics if 'glyslow'. Any other string defaults to kinetics in the mod file. Unused parameters: cellname, debug, message. """ sec = self.section psd = [] sec.push() for k in range(0, nReceptors): psd.append( h.Gly6S(loc, sec) ) # simple using Trussell model 6 states with desens if debug: print("Gly6S psdtype: ", psdtype) if ( psdtype == "glyslow" ): # fit on 8 March 2010, error = 0.164, max open: 0.155 psd[-1].Rd = 1.177999 psd[-1].Rr = 0.000005 psd[-1].Rb = 0.009403 psd[-1].Ru2 = 0.000086 psd[-1].Ro1 = 0.187858 psd[-1].Ro2 = 1.064426 psd[-1].Ru1 = 0.028696 psd[-1].Rc1 = 0.103625 psd[-1].Rc2 = 1.730578 h.pop_section() par = { "Rb": ("n", psd[0].Rb), # retrive values in the MOD file "Ru1": ("r", psd[0].Ru1), "Ru2": ("r", psd[0].Ru2), "Rd": ("f", psd[0].Rd), "Rr": ("f", psd[0].Rr), "Ro1": ("f", psd[0].Ro1), "Ro2": ("r", psd[0].Ro2), "Rc1": ("f", psd[0].Rc1), "Rc2": ("r", psd[0].Rc2), } return (psd, par) def template_Gly_PSD_State_PL( self, debug=False, nReceptors=2, cellname=None, psdtype=None, message=None, loc=0.5, ): """ Template to build PSD using state model of glycine receptors, model glypl.mod Parameters ---------- nReceptors : int, default=2 number of sites to implement loc : float, default=0.5 Position on the postsynaptic section to insert the mechanism, from [0..1]. psdtype : str, default=None resets the psd type to have slow kinetics if 'glyslow'. 'glyfast' forces fast kinetics. Any other string defaults to the default kinetics in the mod file. Unused parameters: cellname, debug, message,. """ sec = self.section psd = [] sec.push() for k in range(0, nReceptors): psd.append(h.GLYaPL(loc, sec)) # simple dextesche glycine receptors if debug: print("PL psdtype: ", psdtype) if psdtype == "glyslow": psd[-1].a1 = 0.000451 psd[-1].a2 = 0.220 psd[-1].b1 = 13.27 psd[-1].b2 = 6.845 psd[-1].kon = 0.00555 psd[-1].koff = 2.256 psd[-1].r = 1.060 psd[-1].d = 55.03 if ( psdtype == "glyfast" ): # fit from 3/5/2010. error = 0.174 maxopen = 0.0385 psd[-1].a1 = 1.000476 psd[-1].a2 = 0.137903 psd[-1].b1 = 1.700306 psd[-1].koff = 13.143132 psd[-1].kon = 0.038634 psd[-1].r = 0.842504 psd[-1].b2 = 8.051435 psd[-1].d = 12.821820 h.pop_section() par = { "kon": ("r", psd[0].kon), # retrive values in the MOD file "koff": ("r", psd[0].koff), "a1": ("r", psd[0].a1), "b1": ("r", psd[0].b1), "a2": ("f", psd[0].a2), "b2": ("f", psd[0].b2), "r": ("f", psd[0].r), "d": ("f", psd[0].d), } return (psd, par) def template_Gly_PSD_State_GC( self, debug=False, nReceptors=2, psdtype=None, message=None, loc=0.5 ): """ Template to build PSD using state model of glycine receptors, model glyaGC.mod Parameters ---------- nReceptors : int, default=2 number of sites to implement loc : float, default=0.5 Position on the postsynaptic section to insert the mechanism, from [0..1]. psdtype : str, default=None resets the psd type to have slow kinetics if 'glyslow'. Any other string defaults to predefined kinetics in the mod file. Unused parameters: cellname, debug, message, psdtype. """ sec = self.section psd = [] sec.push() for k in range(0, nReceptors): psd.append(h.GLYaGC(loc, sec)) # simple Dextesche glycine receptors if psdtype == "glyslow": psd[-1].k1 = 12.81 # (/uM /ms) : binding psd[-1].km1 = 0.0087 # (/ms) : unbinding psd[-1].a1 = 0.0195 # (/ms) : opening psd[-1].b1 = 1.138 # (/ms) : closing psd[-1].r1 = 6.13 # (/ms) : desense 1 psd[-1].d1 = 0.000462 # (/ms) : return from d1 psd[-1].r2 = 0.731 # (/ms) : return from deep state psd[-1].d2 = 1.65 # (/ms) : going to deep state psd[-1].r3 = 3.83 # (/ms) : return from deep state psd[-1].d3 = 1.806 # (/ms) : going to deep state psd[-1].rd = 1.04 # (/ms) psd[-1].dd = 1.004 # (/ms) h.pop_section() par = { "k1": ("r", psd[0].k1), # retrive values in the MOD file "km1": ("r", psd[0].km1), "a1": ("r", psd[0].a1), "b1": ("r", psd[0].b1), "r1": ("f", psd[0].r1), "d1": ("f", psd[0].d1), "r2": ("f", psd[0].r2), "d2": ("f", psd[0].d2), "r3": ("f", psd[0].r3), "d3": ("f", psd[0].d3), "rd": ("f", psd[0].rd), "dd": ("f", psd[0].dd), } return (psd, par)