Skip to content

Conversation

@thorstenhater
Copy link
Contributor

@thorstenhater thorstenhater commented Jun 10, 2025

Begin adding the most requested feature in the history of Arbor: Tuning parameters online.
The API is still rough, but centers on presenting a proxy object of the cell to an editor specific to the cell kind.

The easy parts

This is quite easy for the simple cell kinds: bench, source, and lif, where the original description objects can be used.
In these cases, the editor is a callable object that changes the description object. Example

lif_editor ed = [](lif_cell& lc) { lc.Cm = 42; }

The descriptions will be pre-filled with the current status and map 1:1 on the lowered representations.

Cable Cells

For cable cells, however, we'll need to think a bit more. The most common request seems to be the ability to tweak mechanism parameters. The current, rough-cut, API allows for that, with some limitations.
All CVs with the given mechanism will be affected, ie, setting hh:gkbar=42 on a cell with two non-overlapping instances of hh will not distinguish between instances. Likewise, we currently do not honour iexpr parameters nor do we allow editing with iexpr. Partially painted CVs are fine, though, by virtue of the weight construction.
Editors here are, as the mapping between representations and editable parameters is no longer bijective, objects describing the action without access to current values.

Dealing with partially painted CVs

Due to Arbor model of orthogonal discretisation and decoration this situation might occur, using hh
as an example

CV 0  :    CV 1    :    CV 2
---------------+-------------
               |
  hh gkbar=A   | hh gkbar=B
               |
---------------+-------------
CV 0  :    CV 1    :    CV 2

Now, CV 1 has a value of gkbar = w A + (1 - w) B where w is computed during
lowering. However, without having access to both w and A we cannot compute an update
to gkbar in CV 1.

The above layout can happen for parameters (like Cm) too and requires the same solutions.

A similar situation in which the two instances share but do not cover a CV

CV 0  :    CV 1    :    CV 2
-----------+-----+-------------
           |     |
hh gkbar=A |     | hh gkbar=B
           |     |
-----------+-----+-------------
CV 0  :    CV 1    :    CV 2

Now, CV 1 has a value of gkbar = w A + v B where w and v the respective weights of the
left and right instances of hh. Again, we need access to both the old value A and the weight
on the CV to compute the update gkbar' - gkbar = w (A' - A) where A' is the desired new value.

The above layout canont happen for parameters.

Dealing with partial / region-based edits

This is a similar, but not identical issue to above and consequently hits similar difficulties.
Depending on the usecase, modellers may want to tweak parameters in a specific region
of the morphology only. This is analog to the paint interface.

Before

CV 0  :    CV 1    :    CV 2
---------------+-------------

  hh gkbar=A
               
---------------+-------------
CV 0  :    CV 1    :    CV 2

After editing with new value B and appropriate region expression

CV 0  :    CV 1    :    CV 2
---------------+-------------
               |
  hh gkbar=A   | hh gkbar=B
               |
---------------+-------------
CV 0  :    CV 1    :    CV 2

Proposed semantics (symbolically) if (paint (region "paint-region") hh (gkbar=A))
then (set hh:gkbar=B (region "edit-region")) should set gkbar=B in the region
defined by (intersect (region "paint-region") (region "edit-region"))

The same holds for parameters.

Potential solutions

If we do not want to keep morphologies and CV discretisations alive inside the simulation
(hint: we dont), we need to store a map cv -> (branch, prox, dist) = msegment instead.
Then, the user can construct a list of msegment from a region and a morphology mrf
that is their responsibility to keep alive via this chain

auto ppw = place_pwlin(mrf);
auto ext = thingify(reg);
auto segs = ppw.all_segments(ext);

which can then be used to update parameters.

However, this has problems.

  1. We cannot check whether mrf has been used to construct the cell being edited.

Dealing with derived mechanisms

i.e. those like pas/e=-80. In the current status, we have no way of distinguishing the concrete
instance in a scenario like this:

dec.paint('(all)', A.density('pas/e=-80'))
dec.paint('(all)', A.density('pas/e=-70'))
dec.paint('(all)', A.density('pas/e=-60'))

in fact, the ABI interface presents the name field as pas and the global parameter default e=-70.
By just iterating and looking for the first match on name, we seem to find the last instance.

A corollary of Arbor's rules

We do not allow two (or more) mechanisms with the same dynamics (base + GLOBAL values) to be present on the same
CV (keyword: overpainting). RANGE parameters are blended according to the relative coverage of the CV, but we cannot
do the the same to GLOBAL (how would we blend a reversal potential?)

Thus we cannot allow editing of GLOBAL parameters

Potential solutions
  • add a field to the globals section along the lines of override to store
  • store derived names, i.e. pas/e=-70 somewhere (additionally to original name?)
  • look into the ppack for a match on globals. That might clash with edits if we can allow those (likely, we cannot)

TODO

  • lif
  • source
  • bench
  • cable
    • partial CVs: Ok
    • iexpr
    • restrict to region
    • derived mechanisms, eg pas/e=-80
  • docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant