NeuroAnalyzer tutorials: Edit: Bad channels/epochs
Initialize NeuroAnalyzer
using NeuroAnalyzer
eeg = load("files/eeg.hdf")
e10 = epoch(eeg, ep_len=10)
delete_epoch!(e10, ep=1:10);Detect bad channels and epochs:
bads = detect_bad(e10,
ch="all",
method=[:flat, :p2p, :var])(bm = Bool[0 0 … 0 0; 0 0 … 0 0; … ; 0 1 … 0 0; 1 1 … 1 1],
be = [3, 4, 5, 6, 19, 26, 27, 32, 52, 53, 63, 98],)
(!) bads will contain matrix of bad channels × epochs (bm) and the list of bad epochs (be).
Detect bad channels and epochs and embed their indices into the object:
detect_bad!(e10,
ch="all",
method=[:flat, :p2p, :var])(!) Matrix of bad channels × epochs will be stored in e10.header.recording[:bad_channel].
View bad channels:
NeuroAnalyzer.plot(e10,
ch="eeg",
bad=true)(!) Bad channels are drawn in less intense color. You may also manually mark channels as bad using iview() and right-clicking on the channel label.
(!) Channels marked as bad will be be automatically excluded from analysis if exclude_bads preference is set to true.
Delete bad epochs:
delete_epoch(e10, ep=bads.be)NeuroAnalyzer.NEURO(NeuroAnalyzer.HEADER(Dict{Symbol, Any}(:weight => -1, :id => "", :middle_name => "", :height => -1, :head_circumference => -1, :handedness => "", :last_name => "528004 SIT 52, 20220831-122227-{d589f756-53fc-4f1b-915d-6e3b8c1560ad}", :first_name => ""), Dict{Symbol, Any}(:epoch_id => "length_10s", :channel_type => ["eeg", "eeg", "eeg", "eeg", "eeg", "eeg", "eeg", "eeg", "eeg", "eeg" … "eeg", "eeg", "ref", "ref", "eeg", "eeg", "eeg", "eog", "eog", "ecg"], :label => ["Fp1", "Fp2", "F3", "F4", "C3", "C4", "P3", "P4", "O1", "O2" … "T5", "T6", "A1", "A2", "Fz", "Cz", "Pz", "EOG1", "EOG2", "ECG"], :prefiltering => ["HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz" … "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz", "HP:0,18Hz LP:104,0Hz"], :gain => [0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218 … 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218, 0.17935713740749218], :data_type => "eeg", :recording_notes => "", :recording_date => "31.08.22", :sampling_rate => 256, :file_type => "EDF"…), Dict(:name => "", :design => "", :notes => "")), [0.0, 0.004, 0.008, 0.012, 0.016, 0.02, 0.023, 0.027, 0.031, 0.035 … 979.961, 979.965, 979.969, 979.973, 979.977, 979.98, 979.984, 979.988, 979.992, 979.996], [0.0, 0.004, 0.008, 0.012, 0.016, 0.02, 0.023, 0.027, 0.031, 0.035 … 9.961, 9.965, 9.969, 9.973, 9.977, 9.98, 9.984, 9.988, 9.992, 9.996], [9.315577492010473 9.710255079592978 … 3.6098484118018916 3.3350885915928945; -4.885131159323168 -4.295718824127116 … -6.997141548495982 0.8552477531963874; … ; -4.302189205623421 -1.7143484202913308 … 0.2371821950384394 10.065182670100544; -29.085297490503052 -23.917738605254527 … -12.83150878412637 -0.26519178414557487;;; 0.8868960310006226 -1.386322963316335 … 14.788383844581976 14.818490253201384; -4.102771275634588 -0.931871582761957 … -0.06405443531212285 -2.24918592688163; … ; 6.287966413876422 8.370093396816323 … -21.435983232351894 -27.89175925719738; -6.207214998229851 -18.714321657611166 … 300.69932311488435 347.39295377041805;;; 1.055185759157597 -2.132424234737236 … -7.180074917116004 -3.9929442767128425; 2.0295537332828966 -3.339140084116014 … -20.849769952743614 -20.55775570426532; … ; 0.6522509869261448 -6.041197498918361 … -37.62357418052237 -35.408288821308375; 0.33112276499815607 -8.971867687369894 … 7.194845638809034 15.731867440934693;;; … ;;; 18.569309294713733 22.89311361283536 … 4.754504204065761 1.2053936473657352; 4.494714018514111 13.02609030059181 … 5.464449674126968 -2.6002896761179723; … ; -0.20841131938738222 12.507075249278618 … -7.241776899887379 -16.6315533872683; -29.255972440543367 -19.25691477874347 … 51.4201275519938 43.947841516236736;;; -1.4299687612461471 -1.312451759360422 … -0.5864522963548433 -6.796427233556682; 0.012850100616558002 0.570051044210814 … 4.181275800561462 -2.4365803124421292; … ; -6.719338934443345 -5.029725597318926 … 3.433495081847715 -3.6700683194834482; 56.10007507089348 40.45064953005437 … 7.692870188391213 -0.9038428781168477;;; -5.560172661791544 -0.11512766557237253 … 19.084481856614218 16.407156218345452; 5.141449021164782 -3.3199724764366856 … 3.3810434974559325 3.5815380669519286; … ; 3.114487125536476 -6.350212297090032 … 9.640660281430884 10.73198290953739; 9.746916484991555 3.5775514229256995 … -21.665073186614904 -26.318948530205475], Dict{Any, Any}(), 0×5 DataFrame
Row │ id start length description channel
│ String Float64 Float64 String Int64
─────┴────────────────────────────────────────────────, 23×9 DataFrame
Row │ label loc_radius loc_theta loc_x loc_y loc_z loc_radius_sp ⋯
│ String Float64 Float64 Float64 Float64 Float64 Float64 ⋯
─────┼──────────────────────────────────────────────────────────────────────────
1 │ Fp1 1.0 108.0 -0.31 0.95 -0.03 1.0 ⋯
2 │ Fp2 1.0 72.0 0.31 0.95 -0.03 1.0
3 │ F7 1.0 144.0 -0.81 0.59 -0.03 1.0
4 │ F3 0.65 129.0 -0.55 0.67 0.5 1.0
5 │ Fz 0.51 90.0 0.0 0.72 0.7 1.0 ⋯
6 │ F4 0.65 51.0 0.55 0.67 0.5 1.0
7 │ F8 1.0 36.0 0.81 0.59 -0.03 1.0
8 │ T3 1.0 180.0 -1.0 0.0 -0.03 1.0
9 │ C3 0.51 180.0 -0.72 0.0 0.7 1.0 ⋯
10 │ Cz 0.0 0.0 0.0 0.0 1.0 1.0
11 │ C4 0.51 0.0 0.72 0.0 0.7 1.0
⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋱
14 │ P3 0.65 231.0 -0.55 -0.67 0.5 1.0
15 │ Pz 0.51 270.0 0.0 -0.72 0.7 1.0 ⋯
16 │ P4 0.65 309.0 0.55 -0.67 0.5 1.0
17 │ T6 1.0 324.0 0.81 -0.59 -0.03 1.0
18 │ O1 1.0 252.0 -0.31 -0.95 -0.03 1.0
19 │ O2 1.0 288.0 0.31 -0.95 -0.03 1.0 ⋯
20 │ A1 1.0 192.0 -0.92 -0.23 -0.55 1.1
21 │ A2 1.0 -12.0 0.92 -0.23 -0.55 1.1
22 │ EOG1 1.01 149.0 -0.87 0.51 -0.37 1.0
23 │ EOG2 1.01 31.0 0.87 0.51 -0.37 1.0 ⋯
3 columns and 2 rows omitted, ["reset_components(OBJ)", "filter(OBJ, ch=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], fprototype=iirnotch, ftype=nothing, cutoff=50, order=8, rp=-1, rs=-1, dir=twopass, w=nothing)", "reset_components(OBJ)", "filter(OBJ, ch=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], fprototype=fir, ftype=hp, cutoff=0.1, order=8, rp=-1, rs=-1, dir=twopass, w=nothing)", "reset_components(OBJ)", "epoch(OBJ, marker=, offset=0, ep_n=nothing, ep_len=2560)", "reset_components(OBJ)", "delete_epoch(OBJ, [10, 9, 8, 7, 6, 5, 4, 3, 2, 1])", "reset_components(OBJ)", "delete_epoch(OBJ, [98, 63, 53, 52, 32, 27, 26, 19, 6, 5, 4, 3])"])
See detect_bad() for the list of available methods and parameters use to tune auto-detection.
Original signal:
NeuroAnalyzer.plot(e10,
ch="all",
ep=1:3)Remove one second ([1, 2] s):
trim!(e10, seg=(1, 2), remove_epochs=false)
NeuroAnalyzer.plot(e10,
ch="all",
ep=1:3)Remove one second ([16, 17] s):
trim!(e10, seg=(16, 17), remove_epochs=true)
NeuroAnalyzer.plot(e10,
ch="all",
ep=1:3)(!) If remove_epochs=false, the segment is removed and the signal is re-epoched (should only be used for signal epoched by fixed length or number of epochs, not by a marker); whole epoch(s) containing the segment are removed if remove_epochs=true.