Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mengelhard committed Oct 30, 2018
0 parents commit 30c9740
Show file tree
Hide file tree
Showing 4 changed files with 17,451 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# sri
108 changes: 108 additions & 0 deletions example.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# Read data from test file\n",
"# Note that this file uses 30 second epochs (i.e. 2880 epochs per day)\n",
"epochs_per_day = 2880\n",
"sleep = pd.read_csv('test.csv')['sleep'].values\n",
"assert len(sleep)%epochs_per_day == 0"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\nAAAAAElFTkSuQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x2135b22c160>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Visualize sleep data\n",
"plt.imshow(~np.reshape(sleep,(-1,epochs_per_day)).astype('uint8'),cmap='Greys',aspect=500)\n",
"plt.xlabel('Epoch (of %i)' % (epochs_per_day))\n",
"plt.ylabel('Day')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"55.902777777777771"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Calculate SRI (with 2880 epochs per day)\n",
"from sri_from_csv import sri\n",
"sri(sleep,epochs_per_day=epochs_per_day)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"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.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
61 changes: 61 additions & 0 deletions sri_from_csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python

"""sri_from_csv.py: Calculate the Sleep Regularity Index from sleep/wake data
usage: sri_from_csv.py [-h] [-e [EPOCHS]] [-c [COLUMN]] fn
example: sri_from_csv.py -e 2880 test.csv
Calculate the Sleep Regularity Index from sleep/wake data
positional arguments:
fn csv file where sleep data is located (in column 'sleepcol')
optional arguments:
-h, --help show this help message and exit
-e [EPOCHS], --epochs [EPOCHS]
number of epochs per day (default: 1440)
-c [COLUMN], --column [COLUMN]
column name in line 1 of 'fn' (csv file) to be used as sleep values (default: sleep)"""

from __future__ import print_function

import argparse
import numpy as np
import pandas as pd

def sri(sleep,epochs_per_day=1440):
'''Returns the approximate sleep regularity index, a measure of sleep consistency, for this activity'''
sleep_mat = np.reshape(sleep,(epochs_per_day,-1),order='F')
assert len(sleep_mat[0]) == len(sleep)/epochs_per_day
sri = [match24(x) for x in sleep_mat if len(x)>1]
return 200*np.mean(sri)-100

def match24(x):
assert np.ndim(x)==1
m = np.diff(x)
m = (m+1)%2
return sum(m)/len(m)

def main():

parser = argparse.ArgumentParser(description='Calculate the Sleep Regularity Index from sleep/wake data')
parser.add_argument('fn', type=str,
help='csv file where sleep data is located (in column \'sleepcol\')')
parser.add_argument('-e', '--epochs', type=int, nargs='?', default=1440,
help='number of epochs per day (default: 1440)')
parser.add_argument('-c', '--column', type=str, nargs='?', default='sleep',
help='column name in line 1 of \'fn\' (csv file) to be used as sleep values (default: sleep)')
args = parser.parse_args()

sleep = pd.read_csv(args.fn)[args.column].values
assert len(sleep)%args.epochs == 0
print('Processed %i days of data' % (len(sleep)//args.epochs))
print('Calculated SRI (with %i epochs per day) is %.2f' % (args.epochs,sri(sleep,epochs_per_day=args.epochs)))

if __name__ == "__main__":
main()

__author__ = "Matthew Engelhard"
__copyright__ = "Copyright 2018, Matthew Engelhard"
__license__ = "MIT"
__email__ = "[email protected]"
Loading

0 comments on commit 30c9740

Please sign in to comment.