Compare commits
9 Commits
6aa852cce4
...
master
Author | SHA1 | Date | |
---|---|---|---|
9e1b64d0c2 | |||
6413897e92 | |||
f05940b1f5 | |||
d451e55639 | |||
5db3ef88ac | |||
c8aaabc502 | |||
6ddb85ebf6 | |||
17c4aa663b | |||
24a1b17445 |
@@ -1,135 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Wed Jun 16 09:34:35 2021
|
||||
|
||||
@author: -
|
||||
"""
|
||||
import os
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from datetime import timedelta
|
||||
from scipy.optimize import curve_fit
|
||||
|
||||
# Formulas
|
||||
|
||||
def ReadCSV(filename):
|
||||
df = pd.read_csv(filename, names=['Datetime', 'Acc X','Acc Y', 'Acc Z'], infer_datetime_format=True)
|
||||
df['Datetime'] = pd.to_datetime(df['Datetime'])
|
||||
df['Date'] = [d.date() for d in df['Datetime']]
|
||||
df = df.reindex(columns=['Datetime','Date','Time','Acc X','Acc Y', 'Acc Z'])
|
||||
return df
|
||||
|
||||
def CreateDays(x, filename, path):
|
||||
|
||||
savename = filename.replace('.csv','')
|
||||
savepath = path + savename
|
||||
os.makedirs(savepath)
|
||||
os.chdir(savepath)
|
||||
|
||||
startdate = x['Date'].iloc[0]
|
||||
week = range(1,8)
|
||||
|
||||
for i in week:
|
||||
weekdayindex = i-1
|
||||
|
||||
day = startdate + timedelta(days=weekdayindex)
|
||||
daydate = x['Date'] == startdate + timedelta(days=weekdayindex)
|
||||
dataday = x[daydate]
|
||||
totalweek = {day:dataday}
|
||||
|
||||
savefile = totalweek[day]
|
||||
varname = filename.replace('.csv','-') + str(day) + '.csv'
|
||||
savefile.to_csv(varname)
|
||||
|
||||
print(varname +' saved')
|
||||
|
||||
return(totalweek)
|
||||
|
||||
|
||||
def SVMEpoch(DF,ResampRate, ResampData):
|
||||
newDF = pd.DataFrame(DF)
|
||||
newDF['X2'] = np.power(newDF['Acc X'], 2)
|
||||
newDF['Y2'] = np.power(newDF['Acc Y'], 2)
|
||||
newDF['Z2'] = np.power(newDF['Acc Z'], 2)
|
||||
newDF['SVM'] = np.sqrt(newDF[['X2', 'Y2', 'Z2']].sum(axis=1))
|
||||
newDF['Datetime'] = pd.to_datetime(newDF['Datetime'])
|
||||
|
||||
EpochSVM = newDF.resample(ResampRate, on = ResampData).mean()
|
||||
return(newDF, EpochSVM)
|
||||
|
||||
def func(x, a, b, c):
|
||||
return a * np.exp(-b*x) + c
|
||||
|
||||
def SlopeWeeker(Keylist, Dict):
|
||||
try:
|
||||
SlopeWeek = pd.DataFrame(columns=['a','b', 'c', 'Name'])
|
||||
SlopeWeek = SlopeWeek.set_index('Name')
|
||||
|
||||
for key in Keylist:
|
||||
newDF, EpochSVM = SVMEpoch(Dict[key], '60S', 'Datetime')
|
||||
|
||||
ENMO = EpochSVM['SVM']-1
|
||||
ENMO = ENMO*1000
|
||||
|
||||
for value in ENMO:
|
||||
if value < 0:
|
||||
value = 0
|
||||
|
||||
BinSize = 5
|
||||
|
||||
ENMOmax = int(ENMO.max())
|
||||
|
||||
if ENMOmax % BinSize == 0:
|
||||
ENMOmax = ENMOmax+1 #to make sure that interference with binsize is impossible
|
||||
|
||||
MaxBin = int(ENMOmax/BinSize)+1
|
||||
ENMO = ENMO.astype(int)
|
||||
|
||||
Counter = pd.DataFrame(np.zeros((1,MaxBin)))
|
||||
|
||||
for x in Counter:
|
||||
Count = (x+1)*BinSize
|
||||
Start = Count - BinSize
|
||||
Number = ENMO.between(Start, Count).sum()
|
||||
Counter[x] = Number
|
||||
|
||||
Counter = Counter.to_numpy()
|
||||
Counter = Counter.astype(float)
|
||||
Counter = Counter.flatten()
|
||||
|
||||
Xscale = np.arange(0,ENMOmax, BinSize)
|
||||
Xscale = Xscale.astype(float)
|
||||
|
||||
popt, _ = curve_fit(func, Xscale, Counter, p0=None) # fit curve through points
|
||||
a, b, c = popt
|
||||
|
||||
Trendline = func(Xscale, a, b, c)
|
||||
|
||||
SlopeWeek.loc[key, 'a'] = a
|
||||
SlopeWeek.loc[key, 'b'] = b
|
||||
SlopeWeek.loc[key, 'c'] = c
|
||||
SlopeWeek.loc[key, 'ENMOmax'] = ENMOmax
|
||||
|
||||
PtName = key.replace('35694_00000', '')
|
||||
PtName = PtName.replace('resampled-','')
|
||||
PtName = PtName.replace('.csv','')
|
||||
|
||||
plt.figure()
|
||||
plt.ylim(0,1440)
|
||||
plt.xlim(0,(ENMOmax+10))
|
||||
plt.title('Intensity plot ' + PtName)
|
||||
plt.xlabel('Movement intensity [bins of ' + str(BinSize) + ' mg]')
|
||||
plt.ylabel('Amount of time spend at intensity [min]')
|
||||
plt.grid()
|
||||
plt.scatter(Xscale, y=Counter)
|
||||
plt.plot(Xscale, Trendline, 'r--')
|
||||
plt.show()
|
||||
|
||||
PtName = (PtName + '.png')
|
||||
plt.savefig(fname=PtName)
|
||||
|
||||
except:
|
||||
print(PtName + ' could not be used')
|
||||
|
||||
return SlopeWeek
|
27
README.md
27
README.md
@@ -0,0 +1,27 @@
|
||||
In this folder you can find 4 scripts that can be used to transfrom 24/7 .csv accelerometer data to intensity plots. The methods are based on the Rowland et al. 2018 article 'Beyond Cut Points: Accelerometer Metrics that Capture the Physical Activity Profile.
|
||||
|
||||
The scripts should be run in the following order:
|
||||
|
||||
1. DailyCutter.py - This script is used to transform single week .csv files (input) into individual day-files (output)
|
||||
The WeekPath should be set to the folder containing the week-files of the patient
|
||||
The ScriptPath should be set to the folder containing the 'formules.py' script. This script holds
|
||||
all functions used in the analysis.
|
||||
|
||||
2. plotter.py - This is the second script used in the analysis and is the script that performs the most.
|
||||
Before getting started, the os.chdir() should be set to the 'formules.py' pathway
|
||||
The rootdir should be set to the folder containing 7 individual .csv day-files
|
||||
The PtName variable should be set accordingly to the name of the files used. This possibly changes
|
||||
between different weeks/different patients.
|
||||
Finally, the CheckWeel.to_csv() should be filled with the used weeknumber, to save the
|
||||
parameters of the trendline for each different week.
|
||||
After changing these variables to your liking, the script should run automatically, using the
|
||||
folder with individual days as input and saving the plots for individual days as well as an
|
||||
overview of the entire week as output.
|
||||
|
||||
3. Totalplotter.py - After running the plotter.py script you should have ended up with 6 .csv files with parameters
|
||||
of the trendlines. Make sure that these files are saved within the same folder and set the path
|
||||
of this folder as the rootdir in this script.
|
||||
Change the names in the plt.title() and plt.savefig() commands accordingly and run the scripts
|
||||
The output will be a plot of all 6 weeks in one figure.
|
||||
|
||||
|
||||
|
@@ -4,7 +4,7 @@ Created on Wed Jun 16 09:34:35 2021
|
||||
|
||||
@author: -
|
||||
"""
|
||||
import osa
|
||||
import os
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
@@ -115,7 +115,7 @@ def SlopeWeeker(Keylist, Dict):
|
||||
PtName = PtName.replace('resampled-','')
|
||||
PtName = PtName.replace('.csv','')
|
||||
|
||||
plt.figure()
|
||||
plt.figure(dpi=720)
|
||||
plt.ylim(0,1440)
|
||||
plt.xlim(0,(ENMOmax+10))
|
||||
plt.title('Intensity plot ' + PtName)
|
||||
@@ -124,10 +124,11 @@ def SlopeWeeker(Keylist, Dict):
|
||||
plt.grid()
|
||||
plt.scatter(Xscale, y=Counter)
|
||||
plt.plot(Xscale, Trendline, 'r--')
|
||||
plt.show()
|
||||
|
||||
PtName = (PtName + '.png')
|
||||
plt.savefig(fname=PtName)
|
||||
|
||||
plt.show()
|
||||
|
||||
except:
|
||||
print(PtName + ' could not be used')
|
||||
|
@@ -54,7 +54,7 @@ for i in Length:
|
||||
|
||||
Xscale = np.arange(0,CheckWeek['ENMOmax'].max(), 5)
|
||||
|
||||
plt.figure()
|
||||
plt.figure(dpi=720)
|
||||
plt.ylim(0,1440)
|
||||
plt.xlim(0,CheckWeek['ENMOmax'].max())
|
||||
plt.title('All weekdays and average plotted ' + PtName)
|
||||
@@ -69,6 +69,7 @@ for i in Length:
|
||||
else:
|
||||
plt.plot(Xscale, Y, 'k--')
|
||||
|
||||
plt.show()
|
||||
plt.savefig(fname=('Weekplot ' + PtName+ '.png'))
|
||||
plt.show()
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user