Skip to content

Commit

Permalink
updated Example Notebooks
Browse files Browse the repository at this point in the history
  • Loading branch information
richrobe committed Sep 30, 2021
1 parent 791c83b commit 1725a27
Show file tree
Hide file tree
Showing 14 changed files with 809 additions and 660 deletions.
14 changes: 4 additions & 10 deletions examples/CFT_Example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,10 @@
"metadata": {},
"outputs": [],
"source": [
"path = Path(\"../example_data/hr_sample_mist.xlsx\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hr_dict = bp.io.ecg.load_hr_phase_dict(path)\n",
"hr_dict = bp.example_data.get_mist_hr_example()\n",
"\n",
"# Alternatively: Use your own data\n",
"# hr_dict = bp.io.ecg.load_hr_phase_dict(\"<path-to-heart-rate-data-dictionary>\")\n",
"df_hr = hr_dict['MIST3']\n",
"\n",
"df_hr.head()"
Expand Down
37 changes: 31 additions & 6 deletions examples/ECG_Analysis_Example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"This example notebook illustrates how to further process time-series heart rate data. This includes assigning study conditions, splitting data further into subphases, resampling data, cutting data of all subjects to equal length, normalizing data, rearranging data, as well as computing aggregated results (such as mean and standard error over all subjects for each (sub)phase.\n",
"This example notebook illustrates how to further process time-series heart rate data extracted from, for instance, ECG data. This includes assigning study conditions, splitting data further into subphases, resampling data, cutting data of all subjects to equal length, normalizing data, rearranging data, as well as computing aggregated results (such as mean and standard error over all subjects for each (sub)phase.\n",
"\n",
" \n",
"As input, this notebook uses the heart rate processing outputs generated from the ECG processing pipeline as shown in <code>ECG_Processing_Example.ipynb</code>).\n",
Expand Down Expand Up @@ -68,6 +68,25 @@
"palette"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
" <b>Note</b>: In order for this notebook to run properly you first need to run the notebook <code>ECG_Processing_Example.ipynb</code> which will export processing results that are used here.\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# path to import and export example processing results\n",
"result_path = Path(\"./results\")"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -139,15 +158,21 @@
"#### Heart Rate Data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Load processed heart rate time-series data of all subjects and concatenate into one dictionary."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Load processed heart rate time-series data of all subjects and concatenate into one dict\n",
"study_data_dict = {}\n",
"for file in list(sorted(Path(\"./results/ecg\").glob(\"hr_result_*.xlsx\"))):\n",
"for file in list(sorted(result_path.joinpath(\"ecg\").glob(\"hr_result_*.xlsx\"))):\n",
" subject_id = re.findall(\"hr_result_(Vp\\w+).xlsx\", file.name)[0]\n",
" study_data_dict[subject_id] = pd.read_excel(file, sheet_name=None, index_col=\"time\")"
]
Expand Down Expand Up @@ -1075,14 +1100,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Compute Heart Rate Variability"
"## Compute Heart Rate Variability (HRV)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For computing *Heart Rate Variability* the following processing steps will be performed:\n",
"For computing *Heart Rate Variability (HRV)* the following processing steps will be performed:\n",
"1. **Load Data**: Load R-peak data per subject and concatenate them into a `SubjectDataDict`, a special nested dictionary structure that contains processed data of all subjects.\n",
"1. **Select Phases** (*optional*): If the following steps should not be performed on the data of *all* phases, but only on a *subset* of them (e.g., because you are not interested in the first phase because it is not relevant for your analysis goal, or you only recorded it for normalizing all other phases against it) this subset phases can be specified and further processing will only be performed on this subset.\n",
"1. **Split into Subphases** (*optional*): If the different phases of your study consist of subphases, which you want to aggregate and analyze separately, you can further split the data in the `SubjectDataDict` further into different subphases, which adds a new dictionary level.\n",
Expand Down Expand Up @@ -1349,7 +1374,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Note at the End:\n",
"## Note at the End\n",
"\n",
"This example notebook had the purpose to show how to \"manually\" process such data step by step. However, `BioPsyKit` also offers an easier, object-oriented, way for performing such processing steps in the `biopsykit.protocols` module. For that, you just need to follow these steps:\n",
"1. Create a new `Prococol` instance (choose from a set of pre-defined, established laboratory protocols, such as `MIST` or `TSST`, or use the `BaseProtocol`)\n",
Expand Down
80 changes: 52 additions & 28 deletions examples/ECG_Processing_Example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"This example notebook illustrates how to import and process ECG data per subject and save intermediate processing results so that further analysis can be performed (e.g., in <code>ECG_Analysis_Example.ipynb</code> or in <code>Protocol_Example.ipynb</code>).\n",
"This example notebook illustrates how to import and process electrocardiogram (ECG) data recorded per subject and how to save intermediate processing results so that further analysis can be performed (e.g., in <code>ECG_Analysis_Example.ipynb</code> or in <code>Protocol_Example.ipynb</code>).\n",
"</div>"
]
},
Expand Down Expand Up @@ -58,9 +58,9 @@
"palette = bp.colors.fau_palette\n",
"sns.set_theme(context=\"notebook\", style=\"ticks\", palette=palette)\n",
"\n",
"plt.rcParams['figure.figsize'] = (10, 5)\n",
"plt.rcParams['pdf.fonttype'] = 42\n",
"plt.rcParams['mathtext.default'] = \"regular\"\n",
"plt.rcParams[\"figure.figsize\"] = (8, 4)\n",
"plt.rcParams[\"pdf.fonttype\"] = 42\n",
"plt.rcParams[\"mathtext.default\"] = \"regular\"\n",
"\n",
"palette"
]
Expand Down Expand Up @@ -156,7 +156,7 @@
"metadata": {},
"outputs": [],
"source": [
"print(ep.ecg_result)"
"display_dict_structure(ep.ecg_result)"
]
},
{
Expand All @@ -166,7 +166,7 @@
"outputs": [],
"source": [
"# Get heart rate and print resulting heart rate \n",
"hr_data = ep.heart_rate['Data']\n",
"hr_data = ep.heart_rate[\"Data\"]\n",
"hr_data.head()"
]
},
Expand All @@ -177,7 +177,7 @@
"outputs": [],
"source": [
"# Plot an overview of the acquired data - with ECG Signal\n",
"fig, axs = ecg.plotting.ecg_plot(ep, key='Data', figsize=(10,5))"
"fig, axs = bp.signals.ecg.plotting.ecg_plot(ep, key=\"Data\")"
]
},
{
Expand All @@ -187,15 +187,17 @@
"outputs": [],
"source": [
"# Plot an overview of the acquired data - without ECG signal\n",
"fig, axs = ecg.plotting.ecg_plot(ep, key='Data', figsize=(10,5), plot_ecg_signal=False)"
"fig, axs = bp.signals.ecg.plotting.ecg_plot(ep, key=\"Data\", plot_ecg_signal=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Compute HRV\n",
"Heart rate variability (HRV) is computed over the complete interval. If you want to compute HRV over different subintervals, you need to split the data first."
"### Compute Heart Rate Variability (HRV)\n",
"Heart rate variability (HRV) is the physiological phenomenon of varying time intervals of consecutive heart beats. HRV is an important marker for the activity of the autonomic nervous system (ANS) since it can be used to assess the activities of the two brances of the ANS: The sympathetic nervous system (SNS) and the parasympathetic nervous system (PNS).\n",
"\n",
"The function `EcgProcessor.hrv_process()` computes HRV over the complete data. If you want to compute HRV over different subintervals, you need to split the data first."
]
},
{
Expand All @@ -204,7 +206,7 @@
"metadata": {},
"outputs": [],
"source": [
"ep.hrv_process(ep, 'Data', index='Vp01', index_name=\"subject_id\")"
"ep.hrv_process(ep, \"Data\", index=\"Vp01\", index_name=\"subject_id\")"
]
},
{
Expand All @@ -220,7 +222,7 @@
"metadata": {},
"outputs": [],
"source": [
"fig, axs = ecg.plotting.hrv_plot(ep, 'Data', figsize=(10,5))"
"fig, axs = bp.signals.ecg.plotting.hrv_plot(ep, \"Data\")"
]
},
{
Expand Down Expand Up @@ -314,7 +316,7 @@
"metadata": {},
"outputs": [],
"source": [
"fig, axs = ecg.plotting.ecg_plot(ep, key='Stress', figsize=(10,5))"
"fig, axs = bp.signals.ecg.plotting.ecg_plot(ep, key=\"Stress\")"
]
},
{
Expand All @@ -323,7 +325,7 @@
"metadata": {},
"outputs": [],
"source": [
"fig, axs = ecg.plotting.hrv_plot(ep, key='Stress')"
"fig, axs = bp.signals.ecg.plotting.hrv_plot(ep, key=\"Stress\")"
]
},
{
Expand Down Expand Up @@ -357,14 +359,14 @@
"outputs": [],
"source": [
"subject_dict = {\n",
" 'Vp01': {\n",
" 'Data': ecg_data, \n",
" 'Time': pd.Series([\"12:32\", \"12:35\", \"12:38\", \"12:41\"], index=[\"Preparation\", \"Stress\", \"Recovery\", \"End\"])\n",
" \"Vp01\": {\n",
" \"Data\": ecg_data, \n",
" \"Time\": pd.Series([\"12:32\", \"12:35\", \"12:38\", \"12:41\"], index=[\"Preparation\", \"Stress\", \"Recovery\", \"End\"])\n",
" }, \n",
" 'Vp02': {\n",
" 'Data': ecg_data_02,\n",
" \"Vp02\": {\n",
" \"Data\": ecg_data_02,\n",
" # The last phase of Vp02 has a length of only 1 minute to demonstrate the functionality of cutting to equal length\n",
" 'Time': pd.Series([\"12:55\", \"12:58\", \"13:01\", \"13:02\"], index=[\"Preparation\", \"Stress\", \"Recovery\", \"End\"])\n",
" \"Time\": pd.Series([\"12:55\", \"12:58\", \"13:01\", \"13:02\"], index=[\"Preparation\", \"Stress\", \"Recovery\", \"End\"])\n",
" }\n",
"}"
]
Expand Down Expand Up @@ -416,10 +418,17 @@
"metadata": {},
"outputs": [],
"source": [
"# load time log file\n",
"timelog_path = Path(\"../example_data/ecg_time_log.xlsx\")\n",
"\n",
"df_time_log = bp.io.load_time_log(timelog_path, index_cols=[\"ID\", \"Condition\"])\n",
"df_time_log = bp.example_data.get_time_log_example()\n",
"# Alternatively: load your own file\n",
"# df_time_log = bp.io.load_time_log(\"<path-to-time-log-file>\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_time_log"
]
},
Expand All @@ -436,7 +445,10 @@
"metadata": {},
"outputs": [],
"source": [
"ecg_base_path = Path(\"../example_data/ecg\")\n",
"# path to folder containing ECG raw data\n",
"ecg_base_path = bp.example_data.get_ecg_path_example()\n",
"# Alternatively: Use your own data\n",
"# ecg_base_path = Path(\"<path-to-ecg-data-folder>\")\n",
"file_list = list(sorted(ecg_base_path.glob(\"*.bin\")))\n",
"print(file_list)"
]
Expand All @@ -456,6 +468,11 @@
"source": [
"from tqdm.auto import tqdm # to visualize for-loop progress\n",
"\n",
"# folder to save processing results (comment to skip)\n",
"ecg_export_path = Path(\"./results/ecg\")\n",
"# create directory and its parent directories (if it not already exists)\n",
"bp.utils.file_handling.mkdirs(ecg_export_path)\n",
"\n",
"# dicionaries to store processing results\n",
"dict_hr_subjects = {}\n",
"dict_hrv_subjects = {}\n",
Expand Down Expand Up @@ -487,9 +504,9 @@
" # save ecg processing result into HR subject dict\n",
" dict_hr_subjects[subject_id] = ep.heart_rate\n",
" \n",
" # save HR data and R-Peak data to file\n",
" bp.io.ecg.write_hr_phase_dict(ep.heart_rate, ecg_export_path.joinpath(\"hr_result_{}.xlsx\".format(subject_id)))\n",
" bp.io.ecg.write_pandas_dict_excel(ep.rpeaks, ecg_export_path.joinpath(\"rpeaks_result_{}.xlsx\".format(subject_id)))"
" # save HR data and R-Peak data to files in export folder (comment to skip)\n",
" # bp.io.ecg.write_hr_phase_dict(ep.heart_rate, ecg_export_path.joinpath(\"hr_result_{}.xlsx\".format(subject_id)))\n",
" # bp.io.ecg.write_pandas_dict_excel(ep.rpeaks, ecg_export_path.joinpath(\"rpeaks_result_{}.xlsx\".format(subject_id)))"
]
},
{
Expand All @@ -507,6 +524,13 @@
"source": [
"display_dict_structure(dict_hr_subjects)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
6 changes: 3 additions & 3 deletions examples/EEG_Example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"palette = bp.colors.fau_palette\n",
"sns.set_theme(context=\"notebook\", style=\"ticks\", palette=palette)\n",
"\n",
"plt.rcParams['figure.figsize'] = (10, 5)\n",
"plt.rcParams['figure.figsize'] = (8, 4)\n",
"plt.rcParams['pdf.fonttype'] = 42\n",
"plt.rcParams['mathtext.default'] = \"regular\"\n",
"\n",
Expand All @@ -53,8 +53,8 @@
"outputs": [],
"source": [
"data, sampling_rate = bp.example_data.get_eeg_example()\n",
"# alternatively:\n",
"#data, sampling_rate = bp.io.eeg.load_eeg_raw_muse(\"<path-to-file>.csv\")"
"# alternatively, load your own data:\n",
"#data, sampling_rate = bp.io.eeg.load_eeg_raw_muse(\"<path-to-muse-eeg-data>\")"
]
},
{
Expand Down
Loading

0 comments on commit 1725a27

Please sign in to comment.