diff --git a/analysis.py b/analysis.py index 79d23ac4d80c5c742ea63c0041f2425d59a8676c..ba1a8edd22eff699922b06001ba1bbe5cd3e7c08 100644 --- a/analysis.py +++ b/analysis.py @@ -1,6 +1,7 @@ import numpy as np import pandas as pd import matplotlib as plt +from scipy.optimize import curve_fit class Analysis: @@ -10,38 +11,91 @@ class Analysis: The results can then be visualized with two plots. """ - def __init__(self, angles): + def __init__(self, positions, bounds): """ The class is initialized with the angles from the detector results and then automatically deletes 'None' entries and computes the minimum range of angles and the error. """ - self.xAngles = pd.Series({'High' : angles[:,0,0], - 'Low' : angles[:,0,1]}) - self.yAngles = pd.Series({'High' : angles[:,1,0], - 'Low' : angles[:,1,1]}) + self.positions = positions + self.xBounds = pd.Series({'High' : bounds[:,0,0], + 'Low' : bounds[:,0,1]}) + self.yBounds = pd.Series({'High' : bounds[:,1,0], + 'Low' : bounds[:,1,1]}) - self.results = pd.DataFrame({'Mean' : np.zeros(2), - 'Error': np.zeros(2)}) + self.results = pd.DataFrame({'Vx' : np.zeros(2), + 'R' : np.zeros(2), + 'y0' : np.zeros(2), + 'z0' : np.zeros(2)}) #Determine mean and std self.rmNone() - self.Angles(self.xAngles['High'], self.xAngles['Low'], call=0) - self.Angles(self.yAngles['High'], self.yAngles['Low'], call=1) + #self.Bounds(self.xBounds['High'], self.xBounds['Low'], call=0) + #self.Bounds(self.yBounds['High'], self.yBounds['Low'], call=1) + + self.xPoints = pd.DataFrame({'Mean': (bounds[:,0,0] + bounds[:0,0,1])/2., + 'Error': (bounds[:,0,0] - bounds[:0,0,1])/2., + 'z' : np.array([positions[i] for i in + range(0, len(bounds[:,0,0]))] )}) + self.yPoints = pd.DataFrame({'Mean': (bounds[:,1,0] + bounds[:0,1,1])/2., + 'Error': (bounds[:,1,0] - bounds[:0,1,1])/2., + 'z' : np.array([positions[i] for i in + range(0, len(bounds[:,1,0]))] )}) + + self.fit() #TODO: Plot def rmNone(self): """ - Fill the angle data into the class vaiebles. + Fill the angle data into the class variables. """ - #print(self.xAngles['High']) - self.xAngles['High'] = np.array([x for x in self.xAngles['High'] if x is not None]) - self.xAngles['Low'] = np.array([x for x in self.xAngles['Low'] if x is not None]) - self.yAngles['High'] = np.array([x for x in self.yAngles['High'] if x is not None]) - self.yAngles['Low'] = np.array([x for x in self.yAngles['Low'] if x is not None]) + #print(self.xBounds['High']) + self.xBounds['High'] = np.array([x for x in self.xBounds['High'] if x is not None]) + self.xBounds['Low'] = np.array([x for x in self.xBounds['Low'] if x is not None]) + self.yBounds['High'] = np.array([x for x in self.yBounds['High'] if x is not None]) + self.yBounds['Low'] = np.array([x for x in self.yBounds['Low'] if x is not None]) + + def xEOM(self, t, xVel): + x = xVel*z + return x + + def yEOM(self, z, R, y0, z0): + y = y0 + np.sqrt(R**2 - (z-z0)**2) + + def fit(self): + xPopt, xPcov = curve_fit(xEOM, + self.xPoints['z'], + self.xPoints['Mean'], + sigma=self.xPoints['Error'], + absolute_sigma=True) + xPerr = np.sqrt(np.diag(xPcov)) + self.results['Vx'][0] = xPopt[0] + self.results['Vx'][1] = xPerr[0] - def Angles(self, high, low, call=0): + yPopt, yPcov = curve_fit(yEOM, + self.yPoints['z'], + self.yPoints['Mean'], + sigma=self.yPoints['Error'], + absolute_sigma=True) + yPerr = np.sqrt(np.diag(xPcov)) + self.results['R'][0] = yPopt[0] + self.results['R'][1] = yPerr[0] + self.results['y0'][0] = yPopt[1] + self.results['y0'][1] = yPerr[1] + self.results['z0'][0] = yPopt[2] + self.results['z0'][1] = yPerr[2] + + """ + def yEOM(self, t, w, yVel, zVel): + y = zVel + (1./w)*(-zVel*np.cos(w*t) + yVel*np.sin(w*t)) + return y + + def zEOM(self, t, w, yVel, zVel): + z = -yVel + (1./w)*(yVel*np.cos(w*t) + zVel*np.sin(w*t)) + return z + """ + def Bounds(self, high, low, call=0): """ Algorithm to compute the minimum possible range of angles. The upper and lower angles must be given as a argument and also