# -*- coding: utf-8 -*- """ Created on Wed Jun 16 09:34:35 2021 @author: - """ import osa 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--') PtName = (PtName + '.png') plt.savefig(fname=PtName) plt.show() except: print(PtName + ' could not be used') return SlopeWeek