-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
mne.minimum_norm.source_band_induced_power has a label param, but in principle it should be possible to return results for multiple labels. Looking at the algorithm, our implementation appears to be:
-
Compute inverse operator
Krestricted to a label:mne-python/mne/minimum_norm/time_frequency.py
Line 372 in 6a701d3
K, sel, Vh, vertno, is_free_ori, noise_norm = _prepare_source_params( -
Compute PSDs for each epoch in parallel:
mne-python/mne/minimum_norm/time_frequency.py
Lines 396 to 397 in 6a701d3
out = parallel( my_compute_source_tfrs( Within each parallel split, take the sum across each epochs:
mne-python/mne/minimum_norm/time_frequency.py
Lines 292 to 294 in 9547c13
power += power_e if with_plv: plv += plv_e -
Take the sum across parallel-splits-of-epochs:
mne-python/mne/minimum_norm/time_frequency.py
Lines 412 to 413 in 6a701d3
power = sum(o[0] for o in out) power /= len(epochs_data) # average power over epochs -
Compute PLV if requested (only used by
source_induced_power, neversource_band_induced_power), noise normalize (i.e., multiply each vertex by some value), baseline correct, returnpowerandplv.
So I think we should in principle be able to add support for list-of-labels for source_band_induced_power and probably also source_induced_power when return_plv=False by doing the following:
- Document the shape of the ndarray that is currently returned (something like
(n_vertices, n_freqs, n_times)) - Add
return_plv=Truetosource_induced_power(the way it acts currently) - Fix documentation of
source_induced_powerto note that it returns bothpowerandplv(whenreturn_plv=True) and add return shapes - Fix documentation to use
(baseline_mode)s)or whatever rather than repeat all options. - Add some small test that actually checks our
source_band_induced_powervalues (e.g.,assert_allclose(phase_lock[some_indices], [[some_array_values]])). This will be useful for all following changes. - Move
noise_norminside the parallel function. - Add support for list-of-label by computing a new
label_opwherelabel_op @ Kaverages across vertices to convert the(n_vertices, n_channels)operatorKto be shape(n_labels, n_channels). This should only be allowed whenwith_plv/return_plv=False, which is always the case forsource_band_induced_powerand will now optionally be possible forsource_band_powerby step (3) above. - Add test that
label=labelwith a.mean(axis=0)gives the same result aslabel=[label]whenbaseline_modeisNoneormean, and hopefully sufficiently similar for other modes (shouldn't have a huge impact).
For point (8), it would be nice if list-of-label with one element [label] returned an identical to the label=label (single label) in all cases, but it wouldn't with these changes. The baseline correction in the list-of-label case will be done after the power is averaged within the label, whereas in the label=label case (like in our existing example) the averaging is done over already baseline-corrected vertex values within the label. I'm not certain which way is better, but 1) I doubt it makes much difference and 2) I think in principle averaging first is probably better / higher SNR, as averaging across vertices within a label first should in principle increase SNR before something like a z-transform, if used, could otherwise amplify noisy values. But either way I think if we explain the difference clearly in Notes I think we're okay.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status