import pandas as pd import numpy as np from scipy.interpolate import griddata from scipy import optimize def updatecp(delta,cpvalues,r): cp2 = r.p0/(1+delta/r.p2) cp2 += r.p1/(1+delta/r.p3) delta = delta.append(delta) cp = cpvalues.append(cp2) powerdf = pd.DataFrame({ 'Delta':delta, 'CP':cp, }) powerdf.dropna(axis=0,inplace=True) powerdf.sort_values(['Delta','CP'],ascending=[1,0],inplace=True) powerdf.drop_duplicates(subset='Delta',keep='first',inplace=True) res = cpfit(powerdf) p1 = res[0] r.p0 = p1[0] r.p1 = p1[1] r.p2 = p1[2] r.p3 = p1[3] r.save() return 1 def cpfit(powerdf): # Fit the data to thee parameter CP model fitfunc = lambda pars,x: abs(pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3]))) errfunc = lambda pars,x,y: fitfunc(pars,x)-y p0 = [500,350,10,8000] p1 = p0 thesecs = powerdf['Delta'] theavpower = powerdf['CP'] if len(thesecs)>=4: p1, success = optimize.leastsq(errfunc, p0[:], args = (thesecs,theavpower)) else: factor = fitfunc(p0,thesecs.mean())/theavpower.mean() p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]] p1 = [abs(p) for p in p1] fitt = pd.Series(10**(4*np.arange(100)/100.)) fitpower = fitfunc(p1,fitt) fitpoints = fitfunc(p1,thesecs) fitpoints0 = fitpoints.copy() dd = fitpoints-theavpower ddmin = dd.min() frac = abs(ddmin)/fitpoints.mean() while frac>0.0001: fitpoints = fitpoints*(fitpoints.mean()-ddmin)/(fitpoints.mean()) dd = fitpoints-theavpower ddmin = dd.min() frac = abs(ddmin)/fitpoints.mean() ratio = fitpoints.mean()/fitpoints0.mean() return p1,fitt,fitpower,ratio def getlogarr(maxt): maxlog10 = np.log10(maxt-5) logarr = np.log10(5.)+np.arange(50)*maxlog10/50. logarr = [int(10.**(la)) for la in logarr] logarr = pd.Series(logarr) logarr.drop_duplicates(keep='first',inplace=True) logarr = logarr.values return logarr def getsinglecp(df): thesecs = df['TimeStamp (sec)'].max()-df['TimeStamp (sec)'].min() if thesecs != 0: maxt = 2*thesecs else: maxt = 1000. logarr = getlogarr(maxt) dfnew = pd.DataFrame({ 'time':1000*(df['TimeStamp (sec)']-df.ix[0,'TimeStamp (sec)']), 'power':df[' Power (watts)'] }) dfnew['workoutid'] = 0 dfgrouped = dfnew.groupby(['workoutid']) delta,cpvalue,avgpower = getcp(dfgrouped,logarr) return delta,cpvalue,avgpower def getcp(dfgrouped,logarr): delta = [] cpvalue = [] avgpower = {} #avgpower[0] = 0 for id,group in dfgrouped: tt = group['time'].copy() ww = group['power'].copy() tmax = tt.max() if tmax > 500000: newlen = int(tmax/2000.) else: newlen = len(tt) if newlen < len(tt): newt = np.arange(newlen)*tmax/float(newlen) ww = griddata(tt.values, ww.values, newt,method='linear', rescale=True) tt = pd.Series(newt) ww = pd.Series(ww) try: avgpower[id] = int(ww.mean()) except ValueError: avgpower[id] = '---' if not np.isnan(ww.mean()): length = len(ww) dt = [] cpw = [] for i in xrange(length-2): deltat,wmax = getmaxwattinterval(tt,ww,i) if not np.isnan(deltat) and not np.isnan(wmax): dt.append(deltat) cpw.append(wmax) dt = pd.Series(dt) cpw = pd.Series(cpw) if len(dt): cpvalues = griddata(dt.values, cpw.values, logarr,method='linear', rescale=True) for cpv in cpvalues: cpvalue.append(cpv) for d in logarr: delta.append(d) delta = pd.Series(delta,name='Delta') cpvalue = pd.Series(cpvalue,name='CP') return delta,cpvalue,avgpower def getmaxwattinterval(tt,ww,i): w_roll = ww.rolling(i+2).mean().dropna() if len(w_roll): # now goes with # data points - should be fixed seconds indexmax = w_roll.idxmax(axis=1) try: t_0 = tt.ix[indexmax] t_1 = tt.ix[indexmax-i] deltat = 1.0e-3*(t_0-t_1) wmax = w_roll.ix[indexmax] except KeyError: pass else: wmax = 0 deltat = 0 return deltat,wmax