In [41]:
import pandas as pd
import numpy as np
import numpy.ma as ma
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit  # import the curve fitting function
%matplotlib inline

Read-In


In [42]:
df = pd.read_excel('Data.xlsx', sheetname=None)

In [43]:
df['Run 1']


Out[43]:
t_f (s) t_u (s) t_d (s)
0 13.60 3.79 2.89
1 14.57 2.82 2.65
2 14.60 4.37 2.73
3 15.51 4.36 2.80
4 13.69 4.67 2.34
5 14.80 4.51 2.45
6 13.78 4.64 2.45
7 14.60 4.12 2.21
8 13.90 4.43 2.60
9 14.09 7.90 2.37

In [44]:
keys = ['Run 1', 'Run 2', 'Run 3', 'Run 4']

In [45]:
# Fall time in seconds when V = 0
tf = np.array([df[key]['t_f (s)'] for key in keys])
tf


Out[45]:
array([[ 13.6 ,  14.57,  14.6 ,  15.51,  13.69,  14.8 ,  13.78,  14.6 ,
         13.9 ,  14.09],
       [  7.19,   7.43,   6.74,   7.31,   7.2 ,   7.28,   6.96,   7.95,
          7.22,   7.61],
       [ 17.14,  18.35,  17.09,  17.41,  18.25,  17.28,  17.75,  16.53,
         15.18,  16.33],
       [  7.91,   7.83,   8.43,   7.92,   8.27,   8.17,   7.82,   8.67,
          8.15,   7.87]])

In [46]:
# Average Fall times for each run (seconds)
avg_tf = np.array([np.mean(tf[i]) for i in np.arange(4)]) 
avg_tf


Out[46]:
array([ 14.314,   7.289,  17.131,   8.104])

In [47]:
# Standard Deviation Fall times for each run (seconds)
std_tf = np.array([np.std(tf[i]) for i in np.arange(4)])
std_tf


Out[47]:
array([ 0.57459899,  0.31503809,  0.89623044,  0.27251422])

Mask points that lie outside 2.5$\sigma$


In [48]:
tf = np.array([ma.masked_outside(entry, np.mean(entry) - 2.5*np.std(entry), np.mean(entry) + 2.5*np.std(entry)) 
                     for entry in tf])

Uncertainty


In [49]:
# Standard deviation of the mean (seconds)
tf_u = np.array([std_tf[i]/np.sqrt(len(tf[i])) for i in np.arange(4)])

tf_u


Out[49]:
array([ 0.18170416,  0.09962379,  0.28341295,  0.08617656])

Fall Speed

All measurements were of the time to travel .5mm


In [50]:
# Units of m/s
speeds = np.array([(.5*1e-3)/entry for entry in avg_tf ])
speeds


Out[50]:
array([  3.49308369e-05,   6.85965153e-05,   2.91868542e-05,
         6.16979269e-05])
\begin{equation} v = \frac{h}{t} \end{equation}
\begin{equation} \delta v = \frac{h}{t^2} \delta t \end{equation}

In [51]:
#Units of m/s
speeds_u = np.array([((.5*1e-3)/avg_tf[i]**2)*tf_u[i] for i in np.arange(4)])
speeds_u


Out[51]:
array([  4.43417508e-07,   9.37555905e-07,   4.82863373e-07,
         6.56085302e-07])

E Field


In [52]:
d = 7.63*1e-3 #Electrode spacer thickness in meters
V = 301.8 #Volts. Constant through all measurements

E = V/d #V/m
E


Out[52]:
39554.39056356488

Air Viscosity


In [53]:
Resistances = np.array([2.065, 2.011, 1.957, 1.959])*1e6 #From thermistor. Used to find temperature. Ohms

In [54]:
temperatures = np.array([24, 25, 26, 26]) #From Thermistor table. Celcius

In [55]:
rho = 885 #kg/m^3. Density of oil drop.
g = 9.80 #gravity

In [56]:
def viscosity(T):
    #Returns the viscosity of air for a given temp in celsius
    # Viscosity units [Ns/m^2]
    return (1.8 + (T-15)/209)*1e-5

In [57]:
viscosities = np.array([viscosity(entry) for entry in temperatures])
viscosities


Out[57]:
array([  1.84306220e-05,   1.84784689e-05,   1.85263158e-05,
         1.85263158e-05])

Drop Radius


