def write_ubi(param): # Save the generated UBI's # # INPUT: The parameter set from the input file and the grain generator # OUTPUT: for each grain the 3x3 UBI matrix # # Jette Oddershede, Risoe DTU, April 4 2008 # filename = '%s/%s.ubi' % (param['direc'], param['stem']) f = open(filename, 'w') format = "%f " * 3 + "\n" for i in range(param['no_grains']): U = param['U_grains_%s' % (param['grain_list'][i])] gr_eps = n.array(param['eps_grains_%s' % (param['grain_list'][i])]) if param['no_phases'] == 1: phase = param['phase_list'][0] else: phase = param['phase_grains_%s' % (param['grain_list'][i])] # Calculate the B-matrix based on the strain tensor for each grain B = tools.epsilon_to_b( gr_eps, param['unit_cell_phase_%i' % phase]) / (2 * n.pi) UBI = n.linalg.inv(n.dot(U, B)) for j in range(3): out = format % (UBI[j, 0], UBI[j, 1], UBI[j, 2]) f.write(out) out = "\n" f.write(out) f.close()
def run_asr(self, topology, ystep, number_y_scans, ymin, g, flt): origin = np.array([topology.shape[0] // 2, topology.shape[0] // 2]) mesh = mesher.create_pixel_mesh(topology, ystep, origin) distance = self.params.get('distance') pixelsize = (self.params.get('y_size') + self.params.get('z_size')) / 2.0 wavelength = self.params.get('wavelength') cell_original = [ self.params.get('cell__a'), self.params.get('cell__b'), self.params.get('cell__c'), self.params.get('cell_alpha'), self.params.get('cell_beta'), self.params.get('cell_gamma') ] strains, directions, omegas, dtys, weights, tths, etas, intensity, sc, G_omegas, hkl = mc.extract_strain_and_directions( cell_original, wavelength, distance, pixelsize, g, flt, ymin, ystep, self.omegastep, number_y_scans) # #With orient # UBs = asr.solve_with_orient( g, hkl, G_omegas, omegas, weights, mesh, dtys, ystep, cell_original ) # voxels = [] # coordinates = mesher.get_elm_centres( mesh ) # #print("UBs.shape",UBs.shape) # for i in range(UBs.shape[0]): # #print(UBs[i,:,:]) # UBI = np.linalg.inv(UBs[i,:,:]) # voxels.append( grain.grain( UBI ) ) # return voxels, coordinates # only strain # tikhonov_solve #eps_xx, eps_yy, eps_zz, eps_yz, eps_xz, eps_xy = asr.tikhonov_solve( mesh, directions, strains , omegas, dtys, weights, ystep, self.gradient_constraint ) #trust region eps_xx, eps_yy, eps_zz, eps_yz, eps_xz, eps_xy = asr.trust_constr_solve( mesh, etas, hkl, tths, intensity, directions, strains, omegas, dtys, weights, ystep, self.gradient_constraint, self.maxiter) voxels = [] coordinates = mesher.get_elm_centres(mesh) for i, elm in enumerate(mesh): # [e11, e12, e13, e22, e23, e33] epsilon_sample = np.array([[eps_xx[i], eps_xy[i], eps_xz[i]], [eps_xy[i], eps_yy[i], eps_yz[i]], [eps_xz[i], eps_yz[i], eps_zz[i]]]) eps_cry = np.dot(np.dot(np.transpose(g.u), epsilon_sample), g.u) eps_cry_flat = [ eps_cry[0, 0], eps_cry[0, 1], eps_cry[0, 2], eps_cry[1, 1], eps_cry[1, 2], eps_cry[2, 2] ] B = tools.epsilon_to_b(eps_cry_flat, cell_original) UBI = np.linalg.inv(np.dot(g.u, B)) * (2 * np.pi) voxels.append(grain.grain(UBI)) return voxels, coordinates
def strain_and_euler_to_ub(self,strain,euler): ''' cell = [a,b,c,alpha,beta,gamma] euler= [phi1,PHI,phi2] ''' U = tools.euler_to_u(euler[0],euler[1],euler[2]) B = tools.epsilon_to_b(strain, self.unit_cell) return np.dot(U,B)
def test_epsilon2B2epsilon(self): 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() ]) eps = (n.random.rand(6) - .5) / 1000. B = tools.epsilon_to_b(eps, ucell) eps2 = tools.b_to_epsilon(B, ucell)
def test_UdotBtoUandB(self): 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() ]) eps = (n.random.rand(6) - .5) / 1000. B = tools.epsilon_to_b(eps, ucell) U = tools.euler_to_u(n.random.rand() * 2. * n.pi, n.random.rand() * 2. * n.pi, n.random.rand() * n.pi) UB = n.dot(U, B) (U1, B1) = tools.ub_to_u_b(UB) diffU = n.abs(U - U1).sum() diffB = n.abs(B - B1).sum() self.assertAlmostEqual(diffU, 0, 9) self.assertAlmostEqual(diffB, 0, 9)
def run(self, start_voxel, end_voxel, log=True, parallel=None): ''' This is the main algorithmic loop that will calculate the diffraction pattern based on a per-voxel definition of the sample. The algorithm deals with one voxel at the time, computing all reflections that would be generated for that voxel in a single go. Therefore, the run time is linear with voxel number regardless of the number of y-scans. Input: start_voxel: Used for running in parrallel, equal to 0 for 1 cpu end_voxel: Used for running in parrallel, equal to number of voxels for 1 cpu log: used to determine of this process should print to stdout or be quiet. parallel: Flag to indicate parallel mode. Such a mode requires that we pass the result of the run to the calling process. ''' self.param['lorentz_apply']=1 tth_lower_bound = self.param['two_theta_lower_bound']*np.pi/180. tth_upper_bound = self.param['two_theta_upper_bound']*np.pi/180. spot_id = 0 # Compute used quanteties once for speed #-------------------------------------------- # Don't make static dictonary calls in loop, slower.. no_voxels = self.param['no_voxels'] beam_width = self.param['beam_width'] omega_start = self.param['omega_start']*np.pi/180 omega_end = self.param['omega_end']*np.pi/180 wavelength = self.param['wavelength'] scale_Gw = wavelength/(4.*np.pi) detz_center = self.param['detz_center'] dety_center = self.param['dety_center'] z_size = self.param['z_size'] y_size = self.param['y_size'] distance = self.param['distance'] wavelength = self.param['wavelength'] if log==True: print('no of voxels ',no_voxels) # print(start_voxel, end_voxel) # with open('solution','w') as f: # for voxel_nbr in range(start_voxel, end_voxel): # if len(self.param['phase_list']) == 1: # phase = self.param['phase_list'][0] # else: # phase = self.param['phase_voxels_%s' %(self.param['voxel_list'][voxel_nbr])] # unit_cell = self.param['unit_cell_phase_%i' %phase] # U = self.param['U_voxels_%s' %(self.param['voxel_list'][voxel_nbr])] # voxel_eps = np.array(self.param['eps_voxels_%s' %(self.param['voxel_list'][voxel_nbr])]) # B = tools.epsilon_to_b(voxel_eps,unit_cell) # UB = np.dot(U,B) # ub = UB.ravel() # f.write("np.array([") # for val in ub: # f.write(str(val)+", ") # f.write("])\n") # raise for voxel_nbr in range(start_voxel, end_voxel): A = [] U = self.param['U_voxels_%s' %(self.param['voxel_list'][voxel_nbr])] if len(self.param['phase_list']) == 1: phase = self.param['phase_list'][0] else: phase = self.param['phase_voxels_%s' %(self.param['voxel_list'][voxel_nbr])] unit_cell = self.param['unit_cell_phase_%i' %phase] self.voxel[voxel_nbr] = variables.voxel_cont(U) voxel_pos = np.array(self.param['pos_voxels_%s' %(self.param['voxel_list'][voxel_nbr])]) voxel_eps = np.array(self.param['eps_voxels_%s' %(self.param['voxel_list'][voxel_nbr])]) # Calculate the B-matrix based on the strain tensor for each voxel B = tools.epsilon_to_b(voxel_eps,unit_cell) # add B matrix to voxel container self.voxel[voxel_nbr].B = B V = tools.cell_volume(unit_cell) voxel_vol = np.pi/6 * self.param['size_voxels_%s' %self.param['voxel_list'][voxel_nbr]]**3 nrefl = 0 for hkl in self.hkl[self.param['phase_list'].index(phase)]: check_input.interrupt(self.killfile) Gc = np.dot(B,hkl[0:3]) Gw = np.dot(self.S,np.dot(U,Gc)) # if hkl[0]==0 and hkl[1]==-2 and hkl[2]==0: # print(np.dot(U,B)) # print(hkl[0:3]) # print(Gw) # raise tth = tools.tth2(Gw,wavelength) # If specified in input file do not compute for two # thetaoutside range [tth_lower_bound, tth_upper_bound] # if tth_upper_bound<tth or tth<tth_lower_bound : # continue costth = np.cos(tth) (Omega, Eta, Omega_mat, Gts) = self.find_omega_general(Gw*scale_Gw,scale_Gw,tth) for omega,eta,Om,Gt in zip(Omega, Eta, Omega_mat, Gts): if omega_start < omega and omega < omega_end: #print(np.degrees(omega)) # Calc crystal position at present omega [tx,ty,tz]= np.dot(Om,voxel_pos) #The 3 beam y positions that could illuminate the voxel beam_centre_1 = np.round(ty/beam_width)*beam_width beam_centre_0 = beam_centre_1+beam_width beam_centre_2 = beam_centre_1-beam_width #Compute precentual voxel beam overlap for the three regions overlaps_info = convexPolygon.compute_voxel_beam_overlap(tx,ty,omega,beam_centre_1, beam_width) regions = [ beam_centre_0, beam_centre_1,beam_centre_2] for beam_centre_y,info in zip(regions,overlaps_info): # perhaps we should have a less restrictive # comparision here, like: if intensity_modifier<0.0001, # there is some possibilty to simulate nosie here intensity_modifier = info[0] if intensity_modifier==0: continue #Lorentz factor if self.param['lorentz_apply'] == 1: if eta != 0: L=1/(np.sin(tth)*abs(np.sin(eta))) else: L=np.inf; else: L = 1.0 intensity = L*intensity_modifier*hkl[3] # If no unit cells where activated we continue dty = beam_centre_y*1000. # beam cetre in microns cx = info[1] cy = info[2] # Compute peak based on cms of illuminated voxel fraction tx = cx ty = cy - beam_centre_y # The sample moves not the beam! # print("tx",tx) # print("ty",ty) # print("") tz = 0 (dety, detz) = self.det_coor(Gt, costth, wavelength, distance, y_size, z_size, dety_center, 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 = np.pi/2.0 + eta + self.param['beampol_direct']*np.pi/180.0 P = 0.5 * (1 + costth*costth -\ self.param['beampol_factor']*np.cos(2*rho)*np.sin(tth)**2) else: P = 1.0 overlaps = 0 # set the number overlaps to zero # if self.param['intensity_const'] != 1: # intensity = intensity_modifier*int_intensity(hkl[3], # L, # P, # self.param['beamflux'], # self.param['wavelength'], # V, # voxel_vol) # else: # intensity = intensity_modifier*hkl[3] #TODO: try and build up the images as we go # Mapp reflection to the correct image self.peak_merger.add_reflection_to_images([self.param['voxel_list'][voxel_nbr], 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,dty,1]) A.append([self.param['voxel_list'][voxel_nbr], 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,dty,1]) nrefl = nrefl+1 #TODO: When run in parallel the spot id might be duplicated.. #but who cares about spot id anyways huh.. spot_id = spot_id+1 # A = np.array(A) # if len(A) > 0: # # sort rows according to omega # A = A[np.argsort(A,0)[:,A_id['omega']],:] # # Renumber the reflections # A[:,A_id['ref_id']] = np.arange(nrefl) # # Renumber the spot_id # A[:,A_id['spot_id']] = np.arange(np.min(A[:,A_id['spot_id']]), # np.max(A[:,A_id['spot_id']])+1) # else: # A = np.zeros((0,len(A_id))) # save reflection info in voxel container, if we are not in parallel mode this # will be the same object that we ran the run() method upon. Otherwise it is by # defualt a copy of that object and we will need to pass the result to the calling # process at the end of the algorithm self.voxel[voxel_nbr].refs = A if parallel and log==True: progress = int(100*(voxel_nbr+1-start_voxel)/float(end_voxel-start_voxel)) print('\rDone approximately %3i percent' %progress, end=' ') sys.stdout.flush() elif log==True: print('\rDone approximately %3i voxel(s) of %3i' %(voxel_nbr+1,self.param['no_voxels']), end=' ') sys.stdout.flush() if log==True: print('\n') # if we are running in parrallel the memory cannot be shared (easily) # so wee return our result in order to merge all results # into a single find_refl.py Object. if parallel: result = {"start_voxel": start_voxel, "end_voxel": end_voxel, "refl_list": self.voxel} return result else: # if not in parallel we may merge here # this allows us to include analyse_images_as_clusters() # easy in profiling self.peak_merger.analyse_images_as_clusters()
def write_grains(param): # Save the generated grain parameters, pos, U and eps # # INPUT: The parameter set from the input file and the grain generator # OUTPUT: grainno x y z phi1 PHI phi2 U11 U12 U13 U21 U22 U23 U31 U32 U33 eps11 eps12 eps13 eps22 eps23 eps33 # # Jette Oddershede, Risoe DTU, March 31 2008 # filename = '%s/%s.gff' % (param['direc'], param['stem']) f = open(filename, 'w') # format = "%d "*1 + "%f "*1 + "%e"*1 + "%f"*18 + "\n" format = "%d " * 1 + "%d " * 1 + "%f " * 1 + "%e " * 1 + "%f " * 6 + "%0.12f " * 9 + "%0.12f " * 9 + "%e " * 6 + "\n" out = "# grain_id phase_id grainsize grainvolume x y z phi1 PHI phi2 U11 U12 U13 U21 U22 U23 U31 U32 U33 UBI11 UBI12 UBI13 UBI21 UBI22 UBI23 UBI31 UBI32 UBI33 eps11 eps12 eps13 eps22 eps23 eps33 \n" f.write(out) for i in range(param['no_grains']): euler = 180 / n.pi * tools.u_to_euler(param['U_grains_%s' % (param['grain_list'][i])]) if len(param['phase_list']) == 1: phase = param['phase_list'][0] else: phase = param['phase_grains_%s' % (param['grain_list'][i])] b = tools.epsilon_to_b( param['eps_grains_%s' % (param['grain_list'][i])], param['unit_cell_phase_%i' % phase]) u = param['U_grains_%s' % (param['grain_list'][i])] ubi = n.linalg.inv(n.dot(u, b)) * 2 * n.pi out = format % ( param['grain_list'][i], phase, param['size_grains_%s' % (param['grain_list'][i])], n.pi / 6 * (param['size_grains_%s' % (param['grain_list'][i])])**3., param['pos_grains_%s' % (param['grain_list'][i])][0], param['pos_grains_%s' % (param['grain_list'][i])][1], param['pos_grains_%s' % (param['grain_list'][i])][2], euler[0], euler[1], euler[2], param['U_grains_%s' % (param['grain_list'][i])][0, 0], param['U_grains_%s' % (param['grain_list'][i])][0, 1], param['U_grains_%s' % (param['grain_list'][i])][0, 2], param['U_grains_%s' % (param['grain_list'][i])][1, 0], param['U_grains_%s' % (param['grain_list'][i])][1, 1], param['U_grains_%s' % (param['grain_list'][i])][1, 2], param['U_grains_%s' % (param['grain_list'][i])][2, 0], param['U_grains_%s' % (param['grain_list'][i])][2, 1], param['U_grains_%s' % (param['grain_list'][i])][2, 2], ubi[0, 0], ubi[0, 1], ubi[0, 2], ubi[1, 0], ubi[1, 1], ubi[1, 2], ubi[2, 0], ubi[2, 1], ubi[2, 2], param['eps_grains_%s' % (param['grain_list'][i])][0], param['eps_grains_%s' % (param['grain_list'][i])][1], param['eps_grains_%s' % (param['grain_list'][i])][2], param['eps_grains_%s' % (param['grain_list'][i])][3], param['eps_grains_%s' % (param['grain_list'][i])][4], param['eps_grains_%s' % (param['grain_list'][i])][5], ) f.write(out) f.close()
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 write_ubi(param): ''' Construct UBI matrices for each voxel and save them to file. If the voxels have been mapped to grains we also output the grain average UBI matrices. ''' # If we specified which voxels belong to which grains # we also get a per voxel average UBI file if param['voxel_grain_map'] is not None: m = param['voxel_grain_map'] grain_U = {} grain_eps = {} #Loop over grain id:s (val = grain number) for val in m.values(): if (val not in grain_U.keys()) and (val not in grain_eps.keys()) : #construct dictionary where the key is grain number and the value is the #list of properties of the voxels populating that grain grain_U[val] = [] grain_eps[val] = [] #loop over all voxels and fill up the dictionaries for voxel in range(param['no_voxels']): voxelId = param['voxel_list'][voxel] U = param['U_voxels_%s' % voxelId] gr_eps = n.array(param['eps_voxels_%s' % voxelId]) voxel_grain_id = m[voxelId] grain_U[voxel_grain_id].append(U) grain_eps[voxel_grain_id].append(gr_eps) filename = '%s/grain_average_%s.ubi' %(param['direc'],param['stem']) with open(filename,'w') as f: format = "%f "*3 + "\n" for voxel in grain_U.keys(): avg_U = n.zeros((3,3)) avg_eps = n.array([0.,0.,0.,0.,0.,0.]) for U,eps in zip(grain_U[voxel],grain_eps[voxel]): avg_U += U avg_eps += eps avg_U[:,0] = avg_U[:,0]/n.linalg.norm(avg_U[:,0]) avg_U[:,1] = avg_U[:,1]/n.linalg.norm(avg_U[:,1]) avg_U[:,2] = avg_U[:,2]/n.linalg.norm(avg_U[:,2]) avg_eps = avg_eps/len(grain_eps[voxel]) #TODO: implement several phases! if len(param['phase_list'])>1: raise ValueError('Currently only single phase simulations are supported') phase = param['phase_list'][0] avg_B = tools.epsilon_to_b(avg_eps,param['unit_cell_phase_%i' %phase])/(2*n.pi) avg_UBI = n.linalg.inv(n.dot(avg_U,avg_B)) for j in range(3): out = format %(avg_UBI[j,0],avg_UBI[j,1],avg_UBI[j,2]) f.write(out) out = "\n" f.write(out) filename = '%s/voxel_%s.ubi' %(param['direc'],param['stem']) with open(filename,'w') as f: format = "%f "*3 + "\n" for i in range(param['no_voxels']): U = param['U_voxels_%s' %(param['voxel_list'][i])] gr_eps = n.array(param['eps_voxels_%s' %(param['voxel_list'][i])]) if param['no_phases'] == 1: phase = param['phase_list'][0] else: phase = param['phase_voxels_%s' %(param['voxel_list'][i])] # Clculate the B-matrix based on the strain tensor for each voxel B = tools.epsilon_to_b(gr_eps,param['unit_cell_phase_%i' %phase])/(2*n.pi) UBI = n.linalg.inv(n.dot(U,B)) for j in range(3): out = format %(UBI[j,0],UBI[j,1],UBI[j,2]) f.write(out) out = "\n" f.write(out)
def write_voxels(param): ''' Save the generated voxel parameters, pos, U and eps INPUT: The parameter set from the input file and the voxel generator OUTPUT: voxelno x y z phi1 PHI phi2 U11 U12 U13 U21 U22 U23 U31 U32 U33 eps11 eps12 eps13 eps22 eps23 eps33 ''' filename = '%s/%s.gff' %(param['direc'],param['stem']) with open(filename,'w') as f: # format = "%d "*1 + "%f "*1 + "%e"*1 + "%f"*18 + "\n" format = "%d "*1 + "%d "*1 + "%f "*1 + "%e "*1 + "%f "*6 + "%0.12f "*9 + "%0.12f "*9 + "%e "*6 +"\n" out = "# voxel_id phase_id voxelsize voxelvolume x y z phi1 PHI phi2 U11 U12 U13 U21 U22 U23 U31 U32 U33 UBI11 UBI12 UBI13 UBI21 UBI22 UBI23 UBI31 UBI32 UBI33 eps11 eps12 eps13 eps22 eps23 eps33 \n" f.write(out) for i in range(param['no_voxels']): euler = 180/n.pi*tools.u_to_euler(param['U_voxels_%s' %(param['voxel_list'][i])]) if len(param['phase_list']) == 1: phase = param['phase_list'][0] else: phase = param['phase_voxels_%s' %(param['voxel_list'][i])] b = tools.epsilon_to_b(param['eps_voxels_%s' %(param['voxel_list'][i])], param['unit_cell_phase_%i' %phase ]) u = param['U_voxels_%s' %(param['voxel_list'][i])] ubi = n.linalg.inv(n.dot(u,b))*2*n.pi out = format %(param['voxel_list'][i], phase, param['size_voxels_%s' %(param['voxel_list'][i])], n.pi/6*(param['size_voxels_%s' %(param['voxel_list'][i])])**3., param['pos_voxels_%s' %(param['voxel_list'][i])][0], param['pos_voxels_%s' %(param['voxel_list'][i])][1], param['pos_voxels_%s' %(param['voxel_list'][i])][2], euler[0], euler[1], euler[2], param['U_voxels_%s' %(param['voxel_list'][i])][0,0], param['U_voxels_%s' %(param['voxel_list'][i])][0,1], param['U_voxels_%s' %(param['voxel_list'][i])][0,2], param['U_voxels_%s' %(param['voxel_list'][i])][1,0], param['U_voxels_%s' %(param['voxel_list'][i])][1,1], param['U_voxels_%s' %(param['voxel_list'][i])][1,2], param['U_voxels_%s' %(param['voxel_list'][i])][2,0], param['U_voxels_%s' %(param['voxel_list'][i])][2,1], param['U_voxels_%s' %(param['voxel_list'][i])][2,2], ubi[0,0], ubi[0,1], ubi[0,2], ubi[1,0], ubi[1,1], ubi[1,2], ubi[2,0], ubi[2,1], ubi[2,2], param['eps_voxels_%s' %(param['voxel_list'][i])][0], param['eps_voxels_%s' %(param['voxel_list'][i])][1], param['eps_voxels_%s' %(param['voxel_list'][i])][2], param['eps_voxels_%s' %(param['voxel_list'][i])][3], param['eps_voxels_%s' %(param['voxel_list'][i])][4], param['eps_voxels_%s' %(param['voxel_list'][i])][5], ) f.write(out)
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')