def test_find_omega_general_nowedge(self): # generate random gvector hkl = n.array([ round(n.random.rand() * 10 - 5), round(n.random.rand() * 10 - 5), round(n.random.rand() * 10 - 5) ]) ucell = n.array([ 3.5 + n.random.rand(), 3.5 + n.random.rand(), 3.5 + n.random.rand(), 89.5 + n.random.rand(), 89.5 + n.random.rand(), 89.5 + n.random.rand() ]) B = tools.form_b_mat(ucell) U = tools.euler_to_u(n.random.rand() * 2. * n.pi, n.random.rand() * 2. * n.pi, n.random.rand() * n.pi) wavelength = 0.95 + n.random.rand() * 0.1 gvec = n.dot(U, n.dot(B, hkl)) tth = tools.tth(ucell, hkl, wavelength) # calculate corresponding eta and Omega using tools.find_omega_general (omega1, eta1) = tools.find_omega_general(gvec * wavelength / (4. * n.pi), tth, 0, 0) Om1 = [] for i in range(len(omega1)): Om1.append(tools.form_omega_mat_general(omega1[i], 0, 0)) # calculate corresponding eta and Omega using tools.find_omega_wedge omega2 = tools.find_omega(gvec, tth) Om2 = [] for i in range(len(omega2)): Om2.append(tools.form_omega_mat(omega2[i])) #assert for i in range(len(omega1)): # print Om1[i] # print Om2[i] diff = n.abs(Om1[i] - Om2[i]).sum() self.assertAlmostEqual(diff, 0, 9)
def make_image(self, grainno=None, refl=None): from scipy import ndimage if grainno == None: do_grains = list(range(self.graindata.param['no_grains'])) else: do_grains = [grainno] # loop over grains for grainno in do_grains: gr_pos = n.array(self.graindata.param['pos_grains_%s' \ %(self.graindata.param['grain_list'][grainno])]) B = self.graindata.grain[grainno].B SU = n.dot(self.graindata.S, self.graindata.grain[grainno].U) if refl == None: do_refs = list(range(len(self.graindata.grain[grainno].refs))) else: do_refs = [refl] # loop over reflections for each grain for nref in do_refs: # exploit that the reflection list is sorted according to omega print('\rDoing reflection %i of %i for grain %i of %i' % (nref + 1, len(self.graindata.grain[grainno].refs), grainno + 1, self.graindata.param['no_grains']), end=' ') sys.stdout.flush() #print 'Doing reflection: %i' %nref if self.graindata.param['odf_type'] == 3: intensity = 1 else: intensity = self.graindata.grain[grainno].refs[nref, A_id['Int']] hkl = n.array([ self.graindata.grain[grainno].refs[nref, A_id['h']], self.graindata.grain[grainno].refs[nref, A_id['k']], self.graindata.grain[grainno].refs[nref, A_id['l']] ]) Gc = n.dot(B, hkl) for i in range(self.odf.shape[0]): for j in range(self.odf.shape[1]): for k in range(self.odf.shape[2]): check_input.interrupt(self.killfile) if self.odf[i, j, k] > self.odf_cut: Gtmp = n.dot(self.Uodf[i, j, k], Gc) Gw = n.dot(SU, Gtmp) Glen = n.sqrt(n.dot(Gw, Gw)) tth = 2 * n.arcsin(Glen / (2 * abs(self.graindata.K))) costth = n.cos(tth) Qw = Gw * self.graindata.param[ 'wavelength'] / (4. * n.pi) (Omega, eta) = tools.find_omega_general( Qw, tth, self.wx, self.wy) try: minpos = n.argmin( n.abs(Omega - self.graindata.grain[grainno]. refs[nref, A_id['omega']])) except: print(Omega) if len(Omega) == 0: continue omega = Omega[minpos] # if omega not in rotation range continue to next step if (self.graindata.param['omega_start']*n.pi/180) > omega or\ omega > (self.graindata.param['omega_end']*n.pi/180): continue Om = tools.form_omega_mat_general( omega, self.wx, self.wy) Gt = n.dot(Om, Gw) # Calc crystal position at present omega [tx, ty, tz] = n.dot(Om, gr_pos) (dety, detz) = detector.det_coor( Gt, costth, self.graindata.param['wavelength'], self.graindata.param['distance'], self.graindata.param['y_size'], self.graindata.param['z_size'], self.graindata.param['dety_center'], self.graindata.param['detz_center'], self.graindata.R, tx, ty, tz) if self.graindata.param['spatial'] != None: # To match the coordinate system of the spline file # SPLINE(i,j): i = detz; j = (dety_size-1)-dety # Well at least if the spline file is for frelon2k (x, y) = detector.detyz_to_xy( [dety, detz], self.graindata.param['o11'], self.graindata.param['o12'], self.graindata.param['o21'], self.graindata.param['o22'], self.graindata.param['dety_size'], self.graindata.param['detz_size']) # Do the spatial distortion (xd, yd) = self.spatial.distort(x, y) # transform coordinates back to dety,detz (dety, detz) = detector.xy_to_detyz( [xd, yd], self.graindata.param['o11'], self.graindata.param['o12'], self.graindata.param['o21'], self.graindata.param['o22'], self.graindata.param['dety_size'], self.graindata.param['detz_size']) if dety > -0.5 and dety <= self.graindata.param['dety_size']-0.5 and\ detz > -0.5 and detz <= self.graindata.param['detz_size']-0.5: dety = int(round(dety)) detz = int(round(detz)) frame_no = int(n.floor((omega*180/n.pi-self.graindata.param['omega_start'])/\ self.graindata.param['omega_step'])) self.frames[frame_no][ dety, detz] = self.frames[frame_no][ dety, detz] + intensity * self.odf[i, j, k]
def find_refl(inp): """ From U, (x,y,z) and B determined for the far-field case calculate the possible reflection on the near-field detector output[grainno][reflno]=[h,k,l,omega,dety,detz,tth,eta] """ S = n.array([[1, 0, 0],[0, 1, 0],[0, 0, 1]]) R = tools.detect_tilt(inp.param['tilt_x'], inp.param['tilt_y'], inp.param['tilt_z']) inp.possible = [] # if structure info is given use this if inp.files['structure_file'] != None: inp.param['structure_phase_0'] = inp.files['structure_file'] xtal_structure = reflections.open_structure(inp.param,0) HKL = reflections.gen_miller(inp.param,0) else: inp.param['unit_cell_phase_0'] = inp.unit_cell inp.param['sgno_phase_0'] = inp.fit['sgno'] HKL = reflections.gen_miller(inp.param,0) for grainno in range(inp.no_grains): inp.possible.append([]) if grainno+1 not in inp.fit['skip']: B = tools.epsilon_to_b(n.array([inp.values['epsaa%s' %grainno], inp.values['epsab%s' %grainno], inp.values['epsac%s' %grainno], inp.values['epsbb%s' %grainno], inp.values['epsbc%s' %grainno], inp.values['epscc%s' %grainno]]), inp.unit_cell) U = tools.rod_to_u([inp.rod[grainno][0]+inp.values['rodx%s' %grainno], inp.rod[grainno][1]+inp.values['rody%s' %grainno], inp.rod[grainno][2]+inp.values['rodz%s' %grainno]]) gr_pos = n.array([inp.values['x%s' %grainno], inp.values['y%s' %grainno], inp.values['z%s' %grainno]]) for hkl in HKL: Gc = n.dot(B,hkl[0:3]) Gw = n.dot(S,n.dot(U,Gc)) tth = tools.tth2(Gw,inp.param['wavelength']) # print hkl[0:3],tth*180./n.pi costth = n.cos(tth) (Omega, Eta) = tools.find_omega_general(inp.param['wavelength']/(4.*n.pi)*Gw, tth, inp.values['wx']*n.pi/180, inp.values['wy']*n.pi/180) if len(Omega) > 0: for solution in range(len(Omega)): omega = Omega[solution] eta = Eta[solution] for i in range(len(inp.fit['w_limit'])//2): if (inp.fit['w_limit'][2*i]*n.pi/180) < omega and\ omega < (inp.fit['w_limit'][2*i+1]*n.pi/180): # form Omega rotation matrix Om = tools.form_omega_mat_general(omega,inp.values['wx']*n.pi/180,inp.values['wy']*n.pi/180) Gt = n.dot(Om,Gw) # Calc crystal position at present omega [tx,ty,tz]= n.dot(Om,gr_pos) # Calc detector coordinate for peak (dety, detz) = detector.det_coor(Gt,costth, inp.param['wavelength'], inp.param['distance'], inp.param['y_size'], inp.param['z_size'], inp.param['y_center'], inp.param['z_center'], R,tx,ty,tz) #If peak within detector frame store it in possible if (-0.5 < dety) and\ (dety < inp.fit['dety_size']-0.5) and\ (-0.5 < detz) and\ (detz < inp.fit['detz_size']-0.5): inp.possible[grainno].append([hkl[0], hkl[1], hkl[2], omega*180/n.pi, dety, detz, tth, eta])
def run(self): spot_id = 0 # Generate orientations of the grains and loop over all grains print('no of grains ', self.param['no_grains']) for grainno in range(self.param['no_grains']): A = [] U = self.param['U_grains_%s' % (self.param['grain_list'][grainno])] if len(self.param['phase_list']) == 1: phase = self.param['phase_list'][0] else: phase = self.param['phase_grains_%s' % (self.param['grain_list'][grainno])] unit_cell = self.param['unit_cell_phase_%i' % phase] self.grain.append(variables.grain_cont(U)) gr_pos = n.array(self.param['pos_grains_%s' % (self.param['grain_list'][grainno])]) gr_eps = n.array(self.param['eps_grains_%s' % (self.param['grain_list'][grainno])]) # Calculate the B-matrix based on the strain tensor for each grain B = tools.epsilon_to_b(gr_eps, unit_cell) # add B matrix to grain container self.grain[grainno].B = B V = tools.cell_volume(unit_cell) grain_vol = n.pi / 6 * self.param[ 'size_grains_%s' % self.param['grain_list'][grainno]]**3 # print 'GRAIN NO: ',self.param['grain_list'][grainno] # print 'GRAIN POSITION of grain ',self.param['grain_list'][grainno],': ',gr_pos # print 'STRAIN TENSOR COMPONENTS (e11 e12 e13 e22 e23 e33) of grain ',self.param['grain_list'][grainno],':\n',gr_eps # print 'U of grain ',self.param['grain_list'][grainno],':\n',U nrefl = 0 # Calculate these values: # totalnr, grainno, refno, hkl, omega, 2theta, eta, dety, detz # For all reflections in Ahkl that fulfill omega_start < omega < omega_end. # All angles in Grain are in degrees for hkl in self.hkl[self.param['phase_list'].index(phase)]: check_input.interrupt(self.killfile) Gc = n.dot(B, hkl[0:3]) Gw = n.dot(self.S, n.dot(U, Gc)) tth = tools.tth2(Gw, self.param['wavelength']) costth = n.cos(tth) (Omega, Eta) = tools.find_omega_general( Gw * self.param['wavelength'] / (4. * n.pi), tth, self.wx, self.wy) if len(Omega) > 0: for solution in range(len(Omega)): omega = Omega[solution] eta = Eta[solution] if (self.param['omega_start']*n.pi/180) < omega and\ omega < (self.param['omega_end']*n.pi/180): # form Omega rotation matrix Om = tools.form_omega_mat_general( omega, self.wx, self.wy) Gt = n.dot(Om, Gw) # Calc crystal position at present omega and continue if this is outside the illuminated volume [tx, ty, tz] = n.dot(Om, gr_pos) if self.param['beam_width'] != None: if n.abs(ty) > self.param['beam_width'] / 2.: continue # Calc detector coordinate for peak (dety, detz) = detector.det_coor( Gt, costth, self.param['wavelength'], self.param['distance'], self.param['y_size'], self.param['z_size'], self.param['dety_center'], self.param['detz_center'], self.R, tx, ty, tz) #If shoebox extends outside detector exclude it if (-0.5 > dety) or\ (dety > self.param['dety_size']-0.5) or\ (-0.5 > detz) or\ (detz > self.param['detz_size']-0.5): continue if self.param['spatial'] != None: # To match the coordinate system of the spline file (x, y) = detector.detyz_to_xy( [dety, detz], self.param['o11'], self.param['o12'], self.param['o21'], self.param['o22'], self.param['dety_size'], self.param['detz_size']) # Do the spatial distortion (xd, yd) = self.spatial.distort(x, y) # transform coordinates back to dety,detz (detyd, detzd) = detector.xy_to_detyz( [xd, yd], self.param['o11'], self.param['o12'], self.param['o21'], self.param['o22'], self.param['dety_size'], self.param['detz_size']) else: detyd = dety detzd = detz if self.param['beampol_apply'] == 1: #Polarization factor (Kahn, J. Appl. Cryst. (1982) 15, 330-337.) rho = n.pi / 2.0 + eta + self.param[ 'beampol_direct'] * n.pi / 180.0 P = 0.5 * (1 + costth*costth -\ self.param['beampol_factor']*n.cos(2*rho)*n.sin(tth)**2) else: P = 1.0 #Lorentz factor if self.param['lorentz_apply'] == 1: if eta != 0: L = 1 / (n.sin(tth) * abs(n.sin(eta))) else: L = n.inf else: L = 1.0 overlaps = 0 # set the number overlaps to zero if self.param['intensity_const'] != 1: intensity = int_intensity( hkl[3], L, P, self.param['beamflux'], self.param['wavelength'], V, grain_vol) else: intensity = hkl[3] A.append([ self.param['grain_list'][grainno], nrefl, spot_id, hkl[0], hkl[1], hkl[2], tth, omega, eta, dety, detz, detyd, detzd, Gw[0], Gw[1], Gw[2], L, P, hkl[3], intensity, overlaps ]) nrefl = nrefl + 1 spot_id = spot_id + 1 # print 'Length of Grain', len(self.grain[0].refl) A = n.array(A) if len(A) > 0: # sort rows according to omega A = A[n.argsort(A, 0)[:, A_id['omega']], :] # Renumber the reflections A[:, A_id['ref_id']] = n.arange(nrefl) # Renumber the spot_id A[:, A_id['spot_id']] = n.arange(n.min(A[:, A_id['spot_id']]), n.max(A[:, A_id['spot_id']]) + 1) else: A = n.zeros((0, len(A_id))) # save reflection info in grain container self.grain[grainno].refs = A print('\rDone %3i grain(s) of %3i' % (grainno + 1, self.param['no_grains']), end=' ') sys.stdout.flush() print('\n')