0

I have tried to fit data on the high and low-temperature regime of the thermal profile, but I couldn't fit properly. According to the experiment report, there should be 3 to 4 measurement points on each level however I couldn't manage it till now due to always there are some points could be outside of thermal profile curve and ruin everything. I checked this post about optimize.curve_fit(), and I'm unsure it can help in my case to optimize it. As it is illustrated in the last picture, measurement points in each high or low regime should be fit in each dwell-time next to each other:

img

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import itertools
import copy
from sklearn import preprocessing

# load dataset
data_train = pd.read_csv("data.csv", header=None)
Temp = data_train.iloc[:, 2::3] 
print(Temp)


"""
stack(): transform your (sliced) dataframe to a series with index (row, col)
reset_index(): reset the double-level index above to level_0 (row), level_1 (col).
"""

def preprocess(data):
    for i in range(data.shape[0] // 480):       
        if 150 in data.iloc[i*480:(i+1)*480].to_numpy() and -40 in data.iloc[i*480:(i+1)*480].to_numpy():
            if 150 in data.iloc[(i-1)*480:i*480].to_numpy():
                data.iloc[i*480:(i+1)*480] = -40
            else:
                data.iloc[i*480:(i+1)*480] = 150

    return data

Temp = data_train.iloc[:, 2::3][100:200].stack().reset_index().reset_index()
Temp.columns = ['idx', 'level_0', 'level_1', 'Temperature']
Temp.Temperature = preprocess(Temp.Temperature)
temperature_data = copy.deepcopy(Temp)

fig, ax = plt.subplots(1,1, figsize=(16,10))
Temp.plot('level_0', 'Temperature', ax=ax, kind='scatter', c='level_0', colormap='prism', colorbar=False, legend=True)
ax.set_title('Temperature data distribution over cycles ', fontweight='bold', fontsize=18)
ax.set_xlabel('Cycles', fontsize=16)
ax.set_ylabel('Temperature', fontsize=16)
ax.tick_params(axis='both', which='major', labelsize=14)
#ax.tick_params(axis='both', which='minor', labelsize=10)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

### A continuous function that somewhat fits the data
### but definitively gets the period and levels. 
### The ramp is less well defined
def fit_func( t, low, high, period, s,  delta):
    return  ( high + low ) / 2. + ( high - low )/2. * np.tanh( s * np.sin( 2 * np.pi * ( t - delta ) / period ) )

time1List = np.arange( data_train.shape[0] )
time2List = np.linspace( 0, data_train.shape[0], 7213*20 )
tempList = np.fromiter( ( np.mean(temperature_data.Temperature[temperature_data.level_0 == t]) for t in time1List ), np.float )

sol, err = curve_fit( fit_func, time1List, tempList, [ -40, 150, 1, 10, 0 ] )
print(sol)

fittedLow, fittedHigh, fittedPeriod, fittedS, fittedOff = sol
# sol = -40, fittedHigh, fittedPeriod, fittedS, fittedOff
realHigh = fit_func( 1/4 * fittedPeriod, *sol)
realLow = fit_func( 3/4 * fittedPeriod, *sol)
print("high, low : ", [ realHigh, realLow ])
print("apprx ramp: ", fittedPeriod/( 2 * np.pi * fittedS ) * 2) 

realAmp = realHigh - realLow
topX, topY = zip( *[ [ t, d ] for t, d in zip( time1List, tempList ) if ( ( d > realHigh - 0.05 * realAmp ) ) ] )
botX, botY = zip( *[ [ t, d ] for t, d in zip( time1List, tempList ) if ( ( d < realLow + 0.05 * realAmp ) ) ] )

fig = plt.figure(figsize=(20, 15))
ax = fig.add_subplot( 2, 1, 1 )
bx = fig.add_subplot( 2, 1, 2 )

ax.plot( time1List, tempList, marker='x', linestyle='', zorder=100 )
ax.plot( time2List, fit_func( time2List, *sol ), zorder=0 )
ax.set_title('Fitting whole MPs on standrad thermal profile ', fontweight='bold', fontsize=25)
ax.set_xlabel('cycles', fontsize=20)
ax.set_ylabel('Thermal regime', fontsize=20)

bx.plot( time1List, tempList, marker='x', linestyle='' )
bx.plot( time2List, fit_func( time2List, *sol ) )
bx.plot( topX, topY, linestyle='', marker='o', markersize=10, fillstyle='none', color='#00FFAA')
bx.plot( botX, botY, linestyle='', marker='o', markersize=10, fillstyle='none', color='#80DD00')
bx.set_title('Fitting part of MPs on standrad thermal profile ', fontweight='bold', fontsize=25)
bx.set_xlabel('cycles', fontsize=20)
bx.set_ylabel('Thermal regime', fontsize=20)
bx.set_xlim( [ 110, 120 ] )
plt.show()

Any suggestion to fix correctly fitting measurement points on dwell-time in thermal profile ?

Mario
  • 1,631
  • 2
  • 21
  • 51
  • 1
    Curve fit tries to fit a function or distribution to your data. What function are you trying to fit? If you just want to connect the dots, use a spline. – James Aug 31 '19 at 20:40
  • @James so in my case, I want to fit the thermal profile to my temperature data. Honestly, I tried, and I couldn't manage it, but in case there is a possibility to connect the dots in the right regime in the right dwell-time via a spline it could be my answer. However, fitting the thermal curve is my preference. – Mario Aug 31 '19 at 20:49
  • @Mario, what informations from the data are you looking for? The data seems to be clean enough to search for rising edge and failling edge using a threshold, i.e. something like `np.nonzero( np.diff(data)>100 ) )`... – xdze2 Sep 03 '19 at 09:34
  • Hi Mario, did you try a larger period as starting point for `curve_fit`, e.g. `[ -40, 150, 3, 10, 0 ]`? – mikuszefski Sep 03 '19 at 09:50

0 Answers0