In [58]:
def radius(speed,visc):
    return np.sqrt(9*visc*speed/(2*g*rho))

In [59]:
radii = np.array([radius(speeds[i],viscosities[i]) for i in np.arange(4)]) #Blob radius in meters
radii


Out[59]:
array([  5.77957729e-07,   8.10971519e-07,   5.29675347e-07,
         7.70107585e-07])

Droplet Mass


In [60]:
def mass(r):
    return (4/3)*np.pi*rho*r**3

In [61]:
masses = np.array([mass(entry) for entry in radii])
masses


Out[61]:
array([  7.15682020e-16,   1.97719128e-15,   5.50885268e-16,
         1.69311354e-15])
\begin{equation} m = \frac{4}{3} \pi r^3 \rho \end{equation}
\begin{equation} \delta m = 4 \pi r^2 \rho \delta r \end{equation}
\begin{equation} r = \sqrt{\frac{9 \eta v_f}{2 g \rho}} \end{equation}
\begin{equation} \delta r = \frac{1}{2}\sqrt{\frac{9 \eta}{2 g \rho}} \frac{\delta v_f}{\sqrt{v_f}} \end{equation}
\begin{equation} \delta m = \pi r^2 \sqrt{\frac{18 \eta \rho}{ g}} \frac{\delta v_f}{\sqrt{v_f}} \end{equation}

In [62]:
masses_u = np.array([np.pi*(radii[i]**2)*np.sqrt(18*viscosities[i]*rho/g)*np.sqrt(1/speeds[i])*speeds_u[i] for i in np.arange(4)])
masses_u


Out[62]:
array([  1.36274693e-17,   4.05354563e-17,   1.36706572e-17,
         2.70064238e-17])

Correction Factor


In [63]:
def gamma(r):
    b = .082*1e-7
    return (1+b/r)**(-3/2)

In [64]:
gammas = np.array([gamma(entry) for entry in radii])
gammas


Out[64]:
array([ 0.97908945,  0.98502247,  0.97721963,  0.98423818])

Upward Movement


In [65]:
# Rise time in seconds when V = +
tu = np.array([df[key]['t_u (s)'] for key in keys])
tu


Out[65]:
array([[  3.79,   2.82,   4.37,   4.36,   4.67,   4.51,   4.64,   4.12,
          4.43,   7.9 ],
       [  6.04,   6.29,   9.16,   9.38,   6.12,   5.89,   5.98,   5.98,
          5.95,   6.04],
       [  5.12,   9.15,   8.3 ,   4.83,   8.81,   4.94,   5.22,   5.42,
          3.42,   3.64],
       [ 11.53,  11.27,  11.38,  12.36,  10.46,  11.65,  11.49,  12.61,
         10.91,  12.1 ]])

In [66]:
#### tu0: Time Up 0'th drop.
#### Average Time
#### Std of Times
#### Resulting Speed
#### Speed Uncertainty

tu0 = ma.masked_array(tu[0],mask=[0,0,0,0,0,0,0,0,0,1])
avg_tu0 = np.mean(tu0)
std_tu0 = np.std(tu0)
tu0_speed = .5*1e-3/avg_tu0
tu0_speed_u = .5*1e-3/(avg_tu0**2)*std_tu0/np.sqrt(len(tu0))

tu1 = ma.masked_array(tu[1],mask=[0,0,1,1,0,0,0,0,0,0])
avg_tu1 = np.mean(tu1)
std_tu1 = np.std(tu1)
tu1_speed = .5*1e-3/avg_tu1
tu1_speed_u = .5*1e-3/(avg_tu1**2)*std_tu1/np.sqrt(len(tu1))

tu2_1 = ma.masked_array(tu[2],mask=[0,1,1,0,1,0,0,0,0,0])
avg_tu2_1 = np.mean(tu2_1)
std_tu2_1 = np.std(tu2_1)
tu2_1_speed = .5*1e-3/avg_tu2_1
tu2_1_speed_u = .5*1e-3/(avg_tu2_1**2)*std_tu2_1/np.sqrt(len(tu2_1))

tu2_2 = ma.masked_array(tu[2],mask=[1,0,0,1,0,1,1,1,1,1])
avg_tu2_2 = np.mean(tu2_2)
std_tu2_2 = np.std(tu2_2)
tu2_2_speed = .5*1e-3/avg_tu2_2
tu2_2_speed_u = .5*1e-3/(avg_tu2_2**2)*std_tu2_2/np.sqrt(len(tu2_2))

