Input Modules, etc:
In [ ]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import math
Set input and output locations:
In [ ]:
#location of data files
inputpath = '/Users/geiger/Box Sync/Science/Data/SHG/2018/120918'
#path of output files
outputpath = '/Users/geiger/Box Sync/Science/Data/SHG/2018/120918/'
Names of files to import, either manually setting them or sequential based off a basename:
In [ ]:
#names of each file if have individual names
#names = ['hemi2pure1a','hemi2pure1b','hemi2salt1a','hemi2salt1b','hemi2pure2a','hemi2pure2b','hemi2salt2a','hemi2salt2b','hemi2pure3a','hemi2pure3b']
#names of each file if have sequential names
names = []
basename = 'pm'
for i in range(26):
names.append(basename+str(i+1))
In [ ]:
#open file for writing scans to
fScans = open(outputpath+'scans.txt','w+')
#initialize data frames to hold data
countsA = pd.DataFrame()
countsB = pd.DataFrame()
pos = pd.DataFrame()
#go through each file
for name in names:
#names of each file
filename = inputpath + '/' + name + '.txt'
#import countsA (signal),countsB (dark counts), and pos (stage position)
countsA[name] = pd.read_csv(filename,sep='\t')['countsA']
countsB[name] = pd.read_csv(filename,sep='\t')['countsB']
pos[name] = pd.read_csv(filename,sep='\t')['stage']
#define function to turn time wave into scan by taking average of intervals
def findAverage(series):
#set number of points per position here
interval = 20
reshaped = np.reshape(series.values,(int(len(series.values)/interval),interval))
return pd.Series(np.mean(reshaped,1))
#apply function to time data to get the scan data
aveCountsA = countsA.apply(findAverage,axis=0)
aveCountsB = countsB.apply(findAverage,axis=0)
pos = pos.apply(findAverage,axis=0)
del countsA,countsB
#correct for dark counts
counts = aveCountsA.sub(aveCountsB)
del aveCountsA,aveCountsB
#create data frame to hold each scan and the position vector
data = counts.copy()
data.insert(0,'pos',pos[names[0]])
#write to file
fScans.write(data.to_csv(sep='\t', index=False, header=True))
fScans.close()
#plot individual
plt.figure()
plt.title('Individual Scan Data')
for column in pos.columns:
plt.plot(pos[column],counts[column],'.')
Initial Fitting, with f free to vary:
In [ ]:
#define fit func, same as IGOR
def sinFunc(x, y0, A, f, phi):
return y0 + A*np.sin(f*x + phi)
#x values from which to plot fit function
xvalues = np.linspace(0,99.7,1000)
#data frame to hold initial fitting parameters
initFitParams = pd.DataFrame(columns=['name','y0','y0error','A','Aerror','f','ferror','phi','phierror'])
initFitValues = pd.DataFrame({'pos':xvalues})
#fit, going through column by column and storing fit parameters in initFits
for column in counts.columns:
#calculate guesses for fit func
y0guess = np.mean(counts[column])
Aguess = (np.amax(counts[column])-np.amin(counts[column]))/2
fguess = 0.05;
phiguess = 0;
guesses = [y0guess,Aguess,fguess,phiguess]
#fit it
popt, pcov = curve_fit(sinFunc,pos[column],
counts[column],p0=guesses)
#calculate standard error
pstd = np.sqrt(np.diag(pcov))
#create row and append it to the dataframe
tdf = pd.DataFrame({'name':[column],'y0':[popt[0]],'y0error':[pstd[0]],'A':[popt[1]],'Aerror':[pstd[1]],
'f':[popt[2]],'ferror':[pstd[2]],'phi':[popt[3]],'phierror':[pstd[3]]})
initFitParams = initFitParams.append(tdf,ignore_index=True)
#calculate fit and add it to fit values
initFitValues[column] = sinFunc(xvalues,popt[0],popt[1],popt[2],popt[3])
#resort columns
columnTitles = ['name','y0','y0error','A','Aerror','f','ferror','phi','phierror']
initFitParams = initFitParams.reindex(columns=columnTitles)
#plot the initial fits
plt.figure()
plt.title('Init Fits')
for column in counts.columns:
plt.plot(pos[column],counts[column],'.')
plt.plot(xvalues,initFitValues[column])
Write Initial Fits to File (optional, to load into igor, etc.):
In [ ]:
#write parameters to file
fInitFitParams = open(outputpath+'initFitParams.txt','w+')
fInitFitParams.write(initFitParams.to_csv(sep='\t', index=False, header=True))
fInitFitParams.close()
#write values to file
fInitFitValues = open(outputpath+'initFitValues.txt','w+')
fInitFitValues.write(initFitValues.round(3).to_csv(sep='\t',index = False, header=True))
fInitFitValues.close()
In [ ]:
#calculate average of f values, then period
fAve = initFitParams['f'].mean()
period = 2*np.pi/fAve
#calculate stdev
fStd = initFitParams['f'].std()
periodError = period*(fStd/fAve)
#print
print('f = '+'%.2f'%period+' +- '+'%.2f'%periodError)
Second Round of Fitting with F Fixed:
In [ ]:
#data frame to hold final fitting parameters and values
finalFitParams = pd.DataFrame(columns=['name','y0','y0error','A','Aerror','f','ferror','phi','phierror'])
finalFitValues = pd.DataFrame({'pos':xvalues})
#go through each column
for column in counts.columns:
#calculate guesses
y0guess = np.mean(counts[column])
Aguess = (np.amax(counts[column])-np.amin(counts[column]))/2
phiguess = 0;
guesses = [y0guess,Aguess,phiguess]
#fit it, with f fixed
popt, pcov = curve_fit(lambda x, y0, A,
phi: sinFunc(x,y0, A, fAve, phi),
pos[column],counts[column],p0=guesses)
#calculate standard error
pstd = np.sqrt(np.diag(pcov))
#create row and append it to the dataframe
tdf = pd.DataFrame({'name':[column],'y0':[popt[0]],'y0error':[pstd[0]],'A':[popt[1]],'Aerror':[pstd[1]],
'f':[fAve],'ferror':[fStd],'phi':[popt[2]],'phierror':[pstd[2]]})
finalFitParams = finalFitParams.append(tdf,ignore_index=True)
#calculate fit and add it to fit values
finalFitValues[column] = sinFunc(xvalues,popt[0],popt[1],fAve,popt[2])
#calculate phi in degrees
finalFitParams['phideg'] = np.degrees(finalFitParams['phi'])
finalFitParams['phidegerror'] = (finalFitParams['phierror']/finalFitParams['phi'])*finalFitParams['phideg']
#resort columns
columnTitles = ['name','y0','y0error','A','Aerror','f','ferror','phi','phierror','phideg','phidegerror']
finalFitParams = finalFitParams.reindex(columns=columnTitles)
#plot the final fits
plt.figure()
plt.title('Final Fits')
for column in counts.columns:
plt.plot(pos[column],counts[column],'.')
plt.plot(xvalues,finalFitValues[column])
Write Final Fits to File:
In [ ]:
#write parameters to file
fFinalFitParams = open(outputpath+'finalFitParams.txt','w+')
fFinalFitParams.write(finalFitParams.to_csv(sep='\t', index=False, header=True))
fFinalFitParams.close()
#write values to file
fFinalFitValues = open(outputpath+'finalFitValues.txt','w+')
fFinalFitValues.write(finalFitValues.round(3).to_csv(sep='\t',index = False, header=True))
fFinalFitValues.close()
In [ ]:
In [ ]: