> Where can I find documentation for kinetic blocks, explaining where
  > f_flux and b_flux are defined, for example, and how << and <->
  > and ~ and (c1,c2) work. I think I understand most  of it, but especially
  > the part about b_flux and f_flux I'd like to see spelled out somewhere.
  > The implementation of a kinetic scheme for the sodium potassium pump
  > is not so straightforward as the calcium pump, as some of the rate
  > constants are voltage dependent, and the Hill coeficient of the dependence
  > of the pump current on Nai is 1.4, though three Na ions are involved in the
  > reaction, of course. Anyway , thanks for any information on documentation
  > that you can give me- can the model accomodate rate constants that are a
  > function of voltage and reactions where there is cooperativity between the
  > binding sites?
The only explicit documentation about KINETIC blocks is in nrn/doc/man/nmodl/scopman.tex but that answers your question about f_flux and b_flux. I am enclosing the relevant fragment at the end. It is perfectly ok to have voltage dependent rates. My guess is that the Hill coefficient will be a phenomenological result of a nonlinear kinetic model and you will have to set rates and perhaps adjust the scheme to get the right coefficient. Eg. do you know if the Hill coefficient of the dependence of pump current on Nai is also dependent on Ko? Cooperativity between binding sites are nicely handled by kinetic schemes. If you send me an verbal description of the reactions you think are essential as well as a KINETIC block you believe embodies them, I'll check your syntax. For example, if you imagine an exchange of 3 Na and 4 K then the simplest scheme is (in analogy to the capump)
	KINETIC nakpump {
		COMPARTMENT area { pump nkpump}
		COMPARTMENT voli { nai ki }
		COMPARTMENT volo { nao ko }
		~ nai << (-(ina - last_ina_pmp)*vol2surfaceratio/FARADAY
		~ 3 nai + 4 ko + pump <-> nkpump	(f1rate(v), b1rate(v))
		~ nkpump <-> 3 nao + 4 ki		(f2rate(v), b2rate(v))
		nai_pmp = unitfactor*FARADAY*(f_flux - b_flux)/area
where the states are pump, nkpump, nai. ko, ki, nao should be CONSTANTs. It should be noted, though, that dimensional considerations make this very confusing since pump and nkpump are in terms of area and concentrations are in terms of mM and if it doesn't pass through modlunit without error then it is certainly wrong. Here I can help or you can do this in analogy to capump.mod using the COMPARTMENT statement. I am enclosing several old email messages that explain some of this.
Subject: Re:  COMPARTMENT statement in SCoP

COMPARTMENT statement syntax is:

        COMPARTMENT size {scalar state list}   or
        COMPARTMENT index, size(index) {vector state list}
This allows the user to select compartment sizes for states such that
quantity of matter is conserved but state units are still convenient.
The invariant that is important is
        stateunits * sizeunits / time (or indepunits)
==      fluxunits
==      rateunits * (product of stateunits^stoichiometry)
It is important that all reactions have the same units or that you
know exactly what you are doing.

Some examples of the use of COMPARTMENT are when:
        diffusion in cylinder with variable diameter or dx
        transfer of matter between compartments of differetnt size
        reaction between substance on a surface and substance in solution
        It is convenient that states have different units.

There is one caveat involving the relationship beteen COMPARTMENT and CONSERVE
Compartment sizes are taken into account on the state side of the CONSERVE
statement, but the user must explicitly specify the ammount conserved.
For example, if state A is in compartment of size a, and B is relative to
compartment of size b, and the total substance of A and B is conserved
with total = a*A + b*B then
        CONSERVE A + B = a*A0 + b*B0
is the proper statement

It is very important that you check the units with modlunit to make sure
that the programs idea of what you are doing is consistent with yours.

Subject: Re:  COMPARTMENT directive
The COMPARTMENT directive  help. It is just that the compartment
units are dimensionless.  The definition of a kinetic equation is that
A_comp1 * k1 is the flux leaving A_comp1 and entering A_comp2 due to this
equation.  The change in A_comp2 per unit time is
compartment_A_comp2 * A_comp2' = sum of all fluxes entering - sum of
all fluxes leaving.

This can make the units of the k's fairly cumbersome since they depend on
the units of the compartment size and the units of the states.
i.e. all fluxes are material (extensive) quantities.
The alternative was to keep the k's in intensive units and
scale the fluxes by the appropriate compartment sizes but that was
deemed less efficient.


The COMPARTMENT syntax has two cases. One for scalar states and one for
vector states.
COMPARTMENT index, volume(index) { list of vector states without
brackets }
COMPARTMENT volume { list of scalar states }

If you understand bnf syntax you can look in nrn/nmodl/SRC/parse1.y
to see how it is parsed. In fact that file is the definitive place for
all nmodl syntax. Look at the lines around

What it means is that states are located in different size compartments and
the that has to be taken into account when calculating the change in a state
per unit time.

~ a<->b (k1,k2)

solves the equations
v1*a' = -k1*a + k2*b
v2*b' = +k1*a + k2*b

Without the COMPARTMENT statements the equations are
a' = -k1*a + k2*b
so compartments affect the rate units since with compartments the  
fluxes are in extensive units (eg, moles/sec)

  ~   [ + ...] <-> ... (kf, kr)
A KINETIC block contains a set of equations describing reactions of the chemical reaction type. On each side of the double arrow \verb+<->+ in a reaction is a sum of terms consisting of an optional stoichiometric number (small integer) multiplying any type of SCoP variable (CONSTANT, ASSIGNED, STATE, INDEPENDENT, STEPPED, or SWEEP). The space between the number and the variable is optional. f_flux and b_flux following each reaction are forward and reverse rate coefficients for the reaction and can be arbitrary expressions. The effect of any type of variable other than a state variable is to multiply one of the rate coefficients by the variable raised to the power of its stoichiometric number. If the variable appears on the left-hand side of the reaction, it multiplies the forward rate coefficient and if it is on the right-hand side it multiplies the reverse rate coefficient. Three additional types of equations are also possible in KINETIC blocks. \\ \verb+~ -> ()+ \\ represents a flux out of a state with the specified rate coefficient. \\ \verb+~ << ()+ \\ represents a flux into a state. \\ \verb9CONSERVE = 9 \\ represents a form of algebraic equation (such as a conservation law) that is solved with the equations from the specified reactions. Each CONSERVE equation added to a KINETIC block results in the deletion of an appropriate equation from the reaction set (to keep the total number of equations constant for the numerical solvers). \verb++ must be a linear equation in the KINETIC state variables. Reactions in a KINETIC block are transformed into ordinary differential equations for the state variables that can be integrated via a SOLVE directive in the EQUATION block. Solvers require that the number of state equations in a KINETIC block be equal to the number of state variables in the block. Immediately following each reaction equation, the variables \verb+f_flux+ and \verb+b_flux+ contain the unidirectional fluxes of the reaction from left to right (``forward'') and right to left (``backward''), respectively. If these flux values are needed, they must be stored by the user before the next reaction equation since the same variables are used for all reaction equations. > conformation. The internal and external concentrations of the ions were > fixed except for nai. > > > ~ pump1 <-> pump2 (a(V),b(V)) > ~ pump2 -> pump1 (c(Na_i)) > ~nai << unitfactor f_flux > ina_pump = (1e-4)3 FARADAY f_flux/area f_flux is not a valid quantity within a reaction. save it in a variable and use the variable as in: ~ pump2 -> pump1 (c(Na_i)) naflux = f_flux ~nai << unitfactor naflux ina_pump = (1e-4)3 FARADAY naflux/area There is another problem, though, in that the solver is going to think the reactions are linear and not bother to do a newton's method iteration. I suggest factoring out an Na_i from c(Na_i) so that the nonlinearity of the kinetics is obvious. ie ~pump2 + nai -> pump1 (c(Na_i)/nai) although I'd change c() instead of doing the division here. Another issue to think about is: what is happening to nai during a time step? The purpose of using a kinetic scheme in this context is for numerical stability. Is there a chance that nai can go negative or change drastically in a single time step? A lot of times, pumps are set up so that in a time step they start out with a large current which is then held constant over the entire timestep which changes the nai too much. This is the beauty of the implicit methods. The value of nai that is used is the value at the END of the time step.




Causes the longitudinal diffusion equation to be applied to the specified states. The syntax is the same as the COMPARTMENT statement except that instead of volume, one specifies the flux area between adjacent compartments. This flux area is normally (but not always since the exact form is determined by the coordinate system of the model) an explicit function of "diam". If that is the case, then the average diameter between this segment and each adjacent segment is used to calculate the area through which the longitudinal fluxes flow. Furthermore, the real volume of the compartment is assumed to be proportional to the length of the segment. For example, longitudinal diffusion of sodium ions under the assumption that concentration does not vary radially would look like: KINETIC { COMPARTMENT PI*(diam/2)^2 {nai} LONGITUDINAL_DIFFUSION Dna*PI*(diam/2)^2 {nai} ~ nai << (-ina/FARADAY*PI*diam*(1e4)) } Notice that the compartment volume is really volume per length and the memebrane ina current flows in through an area measured in area/length. Here, diam, is the diameter of the center of the segment. On the other hand, in calculating the longitudinal flux area, the diameter used is appropriate for each edge area of the segment that has an adjacent connecting segment. Longitudinal diffusion in combination with radial diffusion. The original radial diffusion model was written as: KINETIC state { COMPARTMENT i, diam*diam*vol[i] {ca CaBuffer Buffer} ~ ca[0] << (-ica*PI*diam*frat[0]/(2*FARADAY)) FROM i=0 TO NANN-2 { ~ ca[i] <-> ca[i+1] (DFree*frat[i+1], DFree*frat[i+1]) } dsq = diam*diam FROM i=0 TO NANN-1 { dsqvol = dsq*vol[i] ~ ca[i] + Buffer[i] <-> CaBuffer[i] (k1buf*dsqvol,k2buf*dsqvol) } cai = ca[0] } to incorporate longitudinal diffusion requires the additional statement (after the COMPARTMENT statement) LONGITUDINAL_DIFFUSION i, diam*diam*vol[i] {ca} The vol[i] factor here works since it is equivalent to the annulus area. Some caution is recommended with respect to 2-d diffusion. Since longitudinally adjacent annuli are hooked together to allow longitudinal diffusion, the case of changing diameter must be considered carefully to make sure this model makes sense, ie the segments are short enough. Our final example is taken from cabpump.mod: KINETIC state { COMPARTMENT i, (1+beta)*diam*diam*vol[i]*1(um) {ca} COMPARTMENT (1e10)*area1 {pump pumpca} COMPARTMENT volo*(1e15) {cao} : all currents except pump ~ ca[0] << (-(ica-last_ica_pmp)*PI*diam*1(um)*(1e4)*frat[0]/(2*FARADAY) :diffusion FROM i=0 TO NANN-2 { ~ ca[i] <-> ca[i+1] (DFree*frat[i+1]*1(um), DFree*frat[i+1}*(1um) } :pump ~ ca[0] + pump <-> pumpca (c1, c2) ~ pumpca <-> pump + cao (c3, c4) ica_pmp = (1e-4)*2*FARADAY*(f_flux - b_flux)/area1 cai = ca[0] } Here, the beta factor in the compartment size results in free internal calcium being in fast equilibrium with a non-saturable buffer in which the ratio of bound to free calcium is beta. The required statement is: LONGITUDINAL_DIFFUSION i, diam*diam*vol[i] {ca}