Adding generated variable in Run Fitness

Using the Multiple Run Fitter, praxis, etc..
Post Reply
aluchko

Adding generated variable in Run Fitness

Post by aluchko »

I'm looking at the Run Fitness generator in the MRF and was wondering how to have it fit a function rather than a variable. I suspect it's possible by adding a custom channel which writes the desired value but was hoping there was a cleaner way.
ted
Site Admin
Posts: 6287
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Adding generated variable in Run Fitness

Post by ted »

aluchko wrote:how to have it fit a function rather than a variable
Not sure what you mean.
aluchko

Re: Adding generated variable in Run Fitness

Post by aluchko »

My data isn't necessarily a single value like soma.v(0.5) but potentially may be something more complicated due to normalization or some other factor such as here http://senselab.med.yale.edu/modeldb/sh ... odel=97756 where they fit soma.g_KCHANNEL*(v(0.5)-ek)*area(0.5)/1000

Using Fitness Function I'm able to calculate this value, but I'm not sure how to do the same with the Run Fitness generator.
ted
Site Admin
Posts: 6287
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Adding generated variable in Run Fitness

Post by ted »

aluchko wrote:97756 where they fit soma.g_KCHANNEL*(v(0.5)-ek)*area(0.5)/1000

Using Fitness Function I'm able to calculate this value, but I'm not sure how to do the same with the Run Fitness generator.
I hope you can come up with a more compelling example. The model cell is a single compartment, and soma.g_KCHANNEL*(v(0.5)-ek)*area(0.5)/1000 is simply the net transmembrane current carried by the KCHANNEL mechanism. The authors could have avoided this awkward expression (and likely time-consuming, because it would have to be interpreted anew at each time step) by doing two things:

1. Recognizing that the model involved only one mechanism that WRITEs ik.* Immediately the expression for net transmembrane current carried by the KCHANNEL mechanism becomes ik*area(0.5)/1000.

2. Recognizing that, if the surface area of a compartment is 100 um2, current density in mA/cm2 is numerically identical to total current in nA. No need to multiply by area or apply any other scale factors. Just set soma diam to 10 um and L to 10/PI. Now the net current in nA carried by the KCHANNEL mechanism is simply ik.

*--"Ah, but suppose there are other mechanisms that also WRITE ik?"
Fair question. To which here's another: why write the NMODL code for the KCHANNEL mechanism in such a way as to hide its contribution to ik? Or, stated in a more positive way, why not make a few minor changes to Kchannel.mod so that its current is exposed to hoc? Specifically:
1. In the NEURON block insert
RANGE i
2. In the ASSIGNED block insert
i (mA/cm2)
3. As the very last statement in the BREAKPOINT block insert
i = ik

Compile the mechanism, and you will find that it now has a new range variable, known to hoc as i_KCHANNEL, which tells you the current generated by the KCHANNEL mechanism.

"Yeah, but what if I the time comes when I really have to use some awful hoc expression instead of a simple variable name?"
Here's a hint, but it comes at the cost of a bet, specifically: I bet you a nickel you'll never have to.
The hint is to use a custom proc advance() (see page 161 of The NEURON Book).

Code: Select all

proc advance() {
  fadvance()
  foo = . . . some ugly code that calculates a value . . .
}
The value of foo will be updated at each time step and you can use it for whatever purpose you like.

One last item: I know you didn't write the code in question, but here's a comment about naming conventions: for the sake of readability.
--UPPERCASE is best reserved for names of constants.
--Capitalized or CamelCase is best reserved for names of point processes and other object classes.
--all other names--names of scalar variables, doubles, strings, objrefs, sections, and density mechanisms (i.e. suffixes)--should probably be in lower case.

Remind me to collect on my bet when I run into you at The Restaurant at the End of the Universe.
aluchko

Re: Adding generated variable in Run Fitness

Post by aluchko »

Thanks the proc advance solution works great.

The reason I wanted to make sure I have arbitrary expression support is I'm developing tool to work over the MRF and wanted to make sure I had maximum flexibility before I settled on the generator since I don't necessarily know the user's requirements.

thanks,
Aaron
aluchko

Re: Adding generated variable in Run Fitness

Post by aluchko »

I think I may have a legitimate scenario.

I'm working with some data from frog eggs that were given calcium channels. A voltage clamp was used and the resulting current was measured.

My current optimization setup involves a separate generator for each voltage and matching the resulting currents.

However we have data sets from multiple frog eggs and I'd like to make use of them. We can just average them, however the actual density of the Ca2+ channels in the membrane of each varies, so before combining the data we first normalize each data set by the maximum observed current so each activation is represented by values [-1,1].

If we're to then fit that same data in neuron we have the issue where we're no longer fitting current, but current normalized by the maximum observed current. It's not really proper to divide our simulated data by the same maximum current from (one of) the experiments, and we're still guessing at the channel densities anyway. Thus we normalize by the maximum current generated by that simulated model.

This brings up two issues, 1) we need to normalize the current for model Z against the maximum current for Z. But if that max current is generated by generator X and we haven't run X yet then we can't compute the normalized current for the current generator Y. And even when we are running X itself we don't know what the max current in X will be so we still can't normalize that data. Also 2) we're no longer fitting a constant but a variable.

For 2) the solution is the one you gave using proc advance().

For 1) the only idea I can come up with is to take note of the voltage producing maximum current in the experiments (hopefully always the same), and make an additional copy of the corresponding generator with 0 weight. We'd run this generator first and it would find the maximum current so the following real generators can normalize with that value. (could also hack up a fitnessfunction to do this in 1 pass to avoid the extra generator)

P{erhaps,robably} I'm thinking about this wrong, but I would like to try fitting the averaged frog egg data and I'm not sure how else to handle it.
Post Reply