123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- # -*- coding: utf-8 -*-
- """
- Created on Sun Aug 26 21:15:03 2018
- @author: USER
- """
- # Codes are free to use. Do whatever you want
- from __future__ import absolute_import
- """junction of xrr and ctr data"""
- ####################### LIBRARY #############################
- # exceptions library
- from exceptions import (Data_Load_Exception)
- # Python stdlib imports
- import pickle
- import os
- # data processing library
- import numpy as np
- import scipy.interpolate as si
- import matplotlib.pyplot as plt
- # pyrod library
- from tool import control
- ####################### CONSTANT ############################
- # data path
- CTR_PATH = os.path.abspath(os.path.dirname('ctr_optimised_result.pickle')) +\
- '/data/ctr_optimised_result.pickle'
-
- XRR_PATH = os.path.abspath(os.path.dirname('xrr_optimised_result.pickle')) +\
- '/data/xrr_optimised_result.pickle'
- FIT_PATH = os.path.abspath(os.path.dirname('fit.pickle')) +\
- '/data/fit.pickle'
-
- # load data
-
- ctr = {}
- xrr = {}
- try:
-
- # load ctr optimised result
- with open(CTR_PATH, 'rb') as c:
- unpickler = pickle.Unpickler(c)
- ctr = unpickler.load()
-
- # load xrr optimised result
- with open(XRR_PATH, 'rb') as x:
- unpickler = pickle.Unpickler(x)
- xrr = unpickler.load()
-
- except Data_Load_Exception:
- print('Loading ctr or xrr optimised result error!')
- # visulise data
- PLINE = np.ones([len(ctr['shkl']), 3])
- PLINE[:,0] = abs(ctr['substrate_ctr'] + ctr['slab_ctr'])
- PLINE[:,1] = abs(xrr['rt']*xrr['inten'] + ctr['substrate_ctr'])
- PLINE[:,2] = ctr['shkl']
-
- ####################### FUNCTIONS ###########################
- # pick data point from a axes graph
- def pick_points(line, number):
-
- # construct figure and axis handle
- fig, ax = plt.subplots()
- # add title
- ax.set_title('pick points', picker = True)
- # plot the , use 'o' to make it easyer to pick
- # l, = ax.plot(line, 'o','^','*', picker = number)
- l1,l2,l3, = ax.plot(np.log(line), 'o', picker = number)
-
- # x, y to store the xdata and ydata of picked points
- x = []
- y = []
-
- # the click function to operate event
- def click(event):
-
- # The PickEvent which is passed to your callback is always fired with two attributes:
- # mouseevent and artist
- # Additionally, certain artists like Line2D and PatchCollection may attach additional
- # meta data like the indices into the data that meet the picker criteria
- # (e.g., all the points in the line that are within the specified epsilon tolerance)
-
- tline = event.artist
- ind = event.ind
-
- # pick xdata and ydata
- xdata = np.take(tline.get_xdata(), ind)[0]
- ydata = np.take(tline.get_ydata(), ind)[0]
-
- # store xdata and ydata
- x.append(xdata)
- y.append(ydata)
-
- # print the picked points
- print('x = ' + str(xdata))
- print('y = ' + str(ydata))
-
- # trigger the events
- fig.canvas.mpl_connect('pick_event', click)
-
- # loop to pause the figure, and pick the points
- while True:
- # before enough points are picked, pause
- if len(x) < number:
- # pause the figure
- plt.pause(0.5)
- # enough points are picked, break from the loop
- else:
- break
-
- plt.close(fig)
-
- return x,y
- ######################## CLASSS #############################
- class connection(object):
-
- def __init__(self, bond):
-
- self.bond = bond
- self.data = np.zeros(len(ctr['q']))
- self.r_square = 0
-
- # show all the optimised data -- xrr, ctr and raw data
- def show(self):
-
- fig, ax = plt.subplots()
-
- line1, = ax.plot(ctr['q'], np.log(PLINE[:,0]), 'g')
- line2, = ax.plot(ctr['q'], np.log(PLINE[:,1]), 'y')
- line3, = ax.plot(ctr['q'], np.log(PLINE[:,2]), 'r')
-
- plt.legend((line1, line2, line3), ('ctr','xrr','raw data'))
-
- # connect xrr and ctr data near first bragg peak
- def connect(self, b = 0.98):
-
- self.bond = b
-
- con_data = np.zeros(len(ctr['q']))
- location = np.argmin(abs(ctr['q'] - self.bond))
-
- con_data[0: location] = PLINE[0: location, 1]
- con_data[location:, ] = PLINE[location:, 0]
-
- con_f = si.interp1d(ctr['q'], con_data)
- self.data = con_f(ctr['q'])
-
- plt.scatter(ctr['q'], np.log(PLINE[:,2]), s = 5, c = 'r')
- plt.plot(ctr['q'], np.log(PLINE[:,2]), c = 'r')
- plt.plot(ctr['q'], np.log(self.data))
-
- # calculate the r_square between raw data and fit y
- # limit: the location of start raw data
- def error(self, limit):
-
- mask = control.bragg_mask(ctr['q'], 6, 1, 'yin', limit)
- number = {i:mask.tolist().count(i) for i in mask}[1]
-
- yhat = np.log(abs(self.data))*mask
- ydat = np.log(abs(ctr['shkl']))*mask
- ybar = np.sum(ydat)/number
-
- ssreg = np.sum((yhat - ybar)**2)
- sstot = np.sum((ydat - ybar)**2)
-
- if ssreg >= sstot:
- r2 = sstot/ssreg
- else:
- r2 = ssreg/sstot
-
- self.r_square = r2
-
- return r2
-
- # save the final fitting data
- def save(self):
-
- fit = {'q': ctr['q'],
- 'fit_y': self.data,
- 'shkl': ctr['shkl'],
- 'r_square': self.r_square}
-
- f = open(FIT_PATH, 'wb')
- pickle.dump(fit, f)
- f.close()
|