Fix issues affecting Deco2018 Figure 3 reproduction#106
Fix issues affecting Deco2018 Figure 3 reproduction#106zhouzx-UCAS wants to merge 10 commits intoneich:mainfrom
Conversation
Clip the coupling state to [0, 1] before computing the linear coupling term. This matches the behavior of the reference WholeBrain implementation for reproducing Deco et al., 2018 (Current Biology). Without this clipping step, the simulator produces different dynamics and fails to reproduce Figure 3B of the paper.
This fixes several issues in the Deco2014 FIC implementation: - explicitly balance on `Ie` - align the `simulate_nodelay` call with the current function signature - derive the excitatory threshold from the model parameters instead of using a hard-coded value - fix the `_update_J` method call - preserve the best `J` candidate with `.copy()` - use `self.t_max` consistently when deriving the optimization window - remove unused variables and dead code
|
Hi, After looking at your PR I have two comments. First, you are doing the clipping at LinearModel, which I am not sure it is correct, since it is the general coupling method for all linear models, and you do not now at that point what is the nature of the state variables. You do not know if they need to be clipped. In a different model than Deco2014 maybe they have another range. Also, model Deco2014 already clips the gating variables. Look at this And second, wrt to fic mechanism implemented in FICDeco2014, I am sure your changes are right. But I strongly not recommend to use FICDeco2014 as fic mechanism since it is a poorly implemented optimization algorithm, and more important you have FICHerzog2022 mechanism that computes exactly the same, even more accurately, and extremely faster. I have to add a deprecated information on FICDeco2014. In fact, all models that use automatic fic use FICHerzog2022. Let me know what you think @zhouzx-UCAS |
|
@zhouzx-UCAS Also look at the latest PRs from 3 weeks ago, I fixed some of the neuronumba previuos problems, and the Deco 2018 figures are ok now. I have checked your fork and your main branch is 49 commits behind the neuronumba main branch. |
|
Hi Ignacio, Thank you for the quick and thoughtful reply! I agree with both of your comments, but I still have a few thoughts that I would like to discuss with you. 0. Clarification about the code version used for testing I would like to clarify that, over the past few weeks, I have been running all of my tests on the version that already includes your latest merged PRs. I know that the https://github.com/zhouzx-UCAS/neuronumba/tree/PR I am aware that you have already made many important updates to the Deco 2018-related implementation, and I would not have been able to reach the current progress without them. For example, I noticed that the current latest version uses a noise level of 1. About clipping before coupling Regarding clipping before coupling, it does not seem necessary for reproducing Figure 3A, but it does seem necessary for Figure 3B, regardless of whether However, I did see that the current version clips the gating variables in the Deco2014/2018 models, and for that reason I did not suspect clipping to be the cause during nearly two weeks of investigation. The key point is that in the current implementation the gating variables are clipped inside def Deco2018_dfun(state: NDA_f8_2d, coupling: NDA_f8_2d):
# Clamping, needed in Deco2018 model and derivatives...
Se = state[0, :].clip(0.0,1.0)
Si = state[1, :].clip(0.0,1.0)
# Eq for I^E (5). I_external = 0 => resting state condition.
Ie = m[np.intp(P.Jext_e)] * m[np.intp(P.I0)] + m[np.intp(P.w)] * m[np.intp(P.J_NMDA)] * Se + m[np.intp(P.J_NMDA)] * coupling[0, :] - m[np.intp(P.J)] * Si + m[np.intp(P.I_external)]As you can see, the clipping there affects the local state variables used in the local terms, but it does not affect the value of the coupling term itself. By contrast, in WholeBrain, the coupling is computed after clipping: @jit(nopython=True)
def dfun(simVars, coupling, I_external):
Se = simVars[0]; Si = simVars[1] # should be [Se, Si] = simVars
Se = utils.doClamping(Se); Si = utils.doClamping(Si) # Clamping, needed in Deco2014 model and derivatives...
coupl = coupling.couple(Se)
Ie = I0 * Jexte + w * J_NMDA * Se + we * J_NMDA * coupl - J * Si + I_external # Eq for I^E (5). I_external = 0 => resting state condition.So although the difference looks small, the two implementations are not actually equivalent: in neuronumba, clipping currently happens too late to affect the coupling term, whereas in WholeBrain the long-range coupling is computed from the already clamped In practice, this difference seems to have only a limited effect in most cases, but it completely changes the Figure 3B pattern. I can also send you the comparison plots if you would like to check whether this difference is indeed fundamental. If you agree, one possible solution would be to make coupling-state preprocessing model-specific: the base class would keep the default identity behavior, while models such as Deco2014/2018 could override a dedicated preprocessing hook to clip bounded gating variables before coupling is computed. If that sounds reasonable to you, I would be happy to submit a separate PR for that. 2. About FIC Regarding FIC, I fully agree that When using If you think it is still useful to keep @neich Let me know what you think. |
|
Hi @zhouzx-UCAS , sorry for the delay. I see your point about clipping. Maybe we should implement a mechanism so each model has a kind of validate_state() that after computing a new state, it makes all clipping and any other check necessary, so all the next computations (including coupling) use a valid state. Would that be acceptable? About, the FIC issue, yes, your contribution is definitely welcome. Make a separate PR and I will accept it |
|
Hi @neich, Thank you very much for the reply. I will make a separate PR for the FIC issue. And yes, I think a Best, |
|
@zhouzx-UCAS I have created PR #109 to deal with the generic validation of state variables. Check it and if it looks reasonable I will merge it |
|
@zhouzx-UCAS I think that the best course of action is just close this PR, then approve #109 and then you can open a new one with the FIC fixes |
|
Hi @neich, I have now carefully read through your PR #109, and I think the logic is sound. In my tests, the new implementation reproduces the trend reported in the paper, and I found that there are small numerical differences (under the same random seed) compared with the results I previously obtained by clipping directly inside I have also updated the Deco2018 model to be compatible with the new PR #109 mechanism and submitted that as PR #110. In addition, I submitted the FIC fix separately as PR #111. Please let me know if you have any concerns or thoughts about these PRs. Best, |
This PR fixes two implementation issues identified during a detailed reproduction of Deco et al., 2018 (Current Biology), especially Figure 3B.
The main fix clips the coupling state to
[0, 1]before applying linear coupling. This restores consistency with the WholeBrain implementation, whereSe/Siare clamped before long-range coupling is computed. Without this step, neuronumba produces systematically different dynamics and cannot reproduce Figure 3B correctly.In addition, this PR fixes several issues in the Deco2014 FIC implementation uncovered during the reproduction process.