-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathSTS.py
65 lines (57 loc) · 2.11 KB
/
STS.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import numpy as np
class STS:
"""
The STS class can calculate the (dI/dV)/(I/V) function out of spectroscopy
measurement performed with as STM. The calculation uses an exponential
broadening function.
"""
def __init__(self, V, I , DV=1, ADJUST=1e-9, **kargs):
"""
V: the voltage array or list
I: the current array or list
dI: the dI/dV array or list
DV: (Delta V), the bandbroadening term
ADJUST: a value which discard I/V values for V<ADJUST (as it would diverge)
"""
if len(V)<2: raise(ValueError)
if V[-1]<V[0]: # Decreasing voltage? Inverse the data
self.V=np.array(V[::-1])
self.I=np.array(I[::-1])
else: # Increasing Voltage data
self.I=np.array(I)
self.V=np.array(V)
Vstep=float(self.V[-1]-self.V[0])/len(self.V) # Voltage step
DVstep=Vstep*np.ceil(DV/Vstep) # Round DV to multiple of Vstep
skip=int(DVstep/Vstep) # The number of Vstep to reach DVstep
## The voltage vector will be extended to min(V)-DV and max(V)+DV and stored as nV
nVb=np.linspace(min(self.V)-DVstep,min(self.V),skip,endpoint=False)
nVe=np.linspace(max(self.V)+Vstep,max(self.V)+DVstep,skip)
self.nV=np.concatenate((nVb,self.V,nVe))
## The window function W is the exponentiel used in the convolution
self.W=np.exp(-np.abs(self.nV)/DV)
## IV stores I/V, discard values for |V|<ADJUST and pad the vector to match the size of nV
if len(self.I.shape)>1:
self.IV=np.pad(self.I/self.V,((0,0),(skip,skip)),'edge')
self.IV[:,np.abs(self.nV)<ADJUST]=0
else:
self.IV=np.pad(self.I/self.V,(skip,skip),'edge')
self.IV[np.abs(self.nV)<ADJUST]=0
## BIV: broadened I/V : calculated by the convolution
if len(self.IV.shape)==1:
BIV=np.convolve(self.IV,self.W,mode='same')/sum(self.W)
self.BIV=BIV[skip:-skip]
else:
BIV=np.empty((0,self.IV.shape[1]))
for i in range(self.IV.shape[0]):
C=np.convolve(self.IV[i,:],self.W,mode='same')/sum(self.W)
BIV=np.vstack((BIV,C))
self.BIV=BIV[:,skip:-skip]
## Various functions to retrieve the usefull values
def getIV(self):
return self.IV
def getBIV(self):
return self.BIV
def getW(self):
return self.W
def getnV(self):
return self.nV