def setup_experiment(pars, cif_file, no_voxels, beam_width, theta_min, theta_max): ''' beam_width needs to be in microns it is here converted to mm ''' o11 = pars.parameters['o11'] o12 = pars.parameters['o12'] o21 = pars.parameters['o21'] o22 = pars.parameters['o22'] dety_size = 2048 detz_size = 2048 (dety_center, detz_center) = detector.xy_to_detyz( [pars.parameters['z_center'], pars.parameters['y_center']], o11, o12, o21, o22, dety_size, detz_size) param = { 'no_voxels': no_voxels, 'beam_width': beam_width / 1000., 'structure_phase_0': cif_file, 'omega_start': 0, 'omega_end': 180, 'omega_step': 1.0, 'omega_sign': pars.parameters['omegasign'], 'wavelength': pars.parameters['wavelength'], 'detz_center': detz_center, #1041.55049636,#detz_center 'dety_center': dety_center, #998.798998,#dety_center 'z_size': pars.parameters['z_size'] / 1000., 'y_size': pars.parameters['y_size'] / 1000., 'distance': pars.parameters['distance'] / 1000., 'o11': pars.parameters['o11'], 'o12': pars.parameters['o12'], 'o21': pars.parameters['o21'], 'o22': pars.parameters['o22'], 'dety_size': dety_size, 'detz_size': detz_size, 'lorentz_apply': 1, 'theta_min': 0, 'theta_max': 12, #i.e only two theta = 2*theta_max or lower is computed for 'tilt_x': pars.parameters['tilt_x'], 'tilt_y': pars.parameters['tilt_y'], 'tilt_z': pars.parameters['tilt_z'], 'wedge': pars.parameters['wedge'], } return param
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 make_image(self, frame_number=None): """ makeimage script produces edf diffraction images using the reflection information Henning Osholm Sorensen, June 23, 2006. python translation Jette Oddershede, March 31, 2008 """ peakshape = self.graindata.param['peakshape'] if peakshape[0] == 0: # spike peak, 2x2 pixels peak_add = 1 frame_add = 1 peakwsig = 0 elif peakshape[0] == 1: # 3d Gaussian peak peak_add = max(1, int(round(peakshape[1]))) frame_add = max(1, int(round(peakshape[1]))) peakwsig = peakshape[2] elif peakshape[0] == 3: # 3d Gaussian peak in 2theta,eta,omega peak_add = 1 frame_add = 1 cen_tth = int(1.5 * peakshape[1] / Delta_tth) frame_tth = 2 * cen_tth + 1 fwhm_tth = peakshape[1] / Delta_tth cen_eta = int(1.5 * peakshape[2] / Delta_eta) frame_eta = 2 * cen_eta + 1 fwhm_eta = peakshape[2] / Delta_eta raw_tth_eta = n.zeros((frame_tth, frame_eta)) raw_tth_eta[cen_tth, cen_eta] = 1 filter_tth_eta = ndimage.gaussian_filter( raw_tth_eta, [0.5 * fwhm_tth, 0.5 * fwhm_eta]) peakwsig = 1. framedimy = int(self.graindata.param['dety_size'] + 2 * frame_add) framedimz = int(self.graindata.param['detz_size'] + 2 * frame_add) totalrefl = 0 if frame_number == None: no_frames = list(range(len(self.graindata.frameinfo))) print('Generating diffraction images') else: no_frames = [frame_number] for i in no_frames: check_input.interrupt(self.killfile) t1 = time.clock() nrefl = 0 frame = n.zeros((framedimy, framedimz)) omega = self.graindata.frameinfo[i].omega omega_step = self.graindata.param['omega_step'] # Jettes hack to add relative movement of sample and detector, modelled to be Gaussian in y and z direction with a spread of 1 micron # movement of 1 micron along x judged to be irrelevant, at least for farfield data y_move = n.random.normal(0, 1. / self.graindata.param['dety_size']) z_move = n.random.normal(0, 1. / self.graindata.param['detz_size']) # loop over grains for j in range(self.graindata.param['no_grains']): # loop over reflections for each grain gr_pos = n.array(self.graindata.param['pos_grains_%s' % j]) for k in range(len(self.graindata.grain[j].refs)): # exploit that the reflection list is sorted according to omega if self.graindata.grain[j].refs[k,A_id['omega']]*180/n.pi > \ omega+omega_step+2*peakwsig: break elif self.graindata.grain[j].refs[k,A_id['omega']]*180/n.pi < \ omega-2*peakwsig: continue dety = self.graindata.grain[j].refs[ k, A_id['detyd']] # must be spot position after detz = self.graindata.grain[j].refs[ k, A_id['detzd']] # applying spatial distortion #apply hack # dety = self.graindata.grain[j].refs[k,A_id['dety']] + y_move # detz = self.graindata.grain[j].refs[k,A_id['detz']] + z_move ndety = int(round(dety)) ndetz = int(round(detz)) yrange = list( range(ndety + frame_add - peak_add, ndety + frame_add + peak_add + 1)) zrange = list( range(ndetz + frame_add - peak_add, ndetz + frame_add + peak_add + 1)) intensity = int( round(self.graindata.grain[j].refs[k, A_id['Int']])) nrefl = nrefl + 1 totalrefl = totalrefl + 1 # Gaussian along omega if peakshape[0] == 1 or peakshape[0] == 3: fraction = norm.cdf((omega-self.graindata.grain[j].refs[k,A_id['omega']]*180/n.pi+omega_step)/(0.5*peakwsig))\ -norm.cdf((omega-self.graindata.grain[j].refs[k,A_id['omega']]*180/n.pi)/(0.5*peakwsig)) else: fraction = 1. if peakshape[0] == 3: # Gaussian peaks along 2theta,eta tth = self.graindata.grain[j].refs[k, A_id['tth']] eta = self.graindata.grain[j].refs[k, A_id['eta']] Om = tools.form_omega_mat_general( self.graindata.grain[j].refs[k, A_id['omega']], 0, -1. * self.graindata.param['wedge'] * n.pi / 180.) [tx, ty, tz] = n.dot(Om, gr_pos) for t in range(frame_tth): tth_present = tth + ( t - cen_tth) * Delta_tth * n.pi / 180. for e in range(frame_eta): eta_present = eta + ( e - cen_eta) * Delta_eta * n.pi / 180. [dety_present, detz_present] = detector.det_coor2( tth_present, eta_present, 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: from ImageD11 import blobcorrector self.spatial = blobcorrector.correctorclass( self.graindata.param['spatial']) # 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_present, detz_present], 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_present, detz_present) = 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']) y = int(round(dety_present)) z = int(round(detz_present)) try: frame[y + frame_add, z + frame_add] = frame[ y + frame_add, z + frame_add] + fraction * intensity * filter_tth_eta[ t, e] except: # FIXME print("Unhandled exception in make_image.py") pass else: # Generate spikes, 2x2 pixels for y in yrange: for z in zrange: if y > 0 and y < framedimy and z > 0 and z < framedimz and abs( dety + frame_add - y) < 1 and abs( detz + frame_add - z) < 1: # frame[y-1,z] = frame[y-1,z] + fraction*intensity*(1-abs(dety+frame_add-y))*(1-abs(detz+frame_add-z)) y = int(round(y)) z = int(round(z)) frame[y, z] = frame[ y, z] + fraction * intensity * ( 1 - abs(dety + frame_add - y)) * ( 1 - abs(detz + frame_add - z)) # 2D Gaussian on detector if peakshape[0] == 1: frame = ndimage.gaussian_filter(frame, peakshape[1] * 0.5) # add background if self.graindata.param['bg'] > 0: frame = frame + self.graindata.param['bg'] * n.ones( (framedimy, framedimz)) # add noise if self.graindata.param['noise'] != 0: frame = n.random.poisson(frame) # apply psf if self.graindata.param['psf'] != 0: frame = ndimage.gaussian_filter( frame, self.graindata.param['psf'] * 0.5) # resize, convert to integers and flip to same orientation as experimental frames frame = frame[frame_add:framedimy - frame_add, frame_add:framedimz - frame_add] # limit values above 16 bit to be 16bit frame = n.clip(frame, 0, 2**16 - 1) # convert to integers frame = n.uint16(frame) #flip detector orientation according to input: o11, o12, o21, o22 frame = detector.trans_orientation(frame, self.graindata.param['o11'], self.graindata.param['o12'], self.graindata.param['o21'], self.graindata.param['o22'], 'inverse') # Output frames if '.edf' in self.graindata.param['output']: self.write_edf(i, frame) if '.edf.gz' in self.graindata.param['output']: self.write_edf(i, frame, usegzip=True) if '.tif' in self.graindata.param['output']: self.write_tif(i, frame) if '.tif16bit' in self.graindata.param['output']: self.write_tif16bit(i, frame) print('\rDone frame %i took %8f s' % (i + 1, time.clock() - t1), end=' ') sys.stdout.flush()
def test3(self): # o11, o12, o21, o22 = -1, 0, 0, -1 detyz = n.array([841.38745747, 62.2754412563]) xy = detector.xy_to_detyz(detyz, -1, 0, 0, -1, 1024, 1024) detyz2 = detector.detyz_to_xy(xy, -1, 0, 0, -1, 1024, 1024) self.assertEqual(detyz.all(), detyz2.all())
def test2(self): # o11, o12, o21, o22 = 1, 0, 0, 1 detyz = [10, 20] (x, y) = detector.xy_to_detyz(detyz, 1, 0, 0, 1, 1024, 1024) self.assertEqual(detyz, [y, x])
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 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')
def get_measured_data(grain, flt, number_y_scans, ymin, ystep, param): ''' np array size (no_dtys,no_refl,3) The data is sorted in falling priority: 1. sorted by dty low to high 2. sorted by h low to high 3. sorted by k low to high 4. sorted by l low to high ''' o11 = param['o11'] o12 = param['o12'] o21 = param['o21'] o22 = param['o22'] dety_size = param['dety_size'] detz_size = param['detz_size'] n = len(flt.sc[grain.mask]) sc = flt.sc[grain.mask] fc = flt.fc[grain.mask] omega = flt.omega[grain.mask] dty = flt.dty[grain.mask] h = flt.h[grain.mask] k = flt.k[grain.mask] l = flt.l[grain.mask] all_measured_data = [] for i in range(n): (dety, detz) = detector.xy_to_detyz([sc[i], fc[i]], o11, o12, o21, o22, dety_size, detz_size) all_measured_data.append( [dety, detz, omega[i], dty[i], h[i], k[i], l[i]]) all_measured_data.sort(key=lambda x: x[3]) data_by_dty = [] k = len(all_measured_data) print("before binning in dty", k) for i in range(number_y_scans): data_by_dty.append([]) print("number_y_scans", number_y_scans) # currdata=[] # currdata.append(all_measured_data[0]) # dty_curr = all_measured_data[0][3] # for i in range(1,len(all_measured_data)): # if dty_curr!=all_measured_data[i][3]: # currdata_sorted = sorted(currdata, key=lambda x: (x[4], x[5], x[6])) # iy = np.round( (dty_curr - ymin) / ystep ).astype(int) # data_by_dty[iy] = np.asarray(currdata_sorted) # currdata = [] # dty_curr = all_measured_data[i][3] # currdata.append(all_measured_data[i]) p = 0 for peak in all_measured_data: iy = np.round((peak[3] - ymin) / ystep).astype(int) # print(peak[3],"=>",iy) data_by_dty[iy].append(peak) p += 1 print("appended", p) for i, dty in enumerate(data_by_dty): data_by_dty[i] = sorted(dty, key=lambda x: (x[4], x[5], x[6])) k = 0 for dty in data_by_dty: k += len(dty) print("after sorting and binning in dty", k) #raise return data_by_dty