Details for oura-test-notebook.ipynb

Published by gedankenstuecke

Description

This is just a test notebook to see whether the Oura Ring data connection works.

1

Tags & Data Sources

beta test ouraconnect

Comments

Please log in to comment.

Notebook
Last updated 2 months, 1 week ago

Testing the Oura dev setup

The Oura Ring allows you to measure vital signs during sleep such as heart rate and temperature. The integration for this is still in an early alpha, so this notebook isn't really useful. It's more for Bastian to check whether the data can be imported. 😉

As usual, here comes the boilerplate to find the actual Oura data on Open Humans. Don't worry much about this at this point. If you haven't connected your Oura account to Open Humans this will fail. Go here to connect your account.

In [1]:
from ohapi import api
import os
import requests
import tempfile

user_details = api.exchange_oauth2_member(os.environ.get('OH_ACCESS_TOKEN'))
for i in user_details['data']:
    if i['source'] == 'direct-sharing-184' and i['basename'] == 'oura-data.json':
        print(i)
        break
import json 
oura = json.loads(requests.get(i['download_url']).content)
{'id': 301331, 'basename': 'oura-data.json', 'created': '2018-10-05T23:29:49.379162Z', 'download_url': 'https://open-humans-production.s3.amazonaws.com/member-files/direct-sharing-184/8d593008-c8f6-11e8-a4cf-aab91a44985f/oura-data.json?AWSAccessKeyId=AKIAIKNTFUJJTNS6N7HA&Signature=B%2FbGdJ%2FKcmA%2Bc3JA%2B3DXtGxPtic%3D&Expires=1538786353', 'metadata': {'tags': ['oura', 'activity', 'temperature', 'sleep'], 'description': 'Oura records'}, 'source': 'direct-sharing-184'}

What's our Oura profile and what are the data we have?

In [2]:
print('we have data on the following things:')
print(oura.keys())
print('\nour profile is:')
print(oura['profile'])
we have data on the following things:
dict_keys(['profile', 'sleep', 'activity', 'readiness'])

our profile is:
{'gender': 'male', 'user_id': 'ADQU2GOQWOO5335PGWICCC2TV3CIRN7A', 'weight': 89, 'age': 41, 'date': '2018-10-05', 'height': 184}

Now comes the obligatory data conversion to make this JSON file into a nice table. We don't use much of it for now:

In [3]:
dates = []
hrs = []
interval = []
for sdate in oura['sleep']:
    if 'hr_5min' in sdate.keys():
        for i,hr_val in enumerate(sdate['hr_5min']):
            interval.append(i)
            hrs.append(hr_val)
            dates.append(sdate['summary_date'])
import pandas as pd
dataframe = pd.DataFrame(
    data = {
        'date': dates,
        'heart_rate': hrs,
        'interval': interval
    }
)

Post-conversion our table looks like this

In [4]:
dataframe.tail()
Out[4]:
date heart_rate interval
45615 2018-10-04 59 80
45616 2018-10-04 63 81
45617 2018-10-04 61 82
45618 2018-10-04 63 83
45619 2018-10-04 65 84

Heart Rate intervals measured during sleep

Let's check the nightly heart rate that's measured in 5 minute intervals. What's the distribution of it? (In my case this data comes from one of the Oura test accounts - this might be made up data!)

In [5]:
%load_ext rpy2.ipython
In [6]:
%%R -i dataframe -w 10 -h 4 --units in -r 200
library(ggplot2)

ggplot(subset(dataframe,dataframe$heart_rate>0), aes(heart_rate)) + geom_density() + theme_minimal()

Looks somewhat poisson-ic to me. But let's see how these values differ over time 5 minutes interval starting off with going to sleep into later at the night and whether there's some difference between weekdays and weekends:

(DEPENDING ON HOW MUCH DATA YOU HAVE IT MIGHT TAKE A WHILE TO PRODUCE THE PLOT BELOW!)

In [8]:
%%R -i dataframe -w 8 -h 4 --units in -r 200
library(ggplot2)
library(lubridate)
library(plyr)
dataframe <- subset(dataframe,dataframe$heart_rate > 0 )
dataframe$date <- as.Date(dataframe$date)
dataframe$weekday <- wday(dataframe$date, label=TRUE)
dataframe$year <- year(dataframe$date)
dataframe$weekend <- dataframe$weekday %in% c('Sun','Sat')

dataframe$weekend <- ifelse(dataframe$weekend == TRUE, "weekend", "weekday")
ggplot(dataframe,aes(dataframe$interval, dataframe$heart_rate,group=date)) + 
    geom_line(alpha=0.1) + 
    stat_smooth(data=dataframe,aes(interval,heart_rate,group=weekend), method='loess') + 
    theme_minimal() + facet_grid(. ~ weekend)

We see, there's a lot of noise over all the nights we 'tracked' the sleep, but there seems to be a minor trend for the Heart Rate to drop in later measured intervals. And it might be wishful thinking, but it seems the heart rate drops more during weekend sleeps?

In [ ]: