neuronsimulator / nrn

NEURON Simulator
http://nrn.readthedocs.io
Other
376 stars 113 forks source link

C++: Make prcellstate output more user-friendly #1783

Open seirios opened 2 years ago

seirios commented 2 years ago

When comparing different simulators set to build the same model, printing all variables in memory for some cells can be very useful to ascertain if the simulators have actually built the same model, or otherwise to find the cause for discrepancies. Performing textual diffs of such output can be done automatically and may be helpful in performing software unit tests, regression tests, etc.

Printing all variables can be achieved from python by looping over all variables accessible from neuron.h, but also natively by using ParallelContext.prcellstate(gid). The output produced by prcellstate is understandable and complete, but it's hard to read for non-developers.

I propose the following changes to make it more user-friendly:

For example:

mechanism pas
soma[0](0.5) g 4.705194648149981e-05
soma[0](0.5) e -79.60374956146968

instead of

type=4 pas size=5
1 0 4.705194648149981e-05
1 1 -79.60374956146968

FYI @pramodk

seirios commented 2 years ago

Additionally, in the netcons section:

For example:

dend[12](0.1) GluSynapse <2> InhPoissonStim true 0.1 [1 0 0 1 0 1]
dend[12](0.1) GluSynapse <2> 3424064 true 0.325 [1 0 0 1 0 0]

instead of

2 InhPoissonStim 1 0.1 1 0 0 1 0 1
2 3424064 1 0.325 1 0 0 1 0 0
seirios commented 2 years ago

In the case where there is more than one point process in a segment, printing objects in ascending segment/nri order hinders direct comparison of prcellstate outputs. Since different simulators may instantiate objects in different order, the same objects may appear in different places, e.g., synapses at 12 nri 12 and 12 nri 13 may appear in opposite order depending on which one is created first.

In order to alleviate this, I propose to sort point processes and netcons within a segment by the numeric order of the values of their properties (compare first property, if value is the same, compare second property, etc.). This way we'd get the same output disregarding object creation order.

Additionally, don't repeat the segment for each property in the output.

For example:

pointprocess ProbAMPANMDA_EMS
...
apic[21](0.590909) <258>
 tau_d_AMPA 1.58187115192413
 Use 0.803843021392822
 Dep 685.599548339844
 Fac 26.2235908508301
...
apic[21](0.590909) <257>
 tau_d_AMPA 1.69333803653717
 Use 0.680706322193146
 Dep 663.794250488281
 Fac 8.49701976776123
...

instead of

type=56 ProbAMPANMDA_EMS size=37
...
391 nri 257
 391 0 1.69333803653717
 391 1 0.680706322193146
 391 2 663.794250488281
 391 3 8.49701976776123
...
391 nri 258
 391 0 1.58187115192413
 391 1 0.803843021392822
 391 2 685.599548339844
 391 3 26.2235908508301
...

By placing the nri inside angled brackets (see this example and the previous one), we make it easy to automate comparison. Since the nri won't be the same for different object creation orders, but everything else will, we can filter the output and remove everything inside angled brackets before diffing.

jamesgking commented 2 years ago

Some quick comments following talk with Michael.

There should be a "human readable" flag that switches. In this way, legacy comparisons between NEURON and CoreNEURON can continue to function (CoreNEURON cannot generate all strings at the moment)

From NEURON, strings can be accessed by using the NrnProperty object. Can see how it is employed in places such as nrnmenu.cpp

I will look more into using and how to move forward.