tu3 = tu[3]
avg_tu3 = np.mean(tu3)
std_tu3 = np.std(tu3)
tu3_speed = .5*1e-3/avg_tu3
tu3_speed_u = .5*1e-3/(avg_tu3**2)*std_tu3/np.sqrt(len(tu3))



#This data can't be used unless the free fall time data is analyzed
tu4 = np.array([4.20, 3.51, 3.44, 3.21, 3.56, 3.27, 3.25]) #This data from an extra column not entered into excel
avg_tu4 = np.mean(tu4)
std_tu4 = np.std(tu4)
tu4_speed = .5*1e-3/avg_tu4
tu4_speed_u = .5*1e-3/(avg_tu4**2)*std_tu4/np.sqrt(len(tu4))

In [67]:
avg_tu0


Out[67]:
4.1900000000000004

In [68]:
std_tu0/np.sqrt(len(tu0))


Out[68]:
0.17307673314329561

In [69]:
def up_charge(vu,vf,gamma,mass):
    return gamma*mass*g*((vu/vf) + 1)/E

In [70]:
qu0 = up_charge(tu0_speed, speeds[0], gammas[0], masses[0])
qu1 = up_charge(tu1_speed, speeds[1], gammas[1], masses[1])
qu2_1 = up_charge(tu2_1_speed, speeds[2], gammas[2], masses[2])
qu2_2 = up_charge(tu2_2_speed, speeds[2], gammas[2], masses[2])
qu3 = up_charge(tu3_speed, speeds[3], gammas[3], masses[3])
qu = np.array([qu0,qu1,qu2_1,qu2_2,qu3])
qu*1e19


Out[70]:
array([  7.6669998 ,  10.65207829,   6.24151668,   3.94410288,   7.01914548])
\begin{equation} \frac{\delta q_u}{q_u} = \sqrt{(\frac{\delta m}{m})^2 + (\frac{\delta v_u}{v_u + v_f})^2 + (\frac{v_u}{v_f}\frac{\delta v_f}{v_f+v_u})^2 } \end{equation}

In [71]:
def delta_qu(qu,dm, m, dvu, vu, dvf, vf):
    return np.sqrt((dm/m)**2 + (dvu/(vu+vf))**2 + ((vu/vf)*dvf/(vf+vu))**2)*qu

In [72]:
qu0_u = delta_qu(qu0,masses_u[0],masses[0],tu0_speed_u, tu0_speed, speeds_u[0], speeds[0])
qu1_u = delta_qu(qu1,masses_u[1],masses[1],tu1_speed_u, tu1_speed, speeds_u[1], speeds[1])
qu2_1_u = delta_qu(qu2_1,masses_u[2],masses[2],tu2_1_speed_u, tu2_1_speed, speeds_u[2], speeds[2])
qu2_2_u = delta_qu(qu2_2,masses_u[2],masses[2],tu2_2_speed_u, tu2_2_speed, speeds_u[2], speeds[2])
qu3_u = delta_qu(qu3,masses_u[3],masses[3],tu3_speed_u, tu3_speed, speeds_u[3], speeds[3])
qu_u = np.array([qu0_u,qu1_u,qu2_1_u,qu2_2_u,qu3_u])
qu_u*1e19


Out[72]:
array([ 0.2949583 ,  0.23510696,  0.30118702,  0.11193648,  0.12587898])

Drop Charge

Downward Movement


In [73]:
df['Run 1']


Out[73]:
t_f (s) t_u (s) t_d (s)
0 13.60 3.79 2.89
1 14.57 2.82 2.65
2 14.60 4.37 2.73
3 15.51 4.36 2.80
4 13.69 4.67 2.34
5 14.80 4.51 2.45
6 13.78 4.64 2.45
7 14.60 4.12 2.21
8 13.90 4.43 2.60
9 14.09 7.90 2.37

In [74]:
# Fall time in seconds when V = -
td = np.array([df[key]['t_d (s)'] for key in keys])
td


Out[74]:
array([[ 2.89,  2.65,  2.73,  2.8 ,  2.34,  2.45,  2.45,  2.21,  2.6 ,
         2.37],
       [ 2.14,  2.39,  2.34,  2.35,  2.24,  2.26,  2.23,  2.26,  2.15,
         2.13],
       [ 2.66,  2.55,  2.53,  2.18,  2.55,  2.43,  2.67,  2.55,  2.52,
         2.54],
       [ 2.79,  3.02,  2.85,  2.85,  2.87,  2.67,  2.97,  3.  ,  3.02,
         3.09]])

In [75]:
#### tu0: Time Up 0'th drop.
#### Average Time
#### Std of Times
#### Resulting Speed
#### Speed Uncertainty



td0 = td[0] #All values here are about the same
avg_td0 = np.mean(td0)
std_td0 = np.std(td0)
td0_speed = .5*1e-3/avg_td0
td0_speed_u = .5*1e-3/(avg_td0**2)*std_td0/np.sqrt(len(td0))

td1 = np.array([td[1]]) #All values here are about the same
avg_td1 = np.mean(td1)
std_td1 = np.std(td1)
td1_speed = .5*1e-3/avg_td1
td1_speed_u = .5*1e-3/(avg_td1**2)*std_td1/np.sqrt(len(td1))

td2 = np.array([td[2]]) #All values here are about the same
avg_td2 = np.mean(td2)
std_td2 = np.std(td2)
td2_speed = .5*1e-3/avg_td2
td2_speed_u = .5*1e-3/(avg_td2**2)*std_td2/np.sqrt(len(td2))


td3 = td[3] #All values here are about the same
avg_td3 = np.mean(td3)
std_td3 = np.std(td3)
td3_speed = .5*1e-3/avg_td3
td3_speed_u = .5*1e-3/(avg_td3**2)*std_td3/np.sqrt(len(td3))

In [76]:
avg_td0


Out[76]:
2.5490000000000004

In [77]:
std_td0/np.sqrt(len(td0))


Out[77]:
0.065961352320885597

Drop Charge


In [78]:
def down_charge(vd,vf,gamma,mass):
    return gamma*mass*g*((vd/vf) - 1)/E

In [79]:
def delta_qd(qu,dm, m, dvu, vu, dvf, vf):
    return np.sqrt((dm/m)**2 + (dvu/(vu-vf))**2 + ((vu/vf)*dvf/(vf-vu))**2)*qu

In [80]:
qd0 = down_charge(td0_speed, speeds[0], gammas[0], masses[0])
qd1 = down_charge(td1_speed, speeds[1], gammas[1], masses[1])
qd2 = down_charge(td2_speed, speeds[2], gammas[2], masses[2])
qd3 = down_charge(td3_speed, speeds[3], gammas[3], masses[3])
qd = np.array([qd0,qd1,qd2,qd3])
qd*1e19


Out[80]:
array([  8.01301491,  10.81352487,   7.74048862,   7.35746513])

In [81]:
qd0_u = delta_qd(qd0,masses_u[0],masses[0],td0_speed_u, td0_speed, speeds_u[0], speeds[0])
qd1_u = delta_qd(qd1,masses_u[1],masses[1],td1_speed_u, td1_speed, speeds_u[1], speeds[1])
qd2_u = delta_qd(qd2,masses_u[2],masses[2],td2_speed_u, td2_speed, speeds_u[2], speeds[2])
qd3_u = delta_qd(qd3,masses_u[3],masses[3],td3_speed_u, td3_speed, speeds_u[3], speeds[3])
qd_u = np.array([qd0_u,qd1_u,qd2_u,qd3_u])
qd_u*1e19


Out[81]:
array([ 0.31975217,  0.67598625,  0.52807592,  0.22772657])

Search for Charge Unit

Upwards Charge


In [123]:
qu*1e19


Out[123]:
array([  7.6669998 ,  10.65207829,   6.24151668,   3.94410288,   7.01914548])

In [124]:
#Check with known e
np.array([qu[0]/1.6, qu[1]/1.6, qu[2]/1.6, qu[3]/1.6,qu[4]/1.6])*1e19


Out[124]:
array([ 4.79187487,  6.65754893,  3.90094792,  2.4650643 ,  4.38696593])

In [125]:
up_e = np.array([qu[0]/5, qu[1]/7, qu[2]/4, qu[3]/3,qu[4]/5])
up_e*1e19


Out[125]:
array([ 1.53339996,  1.52172547,  1.56037917,  1.31470096,  1.4038291 ])

Upwards Uncer


In [126]:
qu_u*1e19


Out[126]:
array([ 0.2949583 ,  0.23510696,  0.30118702,  0.11193648,  0.12587898])

In [122]:
up_e_u = np.array([qu_u[0]/5, qu_u[1]/7, qu_u[2]/4, qu_u[3]/3,qu_u[4]/5])
up_e_u*1e19


Out[122]:
array([ 0.05899166,  0.03358671,  0.07529675,  0.03731216,  0.0251758 ])

Down Charge


In [87]:
qd*1e19


Out[87]:
array([  8.01301491,  10.81352487,   7.74048862,   7.35746513])

In [88]:
#Check with known e
np.array([qd[0]/1.6, qd[1]/1.6, qd[2]/1.6, qd[3]/1.6])*1e19


Out[88]:
array([ 5.00813432,  6.75845304,  4.83780538,  4.5984157 ])

In [116]:
down_e = np.array([qd[0]/5, qd[1]/7, qd[2]/5, qd[3]/5])
down_e*1e19


Out[116]:
array([ 1.60260298,  1.54478927,  1.54809772,  1.47149303])
Down Uncer

In [113]:
qd_u*1e19


Out[113]:
array([ 0.31975217,  0.67598625,  0.52807592,  0.22772657])

In [114]:
down_e_u = np.array([qd_u[0]/5, qd_u[1]/7, qd_u[2]/5, qd_u[3]/5])
down_e_u*1e19


Out[114]:
array([ 0.06395043,  0.09656946,  0.10561518,  0.04554531])

Determine Electron Charge


In [92]:
Charges = np.hstack((up_e,down_e))
Charges*1e19


Out[92]:
array([ 1.53339996,  1.52172547,  1.56037917,  1.97205144,  1.75478637,
        2.00325373,  1.80225414,  1.29008144,  1.22624419])

In [93]:
Charge_Best = np.mean(Charges)
Charge_Best*1e19


Out[93]:
1.6293528783984601

In [94]:
Charges_u = np.hstack((up_e_u,down_e_u))
Charges_u*1e19


Out[94]:
array([ 0.04915972,  0.03918449,  0.07529675,  0.03731216,  0.03146975,
        0.06395043,  0.09656946,  0.10561518,  0.04554531])

In [95]:
delta_e = np.std(Charges)/np.sqrt(len(Charges))

#delta_e_meas = np.sqrt(np.sum(np.array([(Charges_u[i]/Charges[i])**2 for i in np.arange(len(Charges))])))*Charge_Best

In [96]:
#delta_e = np.sqrt(delta_e_ran**2 + delta_e_meas**2)
#delta_e = delta_e_meas

In [97]:
delta_e*1e19


Out[97]:
0.08649714763769184

In [98]:
print('e = (%.3f +/- %.3f)x10^(-19) C' % (Charge_Best*1e19,delta_e*1e19))


e = (1.629 +/- 0.086)x10^(-19) C

Charge to Mass Ratio

e/m = (1.648 +/- 0.287)x10^11 C/kg


In [99]:
# From a previous lab
eperm = 1.648*1e11 #C/kg
eperm_u = .287*1e11

In [100]:
m = Charge_Best/eperm
m


Out[100]:
9.8868499902819185e-31

In [101]:
dm = np.sqrt( (delta_e/Charge_Best)**2 + (eperm_u/eperm)**2 )*m
dm


Out[101]:
1.8000204755746357e-31

In [102]:
print('m = (%.3f +/- %.3f)x10^(-31) Kg' % (m*1e31,dm*1e31))


m = (9.887 +/- 1.800)x10^(-31) Kg

Plank Constant


In [103]:
eo = 8.854*1e-12

In [104]:
E_r = 13.77 #eV
E_r = E_r*1.602*1e-19
dE_r = .01 #Ev

In [105]:
h = np.sqrt(m * Charge_Best**4/(8*eo**2 * E_r))
h


Out[105]:
7.0970283421945408e-34

In [106]:
dh = np.sqrt((dm/m)**2 + (.01/13.77)**2 + (delta_e/Charge_Best)**2)*h
dh


Out[106]:
1.3459180330082851e-34

In [107]:
print('h = (%.3f +/- %.3f)x10^(-34) Js' % (h*1e34,dh*1e34))


h = (7.097 +/- 1.346)x10^(-34) Js

In [ ]: