Delay Plasticity Only Working in One Direction

Hi @butlerK, this behaviour is unfortunately entirely non-obvious. Currently, Brian’s correct behaviour would have been to raise an error, actually, since you cannot change the delays during a run… This is a feature that would be nice to have, but no one found the time to look into this in detail yet (see Delays as variables and the linked GitHub issue). The reason why this is not possible at the moment is that delays are translated into integer delays (i.e. timesteps) at a beginning of a simulation, and these values are used as the actual delays. As I mention in the discussion linked above, we did this to avoid repeatedly doing the “time delay” → “timestep delay” conversion, but I am not entirely sure whether this is actually saving any meaningful amount of time. If it isn’t, we could remove this optimization and would get delay plasticity for free! In the other discussion I mention the only possible workaround at the moment: use a “batch” approach where you simulate for a certain time and accumulate the delay changes in a variable, without actually changing the delays during the run. Then, update the actual delays based on that variable and continue the simulation. Given that the delay changes are probably small and need a while to sum up before they make a difference, this might not introduce a very big error.

All this does of course not explain your observation that the delay changes only work “in one direction” (but to emphasize again, the changes in the delay variable during a run do not change the actual synaptic delay that is used). The reason is that in a synapse with a pre and post pathway there are two delays, the pre and the post delay, i.e. the time delay after a pre-synaptic/post-synaptic spike, before the on_pre/on_post statement is triggered. Since most synapses do only have the pre pathway, you can directly write S.delay for a Synapses object S, but this is a shorthand for S.pre.delay. The delay for the post pathway does not have such a shorthand, so you always have to access it as S.post.delay. Within code, such as on_pre or on_post, the name delay refers to the delay of the respective pathway. When you said you saw increasing delays from the update in the on_pre but not from the on_post statements, I guess you verified SE.delay, so effectively SE.pre.delay ­– if you have a look at SE.post.delay you should see that it changed as well. But, alas, to repeat myself: seeing these changes does not mean that they are actually influencing the actual simulation delays :frowning:

Hope that cleared things up!

PS: Python code becomes more readable in the forum if you enclose it in three backticks like this:

```
# This is Python code
print("something")
```

I edited your post accordingly.