Dear Júlia,

Please forgive the exceedingly late reply, this is a really interesting case and it took some investigation to get to the bottom of this. I then actually sent a reply to the mailing list already a few weeks ago, but it turned out that the mail server had eaten my email!

You are completely right in pointing out the incorrect implementation in NEST for this edge case (where a pre and postsynaptic spike arrive precisely simultaneously at the synapse). I have opened a GitHub issue for it (https://github.com/nest/nest-simulator/issues/1990) and we will address this in the upcoming time. Perhaps we could ask you to be a reviewer on the resulting pull request?

Again many thanks!
Charl


On Wed, Feb 3, 2021, at 18:02, Julia Gallinaro wrote:
Dear Charl,

just a quick update on this triplets issue. First of all, thank you so much again for taking the time and helping me with this!

I noticed from your code I wasn't setting all time constants and delays for the triplets in both neuron and synapse model correctly, and that solved most of the problem. I still noticed some small differences to NEST calculated weights, though, when delays were small and simulation was a bit longer (delay=1.5ms and sim_time=100000ms for example).

I looked a bit more into it, and I think the problem was that on NEST, in practice, all traces are used before increment:

1) Potentiation due to a postsynaptic spike is executed before the update on presynaptic trace (Kplus_ or r1). Which means that, if there was a presynaptic spike exactly at post spike + delay, the value of r1 used is the value propagated since the last presynaptic spike, but before the increment.

2) Depression due to presynaptic spike uses get_K_value(), which gets the K_value (o1) from the postsynaptic neuron. I don't know exactly in which order things are executed, but I guess the value of the synaptic weight is updated before K_value on the neuron model. Or at least assuming that is how it works seems to solve the problem.

In summary, the problem seems to be fixed:
1) In your code: by including before_increment=True for all traces (r1,o2 and o1,r2).
2) In my code: by subtracting 1 from o1_at_pre_spk when there is a postsynaptic spike exactly at pre spike - delay. There is no need to subtract anything from r1 in my case, since I execute depression after potentiation as in NEST code. So in practice, r1 is used before increment.

The differences are small, but the weights seem to match better now.

Cheers,
Júlia

Em seg., 11 de jan. de 2021 às 20:17, Julia Gallinaro <juliavg@gmail.com> escreveu:
Dear Charl,

That is great. I have run some tests here, and am also convinced by this result. Thank you so much for putting effort into this!
All the best for the new year too!

cheers,
Júlia

Em dom., 10 de jan. de 2021 às 08:32, Charl Linssen <nest-users@turingbirds.com> escreveu:
Dear Júlia,

Best wishes for the new year! I have tinkered around a bit with the script, and rewrote it along these lines:
- time is evolved strictly chronologically from spike to spike
- there is a helper function (with parameter t) to obtain the pre or post trace value at any time t
- dendritic delay is accounted for by simply adding the delay value to all the postsynaptic somatic spike times, to obtain the postsynaptic synaptic-perspective spike times

With these changes, the NEST weight evolution seems to be replaced precisely—please see the bottom panel in the figure generated by the script. Caveat: I only did a visual comparison for very long simulation time, it would be great if you could confirm that you are indeed also convinced by this result!

Cheers,
Charl



On Wed, Dec 16, 2020, at 11:32, Julia Gallinaro wrote:
> Hi Charl,
>
> Thanks a lot for looking into this and for the suggestions. I will do
> some more tests considering what you wrote and let you know if I have
> any updates.
>
> I wish you nice Holidays!
>
> Best,
> Júlia
>
> On Wed, 16 Dec 2020 10:22:22 +0100
>  "Charl Linssen" <nest-users@turingbirds.com> wrote:
> >Hi Júlia,
> >
> >Thanks for writing in. Of course, we try to ensure the correctness of
> >NEST Simulator by validation and unit testing, but it is a complex
> >piece of software with a long history, and it is not impossible that a
> >bug may exist in the triplet STDP synapse. I am not the original
> >author of that model, but I've been working with other synaptic
> >plasticity models and would be happy to investigate.
> >
> >You probably know already that the (dendritic) communication delay
> >introduces a few quirks in the code. In particular, the postsynaptic
> >spike arrives at the synapse delayed by this amount, whereas the
> >postsynaptic trace values are obtained without the delay (that is, at
> >the actual time that the somatic action potential is fired).
> >
> >I had a look at your script, and couldn't immediately find anything
> >out of the ordinary. You reproduced the NEST buffering methodology
> >quite accurately (postsynaptic spikes are buffered, and only handled
> >after a presynaptic spike arrives), but during this stage of finding
> >the reason for the discrepancy, it might help to just treat all the
> >spikes (pre and post) chronologically.
> >
> >Perhaps you already found this, but there are some unit tests in place
> >in pynest/nest/tests/test_stdp_triplet_synapse.py, that do some
> >behavioural validation of the synapse. I don't think these cover the
> >general case (as in your script), but might help honing in on a bug.
> >
> >I'll try to get back to you over the next few weeks (modulo the
> >holidays...) with more details. If there are any updates from your
> >side in the mean time, please do share!
> >
> >Best regards,
> >Charl Linssen
> >
> >
> >
> >On Thu, Dec 10, 2020, at 19:16, Julia Gallinaro wrote:
> >> Dear NEST community,
> >>
> >> I am working with the triplets STDP connection on NEST simulations,
> >and I am interested in how the weight dynamics change when the spike
> >trains are altered in some specific ways.
> >>
> >> In order to do that, I run a network simulation using NEST and the
> >triplets STDP rule and save the full spike trains of two neurons which
> >are synaptically connected (one pre and one post). I then recreate the
> >weight changes on a code outside the NEST loop, so that I can
> >manipulate the spike trains and observe what happens to the synaptic
> >weights.
> >>
> >> Trying to validate this approach, though, I find that my code
> >(outside NEST loop) generates different weight values than the NEST
> >simulation when using the same spike trains generated during the
> >simulation. I guess I have some error in my implementation of the
> >triplets rule. I thought it could be something with the implementation
> >of the delays, or the moment when the weights are measured in the
> >simulation, but I have had no success trying to fix it yet.
> >>
> >> I know this is not exactly a NEST issue, but I thought I would give
> >it a try and ask here at the list. In case someone has already worked
> >with the triplets rule and could point me out to what is/could be
> >wrong in my implementation, I would very much appreciate it :)
> >>
> >> Thanks!
> >>
> >> best,
> >> Júlia
> >> _______________________________________________
> >> NEST Users mailing list -- users@nest-simulator.org
> >> To unsubscribe send an email to users-leave@nest-simulator.org
> >>
> >>
> >> *Attachments:*
> >>  * triplets_NEST_offline.py
> _______________________________________________
> NEST Users mailing list -- users@nest-simulator.org
> To unsubscribe send an email to users-leave@nest-simulator.org
>_______________________________________________
NEST Users mailing list -- users@nest-simulator.org
To unsubscribe send an email to users-leave@nest-simulator.org
_______________________________________________
NEST Users mailing list -- users@nest-simulator.org
To unsubscribe send an email to users-leave@nest-simulator.org


Attachments: