How to use it


In [1]:
cd ~/


/Users/htelg

In [2]:
import sys
sys.path.append('/Users/htelg/projecte/POPS/prog/')
from POPS_lib import calibration
from POPS_lib import peaks
import hagmods as hm

In [3]:
%matplotlib inline
hm.setRcParams(plt)

Read and save Data

This section shows how to read and save calibration data. In the process the data will be fit and a calibration function is created. Data and function can be plotted using the plot function mentioned below.

read from string

create a string where each line consist of a diameter value (in nm) and an amplitude (in digitizer bin) seperated by space.
Note, in the example below the secend column is the $log_{10}(amplitude)$. The following cell does the convertion!


In [6]:
data = """130 1.73
140 1.85
150 1.99
173 2.28
200 2.53
233 2.77
270 2.96
315 3.04
365 3.165
420 3.213
490 3.355
570 3.56
660 3.72
770 3.795
890 3.86
1040 4.0
1200 4.05
1400 4.1
1600 4.18
1880 4.32
2180 4.44
2500 4.5"""

In [7]:
cal = calibration.read_Calibration_fromString(data)
cal.data.amp = 10**cal.data.amp
cal.calibrationFunction = cal.get_calibrationFunctionSpline()
cal.data


Out[7]:
d amp
0 130 53.703180
1 140 70.794578
2 150 97.723722
3 173 190.546072
4 200 338.844156
5 233 588.843655
6 270 912.010839
7 315 1096.478196
8 365 1462.177174
9 420 1633.051948
10 490 2264.644308
11 570 3630.780548
12 660 5248.074602
13 770 6237.348355
14 890 7244.359601
15 1040 10000.000000
16 1200 11220.184543
17 1400 12589.254118
18 1600 15135.612484
19 1880 20892.961309
20 2180 27542.287033
21 2500 31622.776602

Save the calibration from above


In [8]:
cd ~/data/POPS_calibrations/


/Users/htelg/data/POPS_calibrations

In [9]:
fname = '150108_M2_DOC'
calibration.save_Calibration(cal,fname)

or


In [16]:
cal.save_csv(fname)

read the file we just saved


In [10]:
out = calibration.read_Calibration_fromFile(fname)

Determine Amplitude by reading a peak file


In [4]:
cd ~/data/20150120_circularPolarizedLight/20150120/


/Users/htelg/data/20150120_circularPolarizedLight/20150120

In [37]:
fname = '20150120_000_POPS_Peak.bin'
m = peaks.read_PeakFile_Binary(fname)
dist = m.peak2peakHeightDistribution()
dist = dist.average_overTime()
dist809 = dist.zoom_time(start = '2015-01-20 11:15:20', end = '2015-01-20 11:15:50')
dist809.plot_distribution(norm = 'log')
hist = dist809.average_overAllTime()
f,a = plt.subplots()
a.plot(dist809.bincenters,hist)
a.semilogx()


Out[37]:
[]

plot the created calibration function and data


In [11]:
f,a,df,gf = cal.plot_calibration()


/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/figure.py:1644: UserWarning: This figure includes Axes that are not compatible with tight_layout, so its results might be incorrect.
  warnings.warn("This figure includes Axes that are not "

Instead of using a spline of these datapoints, use a spine of a flattened mie curve -- incomplete


In [12]:
import pops_mie as pm

In [13]:
from hagpack import dataOperations as dopt

In [14]:
d,amp = pm.makeMie_diameter(IOR = 1.455,
                            radiusRangeInMikroMeter=[0.025, 2],
                            noOfdiameters = 1000,
                            mirrorJetDist = 11.)


1/1 wavelength

In [15]:
dPSL,ampPSL = pm.makeMie_diameter(IOR = 1.62,
                            radiusRangeInMikroMeter=[0.025, 2],
                            noOfdiameters = 1000,
                            mirrorJetDist = 11.)


1/1 wavelength

In [16]:
This exists now in hagpack, I think
ww = 20
wwII = 100
dchange = 0.6


da = dopt.moving_average(d,ww)
ampa = dopt.moving_average(amp,ww)

arg_change = dopt.closest(da,dchange)
print arg_change
da = da[:arg_change]
ampa = ampa[:arg_change]


daII = dopt.moving_average(d,wwII)
ampaII = dopt.moving_average(amp,wwII)

arg_change = dopt.closest(daII,dchange)+1
print arg_change
daII = daII[arg_change:]
ampaII = ampaII[arg_change:]

daIII = np.concatenate((da,daII))
ampaIII = np.concatenate((ampa, ampaII))


557
516

In [17]:
f,a = plt.subplots()
a.plot(d,amp)
a.plot(da,ampa)
a.plot(daII,ampaII)
a.plot(daIII,ampaIII, '--')


a.loglog()
a.set_xlim((d.min(),d.max()))
a.set_ylim((amp.min(),amp.max()))


Out[17]:
(2.0622487501399522, 927088.45707912999)

In [125]:
%matplotlib  inline
hm.setRcParams(plt)

In [21]:
scale = 10
offset = 0
f,a = plt.subplots()
a.plot(d*1000,amp/scale + offset)
a.plot(dPSL*1000,ampPSL/scale + offset)
a.plot(cal.data.d,cal.data.amp, 'o')
# a.plot(daIII*1000,ampaIII/11.5)
a.loglog()
a.set_xlim((cal.data.d.min()*0.9,cal.data.d.max()*1.1))
a.set_ylim((cal.data.amp.min()*0.9, cal.data.amp.max()*1.1))


Out[21]:
(48.332861673322746, 34785.054261852172)

Assuming we can measure reliably 130 nm DOS particles, what diameter PSL would have the same intenisty?
int(DOS@130nm) = 61.7
=> PSL@117nm
Note this considers an noise level of 12 which is the deviation of the small diameters from the Mie curve. When the 12 is added the small diameters are way nicer on the predicted curve


In [85]:
f,a = plt.subplots()
a.plot(cal.data.d,cal.data.amp, 'o')
a.plot(daIII*1000,ampaIII/12.)
a.loglog()
a.set_xlim((cal.data.d.min()*0.9,cal.data.d.max()*1.1))
a.set_ylim((cal.data.amp.min()*0.9, cal.data.amp.max()*1.1))


Out[85]:
(42.780170334852464, 31724.346534392665)

In [78]:
f,a = plt.subplots()
a.plot(cal.data.d,cal.data.amp, 'o')
a.plot(daIII*1000,ampaIII/14.)
a.loglog()
a.set_xlim((cal.data.d.min()*0.9,cal.data.d.max()*1.1))
a.set_ylim((cal.data.amp.min()*0.9, cal.data.amp.max()*1.1))


Out[78]:
(42.780170334852464, 31724.346534392665)

In [98]:
f,a = plt.subplots()
a.plot(cal.data.d,cal.data.amp, 'o')
a.plot(daIII*1000,ampaIII/17.)
a.loglog()
a.set_xlim((cal.data.d.min()*0.9,cal.data.d.max()*1.1))
a.set_ylim((cal.data.amp.min()*0.9, cal.data.amp.max()*1.1))


Out[98]:
(42.780170334852464, 31724.346534392665)

In [ ]:


In [ ]:

Development


In [1]:
import numpy as np
import pandas as pd

In [2]:
from StringIO import StringIO as io

In [3]:
data = """140 88
150 102
173 175
200 295
233 480
270 740
315 880
365 1130
420 1350
490 1930
570 3050
660 4200
770 5100
890 6300
1040 8000
1200 8300
1400 10000
1600 11500
1880 16000
2180 21000
2500 28000
3000 37000"""

In [26]:
def read_Calibration_fromString(data):
    '''unit of diameter must be nm
    e.g.:
data = """140 88
150 102
173 175
200 295
233 480
270 740
315 880
365 1130
420 1350
490 1930
570 3050
660 4200
770 5100
890 6300
1040 8000
1200 8300
1400 10000
1600 11500
1880 16000
2180 21000
2500 28000
3000 37000"""
    '''
    sb = io(data)
    dataArray = pd.read_csv(sb, sep = ' ', names = ('d','int'))
    return dataArray

def read_Calibration_fromFile(fname):
    calDataFrame = pd.read_csv(fname)
    return calDataFrame

def save_Calibration(fname):
    dataArray.to_csv(fname, index = False)
    return

In [ ]:
from scipy.interpolate import UnivariateSpline
def get_calibrationFunctionSpline(cal, fitOrder = 1):# = 1, noOfPts = 500, plot = False):
    """
    Performes a spline fit/smoothening (scipy.interpolate.UnivariateSpline) of d over amp (yes this way not the other way around).

    Returns (generates): creates a function self.spline which can later be used to calculate d from amp 

    Optional Parameters:
    \t s: int - oder of the spline function
    \t noOfPts: int - length of generated graph
    \t plot: boolean - if result is supposed to be plotted
    """       
    # The following two step method is necessary to get a smooth curve. 
    #When I only do the second step on the cal_curve I get some wired whiggles
    ##### First Step
    fitOrder = 1
    sf = UnivariateSpline(cal.data.d.values, cal.data.amp.values, s=fitOrder)
    d = np.logspace(np.log10(cal.data.d.values.min()), np.log10(cal.data.d.values.max()), 500)
    amp = sf(x)

    ##### second step
    cal_function = UnivariateSpline(amp, d, s=fitOrder)
    return cal_function

In [7]:
def plot_calibration(cal):
    """Plots the calibration function and data
    Arguments
    ------------
        cal: calibration instance
    
    Returns
    ------------
        figure
        axes
        calibration data graph
        calibration function graph
    """
    cal_function = cal.calibrationFunction
    amp = np.logspace(np.log10(cal.data.amp.min()), np.log10(cal.data.amp.max()), 500)
    d = cal_function(amp)

    f,a = plt.subplots()
    
    cal_data, = a.plot(cal.data.d,  cal.data.amp, 'o',label = 'data',)
    cal_func, = a.plot(d,amp, label = 'function')
    
    a.loglog()

    a.set_xlim(0.9*cal.data.d.min(), 1.1*cal.data.d.max())
    a.set_xlabel('Diameter (nm)')#($\mu$m)')

    a.set_ylim(0.9*cal.data.amp.min(), 1.1*cal.data.amp.max()) 
    a.set_ylabel('Amplitude (digitizer bins)')

    a.set_title('Calibration curve')
    a.legend(loc = 2)
    return f,a,cal_data, cal_func
f,a,dg,fg = plot_calibration(cal)

In [ ]: