You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.1 KiB
136 lines
4.1 KiB
# -*- 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(dpi=720) |
|
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--') |
|
|
|
PtName = (PtName + '.png') |
|
plt.savefig(fname=PtName) |
|
|
|
plt.show() |
|
|
|
except: |
|
print(PtName + ' could not be used') |
|
|
|
return SlopeWeek
|
|
|