123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- # -*- coding: utf-8 -*-
- """
- Created on Wed Aug 15 23:42:12 2018
- @author: USER
- """
- # Codes are free to use. Do whatever you want
- from __future__ import absolute_import
- """Read raw data"""
- ####################### LIBRARY #############################
- # exceptions library
- # Python stdlib imports
- # data processing library
- import numpy as np
- # pyrod library
- from tool.properties import roughness
- import tool.control as tc
- import read.read_parameters as rp
- ####################### CONSTANT ############################
- # constant
- ####################### FUNCTIONS ###########################
- def atomic_form_factor(ei_list,square_q,mode = 'factor'):
-
- """atomic form factors"""
-
- rp.check_ions(ei_list)
-
- if mode == 'factor':
-
- # atomic form factor
- af = rp.IONS_TABLE
-
- f = np.mat(np.zeros([np.size(square_q,0),len(ei_list)]))
-
- num = 0
-
- for ei in ei_list:
-
- f[:,num] = np.mat(af.at[ei,'a1']*np.exp(-af.at[ei,'b1']*square_q/4) +\
- af.at[ei,'a2']*np.exp(-af.at[ei,'b2']*square_q/4) +\
- af.at[ei,'a3']*np.exp(-af.at[ei,'b3']*square_q/4) +\
- af.at[ei,'a4']*np.exp(-af.at[ei,'b4']*square_q/4) +\
- af.at[ei,'c']).T
- num = num + 1
-
- elif mode == 'electron':
-
- # atomic form factor
- af = rp.IONS_TABLE
-
- f = np.mat(np.ones([np.size(square_q,0),len(ei_list)]))
-
- num = 0
-
- for ei in ei_list:
-
- f[:,num] = f[:,num]*(af.at[ei,'a1'] + af.at[ei,'a2'] + af.at[ei,'a3'] + af.at[ei,'a4'] + af.at[ei,'c'])
-
- num = num + 1
-
- return f
- def debye_waller_factor(dw,q,u,v):
-
- """
- ______________________________________________________
-
- debye waller factors
- """
- # debye waller factor obtained from parameters.xlsx
- # actually its thermal vibration distance of atoms
- # default setting is 0.1 A
- # dw = slab['dw']
- num = 0
-
- # debye waller factor matrix--sampling number x atoms number
- d = np.mat(np.zeros([len(q),np.size(dw,1)]))
-
- for ei in dw.columns:
-
- ds = np.exp(-np.square(2*np.pi)*(\
- (dw.at['dw_x',ei]*u)**2+\
- (dw.at['dw_y',ei]*v)**2+\
- (dw.at['dw_z',ei]*q)**2)/2)
-
- d[:,num] = np.mat(ds).T
- num = num + 1
-
- return d
- def substrate_ctr(var_list, iq,
- sub_ubr,
- sub_index,
- beta = 0, u = 0, v = 0, scale = 1e-4,
- key_list = ['absorption',
- 'pos',
- 'roughness',
- 'dw',
- 'scale']):
- """
- calculate the ctr rods of substrate
- """
-
- square_q = iq**2
- # sn for sampling number
- sn = len(iq)
-
- atoms = var_list['substrate']['pos']
- ions = (np.array(var_list['substrate']['ions']).tolist())[0]
-
- p = atoms.as_matrix()
- # thermal vibration distance
- dw = var_list['substrate']['dw']
-
- # r-- crystal surface roughness
- r = np.mat(np.ones([sn,1]))
-
- "---------------------------------------------------------"
-
- # introduce the contral variable list
- # indicator to indicate the variable postion in ubr list
-
- for key in key_list:
-
- if key == 'absorption':
- # aor-- absorption indicator
- aor = tc.indicator_contral_vars(sub_ubr,sub_index,'substrate','absorption')
- beta = beta + (1-sub_ubr[aor[0]:aor[1]][0])
-
- elif key == 'roughness':
- # ror--roughness indicator
- ror = tc.indicator_contral_vars(sub_ubr,sub_index,'substrate','roughness')
- # beta_r- roughness beta distinguish with absorption beta
- beta_r = sub_ubr[ror[0]:ror[1]][0]-1
- cr = roughness(iq)
- r = np.mat(cr.robinson_roughness(beta_r)).T
-
- elif key == 'scale':
- # sor-- scale indicator
- sor = tc.indicator_contral_vars(sub_ubr,sub_index,'substrate','scale')
- scale = scale + sub_ubr[sor[0]:sor[1]][0]
-
- elif key == 'pos':
- # por-- pos indicator
- por = tc.indicator_contral_vars(sub_ubr,sub_index,'substrate','pos')
- # get pos ubr and reshape it into 3x5 matrix p.shape
- p_ubr = np.reshape(np.array(sub_ubr[por[0]:por[1]]),p.shape)
- p = np.multiply(p, p_ubr)
-
- elif key == 'dw':
- # dor-- debye waller factor indicator
- dor = tc.indicator_contral_vars(sub_ubr,sub_index,'substrate','dw')
- d_ubr = np.reshape(np.array(sub_ubr[dor[0]:dor[1]]),dw.shape)
- dw = np.multiply(dw, d_ubr)
-
- "---------------------------------------------------------"
-
- # a--atomic form factor
- a = atomic_form_factor(ions,square_q)
-
- # d--debye waller factor
- d = debye_waller_factor(dw,iq,u,v)
-
- # q--construct 3d qs space
- q = np.mat(np.zeros([sn,3]))
-
- q[:,0] = np.mat(np.ones([sn,1]))*u # qx
- q[:,1] = np.mat(np.ones([sn,1]))*v # qy
- q[:,2] = np.mat(iq).T
-
- # f--structure form factor
- f = np.multiply(np.multiply(a,d),
- np.exp(1j*2*np.pi*(np.dot(q,p))))
-
- # s--shape function
- s = 1/(1 - np.exp(-1*1j*2*np.pi*np.dot(q,np.mat([0,0,1]).T))*\
- np.exp(-beta) +\
- scale)
-
- #sctr--structure form factor for crystal turncation rod
- sctr = np.multiply(f,s)
-
- return np.multiply(np.sum(sctr,1), r)
- def film_ctr(varl,vart,subr,sindex, iq, u, v,key_list = ['lattice_abc','dw','pos']):
-
- "--------------------------------------------------------------------------"
- for key in key_list:
-
- # lattice abc modulation
- if key == 'lattice_abc':
- # lattice contral variable
- pos_ctable = []
- # layer loop
- for l in vart['slab_list']:
- # the indicator of the lattice constant contral variable for each layer
- pos_indicator = tc.indicator_contral_vars(subr,sindex,l,key)
- pos_contral = subr[pos_indicator[0]:pos_indicator[1]]
- pos_ctable.append(pos_contral)
-
- # debye_waller_factor modultion
- elif key == 'dw':
- # dw contral table
- dw_ctable = []
- # dw contral variable
- for l in vart['slab_list']:
- # indicator of debye waller factor for each layer
- dw_indicator = tc.indicator_contral_vars(subr,sindex,l,key)
- dw_contral = subr[dw_indicator[0]:dw_indicator[1]]
- dw_ctable.append(np.reshape(dw_contral,(3,varl[l]['atoms_num'])))
-
- # posz--modulate lattice c, modualte it indivual
-
- "--------------------------------------------------------------------------"
- m,n = vart['posz_table'].shape
- u,v = 0,0
- sn = len(iq)
- # Note! data type = complex!
- # ComplexWarning: Casting complex values to real discards the imaginary part
- slab_ctr = np.mat(np.zeros([sn,1],dtype = complex))
-
- # q--construct 3d qs space
- q = np.mat(np.zeros([sn,3]))
-
- q[:,0] = np.mat(np.ones([sn,1]))*u # qx
- q[:,1] = np.mat(np.ones([sn,1]))*v # qy
- q[:,2] = np.mat(iq).T
-
- square_q = np.square(iq)
-
- # loop for layer
-
- tot_layer = 0
-
- for layeri in range(m):
-
- # debye waller factor
- if 'dw' in key_list:
- dw_factor = np.multiply(vart['dw_table'][layeri],dw_ctable[layeri])
- else:
- dw_factor = vart['dw_table'][layeri]
- dw_layeri = debye_waller_factor(dw_factor,iq,u,v)
-
- # lattice constant modulation
- slabi = vart['slab_list'][layeri]
-
- if 'lattice_abc' in key_list:
- lattice_abc = pos_ctable[layeri]
- else:
- lattice_abc = [1,1,1]
-
- sub_c = varl['substrate']['lattice'].at['constant','c']
- # multivarible optimization of postion
- if 'pos' in key_list:
- slab_c = varl[slabi]['lattice'].at['constant','c']*lattice_abc[2]*subr[layeri]
- else:
- slab_c = varl[slabi]['lattice'].at['constant','c']*lattice_abc[2]
-
- tot_layer = tot_layer + slab_c/sub_c
-
- # loop for atom
- for atomi in range(n):
- posi = [vart['posx_table'][layeri,atomi]*lattice_abc[0],
- vart['posy_table'][layeri,atomi]*lattice_abc[1],
- tot_layer + varl[slabi]['pos'].as_matrix()[2,atomi] - \
- varl['substrate']['layers_num']*1]
-
- # the ocupany, contral vancany
- ocui = vart['ocu_table'][layeri,atomi]
- # ion name
- ion = vart['ion_table'][layeri][atomi]
- #
- a = ocui*atomic_form_factor([ion],square_q)
- d = dw_layeri[:,atomi]
- f = np.multiply(np.multiply(a,d),
- np.exp(1j*2*np.pi*(np.dot(q,np.mat(posi).T))))
-
- slab_ctr = slab_ctr + f
-
- return slab_ctr
- ######################## CLASSS #############################
-
|