{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2.2.1\n"
]
}
],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"print(pd.__version__)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"# loading emg data & time marker from test-1 folder\n",
"emg_data_path = 'test-new/0-New_Task-recording-0.csv'\n",
"time_marker_path = 'test-new/time_marker.csv'\n",
"\n",
"emg_data = pd.read_csv(emg_data_path, skiprows=[0,1,3,4])\n",
"time_marker = pd.read_csv(time_marker_path)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### EMG data Processing"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" 17 | \n",
" 18 | \n",
" 19 | \n",
" 20 | \n",
" 21 | \n",
" 22 | \n",
" 23 | \n",
" 24 | \n",
"
\n",
" \n",
" Channels | \n",
" | \n",
" | \n",
" | \n",
" | \n",
" | \n",
" | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 2508 | \n",
" 1311 | \n",
" 2601 | \n",
" 1099 | \n",
" 1212 | \n",
" 1028 | \n",
" -1143 | \n",
" -1249 | \n",
"
\n",
" \n",
" 1600 | \n",
" 1865 | \n",
" 1182 | \n",
" 754 | \n",
" 94 | \n",
" 68 | \n",
" 11 | \n",
" -1138 | \n",
" -1130 | \n",
"
\n",
" \n",
" 3200 | \n",
" 382 | \n",
" 961 | \n",
" -327 | \n",
" 240 | \n",
" -462 | \n",
" -75 | \n",
" -445 | \n",
" -66 | \n",
"
\n",
" \n",
" 4800 | \n",
" -493 | \n",
" -87 | \n",
" -1505 | \n",
" -375 | \n",
" -872 | \n",
" -558 | \n",
" -722 | \n",
" -211 | \n",
"
\n",
" \n",
" 6400 | \n",
" -1565 | \n",
" -666 | \n",
" -2092 | \n",
" -724 | \n",
" -1142 | \n",
" -809 | \n",
" -769 | \n",
" 255 | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 95198400 | \n",
" -2717 | \n",
" -2701 | \n",
" -2697 | \n",
" -2706 | \n",
" -2692 | \n",
" -2691 | \n",
" -2680 | \n",
" -2703 | \n",
"
\n",
" \n",
" 95194910 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 95196510 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 95198110 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 95199710 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
"
\n",
"
59504 rows × 8 columns
\n",
"
"
],
"text/plain": [
" 17 18 19 20 21 22 23 24\n",
"Channels \n",
"0 2508 1311 2601 1099 1212 1028 -1143 -1249\n",
"1600 1865 1182 754 94 68 11 -1138 -1130\n",
"3200 382 961 -327 240 -462 -75 -445 -66\n",
"4800 -493 -87 -1505 -375 -872 -558 -722 -211\n",
"6400 -1565 -666 -2092 -724 -1142 -809 -769 255\n",
"... ... ... ... ... ... ... ... ...\n",
"95198400 -2717 -2701 -2697 -2706 -2692 -2691 -2680 -2703\n",
"95194910 0 0 0 0 0 0 0 0\n",
"95196510 0 0 0 0 0 0 0 0\n",
"95198110 0 0 0 0 0 0 0 0\n",
"95199710 0 0 0 0 0 0 0 0\n",
"\n",
"[59504 rows x 8 columns]"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Reset emg data index with Channels\n",
"emg_data = emg_data.set_index('Channels')\n",
"emg_data"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Index: 59504 entries, 0 to 95199710\n",
"Data columns (total 8 columns):\n",
" # Column Non-Null Count Dtype\n",
"--- ------ -------------- -----\n",
" 0 17 59504 non-null int64\n",
" 1 18 59504 non-null int64\n",
" 2 19 59504 non-null int64\n",
" 3 20 59504 non-null int64\n",
" 4 21 59504 non-null int64\n",
" 5 22 59504 non-null int64\n",
" 6 23 59504 non-null int64\n",
" 7 24 59504 non-null int64\n",
"dtypes: int64(8)\n",
"memory usage: 4.1 MB\n"
]
}
],
"source": [
"emg_data.info()"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"# Get signal data from difference of emg_data\n",
"signal_left_lateral = emg_data['21'] - emg_data['3']\n",
"signal_left_medial = emg_data['22'] - emg_data['2']\n",
"\n",
"signal_right_lateral = emg_data['16'] - emg_data['6']\n",
"signal_right_medial = emg_data['17'] - emg_data['5']"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [],
"source": [
"# Get signal data from difference of emg_data\n",
"signal_left_lateral = emg_data['17'] - emg_data['18']\n",
"signal_left_medial = emg_data['19'] - emg_data['20']\n",
"\n",
"signal_right_lateral = emg_data['23'] - emg_data['24']\n",
"signal_right_medial = emg_data['21'] - emg_data['22']"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Mean of RMS Signal 1: 414.735, Std Dev of RMS Signal 1: 702.679\n",
"Mean of RMS Signal 2: 443.660, Std Dev of RMS Signal 2: 578.622\n",
"Mean of RMS Signal 3: 440.785, Std Dev of RMS Signal 3: 622.244\n",
"Mean of RMS Signal 4: 483.905, Std Dev of RMS Signal 4: 758.514\n"
]
}
],
"source": [
"# RMS caculation\n",
"\n",
"# Define the moving average window size\n",
"N = 25\n",
"\n",
"# Function to calculate moving RMS\n",
"def moving_rms(signal, window_size):\n",
" rms = np.sqrt(pd.Series(signal).rolling(window=window_size).mean()**2)\n",
" rms.index = signal.index # Ensure the index matches the original signal\n",
" return rms\n",
"\n",
"# Calculate moving RMS for each channel\n",
"signal_left_lateral_RMS = moving_rms(signal_left_lateral, N)\n",
"signal_left_medial_RMS = moving_rms(signal_left_medial, N)\n",
"signal_right_lateral_RMS = moving_rms(signal_right_lateral, N)\n",
"signal_right_medial_RMS = moving_rms(signal_right_medial, N)\n",
"\n",
"# Calculate mean and standard deviation of the RMS signals\n",
"mean_ch1_rms = np.mean(signal_left_lateral_RMS)\n",
"std_ch1_rms = np.std(signal_left_lateral_RMS)\n",
"\n",
"mean_ch2_rms = np.mean(signal_left_medial_RMS)\n",
"std_ch2_rms = np.std(signal_left_medial_RMS)\n",
"\n",
"mean_ch3_rms = np.mean(signal_right_lateral_RMS)\n",
"std_ch3_rms = np.std(signal_right_lateral_RMS)\n",
"\n",
"mean_ch4_rms = np.mean(signal_right_medial_RMS)\n",
"std_ch4_rms = np.std(signal_right_medial_RMS)\n",
"\n",
"# Print mean and standard deviation values\n",
"print(f'Mean of RMS Signal 1: {mean_ch1_rms: .3f}, Std Dev of RMS Signal 1: {std_ch1_rms: .3f}')\n",
"print(f'Mean of RMS Signal 2: {mean_ch2_rms: .3f}, Std Dev of RMS Signal 2: {std_ch2_rms: .3f}')\n",
"print(f'Mean of RMS Signal 3: {mean_ch3_rms: .3f}, Std Dev of RMS Signal 3: {std_ch3_rms: .3f}')\n",
"print(f'Mean of RMS Signal 4: {mean_ch4_rms: .3f}, Std Dev of RMS Signal 4: {std_ch4_rms: .3f}')"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Channels\n",
"0 NaN\n",
"1600 NaN\n",
"3200 NaN\n",
"4800 NaN\n",
"6400 NaN\n",
"8000 NaN\n",
"9600 NaN\n",
"11200 NaN\n",
"12800 NaN\n",
"14400 NaN\n",
"16000 NaN\n",
"17600 NaN\n",
"19200 NaN\n",
"20800 NaN\n",
"22400 NaN\n",
"24000 NaN\n",
"25600 NaN\n",
"27200 NaN\n",
"28800 NaN\n",
"30400 NaN\n",
"32000 NaN\n",
"33600 NaN\n",
"35200 NaN\n",
"36800 NaN\n",
"38400 101.80\n",
"40000 187.36\n",
"41600 257.64\n",
"43200 258.04\n",
"44800 249.12\n",
"46400 213.04\n",
"dtype: float64"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"signal_left_lateral_RMS.head(30)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"131.65497112394493"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.mean(signal_left_lateral_RMS.loc[:10000000])"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"101.73584628144596"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.std(signal_left_lateral_RMS.loc[:10000000])"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"90.46881927178374"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"signal_left_lateral_RMS.loc[:10000000].std()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Time Marker Processing"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" event_time | \n",
" description | \n",
" tag | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 78357902.0 | \n",
" Cough | \n",
" start | \n",
"
\n",
" \n",
" 1 | \n",
" 79670999.0 | \n",
" Cough | \n",
" end | \n",
"
\n",
" \n",
" 2 | \n",
" 81227489.0 | \n",
" Bite | \n",
" start | \n",
"
\n",
" \n",
" 3 | \n",
" 82465323.0 | \n",
" Bite | \n",
" end | \n",
"
\n",
" \n",
" 4 | \n",
" 84239727.0 | \n",
" Swallow | \n",
" start | \n",
"
\n",
" \n",
" 5 | \n",
" 85434346.0 | \n",
" Swallow | \n",
" end | \n",
"
\n",
" \n",
" 6 | \n",
" 86628547.0 | \n",
" Swallow | \n",
" start | \n",
"
\n",
" \n",
" 7 | \n",
" 87951834.0 | \n",
" Swallow | \n",
" end | \n",
"
\n",
" \n",
" 8 | \n",
" 89673825.0 | \n",
" Swallow | \n",
" start | \n",
"
\n",
" \n",
" 9 | \n",
" 91158663.0 | \n",
" Swallow | \n",
" end | \n",
"
\n",
" \n",
" 10 | \n",
" 92257779.0 | \n",
" Cough | \n",
" start | \n",
"
\n",
" \n",
" 11 | \n",
" 93714668.0 | \n",
" Cough | \n",
" end | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" event_time description tag\n",
"0 78357902.0 Cough start\n",
"1 79670999.0 Cough end\n",
"2 81227489.0 Bite start\n",
"3 82465323.0 Bite end\n",
"4 84239727.0 Swallow start\n",
"5 85434346.0 Swallow end\n",
"6 86628547.0 Swallow start\n",
"7 87951834.0 Swallow end\n",
"8 89673825.0 Swallow start\n",
"9 91158663.0 Swallow end\n",
"10 92257779.0 Cough start\n",
"11 93714668.0 Cough end"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"time_marker = pd.read_csv(time_marker_path)\n",
"time_marker = time_marker[['0-New_Task-recording_time(us)', 'description', 'tag']]\n",
"time_marker = time_marker.rename(columns={'0-New_Task-recording_time(us)': 'event_time'})\n",
"time_marker"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" event_time | \n",
" name | \n",
" tag | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 32030195.0 | \n",
" bite | \n",
" start | \n",
"
\n",
" \n",
" 1 | \n",
" 56294235.0 | \n",
" bite | \n",
" end | \n",
"
\n",
" \n",
" 2 | \n",
" 60284534.0 | \n",
" swallow | \n",
" start | \n",
"
\n",
" \n",
" 3 | \n",
" 62478843.0 | \n",
" swallow | \n",
" end | \n",
"
\n",
" \n",
" 4 | \n",
" 67892676.0 | \n",
" swallow | \n",
" start | \n",
"
\n",
" \n",
" 5 | \n",
" 69216432.0 | \n",
" swallow | \n",
" end | \n",
"
\n",
" \n",
" 6 | \n",
" 71896644.0 | \n",
" swallow | \n",
" start | \n",
"
\n",
" \n",
" 7 | \n",
" 73034917.0 | \n",
" swallow | \n",
" end | \n",
"
\n",
" \n",
" 8 | \n",
" 77098837.0 | \n",
" cough | \n",
" start | \n",
"
\n",
" \n",
" 9 | \n",
" 79341557.0 | \n",
" cough | \n",
" end | \n",
"
\n",
" \n",
" 10 | \n",
" 82717865.0 | \n",
" cough | \n",
" start | \n",
"
\n",
" \n",
" 11 | \n",
" 83992269.0 | \n",
" cough | \n",
" end | \n",
"
\n",
" \n",
" 12 | \n",
" 86344529.0 | \n",
" cough | \n",
" start | \n",
"
\n",
" \n",
" 13 | \n",
" 88152623.0 | \n",
" cough | \n",
" end | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" event_time name tag\n",
"0 32030195.0 bite start\n",
"1 56294235.0 bite end\n",
"2 60284534.0 swallow start\n",
"3 62478843.0 swallow end\n",
"4 67892676.0 swallow start\n",
"5 69216432.0 swallow end\n",
"6 71896644.0 swallow start\n",
"7 73034917.0 swallow end\n",
"8 77098837.0 cough start\n",
"9 79341557.0 cough end\n",
"10 82717865.0 cough start\n",
"11 83992269.0 cough end\n",
"12 86344529.0 cough start\n",
"13 88152623.0 cough end"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"time_marker = pd.read_csv(time_marker_path)\n",
"time_marker = time_marker[['0-New_Task-recording_time(us)', 'name', 'tag']]\n",
"time_marker = time_marker.rename(columns={'0-New_Task-recording_time(us)': 'event_time'})\n",
"time_marker"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [],
"source": [
"# Select column value with odd/even index\n",
"event_start_times = time_marker.loc[0::2]['event_time'].values.astype(int)\n",
"event_end_times = time_marker.loc[1::2]['event_time'].values.astype(int)\n",
"event_names = time_marker.loc[0::2]['description'].values"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [],
"source": [
"# Select column value with odd/even index\n",
"event_start_times = time_marker.loc[0::2]['event_time'].values.astype(int)\n",
"event_end_times = time_marker.loc[1::2]['event_time'].values.astype(int)\n",
"event_names = time_marker.loc[0::2]['name'].values"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"signal LL basic 10s std : 90.469\n",
"signal RL basic 10s std : 64.398\n"
]
}
],
"source": [
"# Get signal basic 10s std\n",
"signal_left_lateral_basics_10s_std = signal_left_lateral_RMS.loc[: 10000000].std()\n",
"print(f\"signal LL basic 10s std : {signal_left_lateral_basics_10s_std: .3f}\")\n",
"\n",
"signal_right_lateral_basics_10s_std = signal_right_lateral_RMS.loc[: 10000000].std()\n",
"print(f\"signal RL basic 10s std : {signal_right_lateral_basics_10s_std: .3f}\")"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"def emg_plot(event_index, event_plot_name, left_std_ratio, left_delta_t, right_std_ratio, right_delta_t):\n",
" \"\"\"\n",
" Plots a 2D quadrant chart for EMG signal analysis with colored squares indicating the quadrant.\n",
"\n",
" Parameters:\n",
" std (float): Standard deviation value of the EMG signal.\n",
" delta_t (float): Delta T value of the EMG signal.\n",
" \"\"\"\n",
" # Create a new figure\n",
" fig, ax = plt.subplots(figsize=(8, 8))\n",
"\n",
" # Determine the quadrant and plot the colored square\n",
" if left_std_ratio > 3 and left_delta_t > 0:\n",
" # First quadrant\n",
" ax.add_patch(plt.Rectangle((2, 2), 6, 6, color='blue', alpha=0.5))\n",
" elif left_std_ratio <= 3 and left_delta_t > 0:\n",
" # Second quadrant\n",
" ax.add_patch(plt.Rectangle((-8, 2), 6, 6, color='blue', alpha=0.5))\n",
" elif left_std_ratio <= 3 and left_delta_t <= 0:\n",
" # Third quadrant\n",
" ax.add_patch(plt.Rectangle((-8, -8), 6, 6, color='blue', alpha=0.5))\n",
" elif left_std_ratio > 3 and left_delta_t <= 0:\n",
" # Fourth quadrant\n",
" ax.add_patch(plt.Rectangle((2, -8), 6, 6, color='blue', alpha=0.5))\n",
" \n",
" # Determine the quadrant and plot the colored square\n",
" if right_std_ratio > 3 and right_delta_t > 0:\n",
" # First quadrant\n",
" ax.add_patch(plt.Rectangle((1.5, 1.5), 6, 6, color='green', alpha=0.5))\n",
" elif right_std_ratio <= 3 and right_delta_t > 0:\n",
" # Second quadrant\n",
" ax.add_patch(plt.Rectangle((-8.5, 1.5), 6, 6, color='green', alpha=0.5))\n",
" elif right_std_ratio <= 3 and right_delta_t <= 0:\n",
" # Third quadrant\n",
" ax.add_patch(plt.Rectangle((-8.5, -8.5), 6, 6, color='green', alpha=0.5))\n",
" elif right_std_ratio > 3 and right_delta_t <= 0:\n",
" # Fourth quadrant\n",
" ax.add_patch(plt.Rectangle((1.5, -8.5), 6, 6, color='green', alpha=0.5))\n",
"\n",
" # Add horizontal and vertical lines to create quadrants\n",
" plt.axhline(y=0, color='black', linestyle='--')\n",
" plt.axvline(x=0, color='black', linestyle='--')\n",
"\n",
" # Add title and axis labels\n",
" plt.title(f'Muscle Coordination Analysis - {event_index}:{event_plot_name}', fontsize=14)\n",
" plt.xlabel('Std Ratio > 3', fontsize=12)\n",
" plt.ylabel('Delta T > 0', fontsize=12)\n",
"\n",
" # Remove axis numbers and labels\n",
" ax.set_xticks([])\n",
" ax.set_yticks([])\n",
" ax.set_xticklabels([])\n",
" ax.set_yticklabels([])\n",
" \n",
" # Set plot legend with color\n",
" plt.legend(['Left', 'Right'], loc='upper left', fontsize=10)\n",
"\n",
" # Set the limits of the plot\n",
" plt.xlim(-10, 10)\n",
" plt.ylim(-10, 10)\n",
"\n",
" # Display the plot\n",
" plt.show()\n"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"78357902"
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"event_start_times[0]"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"79670999"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"event_end_times[0]"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"numpy.int32"
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(event_start_times[0])"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"pandas.core.series.Series"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(signal_left_lateral_RMS)"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Channels\n",
"78358400 369.00\n",
"78360000 380.12\n",
"78361600 285.88\n",
"78363200 238.68\n",
"78364800 215.96\n",
" ... \n",
"79664000 36.44\n",
"79665600 34.52\n",
"79667200 32.32\n",
"79668800 29.92\n",
"79670400 14.52\n",
"Length: 821, dtype: float64"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mask = (signal_left_lateral_RMS.index >= event_start_times[0]) & (signal_left_lateral_RMS.index <= event_end_times[0])\n",
"signal_left_lateral_RMS.iloc[mask]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"ename": "KeyError",
"evalue": "78357902",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:3805\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3804\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m-> 3805\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_engine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcasted_key\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3806\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n",
"File \u001b[1;32mindex.pyx:167\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n",
"File \u001b[1;32mindex.pyx:196\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n",
"File \u001b[1;32mpandas\\\\_libs\\\\hashtable_class_helper.pxi:2606\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[1;34m()\u001b[0m\n",
"File \u001b[1;32mpandas\\\\_libs\\\\hashtable_class_helper.pxi:2630\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[1;34m()\u001b[0m\n",
"\u001b[1;31mKeyError\u001b[0m: 78357902",
"\nThe above exception was the direct cause of the following exception:\n",
"\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[76], line 6\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m series\u001b[38;5;241m.\u001b[39mindex[series\u001b[38;5;241m.\u001b[39mindex\u001b[38;5;241m.\u001b[39mget_loc(timestamp)]\n\u001b[0;32m 5\u001b[0m \u001b[38;5;66;03m# Then use:\u001b[39;00m\n\u001b[1;32m----> 6\u001b[0m start_idx \u001b[38;5;241m=\u001b[39m \u001b[43mget_nearest_index\u001b[49m\u001b[43m(\u001b[49m\u001b[43msignal_left_lateral_RMS\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mevent_start_times\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m \n\u001b[0;32m 7\u001b[0m end_idx \u001b[38;5;241m=\u001b[39m get_nearest_index(signal_left_lateral_RMS, event_end_times[\u001b[38;5;241m0\u001b[39m])\n\u001b[0;32m 8\u001b[0m event_data \u001b[38;5;241m=\u001b[39m signal_left_lateral_RMS\u001b[38;5;241m.\u001b[39mloc[start_idx:end_idx]\n",
"Cell \u001b[1;32mIn[76], line 3\u001b[0m, in \u001b[0;36mget_nearest_index\u001b[1;34m(series, timestamp)\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget_nearest_index\u001b[39m(series, timestamp):\n\u001b[1;32m----> 3\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m series\u001b[38;5;241m.\u001b[39mindex[\u001b[43mseries\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mindex\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimestamp\u001b[49m\u001b[43m)\u001b[49m]\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:3812\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3807\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(casted_key, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m (\n\u001b[0;32m 3808\u001b[0m \u001b[38;5;28misinstance\u001b[39m(casted_key, abc\u001b[38;5;241m.\u001b[39mIterable)\n\u001b[0;32m 3809\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28many\u001b[39m(\u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m x \u001b[38;5;129;01min\u001b[39;00m casted_key)\n\u001b[0;32m 3810\u001b[0m ):\n\u001b[0;32m 3811\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidIndexError(key)\n\u001b[1;32m-> 3812\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01merr\u001b[39;00m\n\u001b[0;32m 3813\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m:\n\u001b[0;32m 3814\u001b[0m \u001b[38;5;66;03m# If we have a listlike key, _check_indexing_error will raise\u001b[39;00m\n\u001b[0;32m 3815\u001b[0m \u001b[38;5;66;03m# InvalidIndexError. Otherwise we fall through and re-raise\u001b[39;00m\n\u001b[0;32m 3816\u001b[0m \u001b[38;5;66;03m# the TypeError.\u001b[39;00m\n\u001b[0;32m 3817\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_indexing_error(key)\n",
"\u001b[1;31mKeyError\u001b[0m: 78357902"
]
}
],
"source": [
"# Convert microsecond timestamps to array indices\n",
"def get_nearest_index(series, timestamp):\n",
" return series.index[series.index.get_loc(timestamp)]\n",
"\n",
"# Then use:\n",
"start_idx = get_nearest_index(signal_left_lateral_RMS, event_start_times[0]) \n",
"end_idx = get_nearest_index(signal_left_lateral_RMS, event_end_times[0])\n",
"event_data = signal_left_lateral_RMS.loc[start_idx:end_idx]"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"ename": "KeyError",
"evalue": "78357902",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:3805\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3804\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m-> 3805\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_engine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcasted_key\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3806\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n",
"File \u001b[1;32mindex.pyx:167\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n",
"File \u001b[1;32mindex.pyx:196\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n",
"File \u001b[1;32mpandas\\\\_libs\\\\hashtable_class_helper.pxi:2606\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[1;34m()\u001b[0m\n",
"File \u001b[1;32mpandas\\\\_libs\\\\hashtable_class_helper.pxi:2630\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[1;34m()\u001b[0m\n",
"\u001b[1;31mKeyError\u001b[0m: 78357902",
"\nThe above exception was the direct cause of the following exception:\n",
"\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[70], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m start_time \u001b[38;5;241m=\u001b[39m \u001b[43msignal_left_lateral_RMS\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mindex\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mevent_start_times\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 2\u001b[0m start_time\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:3812\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3807\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(casted_key, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m (\n\u001b[0;32m 3808\u001b[0m \u001b[38;5;28misinstance\u001b[39m(casted_key, abc\u001b[38;5;241m.\u001b[39mIterable)\n\u001b[0;32m 3809\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28many\u001b[39m(\u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m x \u001b[38;5;129;01min\u001b[39;00m casted_key)\n\u001b[0;32m 3810\u001b[0m ):\n\u001b[0;32m 3811\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidIndexError(key)\n\u001b[1;32m-> 3812\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01merr\u001b[39;00m\n\u001b[0;32m 3813\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m:\n\u001b[0;32m 3814\u001b[0m \u001b[38;5;66;03m# If we have a listlike key, _check_indexing_error will raise\u001b[39;00m\n\u001b[0;32m 3815\u001b[0m \u001b[38;5;66;03m# InvalidIndexError. Otherwise we fall through and re-raise\u001b[39;00m\n\u001b[0;32m 3816\u001b[0m \u001b[38;5;66;03m# the TypeError.\u001b[39;00m\n\u001b[0;32m 3817\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_indexing_error(key)\n",
"\u001b[1;31mKeyError\u001b[0m: 78357902"
]
}
],
"source": [
"start_time = signal_left_lateral_RMS.index.get_loc(int(event_start_times[0]))\n",
"start_time"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"ename": "KeyError",
"evalue": "78357902",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:3805\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3804\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m-> 3805\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_engine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcasted_key\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3806\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n",
"File \u001b[1;32mindex.pyx:167\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n",
"File \u001b[1;32mindex.pyx:196\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n",
"File \u001b[1;32mpandas\\\\_libs\\\\hashtable_class_helper.pxi:2606\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[1;34m()\u001b[0m\n",
"File \u001b[1;32mpandas\\\\_libs\\\\hashtable_class_helper.pxi:2630\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[1;34m()\u001b[0m\n",
"\u001b[1;31mKeyError\u001b[0m: 78357902",
"\nThe above exception was the direct cause of the following exception:\n",
"\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[72], line 5\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# Use nearest method to find the closest index values\u001b[39;00m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;66;03m# start_time = signal_left_lateral_RMS.index.get_loc(event_start_times[0], method='nearest')\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;66;03m# end_time = signal_left_lateral_RMS.index.get_loc(event_end_times[0], method='nearest')\u001b[39;00m\n\u001b[1;32m----> 5\u001b[0m \u001b[43msignal_left_lateral_RMS\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mloc\u001b[49m\u001b[43m[\u001b[49m\u001b[43mevent_start_times\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mevent_end_times\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m]\u001b[49m\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexing.py:1191\u001b[0m, in \u001b[0;36m_LocationIndexer.__getitem__\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 1189\u001b[0m maybe_callable \u001b[38;5;241m=\u001b[39m com\u001b[38;5;241m.\u001b[39mapply_if_callable(key, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mobj)\n\u001b[0;32m 1190\u001b[0m maybe_callable \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_deprecated_callable_usage(key, maybe_callable)\n\u001b[1;32m-> 1191\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_getitem_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmaybe_callable\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexing.py:1411\u001b[0m, in \u001b[0;36m_LocIndexer._getitem_axis\u001b[1;34m(self, key, axis)\u001b[0m\n\u001b[0;32m 1409\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(key, \u001b[38;5;28mslice\u001b[39m):\n\u001b[0;32m 1410\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_validate_key(key, axis)\n\u001b[1;32m-> 1411\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_get_slice_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1412\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m com\u001b[38;5;241m.\u001b[39mis_bool_indexer(key):\n\u001b[0;32m 1413\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_getbool_axis(key, axis\u001b[38;5;241m=\u001b[39maxis)\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexing.py:1443\u001b[0m, in \u001b[0;36m_LocIndexer._get_slice_axis\u001b[1;34m(self, slice_obj, axis)\u001b[0m\n\u001b[0;32m 1440\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m obj\u001b[38;5;241m.\u001b[39mcopy(deep\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[0;32m 1442\u001b[0m labels \u001b[38;5;241m=\u001b[39m obj\u001b[38;5;241m.\u001b[39m_get_axis(axis)\n\u001b[1;32m-> 1443\u001b[0m indexer \u001b[38;5;241m=\u001b[39m \u001b[43mlabels\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mslice_indexer\u001b[49m\u001b[43m(\u001b[49m\u001b[43mslice_obj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mslice_obj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mslice_obj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstep\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1445\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(indexer, \u001b[38;5;28mslice\u001b[39m):\n\u001b[0;32m 1446\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mobj\u001b[38;5;241m.\u001b[39m_slice(indexer, axis\u001b[38;5;241m=\u001b[39maxis)\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:6662\u001b[0m, in \u001b[0;36mIndex.slice_indexer\u001b[1;34m(self, start, end, step)\u001b[0m\n\u001b[0;32m 6618\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mslice_indexer\u001b[39m(\n\u001b[0;32m 6619\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m 6620\u001b[0m start: Hashable \u001b[38;5;241m|\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m 6621\u001b[0m end: Hashable \u001b[38;5;241m|\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m 6622\u001b[0m step: \u001b[38;5;28mint\u001b[39m \u001b[38;5;241m|\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m 6623\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28mslice\u001b[39m:\n\u001b[0;32m 6624\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 6625\u001b[0m \u001b[38;5;124;03m Compute the slice indexer for input labels and step.\u001b[39;00m\n\u001b[0;32m 6626\u001b[0m \n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 6660\u001b[0m \u001b[38;5;124;03m slice(1, 3, None)\u001b[39;00m\n\u001b[0;32m 6661\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m-> 6662\u001b[0m start_slice, end_slice \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mslice_locs\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mend\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstep\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstep\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 6664\u001b[0m \u001b[38;5;66;03m# return a slice\u001b[39;00m\n\u001b[0;32m 6665\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m is_scalar(start_slice):\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:6879\u001b[0m, in \u001b[0;36mIndex.slice_locs\u001b[1;34m(self, start, end, step)\u001b[0m\n\u001b[0;32m 6877\u001b[0m start_slice \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 6878\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m start \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m-> 6879\u001b[0m start_slice \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_slice_bound\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstart\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mleft\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 6880\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m start_slice \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 6881\u001b[0m start_slice \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:6804\u001b[0m, in \u001b[0;36mIndex.get_slice_bound\u001b[1;34m(self, label, side)\u001b[0m\n\u001b[0;32m 6801\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_searchsorted_monotonic(label, side)\n\u001b[0;32m 6802\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m:\n\u001b[0;32m 6803\u001b[0m \u001b[38;5;66;03m# raise the original KeyError\u001b[39;00m\n\u001b[1;32m-> 6804\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m err\n\u001b[0;32m 6806\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(slc, np\u001b[38;5;241m.\u001b[39mndarray):\n\u001b[0;32m 6807\u001b[0m \u001b[38;5;66;03m# get_loc may return a boolean array, which\u001b[39;00m\n\u001b[0;32m 6808\u001b[0m \u001b[38;5;66;03m# is OK as long as they are representable by a slice.\u001b[39;00m\n\u001b[0;32m 6809\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m is_bool_dtype(slc\u001b[38;5;241m.\u001b[39mdtype)\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:6798\u001b[0m, in \u001b[0;36mIndex.get_slice_bound\u001b[1;34m(self, label, side)\u001b[0m\n\u001b[0;32m 6796\u001b[0m \u001b[38;5;66;03m# we need to look up the label\u001b[39;00m\n\u001b[0;32m 6797\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m-> 6798\u001b[0m slc \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlabel\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 6799\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[0;32m 6800\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
"File \u001b[1;32mc:\\ProgramData\\anaconda3\\envs\\snomed\\lib\\site-packages\\pandas\\core\\indexes\\base.py:3812\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 3807\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(casted_key, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m (\n\u001b[0;32m 3808\u001b[0m \u001b[38;5;28misinstance\u001b[39m(casted_key, abc\u001b[38;5;241m.\u001b[39mIterable)\n\u001b[0;32m 3809\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28many\u001b[39m(\u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mslice\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m x \u001b[38;5;129;01min\u001b[39;00m casted_key)\n\u001b[0;32m 3810\u001b[0m ):\n\u001b[0;32m 3811\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidIndexError(key)\n\u001b[1;32m-> 3812\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01merr\u001b[39;00m\n\u001b[0;32m 3813\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m:\n\u001b[0;32m 3814\u001b[0m \u001b[38;5;66;03m# If we have a listlike key, _check_indexing_error will raise\u001b[39;00m\n\u001b[0;32m 3815\u001b[0m \u001b[38;5;66;03m# InvalidIndexError. Otherwise we fall through and re-raise\u001b[39;00m\n\u001b[0;32m 3816\u001b[0m \u001b[38;5;66;03m# the TypeError.\u001b[39;00m\n\u001b[0;32m 3817\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_indexing_error(key)\n",
"\u001b[1;31mKeyError\u001b[0m: 78357902"
]
}
],
"source": [
"# Use nearest method to find the closest index values\n",
"# start_time = signal_left_lateral_RMS.index.get_loc(event_start_times[0], method='nearest')\n",
"# end_time = signal_left_lateral_RMS.index.get_loc(event_end_times[0], method='nearest')\n",
"\n",
"signal_left_lateral_RMS.loc[event_start_times[0] : event_end_times[0]]"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Event 1: Cough\n",
"Start time: 78.358 sec, End time: 79.671 sec\n",
"left std ratio: 1.008, right std ratio: 2.445\n",
"LM_max_index: 79.310, LL_max_index: 78.360, left delta t: 0.950\n",
"RM_max_index: 78.814, RL_max_index: 79.126, right delta t: -0.312\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAApQAAAKnCAYAAAA4Id0/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABP0ElEQVR4nO3deXgUVd7+/7uT7izdCRFoEBBIcEMEVDAsIpLEDQyuyCKoQ0BHHXFDQJ1hFHj8gQ4jjiuOjwugAgIqiKCgo0QcRQ0KuIC4gcgiEIQA6ew5vz/4ph9iFpJUJZWk36/rymVZfbrr051Oc/c5Vee4jDFGAAAAQA2FOV0AAAAAGjYCJQAAACwhUAIAAMASAiUAAAAsIVACAADAEgIlAAAALCFQAgAAwBICJQAAACwhUAIAAMASAiVQgfT0dLlcLk2ePNnpUhqEil6vhIQEJSQkOFJTRdLS0uRyubR161anS6m3Zs+eLZfLpdmzZ9f6sfhbq9/4/aAqCJSw3datW+VyueRyuXTCCSeoqKio3HZff/11sN1pp51Wx1XWH4FAQI8//rhSUlLUokULeTweNWvWTH379tXDDz+svXv3Ol1ig1OXYchuH3zwQfDvYtmyZU6XE5KefPJJjRo1SmeccYbcbrdcLpfS09Nr/HjGGL3xxhsaNGiQ2rZtq8jISMXGxurMM8/U2LFjtXHjRvuKBxzidroANF5ut1s7d+7UypUrlZqaWub2F154QW63W4WFhQ5UVz9s2LBBV1xxhX755RfFx8fr8ssv1/HHH6+DBw/q008/1V//+lc99NBD2rlzp3w+n9Pl1sj777/vdAllPPTQQ7rvvvt0wgknOF1KGS+++KIkyeVy6YUXXtCll17qcEW1r2fPntq0aZP8fr/TpUiS7rjjDklS69at1aJFC/322281fqzff/9dQ4YM0QcffKDjjjtOF110kU488UTl5+fr22+/1cyZM/XEE0/o/fffV3Jysk3PAKh7BErUmj59+mjDhg168cUXywTK/Px8zZ07V6mpqVq6dKlDFTpr+/btuvjii5WZmakZM2bozjvvVHh4eKk269at02233aaCggKHqrTupJNOcrqEMlq3bq3WrVs7XUYZBw4c0BtvvKGePXsqKipKy5Yt0+7du3X88cc7XVqt8nq99WqUYtmyZTr77LPVqlUr3XLLLXr22Wdr9DiFhYW66qqrtHr1al133XV6+umn1aRJk1Jtdu3apYkTJyorK8uO0gHHMOSNWhMdHa1hw4bprbfeUmZmZqnbli5dqszMTI0aNarc+1Z2jtvkyZPLHYJ6/fXXlZSUpJYtWyoqKkrt2rXTgAEDtGTJkjKP8dVXX+m6664LDj+1bt1aAwYM0FtvvVWl57Znzx6NHTtWJ598siIjI+X3+3X11Vfrm2++qdL9JWnixInas2eP/va3v+nuu+8uEyYlqVu3bvrwww/L/CO0bNkypaSkKC4uTtHR0TrrrLP02GOPVXh6QVXbl5yukJaWpu+++06DBg2S3+8v9bvIycnRfffdp3bt2ikqKkpdunTRc889V+HzLO8cyqN/hwsXLlT37t0VHR2t1q1b64477lBOTk6p9vn5+XryySfVv39/tWvXTpGRkWrZsqUGDRqkdevWlWqblpYWfF+NGjUqOHzscrlKtano/TVnzhz17t1bMTExiomJUe/evTVnzpwy7Y4+r+zLL79U//79FRsbq7i4OF111VU1Oj9z3rx5ysnJ0fXXX68//elPKiws1EsvvVRu26Ofw8yZM9WpUydFRUUpPj5eU6ZMUXFxcan2WVlZ+sc//qGkpCS1adNGERERatOmjf70pz/pp59+OmZthw4dUmxsrDp37lzu7UVFRWrTpo1atGih/Px8SVJubq5mzJihM888U3FxcYqJidFJJ52k4cOH6+uvvw7et6Jz9H744QeNGjVKHTp0UFRUlPx+v7p3765x48Yds14rBg4cqFatWll+nJdfflmrV69Wv379NGfOnDJ/x9KRLzcvvviiBgwYUGr/t99+q2HDhqlly5aKjIxUhw4dNHbsWP3+++9lHsPlclXYu1nROcxbt27VsGHD1KxZM8XExCgpKUmrV6+u8PO1hF3vdTQ+BErUqtGjRwd7I4/24osvqmXLlrYN5z3zzDMaPHiwfvjhB1111VW6++67deGFF+rXX38tEygXL16snj17auHCherVq5fGjRungQMHaseOHXrhhReOeayffvpJZ599th5//HGdfPLJuv3225WamqoVK1aod+/e+uyzz475GIFAQK+++qqio6M1fvz4Stu63W6Fhf3fn+rjjz+uyy67TF999ZVGjBihMWPGKCcnR2PHjtXQoUNljCl1/+q2l6Qff/xRvXv31u7duzVy5EilpaUpIiJCxcXFuvzyy/WPf/xDTZs21Z133qnevXtr7NixmjFjxjGf9x89/fTTGj16tDp16qS//OUvatq0qZ588kndeOONpdr9/vvvuuuuu5SXl6fU1FSNHTtWycnJevvtt9WnTx9lZGQE21555ZW64oorJElXXHGFJk2aFPw5lrFjxyotLU3bt2/XDTfcoBtvvFE7duxQWlqa7r777nLvs3btWp133nlyu926+eablZiYqCVLlujCCy9Ubm5utV6PF154QR6PR9dcc42GDBmi6OjoY74nJ0yYoEmTJql37966+eabJR0J7Pfff3+pdps2bdIDDzyg6OhoXXXVVbrrrruUmJioefPmqWfPnvrll18qPU5sbKyGDx+ujRs36pNPPilz+/Lly7Vr1y6NHDlSERERkqSRI0cG39+jRo3SmDFj1LNnT61atUpffPFFpcfbuXOnevbsqblz5+qss87SXXfdpWuuuUYtWrTQk08+Wel961pJCPtjIC753f39738v9TdcnsjIyOD2J598ol69eumNN97QBRdcoLvvvlsJCQl67LHH1Lt3b+3bt89SvTt27FCfPn20cOFCnXPOObrjjjvk9/t18cUXV/r5Zed7HY2QAWy2ZcsWI8n079/fGGNM586dzRlnnBG8ffv27SY8PNyMGzfOGGOMJNOxY8dSjzFy5EgjyWzZsqXM40+aNMlIMqtWrQru6969u4mIiDB79uwp0z4zMzO4vXv3bhMTE2N8Pp/58ssvy7T99ddfg9urVq0yksykSZNKtenTp49xu93m3XffLbV/8+bNJjY21nTt2rXM4/5Renq6kWT69u17zLZH++mnn4zb7TYtW7Y027ZtC+7Py8szSUlJRpJ5+eWXa9y+5Hcnydx///1ljj9r1iwjyQwYMMAUFhYG93/11VcmIiKi3NcrPj7exMfHl9pX8juMi4sz3333XXB/IBAwp556qnG5XGbHjh3B/bm5uWb79u1l6vnmm29MTEyMufDCC8utc9asWWXuY0z576/Vq1cbSaZTp07mwIEDwf0HDhwwp512mpFkPvroo+D+kveHJPPqq6+Wevzrr7/eSDLz588v9/jlWbdunZFkLr/88uC+4cOHG0nmv//9b4XPoUOHDmbnzp3B/Xv37jXHHXeciY2NNXl5eaWex759+8o8zgcffGDCwsLMjTfeWGp/ea9hRkaGkWRGjRpV5nEuv/xyI8ls2rQpeDyXy2USExNLvVeMMaawsNDs378/+P/l/a098cQTRpJ5/PHHyxxr7969ZfbVlptvvrnM580flbyfj66/oKDAeDwe43a7TU5OTpWPV1RUZE455RQjyaxYsaLUbX/961+NJHPDDTeU2i/JJCUllft45f39XXfddUaS+ec//1lqf8nv/I/P1+73OhoneihR60aNGqWvvvoq2CMxe/ZsFRUVafTo0bYex+PxyOPxlNnfvHnz4PacOXN0+PBhjRs3Tt26dSvTtm3btpUeY926dfrkk080cuRIXXTRRaVuO/XUU/XnP/9ZX3/99TGHvktO8j/W8f5o7ty5Kiws1Lhx49SuXbvg/oiICD388MOSVOrK5uq2L9GqVSv9/e9/L7O/ZPh16tSppYbou3btquuvv75az0WS7rzzTnXs2DH4/9HR0Ro+fLiMMaV6sCIjI8u9gKZz585KSUnR6tWrLZ9nWvI6TJ48WXFxccH9cXFxwd7N8l6rfv36adiwYaX2lby3j+45PZaS3qyjX8c//elPpW4rz/3331/qfFC/368rrrhChw4d0ubNm0s9j2bNmpW5f0pKijp37qz//Oc/x6wxMTFR3bt318KFC3Xo0KHg/t9++01vv/22+vbtGzwX0uVyyRijyMjIMqdzhIeH67jjjjvm8aQj74k/qi8X75S47bbbtGnTJt12223Bffv27VNBQYH8fr+ioqKq/Fgff/yxfvjhB11yySXq379/qdsmTpyo5s2ba968ecHTCqorLy9PixYt0vHHHx+8+KjEyJEjKz2X1a73OhonAiVq3fXXXy+PxxO8enX27Nnq1auXTj/9dNuOMXToUGVnZ6tLly4aP368li1bpgMHDpRp9/nnn0uSLr744hod59NPP5V05B/QyZMnl/n57rvvJCn4X7uVnC9Y3vlSvXv3VnR0tNavX1/j9iXOPPPM4LDl0TZs2CCv16vu3buXue28886r2pM4SnmPUxKy//j7W79+vUaMGKH27dsrIiIieF7kW2+9pfz8/DLn6VZXZa9Vyb7yXqvqPIeK5OXlae7cuTruuON02WWXBfdfdNFFat26tRYuXKjDhw+Xe9/qHD89PV1XXnmlWrduLY/HE3wNv/76a+3cubNKtd58883Kzs7W/Pnzg/tmz56twsLCUqcqNGnSRAMGDNDHH3+s7t27a9q0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pZd0zTXXqGfPnrr88svVsWNHZWZm6rPPPlNCQkK5E6Efbf78+UpJSdE111yjxx57TGeffbaioqK0bds2rVmzRnv37q3SnGxt27bVu+++qyuvvFJ33nmn/vWvf+mCCy4ILr34+eefKyMjQ02aNAlevX7SSSfpH//4h8aNG6czzjhDQ4cOlc/n07Jly/Tdd9/piiuu0HXXXRc8RnXbH8vIkSM1b948rVixQt26ddMll1yi33//XfPnz9fFF19ca71Gt99+u95991317dtXQ4cOVVRUlNLT07Vjxw4lJyeX6c0555xzFB0drccee0wHDx4Mni9WEqLL069fP91+++168skn1aVLF1199dXBNZh//fVX3XHHHerXr5+tz6u4uDi47nhlwf7aa6/VhAkT9PLLL+uhhx4qdzaDY7n99tt1++23q1u3bho8eLAKCwv13nvvyRijM888Uxs2bKjW4918883BcyjL653csWOHevXqpc6dO6t79+464YQTtG/fPr355psqKCjQPffcU+njz507VzNnzlRycrJOPvlkNWnSRBs3btTbb78tv99v+ywRR3v44YeDF9aVjEY8/PDDwS+4N954o/r27Rts/9RTT2nKlCmaNGlSqbko3W63lixZoiFDhmjOnDlaunSpLr74YnXo0EH5+fnauHGj0tPTVVBQEPw7DAsL0+zZs9W/f3+lpqZqyJAhio+P12effaYPPvhAJ510UnCGhhJjx47Vu+++q4EDB2r48OHyer167733dNxxx5W7ItRDDz2k//znP5owYYJWrVqls846S5s3b9ayZcs0YMAArVix4pjzZgJl1PE0RQgBf5yH8lhUzjyUxhjz888/myuuuMLExsYan89nLrjgApORkVHuPJQzZ840l19+uYmPjzdRUVGmefPmplevXubZZ581BQUFZR573bp1ZujQoeb44483Ho/HtG7d2lxyySVm2bJlwTYVzUNpjDG///67+fvf/266dOlioqOjTUxMjDnllFPMiBEjzBtvvFGl510iOzvbPPbYYyYpKcn4/X7jdrvNcccdZ8455xzz//1//1+peTRLvPnmmyYpKcnExsaayMhI07VrVzNjxoxyn2t12pf87kaOHFlpvffcc4854YQTTGRkpDn99NPNs88+W+HrVdk8lOXN7VfRHJKvvfaa6d69u/F6vcbv95uhQ4ean376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5ptvNHPmTL388ss6fPiwbrvtNku1bdmyRZJ06qmnBvfl5eXp999/1/jx47VkyRLNnz9fffv21aBBg/TSSy8F261Zs0bR0dFKTU0N1jtz5swKjzVv3jxdccUVatKkiebPn68XXnhB+/fvV3Jysv773/8es9b33ntP3bp100MPPaT27dsrKSlJ//73v5WZmVnj519YWKicnBytW7dOd911l0499VQNGjSoxo8HIEQYAKhjmZmZpm/fvkaSkWQ8Ho/p06ePeeihh8yhQ4dKte3cubNJSkoq8xj33nuvcblcZv369aX2X3TRRUaSWbVqVaU1zJo1y0gyn376qSkoKDCHDh0yK1asMK1atTL9+vUzBQUFFd63sLDQFBQUmBtuuMF069at1G0+n8+MHDmyzH1WrVpVqq6ioiLTpk0b07VrV1NUVBRsd+jQIdOyZUvTp0+fSus/Wn5+vlm2bJm57rrrTGxsrHG73SY1NdW8/PLLZV7PyuzatSv4O5FkevXqZXbs2FHl+wMIXfRQAqhzzZs310cffaSMjAw9/PDDuuKKK/T999/rr3/9q7p27VqlHrZVq1apc+fOOvPMM0vtHzFiRLVq6d27tzwej2JjYzVgwAA1bdpUb775Zplh3kWLFuncc89VTEyM3G63PB6PXnjhBW3atKlaxyuxefNm7dy5U9dff32pYf6YmBhdffXV+vTTTxUIBKr0WB6PRwMHDtTLL7+sPXv26NVXX5XP59NNN92kli1batGiRVV6HL/fr4yMDP33v//Vc889p99//10pKSnatWtXjZ4jgNBBoATgmMTERN17771atGiRdu7cqbFjx2rr1q1VujBn3759atWqVZn95e2rzEsvvaSMjAx98MEHuvnmm7Vp0yYNHz68VJs33nhDQ4cO1QknnKBXXnlFa9asUUZGhkaPHq3c3NxqHe/o+iWpdevWZW5r06aNiouLa3SleU5OjrKyspSVlaWCggL5fD5FRUVV6b5ut1uJiYk699xzdeONN+qDDz7Qzz//rIcffrjadQAILZxpDaBe8Hg8mjRpkv71r3/pm2++OWb75s2b67fffiuzv7x9lenUqVPwQpyUlBQVFRXp+eef12uvvabBgwdLkl555RV16NBBCxYskMvlCt43Ly+vWsf6Y/2Syu3927lzp8LCwtS0adMqPdahQ4f05ptv6tVXX9W7776ryMhIXXHFFXrzzTd18cUX1/iimrZt26pNmzb6/vvva3R/AKGDHkoAda6iIdSS4eM2bdoE90VGRionJ6dM25SUFH377bfasGFDqf3z5s2zVNv06dPVtGlTPfDAAyouLpZ05OrtiIiIUmHyt99+K3OVd2X1/lHHjh11wgknaN68eTLGBPdnZ2fr9ddfD175XZkFCxZo0KBBatmypW644QaFh4cHh71feeUVpaamWrpC+8cff9T27dt18skn1/gxAIQGAiWAOte/f3+lpqbqmWee0apVq/T+++9rxowZGjRokGJiYnTnnXcG23bt2lUbNmzQggULlJGRoa+//lqSdNddd8nv92vgwIGaPXu23nnnHV133XX67rvvLNXWtGlT/fWvf9WmTZuC4fTSSy/V5s2bdeutt+qDDz7QnDlz1Ldv33KHq7t27ar09HS99dZbWrt2rTZv3lzuccLCwjR9+nStX79el156qZYuXapFixYpJSVFBw4cqNIw84gRI3TgwAE9+eST2r17t958800NGzZM0dHR1XrOX331lS644AI988wzWrlypd577z09+uijSklJUfPmzTV+/PhqPR6AEOT0VUEAQs+CBQvMiBEjzCmnnGJiYmKMx+Mx7du3N9dff73ZuHFjqbZbt241F198sYmNjTWSTHx8fPC2jRs3mosuushERUWZZs2amRtuuMG8+eab1brKOyMjo8xtOTk5pn379uaUU04xhYWFxhhjHn74YZOQkGAiIyNNp06dzHPPPWcmTZpk/vgxun79enPuuecar9drJAWvUP/jVd4llixZYnr16mWioqKMz+czF1xwgfn444+r9Dru3LmzSu2O5bfffjPXXXedOemkk4zX6zURERHmxBNPNLfccovZtm2bLccA0Li5jDlqrAUAAACoJoa8AQAAYAmBEgAAAJYQKAEAAGAJgRIAAACWECgBAABgCYESAAAAlhAoAQAAYAmBEgAAAJYQKAEAAGAJgRIAAACWECgBAABgyf8Pez2h27lu0DEAAAAASUVORK5CYII=",
"text/plain": [
"