Skip to content

Instantly share code, notes, and snippets.

@neurobittechnologies
Last active May 27, 2020 07:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save neurobittechnologies/e1d13e0b59c56f5804af7c127b36d20d to your computer and use it in GitHub Desktop.
Save neurobittechnologies/e1d13e0b59c56f5804af7c127b36d20d to your computer and use it in GitHub Desktop.
Clinical Grade Sleep Tracking from Heart Rate using Z3Score-HRV API
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 110,
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"import patoolib\n",
"import pyedflib\n",
"import pandas as pd\n",
"import numpy as np\n",
"from tqdm import tqdm\n",
"from requests import post\n",
"from pyndf import create_ndf_from_ecg\n",
"from sklearn.metrics import cohen_kappa_score"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# lets download the ISRUC subgroup 3 dataset, comprises of 10 healthy subjects\n",
"# You can use multi-threading to speed this up, but I had all night to download!\n",
"for i in range(10):\n",
" url = \"http://dataset.isr.uc.pt/ISRUC_Sleep/subgroupIII/%d.rar\" %(i+1)\n",
" response = requests.get(url, stream=True)\n",
" filename = str(i+1) + \".rar\"\n",
" print(\"Downloading %s\" %(filename))\n",
" with open(filename, \"wb\") as handle:\n",
" for data in tqdm(response.iter_content()):\n",
" handle.write(data)\n",
" print(\"unzipping...\")\n",
" patoolib.extract_archive(filename, outdir=\".\")\n",
" print('removing the zip file')\n",
" os.remove(str(i+1) + \".rar\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# license key\n",
"serverURL = 'https://z3score.com/api/v4'\n",
"email = r'youremail@mail.com'\n",
"key = r'yourAccessKey'"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": "Scoring: 1\\1.rec\nScoring: 2\\2.rec\nScoring: 3\\3.rec\nScoring: 4\\4.rec\nScoring: 5\\5.rec\nScoring: 6\\6.rec\nScoring: 7\\7.rec\nScoring: 8\\8.rec\nScoring: 9\\9.rec\nScoring: 10\\10.rec\n"
}
],
"source": [
"# Now lets score all the files\n",
"for i in range(1,11):\n",
" filename = '%d\\\\%d.rec' %(i,i)\n",
" print('Scoring: %s' %(filename))\n",
" edf_file = pyedflib.EdfReader(filename)\n",
" labels = edf_file.getSignalLabels()\n",
" try:\n",
" idx = labels.index('X2')\n",
" except ValueError:\n",
" print('ECG channel not found')\n",
" continue\n",
"\n",
" fs = edf_file.getSampleFrequency(idx)\n",
" ecg = np.asarray(edf_file.readSignal(idx))*10\n",
" edf_file._close()\n",
" stream = create_ndf_from_ecg(ecg, fs)\n",
" response = post(serverURL+'/hrv', files={'file': ('stream.ndf', stream)}, data={'email':email, 'key':key})\n",
" data = response.json()\n",
" auto_scores = np.array(data['message'])\n",
" savefile = '%d\\\\%d_auto.csv' %(i,i)\n",
" np.savetxt(savefile, auto_scores, fmt=\"%d\", delimiter=',')"
]
},
{
"cell_type": "code",
"execution_count": 119,
"metadata": {},
"outputs": [],
"source": [
"# compare accuracy\n",
"# Wake, Light Sleep, Deep Sleep & REM\n",
"df = pd.DataFrame(columns=['Accuracy 1','Accuracy 2','kappa 1', 'kappa 2'])\n",
"for i in range(1,11):\n",
" expert1 = '%d\\\\%d_1.txt' %(i,i)\n",
" expert2 = '%d\\\\%d_2.txt' %(i,i)\n",
" auto = '%d\\\\%d_auto.csv' %(i,i)\n",
"\n",
" exp_score1 = np.genfromtxt(expert1, delimiter=',')\n",
" exp_score2 = np.genfromtxt(expert2, delimiter=',')\n",
" auto_score = np.genfromtxt(auto, delimiter=',')\n",
"\n",
" num_epochs = min(auto_score.size, exp_score1.size, exp_score2.size)\n",
"\n",
" auto_score = auto_score[0:num_epochs,0]\n",
" exp_score1 = exp_score1[0:num_epochs]\n",
" exp_score2 = exp_score2[0:num_epochs]\n",
" exp_score1[exp_score1==1] = 2\n",
" exp_score2[exp_score2==1] = 2\n",
"\n",
" accuracy1 = np.sum(exp_score1 == auto_score)*100.0/num_epochs\n",
" accuracy2 = np.sum(exp_score2 == auto_score)*100.0/num_epochs\n",
" kappa1 = cohen_kappa_score(exp_score1, auto_score)\n",
" kappa2 = cohen_kappa_score(exp_score2, auto_score)\n",
" df = df.append({'Accuracy 1':accuracy1, 'Accuracy 2':accuracy2, 'kappa 1':kappa1, 'kappa 2':kappa2}, ignore_index=True)"
]
},
{
"cell_type": "code",
"execution_count": 120,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Accuracy 1 70.967779\nAccuracy 2 72.601184\nkappa 1 0.556185\nkappa 2 0.579426\ndtype: float64"
},
"metadata": {},
"execution_count": 120
}
],
"source": [
"df.mean()"
]
},
{
"cell_type": "code",
"execution_count": 121,
"metadata": {},
"outputs": [],
"source": [
"# compare accuracy\n",
"# Wake, NREM & REM\n",
"df = pd.DataFrame(columns=['Accuracy 1','Accuracy 2','kappa 1', 'kappa 2'])\n",
"for i in range(1,11):\n",
" expert1 = '%d\\\\%d_1.txt' %(i,i)\n",
" expert2 = '%d\\\\%d_2.txt' %(i,i)\n",
" auto = '%d\\\\%d_auto.csv' %(i,i)\n",
"\n",
" exp_score1 = np.genfromtxt(expert1, delimiter=',')\n",
" exp_score2 = np.genfromtxt(expert2, delimiter=',')\n",
" auto_score = np.genfromtxt(auto, delimiter=',')\n",
"\n",
" num_epochs = min(auto_score.size, exp_score1.size, exp_score2.size)\n",
"\n",
" auto_score = auto_score[0:num_epochs,0]\n",
" exp_score1 = exp_score1[0:num_epochs]\n",
" exp_score2 = exp_score2[0:num_epochs]\n",
" exp_score1[exp_score1==1] = 2\n",
" exp_score2[exp_score2==1] = 2\n",
" exp_score1[exp_score1==3] = 2\n",
" exp_score2[exp_score2==3] = 2\n",
" auto_score[auto_score==3] = 2\n",
"\n",
" accuracy1 = np.sum(exp_score1 == auto_score)*100.0/num_epochs\n",
" accuracy2 = np.sum(exp_score2 == auto_score)*100.0/num_epochs\n",
" kappa1 = cohen_kappa_score(exp_score1, auto_score)\n",
" kappa2 = cohen_kappa_score(exp_score2, auto_score)\n",
" df = df.append({'Accuracy 1':accuracy1, 'Accuracy 2':accuracy2, 'kappa 1':kappa1, 'kappa 2':kappa2}, ignore_index=True)"
]
},
{
"cell_type": "code",
"execution_count": 122,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Accuracy 1 82.520431\nAccuracy 2 83.576178\nkappa 1 0.608654\nkappa 2 0.631983\ndtype: float64"
},
"metadata": {},
"execution_count": 122
}
],
"source": [
"df.mean()"
]
}
],
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.10-final"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python361064bitdevenvvenvcd022a983f794dd1941c299f2f977cbf",
"display_name": "Python 3.6.10 64-bit ('devenv': venv)"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment