arbor icon indicating copy to clipboard operation
arbor copied to clipboard

Further analysis of Arbor vs. Neuron discrepancy for BBP mechanisms (K_Tst and K_Pst)

Open lukasgd opened this issue 3 years ago • 1 comments

In the BluePyOpt integration, a validation test between Arbor and Neuron has been developed and evaluated for the BBP catalogue that is used in the layer-5 pyramidal cell model. While showing good agreement for most mechanisms, there is a discrepancy for K_Tst and K_Pst that was discussed here (cf. latest results) and cannot be explained by differences in the NMODL definition (driving Neuron with Arbor's NMODL gives the same discrepancy).

The purpose of this issue is to identify the source of this error, possibly by first time-integrating the ODEs for a single-compartimental setup with an individual mechanism using scipy to identify the correct solution and then narrowing down the error in the affected simulator.

lukasgd avatar Oct 24 '22 14:10 lukasgd

Interestingly, just running a Ball-and-Stick cell with any of the BBP channels --- incl K_P and K_T, but excl Nap --- doesn't show measurable differences. Nap is different, there NRN 8 diverges with t, while ARB just show a beginning of unbounded growth.

I'd like a more condensed version of the test case that demonstrates the issue, excl all the surrounding noise and with a significantly simpler morphology.

thorstenhater avatar Apr 17 '24 14:04 thorstenhater

I found the issue. As is New Year's tradition I am trawling the backlog for issues to close and prioritize. Since I had some problems with the Allen mechanisms I decided to check for the same problem here, but now luck. Then I decided to take one look at the generated C++. With SIMD it's ironically easier to see:

DERIVATIVE states {
    LOCAL qt, mInf, hInf, mTau, hTau

    qt   = 2.3^((34 - 21)/10)
    mInf = m_inf(v)
    # vvvvv
    mTau = 0.34 + 0.92*exp(-((v + 81)/59)^2)
    # ^^^^^
    hInf = h_inf(v)
    hTau = 8 + 49*exp(-((v + 83)/23)^2)

    m' = qt*(mInf - m)/mTau
    h' = qt*(hInf - h)/hTau
}

The marked line becomes in the the C++ code:

assign(mTau, S::add(0.34,
                     S::mul(0.92,
                             S::exp(S::mul(S::neg(S::mul(S::add(v, 81.0), 0.016949152542372881)),
                                           S::neg(S::mul(S::add(v, 81.0), 0.016949152542372881)))))));

(modulo clean-up) and one can basically see how precedence is mishandled. For reference, -(...)^2 is misinterpreted as (-(...))^2.

thorstenhater avatar Jan 06 '25 10:01 thorstenhater

after adding some special handling for power when parsing unary (negation)

        assign(mTau,
               S::add(0.34,
                      S::mul(0.92,
                             S::exp(S::neg(S::mul(S::mul(S::add(v, 81.0), 0.016949152542372881),
                                                  S::mul(S::add(v, 81.0), 0.016949152542372881)))))));

which seems correct.

thorstenhater avatar Jan 06 '25 11:01 thorstenhater

Screenshot 2025-01-08 at 15 14 05 For reference; before #2432 Screenshot 2025-01-08 at 15 14 44 And afterwards

thorstenhater avatar Jan 08 '25 14:01 thorstenhater

Case closed

thorstenhater avatar Jan 08 '25 14:01 thorstenhater