Skip to content

Conversation

@AdoNunes
Copy link
Contributor

Closes #7077

I have added (temporally in the wrong place) a function script to mark suspicious channels of being bad, a muscle artifact detection (in practice almost the same as if Fieltrip) and movement annotation and head position trans correction.

The muscle and movement might be crucial in some datasets when Maxfilter is not applied and currently mne-python does not provide these functions.

@codecov
Copy link

codecov bot commented Nov 21, 2019

Codecov Report

❗ No coverage uploaded for pull request base (master@23dd105). Click here to learn what that means.
The diff coverage is 93.85%.

@@            Coverage Diff            @@
##             master    #7096   +/-   ##
=========================================
  Coverage          ?   89.79%           
=========================================
  Files             ?      447           
  Lines             ?    80506           
  Branches          ?    12873           
=========================================
  Hits              ?    72289           
  Misses            ?     5390           
  Partials          ?     2827

@agramfort
Copy link
Member

@AdoNunes can you your file plot_ and not demo_ so it gets executed thanks

@agramfort
Copy link
Member

@AdoNunes it needs to be in examples/preprocessing folder so it’s rendered by circle ci

@AdoNunes
Copy link
Contributor Author

@AdoNunes it needs to be in examples/preprocessing folder so it’s rendered by circle ci

sorry, I got it now....

@AdoNunes
Copy link
Contributor Author

Why I am getting the ci errors?
Like this:
generating gallery for auto_examples/preprocessing... [ 5%] plot_artifact_detection.py
Killed
Makefile:49: recipe for target 'html_dev-pattern' failed
make: *** [html_dev-pattern] Error 137
Exited with code 2

@jasmainak
Copy link
Member

I suspect it's a memory issue. Can you check using a memory profiler how much memory you consume?

@larsoner
Copy link
Member

To follow what @jasmainak said, you should try to keep examples below 1.5 GB memory consumption, otherwise you risk CircleCI failing. mprof run my_example.py then mprof plot will show you consumption. If you can get away with using 30 sec or 60 sec of data, do read_raw_ctf(fname).crop(None, 30).load_data() to save memory. It's why a lot of our examples start that way.

@AdoNunes
Copy link
Contributor Author

That it's tight! It peaks at 1.7Gb but then it goes down.
image

…python into artifact_detection

conflict
Conflicts:
	examples/preprocessing/plot_artifact_detection.py
@jasmainak
Copy link
Member

Try to see if you're making any redundant copies and get rid of them. You can also use preload=False to save memory.

@AdoNunes
Copy link
Contributor Author

Try to see if you're making any redundant copies and get rid of them. You can also use preload=False to save memory.

By shortening even more, changing the order and decimating first then notching it worked :)

I will fix the ::doc things and I will resubmit

@AdoNunes
Copy link
Contributor Author

I am getting an error and I don't know who is wrong.

When I crop de raw, say from (100, 300). The raw.times starts at 0, although, the raw.first_time is 100. Is that how it is supposed to be?

Because, then the function _calculate_head_pos_ctf returns "quats", the quats[:, 0] is the time, and in chpi.py line 264 -> quats[:, 0] += raw._first_time. So the quats time has an offset that does not match the cropped raw.times and this gives me wrong annotation timings.

Any insights?

@jasmainak
Copy link
Member

I don't know about quats but it looks like you just need to handle it correctly by adding raw.first_time in the right places. You might find this tutorial useful: https://mne.tools/stable/auto_tutorials/raw/plot_30_annotate_raw.html

Let's make it work so that CircleCI renders something with plots and then we can worry about these details later.

raw.notch_filter([60, 120, 180, 240]).resample(300, npad="auto")

# Detect bad channels
bad_chns = detect_bad_channels(raw, zscore_v=4, method='both', t1=0, t2=190,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bad_chns -> bad_chs to be consistent with rest of repo

decreased local correlation with other channels"""

# set recording length
Fs = raw.info['sfreq']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fs -> sfreq

# Get data
raw_copy = raw.copy().crop(t1x, t2x).load_data()
raw_copy = raw_copy.pick_types(meg=True, ref_meg=False)\
.filter(1, 45).resample(150, npad='auto')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You want to hardcode these numbers?

data_chans = raw_copy.get_data()

# Get channel distances matrix
chns_locs = np.asarray([x['loc'][:3] for x in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chns_locs -> ch_locs

def detect_bad_channels(raw, zscore_v=4, method='both', t1=30, t2=220,
neigh_max_distance=.035):
""" detect bad channels based on z-score amplitude deviation or/ and
decreased local correlation with other channels"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a docstring to explain what each of these parameters are

"""
Created on Tue Nov 19 09:40:37 2019

@author: an512
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not kosher. Put this file under mne/preprocessing/ and then format the header like the other files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that these scripts were temporary. Fixing it!

"""

from scipy.stats import zscore
import mne
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mne import should come after numpy and scipy

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually you shouldn't import mne at all unless you're writing a tutorial or a test. You should do relative imports.

@larsoner
Copy link
Member

@mmagnuski let me know if you're happy now and I'll have a look

@mmagnuski
Copy link
Member

@AdoNunes weird error, I don't have a clue, but @larsoner probably knows. :)

@mmagnuski
Copy link
Member

oh, I had an old unrefreshed tab it seems :) I don't have anything to add here, but don't have experience with MEG, so I mostly commented on code style and docs.

