def __init__(self, lttc, *, x=None, y=None, z=None): super().__init__() self.lattice = lttc if (not x is None) and (not isinstance(x, LTTC.index)): self.indexx = LTTC.index(x) else: self.indexx = x if (not y is None) and (not isinstance(y, LTTC.index)): self.indexy = LTTC.index(y) else: self.indexy = y if (not z is None) and (not isinstance(z, LTTC.index)): self.indexz = LTTC.index(z) else: self.indexz = z self.orientation_decided = False self.rcp_matrix = self.lattice.rcp_matrix if self.check_orientation(): logging.info('orientation is decided!') # self.Guess_rotation((Vector(0,0,1), Vector(1,0,0)), (self.vecz, self.vecx)) self.Guess_rotation((self.vecz, self.vecx), (Vector(0, 0, 1), Vector(1, 0, 0))) self.Calc_rcp_matrix() else: logging.info('orientation is not decided!')
def vx(self): if not hasattr(self, '_vx'): if self.inc[1] == 0 and self.inc[0] == 0: self._vx = Vector(1, 0, 0) return self._vx self._vx = Vector((self.inc[1], -self.inc[0], 0)) if self.inc[1] < 0: self._vx = -self._vx return self._vx
def direct_matrix(self): if hasattr(self, '_direct_matrix'): return self._direct_matrix v1 = self.a * Vector((1, 0, 0)) v2 = self.b * Vector((np.cos(self.gamma), np.sin(self.gamma), 0)) v3 = self.c * Vector( (np.cos(self.beta), (np.cos(self.alpha) - np.cos(self.beta) * np.cos(self.gamma)) / np.sin(self.gamma))).norm m = np.vstack((v1, v2, v3)) logging.debug('Direct matrix is\n %s' % (str(m))) self._direct_matrix = m return m
def Calc_tthgam_map(self, inc=None, x=None): if inc is None: inc = self.normal if x is None: x = Vector(inc[1], -inc[0], 0) if inc[1] < 0: x = -x n = self.normal logging.debug('inc = %r, vx = %r, normal = %r' % (inc, x, n)) def tthgam_map(tth, gamma, on=True): v = Vector(tth=tth, gamma=gamma, z=inc, x=x) p = n.dot(v) logging.debug('v: %r, p: %r' % (v, p)) if p <= 0: return None v_in_det = self.dist * (v / p - n) vx = v_in_det.dot(self.x) + self.poni[0] vy = v_in_det.dot(self.y) + self.poni[1] logging.debug('tth: %3f, gamma: %3f, vx: %.3f, vy: %.3f' % (np.rad2deg(tth), np.rad2deg(gamma), vx, vy)) if on and not self.on((vx, vy)): return None return (vx, vy) self.map = tthgam_map self.direct_beam = self.map(0, 0, on=False) if self.direct_beam is None: logging.warn('Direct beam is not on plane of detector!') else: logging.debug('direct beam: (%.3f,%.3f)' % (self.direct_beam[0], self.direct_beam[1]))
def Save_rcp_space(self, filename, res_tth=0.1, res_gamma=0.1): if (not hasattr(self, 'rcp_space_num')) or self.rcp_space_num == 0: raise ValueError('No rcp_space') def mesh_tthgam(tths, gammas): for tth in tths: if tth in (0, np.pi): yield (tth, 0) else: for gamma in gammas: yield (tth, gamma) tths = np.linspace(0, np.pi, 180 // res_tth, endpoint=True) gammas = np.linspace(0, 2 * np.pi, 360 // res_gamma, endpoint=False) num = self.rcp_space_num * len(list(mesh_tthgam(tths, gammas))) with open(filename, 'w') as f: f.writelines('%d\n' % (num)) f.writelines('h k l kx ky kz intn\n') for hklfamily, radius, intn in zip(self.rcp_space_hkls, self.rcp_space_d, self.rcp_space_intn): for tth, gamma in mesh_tthgam(tths, gammas): vec = Vector(tth=tth, gamma=gamma) # print(tth, gamma, vec, radius) f.writelines('%s %f %f %f %f\n' % (hklfamily.str, radius * vec[0], radius * vec[1], radius * vec[2], intn))
def vec_in_rcp(self, hkl, rcp_matrix=None): if hkl is None: return None if rcp_matrix is None: rcp_matrix = self.rcp_matrix return Vector(np.dot(hkl, rcp_matrix))
def tthgam_map(tth, gamma, on=True): v = Vector(tth=tth, gamma=gamma, z=inc, x=x) p = n.dot(v) logging.debug('v: %r, p: %r' % (v, p)) if p <= 0: return None v_in_det = self.dist * (v / p - n) vx = v_in_det.dot(self.x) + self.poni[0] vy = v_in_det.dot(self.y) + self.poni[1] logging.debug('tth: %3f, gamma: %3f, vx: %.3f, vy: %.3f' % (np.rad2deg(tth), np.rad2deg(gamma), vx, vy)) if on and not self.on((vx, vy)): return None return (vx, vy)
def __init__(self, arr): super(LatticeParameter, self).__init__() logging.debug('input arr is %s' % (str(arr))) if len(arr) == 6: self.a, self.b, self.c, self.alpha, self.beta, self.gamma = arr[ 0], arr[1], arr[2], np.deg2rad(arr[3]), np.deg2rad( arr[4]), np.deg2rad(arr[5]) elif np.array(arr).shape == (3, 3): logging.debug('input matrix is %s' % (str(arr))) va, vb, vc = arr va, vb, vc = Vector(va), Vector(vb), Vector(vc) self.a, self.b, self.c = va.length, vb.length, vc.length self.alpha = vb.betweenangle_rad(vc) self.beta = vc.betweenangle_rad(va) self.gamma = va.betweenangle_rad(vb) else: raise ValueError('Unknown Parameters!') logging.debug('lattice parameters = (%f %f %f %f %f %f)' % (self.a, self.b, self.c, np.rad2deg(self.alpha), np.rad2deg(self.beta), np.rad2deg(self.gamma))) if not self.isvalid(): raise Error('lattice parameter is invalid!')
def Guess_rotation(self, vsbefore, vsafter): vbefore1, vafter1 = vsbefore[0].norm, vsafter[0].norm if ((vafter1 - vbefore1).length < EPS): axis1, angle1 = Vector((1, 0, 0)), 0 else: axis1, angle1 = vbefore1.cross(vafter1), vbefore1.betweenangle_rad( vafter1) qua1 = Quaternion(axis=axis1, angle=angle1).unit logging.debug("axis1 = %s, angle1 = %f" % (str(qua1.axis), qua1.degrees)) logging.debug("Residual = %s" % (str(vbefore1.rotate_by(qua1) - vafter1))) vbefore2, vafter2 = vsbefore[1].norm, vsafter[1].norm vafterq1 = vbefore2.rotate_by(qua1) if ((vafterq1 - vafter2).length < EPS): axis2, angle2 = Vector((1, 0, 0)), 0 else: axis2 = vafter1 angle2 = vafter2.cross(axis2).betweenangle_rad( vafterq1.cross(axis2)) if vafterq1.cross(vafter2).dot(axis2) < 0: angle2 = -angle2 qua2 = Quaternion(axis=axis2, angle=angle2).unit logging.debug("axis2 = %s, angle2 = %f" % (str(qua2.axis), qua2.degrees)) logging.debug("Residual = %s" % (str(vafterq1.rotate_by(qua2) - vafter2))) qua = qua2 * qua1 logging.debug("axis = %s, angle = %f" % (str(qua.axis), qua.degrees)) self.R = qua
def strain1d(self, axis=(1, 0, 0), index=None, ratio=0): if not index is None: axis = self.vec_in_rcp(index).norm else: axis = Vector(axis).norm vecs = [] for vec in self.direct_matrix: d = vec.dot(axis) vec_ = vec + axis * ratio * d vecs.append(vec_) self.lattice.Add_latticeparameters( LTTC.LatticeParameter(np.array(vecs))) self.direct_matrix = vecs
def __add__(self, other): if not isinstance(other, Pattern2d): raise ValueError('Only \'Pattern2d\' can be added!') if not hasattr(other, 'peaks'): raise ValueError('No peaks information!') if not self.xray == other.xray: raise ValueError('XRAY should be identical!') new = self.copy() new.sx = np.hstack((self.sx, other.sx)) new.num_tag(self.sx) new.peaks = np.hstack((self.peaks, other.peaks)) return new if __name__ == '__main__': lttc = LTTC.Lattice(material='Si') sx = SX.SingleXtal(lttc, x=(1, 0, 0), z=(0, 0, 1)) # sx.rotate_by(axis = (1,0,0), degree = -6) # xr = XR.Xray(wavelength = np.linspace(0.5, 0.6, 1000)) xr = XR.Xray('White') inc = Vector(0, 0, 1) p = Pattern2d(sx=sx, xray=xr, inc=inc) p.Calc(hklrange=(5, 5, 10)) p.show() p.save('peaks.txt')
def Calc_geometry(self): num_of_None = np.sum( [1 if vec is None else 0 for vec in (self.normal, self.x, self.y)]) logging.debug('num of None: %d' % (num_of_None)) if num_of_None >= 2: if not self.normal is None: logging.info('Only normal is known, x & y will be guessed') normal = self.normal.norm if normal.isparallel(Vector(0, 0, 1)): x = Vector((-1, 0, 0)) y = Vector((0, 1, 0)) elif normal.isparallel(Vector(0, 0, -1)): x = Vector((1, 0, 0)) y = Vector((0, 1, 0)) else: x = Vector(normal[1], -normal[0], 0) y = normal.cross(x) self.normal = normal self.x = x self.y = y logging.info('x and y are guessed as %s, %s, respectively' % (str(x), str(y))) else: raise ValueError('Geometry is not decided!') if num_of_None == 0: normal = Vector(self.normal).norm x = Vector(self.x).norm y = Vector(self.y).norm if not normal.isperpendicular(x) or not normal.isperpendicular( y) or not x.isperpendicular(y): raise ValueError( 'x,y,normal of detector is not perpendicular!') self.normal = normal self.x = x self.y = y return if num_of_None == 1: if self.normal is None: logging.info('Normal is empty') x = Vector(self.x).norm y = Vector(self.y).norm if not x.isperpendicular(y): logging.debug('x is %r, y is %r' % (x, y)) raise ValueError('x,y of detector is not perpendicular!') self.x = x self.y = y self.normal = x.cross(y) logging.debug('normal is %r' % (self.normal)) return if self.x is None: logging.info('x is empty') normal = Vector(self.normal).norm y = Vector(self.y).norm if not normal.isperpendicular(y): logging.debug('normal is %r, y is %r' % (normal, y)) raise ValueError( 'normal,y of detector is not perpendicular!') self.normal = normal self.y = y self.x = y.cross(normal) logging.debug('x is %r' % (self.x)) return if self.y is None: logging.info('y is empty') normal = Vector(self.normal).norm x = Vector(self.x).norm if not normal.isperpendicular(x): logging.debug('normal is %r, x is %r' % (normal, x)) raise ValueError( 'normal,x of detector is not perpendicular!') self.normal = normal self.x = x self.y = normal.cross(x) logging.debug('y is %r' % (self.y)) return
plt.legend() plt.show() if __name__ == '__main__': Ta = LTTC.Lattice(material='Ta') Cu = LTTC.Lattice(material='Cu') Mg = LTTC.Lattice(material='Mg') Al = LTTC.Lattice(material='Al') # sx = SX.SingleXtal(Al, z = (1,1,1), x = (-1,1,0)) # sx.rotate_by(axis = (1,0,0), degrees = -6) # sx.strain1d(axis = (1,0,0), ratio = -0.03) px = PX.PolyXtal(Al) # xr = XR.Xray(filename = 'u18_gap12mm.txt', islambda = False, EPS = 1e13) # xr.show() xr = XR.Xray(wavelength=0.53) inc = Vector(0, 0, -1) # inc = inc.rotate_by(axis = (1,0,0), degree = 10) # p = S2D.Pattern2d(sx = sx, xray = xr, inc = Vector(0,0,-1)) # p.Calc(hklrange = (5,5,5)) p = S1D.Profile1D(xray=xr, px=px) p.Calc(range_2th=(10, 50), precision=0.001) # p.show() p.Add_geometry(inc=inc, x=Vector(1, 0, 0)) # det1 = Detector(normal = -inc , size = (400, 400), poni = ('c','c'), x = (1,0,0), dist = 250) det1 = Detector(normal=inc, size=(400, 400), poni=('c', 'c'), dist=250) # det1.rotate_by(axis = (1,1,0), degree = 60) # det1.set(poni = (-50,'c')) det1.Calc_peaks(p) det1.show()
def Add_geometry(self, inc=Vector(0, 0, -1), x=Vector(1, 0, 0)): self.inc = inc self.vx = x
print('No peaks!') return with open(filename, 'w') as f: f.writelines('%d\n' % (len(self.peaks))) f.writelines('index tth intn d_spacing lambda\n') for p in self.peaks: f.writelines('%s %d %f %f %f\n' % (p.index.str, np.rad2deg( p.tth), p.intn, p.d_spacing, p.wl)) if __name__ == '__main__': Ta = LTTC.Lattice(material='Ta') Cu = LTTC.Lattice(material='Cu') Mg = LTTC.Lattice(material='Mg') # sx = SX.SingleXtal(Ta, z = (1,1,1), x = (-1,1,0)) # sx.rotate_by(axis = (1,0,0), degrees = -6) # sx.strain1d(axis = (1,0,0), ratio = -0.03) px = PX.PolyXtal(Mg) # xr = XR.Xray(filename = 'u18_gap12mm.txt', islambda = False, EPS = 1e13) # xr.show() xr = XR.Xray(wavelength=0.52) inc = Vector(0, 0, -1) # inc = inc.rotate_by(axis = (1,0,0), degree = 10) # p = S2D.Pattern2d(sx = sx, xray = xr, inc = Vector(0,0,-1)) # p.Calc(hklrange = (5,5,5)) p = Profile1D(xray=xr, px=px) p.Calc(range_2th=(10, 20), precision=0.001) p.show() p.save_peaks('1d.dat')