{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":59093,"databundleVersionId":7469972,"sourceType":"competition"}],"dockerImageVersionId":30646,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# HMS - Harmful Brain Activity Classification\n## Preprocess and plot with MNE (for Human)","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom functools import cache\nfrom typing import Literal\nimport matplotlib.pyplot as plt\n\nBASE_PATH = '/kaggle/input/hms-harmful-brain-activity-classification'\n\ntrain_df = pd.read_csv(f'{BASE_PATH}/train.csv')\ntrain_df.head()\n\n@cache\ndef load_eeg(eeg_id, data_type:Literal['train','test']='train'):\n    eeg_df = pd.read_parquet(f'{BASE_PATH}/{data_type}_eegs/{eeg_id}.parquet')\n    return eeg_df","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eeg_df = load_eeg(1628180742)\neeg_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## MNE\nhttps://mne.tools/stable/index.html","metadata":{}},{"cell_type":"code","source":"import mne","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"info = mne.create_info(\n    eeg_df.columns.to_list(),\n    ch_types=([\"eeg\"]*(len(eeg_df.columns)-1))+['ecg'],\n    sfreq=200\n)\ninfo.set_montage(\"standard_1020\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"raw = mne.io.RawArray(\n    eeg_df.to_numpy().T*1e-6,    # µV to V\n    info\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mne.set_config('MNE_BROWSE_RAW_SIZE','16,8')\nraw.plot(start=20, duration=10)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- [learningeeg.com](https://www.learningeeg.com/montages-and-technical-components#filters) suggests these filters:\n    - Highpass: 1Hz\n    - Lowpass: 70Hz\n    - Notch: 60Hz (50Hz for Europe)","metadata":{}},{"cell_type":"code","source":"raw_filtered = raw.copy().filter(l_freq=1, h_freq=70,).notch_filter(60, picks='eeg')\nraw_filtered.plot(start=20, duration=10)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bipolar = [\n    ['Fp1', 'F7'], ['F7', 'T3'], ['T3', 'T5'], ['T5', 'O1'],    # Left Temporal\n    ['Fp2', 'F8'], ['F8', 'T4'], ['T4', 'T6'], ['T6', 'O2'],    # Right Temporal\n    ['Fp1', 'F3'], ['F3', 'C3'], ['C3', 'P3'], ['P3', 'O1'],    # Left Parasagittal\n    ['Fp2', 'F4'], ['F4', 'C4'], ['C4', 'P4'], ['P4', 'O2'],    # Right Parasagittal\n    ['Fz', 'Cz'], ['Cz', 'Pz'],   # Central\n]\n\nanode, cathode = list(map(list,zip(*bipolar)))\n\nraw_bip_ref = mne.set_bipolar_reference(raw_filtered, anode=anode, cathode=cathode)\nraw_bip_ref.plot(start=20, duration=10)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"raw_bip_ref.time_as_index(1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Utility\n\nIn summary, you can copy and use the following cell.","metadata":{}},{"cell_type":"code","source":"from functools import cache\nfrom typing import Literal\nimport numpy as np\nimport pandas as pd\n\nimport mne\n\nmne.set_config('MNE_BROWSE_RAW_SIZE','16,8')\n\n@cache\ndef load_eeg(eeg_id, data_type:Literal['train','test']='train'):\n    BASE_PATH = '/kaggle/input/hms-harmful-brain-activity-classification'\n    eeg_df = pd.read_parquet(f'{BASE_PATH}/{data_type}_eegs/{eeg_id}.parquet')\n    return eeg_df\n\n@cache\ndef get_filtered_bipolar(eeg_id, data_type:Literal['train','test']='train'):\n    bipolar = [\n        ['Fp1', 'F7'], ['F7', 'T3'], ['T3', 'T5'], ['T5', 'O1'],    # Left Temporal\n        ['Fp2', 'F8'], ['F8', 'T4'], ['T4', 'T6'], ['T6', 'O2'],    # Right Temporal\n        ['Fp1', 'F3'], ['F3', 'C3'], ['C3', 'P3'], ['P3', 'O1'],    # Left Parasagittal\n        ['Fp2', 'F4'], ['F4', 'C4'], ['C4', 'P4'], ['P4', 'O2'],    # Right Parasagittal\n        ['Fz', 'Cz'], ['Cz', 'Pz'],   # Central\n    ]\n    anode, cathode = list(map(list,zip(*bipolar)))\n\n    eeg_df = load_eeg(eeg_id, data_type)\n    \n    info = mne.create_info(\n        eeg_df.columns.to_list(),\n        ch_types=([\"eeg\"]*(len(eeg_df.columns)-1))+['ecg'],\n        sfreq=200\n    )\n    info.set_montage(\"standard_1020\")\n    \n    raw = mne.io.RawArray(\n        eeg_df.to_numpy().T*1e-6,    # µV to V\n        info\n    ).filter(l_freq=1, h_freq=70,).notch_filter(60, picks='eeg')\n    \n    return mne.set_bipolar_reference(raw, anode=anode, cathode=cathode)\n\ndef bipolar(eeg_id, offset=0., duration=10.0, data_type:Literal['train','test']='train', plot=True):\n    bip_ref = get_filtered_bipolar(eeg_id, data_type)\n    \n    start = 25.0 + offset - duration/2\n    if plot:\n        bip_ref.plot(start=start, duration=duration)\n    \n    start_idx = bip_ref.time_as_index(start).item()\n    stop_idx = bip_ref.time_as_index(start + duration).item()\n    return bip_ref.get_data(start=start_idx, stop=stop_idx)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Examples","metadata":{}},{"cell_type":"code","source":"data = bipolar(1628180742, 24, 10)\ndata.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = bipolar(1628180742, 6, 10)\ndata.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}