@mmagnuski
Copy link
Member

Do we need a test here is the example enough?

@larsoner
Copy link
Member

Yes we need some tests. @AdoNunes you can make use of this existing pos_fname and associated raw file in the testing data:

https://github.com/mne-tools/mne-python/blob/master/mne/preprocessing/tests/test_maxwell.py#L65

Basically choose some thresholds that should mark segments as bad and verify that they are indeed marked as bad. You can iteratively test pos/velocity translational/rotational since it should have all of these types in a short window (we asked the subject to move their head for this recording)

[-0.01964518, 0.13086313, 0.99120578, 0.07258289],
[0., 0., 0., 1.]])

assert_allclose(dev_head_t_ori, dev_head_t['trans'], rtol=1e-5, atol=0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this needs to be nested inside a function like def test_artifact_detection(): otherwise it will be run on test collection (see how we do it in other files).


with warnings.catch_warnings(record=True):
warnings.simplefilter("ignore")
raw = read_raw_fif(raw_fname, allow_maxshield=True).load_data()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allow_maxshield='yes' then you don't need any warnings gymnastics (see existing cHPI code for example)

@AdoNunes
Copy link
Contributor Author

AdoNunes commented Jan 28, 2020 via email

larsoner and others added 4 commits January 28, 2020 15:40
I thought it would be didactically illustrative to show the original head position compared to the averaged. Let's see what Travis complains about...
Copy link
Member

@agramfort agramfort left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AdoNunes
Copy link
Contributor Author

Great!!!!
It took longer than expected! I hope people will use these functions in the future!
Thanks for the help

@agramfort
Copy link
Member

agramfort commented Jan 29, 2020 via email

@larsoner larsoner merged commit cce705b into mne-tools:master Jan 29, 2020
@larsoner
Copy link
Member

Thanks @AdoNunes !

AdoNunes added a commit to AdoNunes/mne-python that referenced this pull request Apr 6, 2020
* artifact detection

* art def

* Rename file

* style corrections

* cropped

* example cropped

* flake corrections

* added docstrings

* fixed doc style errors

* updatex example

* fix docstring

* added offset removal

* added compute_average_dev_head_t

* New head pos trans and annotate movement

* Copy raw instance, corrected pos time

* docstring fix

* movement artifact only

* Updated func names and example

* enh doc & quat average

* define  norm

* docstring correction

* revive CI

* quat 3

* docstrings improvement

* logger and docstrings

* docstrings

* docstring, reference, latest

* funct import

* add func in init

* import typo

* quoted BAD_

* docstrings

* FIX: Nesting test

* added test

* read raw

* test def

* docstring

* docstring

* test function

* WIP: Tweaks

* orig head pos line

I thought it would be didactically illustrative to show the original head position compared to the averaged. Let's see what Travis complains about...

* docstrings

* warning to logger

Co-authored-by: Eric Larson <larson.eric.d@gmail.com>
AdoNunes added a commit to AdoNunes/mne-python that referenced this pull request Apr 6, 2020
* artifact detection

* art def

* Rename file

* style corrections

* cropped

* example cropped

* flake corrections

* added docstrings

* fixed doc style errors

* updatex example

* fix docstring

* added offset removal

* added compute_average_dev_head_t

* New head pos trans and annotate movement

* Copy raw instance, corrected pos time

* docstring fix

* movement artifact only

* Updated func names and example

* enh doc & quat average

* define  norm

* docstring correction

* revive CI

* quat 3

* docstrings improvement

* logger and docstrings

* docstrings

* docstring, reference, latest

* funct import

* add func in init

* import typo

* quoted BAD_

* docstrings

* FIX: Nesting test

* added test

* read raw

* test def

* docstring

* docstring

* test function

* WIP: Tweaks

* orig head pos line

I thought it would be didactically illustrative to show the original head position compared to the averaged. Let's see what Travis complains about...

* docstrings

* warning to logger

Co-authored-by: Eric Larson <larson.eric.d@gmail.com>
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.

ENH: make mne python for CTF data preprocessing more friendly

6 participants