mbauman / Signals.jl

An abandoned work-in-progress for a high level Signal type with a common timebase (in seconds) and groups of channels. Deprecated in favor of AxisArrays.jl.
github.com/JuliaArrays/AxisArrays.jl
Other
6 stars 0 forks source link

Spectrograms and generalization #9

Closed mbauman closed 9 years ago

mbauman commented 9 years ago

In the case of a spectrogram, we no longer have a vector that describes each channel across time, we have a matrix. And, really, in the data representation, we want to have dimensions (freq, time, channels…), so shoehorning spectrograms into existing Signals would require transposes every time you wanted to work with the spectrogram in a typical analysis.

Further, the frequency dimension is exactly like the time dimension — it also has a vector that labels the dimension. It'd be nice to carry that information around within the Signal, too.

This really smells like there's a further generalization to be made here. Signals are, at their core, an array whose elements are arrays with named and dimensional axes. But must the axes be unit-ful? Are there cases where someone might want axes that aren't time or inverse-time?

We're really starting to get close to NamedArrays.jl functionality here…

mbauman commented 9 years ago

Really, Signals could be thought of as a type with inner and outer arrays. Currently, a Signal{…, N} has elements that are inner arrays of dimension 1, and iterates across an outer array of dimension N (that is, it is itself an array of dimension N). Internally, the data are stored in a dense matrix with dimension N+1, and sig[idxs...] is simply sig.data[:,idxs...]. We could implement spectrograms in a few ways.

  1. A specific Spectrogram type, with time and freq fields. This would probably be the easiest and maybe even the most useful in terms of working with typical data workflows. It'd return matrices of dimension 2: freq by time. sig.data has dimension N+2, and indexing sig[idxs...] is sig.data[:,:,idxs...].
  2. A Signal2d type, with the ability to name and quantify the inner-most axis with whatever type you'd like. The second dimension of the inner array would always be time.
  3. A fully generic Signal{… N_inner, N_outer} type, which would have dimension of N_outer and its iteration would return arrays of dimension N_inner. We'd have names and accessors for all fields, with an NTuple{N_inner, Vector[]} of axis dimensions for each of the inner dimensions. This would be most powerful, but would also take the most work. It'd allow, for example, the result of an FFT to be returned as a Signal (with just a frequency axis, and no time).
mbauman commented 9 years ago

Cc: @codles. It'd be interesting to get feedback from an EEG workflow. I'm still trying to get the vocabulary in how I describe Signals consistent, but I really like this new direction.

mbauman commented 9 years ago

Superseded by #12 which is much more concrete.