control.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Wed Aug 15 23:33:19 2018
  4. @author: USER
  5. """
  6. # Codes are free to use. Do whatever you want
  7. from __future__ import absolute_import
  8. """Read raw data"""
  9. ####################### LIBRARY #############################
  10. # exceptions library
  11. # Python stdlib imports
  12. # data processing library
  13. import numpy as np
  14. # pyrod library
  15. ####################### CONSTANT ############################
  16. # constant
  17. ####################### FUNCTIONS ###########################
  18. def contral_vars(varl,
  19. key_list = ['roughness',
  20. 'vacancy',
  21. 'absorption',
  22. 'dis',
  23. 'dw',
  24. 'ocu',
  25. 'pos',
  26. 'scale',
  27. 'lattice',
  28. 'lattice_abc']):
  29. """
  30. contral independent var list
  31. """
  32. # ubr_index--which kind if variable dose this var contral and their values
  33. ubr_index = {}
  34. for slab in varl:
  35. # ubr_slab_index-- the index of independent var list of one slab
  36. ubr_slab_index = {}
  37. # for substrate, there are two different modulation parametes
  38. #scale: bragg peaks intensity
  39. #beta: surface roughness
  40. if slab == 'substrate':
  41. ubr_slab_index['scale'] = 1e-4
  42. ubr_slab_index['beta'] = 0
  43. for key in key_list:
  44. slab_dict = varl[slab]
  45. # roughness-- contral variable: beta
  46. if key == 'roughness':
  47. ubr_slab_index[key] = 1
  48. # vacancy-- contral variable:alpha,layers,vacmi,vacma
  49. elif key == 'vacancy':
  50. ubr_slab_index[key] = np.array([1,1,1,1])
  51. # absorption-- contral variable: absorption
  52. elif key == 'absorption':
  53. ubr_slab_index[key] = 1
  54. # scale: contral the bragg peak intensity
  55. elif key == 'scale':
  56. ubr_slab_index[key] = 0
  57. elif key == 'lattice_abc':
  58. ubr_slab_index[key] = np.array([1,1,1])
  59. else:
  60. ubr_slab_index[key] = np.mat(np.ones(slab_dict[key].shape))
  61. ubr_index[slab] = ubr_slab_index
  62. # this parameter is used to scale the intensity between experiment data and
  63. # fitting data
  64. ubr_index['intensity'] = 1
  65. return ubr_index
  66. def initialize_contral_vars(ubr_index,slabs,keys):
  67. """
  68. for multi-dimensional minimum, variables should be a list or array
  69. """
  70. # to change the pandas matrix in ubr_index to list
  71. def tolist(mat):
  72. # get the matrix size
  73. c,r = mat.shape
  74. # target list
  75. tlist = []
  76. # Noted! this loop determine the path from matrix to list
  77. # recover list to matrix recall the revse path
  78. # line1: from left to right-line2:.......
  79. for ci in range(c):
  80. for ri in range(r):
  81. tlist.append(mat[ci,ri])
  82. return tlist
  83. # the parameters are rank as a list
  84. slab_ubr = []
  85. # the index of slab and keys, used to index the parameters and recover
  86. slab_ubr_index = []
  87. # loop of slabs
  88. for slab in slabs:
  89. slab_index = []
  90. ubr_slab = ubr_index[slab]
  91. # loop of keys in slab
  92. for key in keys:
  93. ubr_key = ubr_slab[key]
  94. # this parameters are single number
  95. if key in ['absorption','beta','roughness','scale']:
  96. slab_index.append([key,1])
  97. slab_ubr.append(ubr_key)
  98. # vacancy is a list
  99. elif key in ['vacancy','lattice_abc']:
  100. slab_index.append([key,len(ubr_key)])
  101. for i in ubr_key:
  102. slab_ubr.append(float(i))
  103. # these parameters are matrix
  104. else:
  105. slab_index.append([key,ubr_key.size])
  106. tlist = tolist(ubr_key)
  107. for i in tlist:
  108. slab_ubr.append(i)
  109. slab_ubr_index.append([slab,slab_index])
  110. return slab_ubr, slab_ubr_index
  111. def indicator_contral_vars(slab_ubr,slab_index,slab,key):
  112. """
  113. Note! slab is str,not a list
  114. indicator value
  115. """
  116. # indicators for slab, keys and variables
  117. indicator_slab = 0
  118. indicator_keys = 0
  119. indicator_ubrs = [0,0]
  120. # used to break outer loop
  121. exit_flag = 0
  122. for slab_part in slab_index:
  123. if slab in slab_part:
  124. # if ture, slab is indicated, indicator for slab = 0
  125. indicator_slab = 0
  126. # keep on indicate the keys
  127. for key_part in slab_part[1]:
  128. # if ture, key is indicated, indicator for key = 0
  129. if key in key_part:
  130. # the postion of ubrs: first place = 0
  131. # second place = first place + variable number -1(start from zeros)
  132. indicator_keys = 0
  133. indicator_ubrs[1] = indicator_ubrs[0] + key_part[1] - 1
  134. # since all the vars have been indicated, break out from the loop
  135. # and set exit _flag = 1 to break outer loop
  136. exit_flag = 1
  137. break
  138. else:
  139. # if key haven't been found, key indicator + 1, search for next key
  140. indicator_keys = indicator_keys + 1
  141. # the start postion of ubrs should change + variable number
  142. indicator_ubrs[0] = indicator_ubrs[0] + key_part[1]
  143. #v if exit_flag = 1, variable have been indcated, break out from the loop
  144. if exit_flag:
  145. break
  146. else:
  147. # slab haven't been found, slab indicator + 1, search for next slab
  148. indicator_slab = indicator_slab + 1
  149. # indicator keys count
  150. indicator_keys = indicator_keys + len(slab_part[1]) - 1
  151. # indicator ubrs count
  152. for key_part in slab_part[1]:
  153. indicator_ubrs[0] = indicator_ubrs[0] + key_part[1]
  154. #v if exit_flag = 1, variable have been indcated, break out from the loop
  155. if exit_flag:
  156. break
  157. # indicated_ubrs = slab_ubr[indicator_ubrs[0]:indicator_ubrs[1]+1]
  158. return [indicator_ubrs[0],indicator_ubrs[1]+1]
  159. # if contral variable is changed, update the variable value in ubr_index
  160. def refresh_index(ubr_index,slab_ubr,slab_index):
  161. # locate slab
  162. for slabi in slab_index:
  163. # slab name
  164. slab_k = slabi[0]
  165. # keys in slab
  166. for keyi in slabi[1]:
  167. # parameters name
  168. key = keyi[0]
  169. # ir-- indicator ubr
  170. ir = indicator_contral_vars(slab_ubr,slab_index,slab_k,key)
  171. # iedr-- inidcated ubr
  172. iedr = slab_ubr[ir[0]:ir[1]]
  173. # ogr -- original ubr
  174. ogr = ubr_index[slab_k][key]
  175. # single vaule parameters
  176. if key in ['absorption',
  177. 'roughness',
  178. 'scale']:
  179. ubr_index[slab_k][key] = iedr
  180. # list vaule parameters
  181. elif key in ['lattice_abc',
  182. 'vacancy']:
  183. ubr_index[slab_k][key] = iedr
  184. # matrix vaule paramters
  185. elif key in ['dis','dw','lattice','ocu','pos']:
  186. iedr_m = np.reshape(iedr,ogr.shape)
  187. ubr_index[slab_k][key] = iedr_m
  188. return ubr_index
  189. def bragg_mask(iq,w,weight,mode = 'yang',limit = 0):
  190. """
  191. set bargg_mask for weight fitting
  192. """
  193. # calculate bragg peaks indice
  194. qs = int(iq[ 0]) + 1
  195. qe = int(iq[-1])
  196. # bg--bragg peaks
  197. bg = range(qs, qe + 1)
  198. # pb--bg postions
  199. pb = []
  200. # bp-- bragg peak
  201. for bp in bg:
  202. # indicate bragg peak postion
  203. pb.append(np.argmin(abs(iq - bp)))
  204. if pb[0] < w or (len(iq) - pb[-1]) < w:
  205. print('Warning!mask width is too large!!')
  206. # set empty mask
  207. yang_mask = np.zeros(len(iq))
  208. yin_mask = np.ones(len(iq))
  209. bragg_mask = np.zeros(len(iq))
  210. # cut window in empty mask
  211. for p in pb:
  212. # cut yang window
  213. if mode == 'yang':
  214. yang_mask[p-w:p+w] = 1
  215. yang_mask[0:int(limit)] = 1
  216. bragg_mask = yang_mask
  217. # cut yin window
  218. elif mode == 'yin':
  219. yin_mask[p-w:p+w] = 0
  220. yin_mask[0:int(limit)] = 0
  221. bragg_mask = yin_mask
  222. return bragg_mask*weight
  223. ######################## CLASSS #############################