junction.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Sun Aug 26 21:15:03 2018
  4. @author: USER
  5. """
  6. # Codes are free to use. Do whatever you want
  7. from __future__ import absolute_import
  8. """junction of xrr and ctr data"""
  9. ####################### LIBRARY #############################
  10. # exceptions library
  11. from exceptions import (Data_Load_Exception)
  12. # Python stdlib imports
  13. import pickle
  14. import os
  15. # data processing library
  16. import numpy as np
  17. import scipy.interpolate as si
  18. import matplotlib.pyplot as plt
  19. # pyrod library
  20. from tool import control
  21. ####################### CONSTANT ############################
  22. # data path
  23. CTR_PATH = os.path.abspath(os.path.dirname('ctr_optimised_result.pickle')) +\
  24. '/data/ctr_optimised_result.pickle'
  25. XRR_PATH = os.path.abspath(os.path.dirname('xrr_optimised_result.pickle')) +\
  26. '/data/xrr_optimised_result.pickle'
  27. FIT_PATH = os.path.abspath(os.path.dirname('fit.pickle')) +\
  28. '/data/fit.pickle'
  29. # load data
  30. ctr = {}
  31. xrr = {}
  32. try:
  33. # load ctr optimised result
  34. with open(CTR_PATH, 'rb') as c:
  35. unpickler = pickle.Unpickler(c)
  36. ctr = unpickler.load()
  37. # load xrr optimised result
  38. with open(XRR_PATH, 'rb') as x:
  39. unpickler = pickle.Unpickler(x)
  40. xrr = unpickler.load()
  41. except Data_Load_Exception:
  42. print('Loading ctr or xrr optimised result error!')
  43. # visulise data
  44. PLINE = np.ones([len(ctr['shkl']), 3])
  45. PLINE[:,0] = abs(ctr['substrate_ctr'] + ctr['slab_ctr'])
  46. PLINE[:,1] = abs(xrr['rt']*xrr['inten'] + ctr['substrate_ctr'])
  47. PLINE[:,2] = ctr['shkl']
  48. ####################### FUNCTIONS ###########################
  49. # pick data point from a axes graph
  50. def pick_points(line, number):
  51. # construct figure and axis handle
  52. fig, ax = plt.subplots()
  53. # add title
  54. ax.set_title('pick points', picker = True)
  55. # plot the , use 'o' to make it easyer to pick
  56. # l, = ax.plot(line, 'o','^','*', picker = number)
  57. l1,l2,l3, = ax.plot(np.log(line), 'o', picker = number)
  58. # x, y to store the xdata and ydata of picked points
  59. x = []
  60. y = []
  61. # the click function to operate event
  62. def click(event):
  63. # The PickEvent which is passed to your callback is always fired with two attributes:
  64. # mouseevent and artist
  65. # Additionally, certain artists like Line2D and PatchCollection may attach additional
  66. # meta data like the indices into the data that meet the picker criteria
  67. # (e.g., all the points in the line that are within the specified epsilon tolerance)
  68. tline = event.artist
  69. ind = event.ind
  70. # pick xdata and ydata
  71. xdata = np.take(tline.get_xdata(), ind)[0]
  72. ydata = np.take(tline.get_ydata(), ind)[0]
  73. # store xdata and ydata
  74. x.append(xdata)
  75. y.append(ydata)
  76. # print the picked points
  77. print('x = ' + str(xdata))
  78. print('y = ' + str(ydata))
  79. # trigger the events
  80. fig.canvas.mpl_connect('pick_event', click)
  81. # loop to pause the figure, and pick the points
  82. while True:
  83. # before enough points are picked, pause
  84. if len(x) < number:
  85. # pause the figure
  86. plt.pause(0.5)
  87. # enough points are picked, break from the loop
  88. else:
  89. break
  90. plt.close(fig)
  91. return x,y
  92. ######################## CLASSS #############################
  93. class connection(object):
  94. def __init__(self, bond):
  95. self.bond = bond
  96. self.data = np.zeros(len(ctr['q']))
  97. self.r_square = 0
  98. # show all the optimised data -- xrr, ctr and raw data
  99. def show(self):
  100. fig, ax = plt.subplots()
  101. line1, = ax.plot(ctr['q'], np.log(PLINE[:,0]), 'g')
  102. line2, = ax.plot(ctr['q'], np.log(PLINE[:,1]), 'y')
  103. line3, = ax.plot(ctr['q'], np.log(PLINE[:,2]), 'r')
  104. plt.legend((line1, line2, line3), ('ctr','xrr','raw data'))
  105. # connect xrr and ctr data near first bragg peak
  106. def connect(self, b = 0.98):
  107. self.bond = b
  108. con_data = np.zeros(len(ctr['q']))
  109. location = np.argmin(abs(ctr['q'] - self.bond))
  110. con_data[0: location] = PLINE[0: location, 1]
  111. con_data[location:, ] = PLINE[location:, 0]
  112. con_f = si.interp1d(ctr['q'], con_data)
  113. self.data = con_f(ctr['q'])
  114. plt.scatter(ctr['q'], np.log(PLINE[:,2]), s = 5, c = 'r')
  115. plt.plot(ctr['q'], np.log(PLINE[:,2]), c = 'r')
  116. plt.plot(ctr['q'], np.log(self.data))
  117. # calculate the r_square between raw data and fit y
  118. # limit: the location of start raw data
  119. def error(self, limit):
  120. mask = control.bragg_mask(ctr['q'], 6, 1, 'yin', limit)
  121. number = {i:mask.tolist().count(i) for i in mask}[1]
  122. yhat = np.log(abs(self.data))*mask
  123. ydat = np.log(abs(ctr['shkl']))*mask
  124. ybar = np.sum(ydat)/number
  125. ssreg = np.sum((yhat - ybar)**2)
  126. sstot = np.sum((ydat - ybar)**2)
  127. if ssreg >= sstot:
  128. r2 = sstot/ssreg
  129. else:
  130. r2 = ssreg/sstot
  131. self.r_square = r2
  132. return r2
  133. # save the final fitting data
  134. def save(self):
  135. fit = {'q': ctr['q'],
  136. 'fit_y': self.data,
  137. 'shkl': ctr['shkl'],
  138. 'r_square': self.r_square}
  139. f = open(FIT_PATH, 'wb')
  140. pickle.dump(fit, f)
  141. f.close()