예제 #1
0
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()
예제 #2
0
파일: ASR.py 프로젝트: jonwright/S3DXRD
    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
예제 #3
0
 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)
예제 #4
0
 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)
예제 #5
0
 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)
예제 #6
0
    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()
예제 #7
0
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()
예제 #8
0
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])
예제 #9
0
파일: file_io.py 프로젝트: jonwright/S3DXRD
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)
예제 #10
0
파일: file_io.py 프로젝트: jonwright/S3DXRD
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)
예제 #11
0
    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')