mne-tools / mne-icalabel

Automatic labeling of ICA components in Python.
https://mne.tools/mne-icalabel/dev/index.html
BSD 3-Clause "New" or "Revised" License
90 stars 14 forks source link

Add utility function for porting from MNE-Python ICA labels/labels_score data structure to internals #81

Open adam2392 opened 2 years ago

adam2392 commented 2 years ago

IN #66 there's some repeated code for handling the conversion of MNE-Python's ICA internal data structures to labels on our end and vice versa. We should create a robust utility function to ensure bugs don't leak thru.

mscheltienne commented 2 years ago

Can you precise this a bit? I'm not sure I'm following

adam2392 commented 2 years ago

It's mainly code like this in the GUI:

        for label, comp_list in labels2save.items():
            mne_label = ICLABEL_LABELS_TO_MNE[label]
            if mne_label not in self._ica.labels_:
                self._ica.labels_[mne_label] = comp_list
                continue
            for comp in comp_list:
                if comp not in self._ica.labels_[mne_label]:
                    self._ica.labels_[mne_label].append(comp)

and code like this in write_components_tsv

    # extract the component labels if they are present in the ICA instance
    if ica.labels_:
        for label, comps in ica.labels_.items():
            this_status = "good" if label == "brain" else "bad"
            if label in ICLABEL_LABELS_TO_MNE.values():
                for comp in comps:
                    status[comp] = this_status
                    ic_type[comp] = label

and we'll probably want to modify the ICA instance in place when running the automated models, so like in ICLabel:

    if inplace:
        from mne_icalabel.config import ICLABEL_LABELS_TO_MNE

        ica.labels_scores_ = labels_pred_proba
        argmax_labels = np.argmax(labels_pred_proba, axis=1)

        # add labels to the ICA instance
        for idx, (_, mne_label) in enumerate(ICLABEL_LABELS_TO_MNE.items()):
            auto_labels = argmax_labels.index[idx]
            if mne_label not in ica.labels_:
                ica.labels_[mne_label] = auto_labels
                continue
            for comp in auto_labels:
                if comp not in ica.labels_[mne_label]:
                    ica.labels_[mne_label].append(comp)

These I just wrote up for the sake of making it work, but prolly best to have a private API for interfacing the conversion between MNE and our ICA label semantics.

mscheltienne commented 2 years ago

OK sure!