AllenInstitute / MIES

Multichannel Igor Electrophysiology Suite
https://alleninstitute.github.io/MIES/user.html
Other
22 stars 6 forks source link

Allow the user to do basic analysis on sweeps #238

Closed t-b closed 5 years ago

t-b commented 5 years ago

User requirements:

Implementation:

We serialize the GUI selections

grafik

into formulas:

(Mean(Derivative((Cursors(AB), AD, "1;3")))-Mean([100ms, 200ms], AD)) vs (Max(Cursors(EF), DA) + Stddev(Cursors(GH), DA))

Where "1;3" is the range of sweeps, defaulting to all sweeps. The sweep list can be also include "removed headstages". The syntax is "1[0,2];2;" which means that headstage 0 and 2 are removed from sweep 1 and all headstages are shown for sweep 2. Sweeps 1 and 3 can have different x scaling and different number of points.

Further ideas:

Known limitations:

Data magnitudes:

Related issue #38.

ukos-git commented 5 years ago

Formula Parser

tokenizer

parse formula to structured json

respect order of calculation: * > +

min - max * sdev

[
  {
    "operator": "+",
    "operation": [
      {
        "function": "min",
        "range": [
          "-inf",
          "inf"
        ],
        "channelType": "AD",
        "sweepList": "1;2;3;"
      }
    ]
  },
  {
    "operator": "-",
    "operation": [
      {
        "operator": "+",
        "operation": [
          {
            "function": "max",
            "range": [
              "-inf",
              "inf"
            ],
            "channelType": "AD",
            "sweepList": "1;2;3;"
          }
        ]
      },
      {
        "operator": "*",
        "operation": [
          {
            "function": "sdev",
            "range": [
              "-inf",
              "inf"
            ],
            "channelType": "AD",
            "sweepList": "1;2;3;"
          }
        ]
      }
    ]
  }
]

Parameters

Formula Check

check valid function names

define a list of valid functions like min,max, derivative

check input wave type

3 types of input waves:

FAIL for invalid input wave usage:

Mean(Derivative) →ok Derivative(Mean) →fail

operations possible on same type and mixed type input waves:

t-b commented 5 years ago

@timjarsky We've discussed how to tackle that today. We would leverage the new JSON XOP to use JSON as intermediate data structure for the parsed formula. This does require IP8 but we already agreed to switch to IP8 only IIRC.

t-b commented 5 years ago

@timjarsky Thx.

ukos-git commented 5 years ago

I consider using a variant of json logic for operations:

{
  "+": [
    1,
    1
  ]
}

instead of the previous suggestion which would look more complicated:

{
  "operator": "+",
  "operation": [
    1,
    1
  ]
}
ukos-git commented 5 years ago

so the syntax for a function call would be similar with the function name as group member.

{
  "min": {
    "range": [
      "-inf",
      "inf"
    ],
    "channelType": "AD",
    "sweepList": "1;2;3;"
  }
}
t-b commented 5 years ago

Don't forget the ignored headstages which probably means that sweeplist needs to be split up.

ukos-git commented 5 years ago

Other than json logic, I currently do not support more than 2 columns of operations:

{
  "+": [
    1,
    1,
    1
  ]
}

That would make the parsing more complicated and I don't see the benefits, as we would need to create the equivivalent wrappers to MatrixOp sumCols for all other operations like columnwise multiplication etc.

You can still add formula like 1+1+1 but it will be calculated in two steps as 1+(1+1).

{
  "+": [
    1,
    {
      "+": [
        1,
        1
      ]
    }
  ]
}
timjarsky commented 5 years ago

@ukos-git is it also possible to support channel number? e.g. AD2

t-b commented 5 years ago

@timjarsky channel numbers are not in the original proposal but we can certainly add them.

@ukos-git we have specified "ad" as all channels of type ad, now "ad2" would mean the obvious.

ukos-git commented 5 years ago

Other than json logic, I currently do not support more than 2 columns of operations:

The multi-column approach is back for addition and multiplication with the current state machine code.

ukos-git commented 5 years ago

multi-columns now for all operations. For the inverse operations (-, /) the first element (dividend, minuend) is inverted. State Machine now fully working but uses lookaheads to determine the order of calculation.

timjarsky commented 5 years ago

@ukos-git @t-b regarding

operations possible on same type and mixed type input waves:

(min + max)
(min * derivative)
(derivative * derivative)

could we also support (in this PR or in the future) e.g., max(derivative(AD)) and max(derivative(derivative(AD)) and integral variations?

ukos-git commented 5 years ago

Screenshot from 2019-09-06 01-08-23

concatenation of functions should not be a problem. I hope the formula parser is robust enough.

max(derivative(derivative(sweeps(cursors(A,B),channel(AD),0;1;2))))

There are still some issues. The most urgent is that operations with sweeps like addition have to be reworked in another way. Calculating with 1dimensional arrays works, though, which means that you can use min(sweeps(cursors(A,B),channel(AD),0;1;2))/2 but not sweeps(cursors(A,B),channel(AD),0;1;2)/2

Other minor issues are

JSON Logic has some additional elements that could come in useful: http://jsonlogic.com/operations.html Please take a look and see if there is anything interesting that could help.

I would personally add an array creation operation () for an easier sweepList and sweepList should be an array then.

1…5 → [1,2,3,4,5]
timjarsky commented 5 years ago

@t-b if you have time tomorrow (Friday) could we test this together?

t-b commented 5 years ago

@timjarsky Yes I have time, how about 10am?

timjarsky commented 5 years ago

@t-b 10am will work. FYI the display button may be missing it's control action procedure.

t-b commented 5 years ago

@ukos-git Here is the whishlist of changes from the testing on friday.

Roughly in the order of importance:

NeedsMoreInfoTopics

Example:

  # save to JSON
  [
    "description" : "minimum",
    "formula" : "min(sweeps(cursors(A,B),channel(AD),[1...inf]))",
    "cursors" : [{A : "100ms"}, {B : "200ms"}],
    "sweeps" " [ 1, 2, 3],
    "experiment" : [ "filea.nwb", "fileb.nwb"]
  ,
    ...
  ]

Separate issue https://github.com/AllenInstitute/MIES/issues/273.

Separate issue https://github.com/AllenInstitute/MIES/issues/281.

ukos-git commented 5 years ago

I kindly ask you to read the documentation that I added. https://github.com/AllenInstitute/MIES/pull/245/commits/61fd68aef6094b8e70e26567e45aa0b4eb2f671a

I will polish the GUI a bit more and do some fixups. I want to bring the remaining bullet points to separate issues to discuss the problems that are only solvable with more time on the associated PR. We should first quit these remaining discussions before proceeding further and as there are 100+ issues open in MIES, 5 more should not be a problem.

I strongly recommend to finish the associated PR first. It is mainly data alignment problems that remain to get tackeled. e.g. derivative*data is not a problem but but normalizations using data/max(data) is currently undefined so we need some formula combinations from you @timjarsky and what should be the defined calculation result from it. Best with simple arrays using range(0,100),range(0,200,2) examples or so.

ukos-git commented 5 years ago

A few thing remain to be done in the MR:

Add Curosr hooks

do we still need that?

One trace per channel number (i.e. if you have AD0 and AD9 shown in the data browser, we want to have two traces)

what was the problem with that again? On my end it was working since forever but maybe I need to test with the DataBrowser to see that.

FindLevel how to pass the direction?

Should I add the findlevel? - I really like `findpeak? more

FindPeak [/B=box /I/M=minAmp /N/P/Q/R=(startX,endX )] waveName The FindPeak operation searches for a minimum or maximum by analyzing the smoothed first and second derivatives of the named wave. Information about the peak position, amplitude, and width are returned in the output variables.

t-b commented 5 years ago

min/max has already the correct alignment of data. Mean got it wrong. I'll add some parametric tests to test it and fix it then.