Пример #1
0
 def test_find_omega_general_nowedge(self):
     # generate random gvector
     hkl = n.array([
         round(n.random.rand() * 10 - 5),
         round(n.random.rand() * 10 - 5),
         round(n.random.rand() * 10 - 5)
     ])
     ucell = n.array([
         3.5 + n.random.rand(), 3.5 + n.random.rand(),
         3.5 + n.random.rand(), 89.5 + n.random.rand(),
         89.5 + n.random.rand(), 89.5 + n.random.rand()
     ])
     B = tools.form_b_mat(ucell)
     U = tools.euler_to_u(n.random.rand() * 2. * n.pi,
                          n.random.rand() * 2. * n.pi,
                          n.random.rand() * n.pi)
     wavelength = 0.95 + n.random.rand() * 0.1
     gvec = n.dot(U, n.dot(B, hkl))
     tth = tools.tth(ucell, hkl, wavelength)
     # calculate corresponding eta and Omega using tools.find_omega_general
     (omega1,
      eta1) = tools.find_omega_general(gvec * wavelength / (4. * n.pi), tth,
                                       0, 0)
     Om1 = []
     for i in range(len(omega1)):
         Om1.append(tools.form_omega_mat_general(omega1[i], 0, 0))
     # calculate corresponding eta and Omega using tools.find_omega_wedge
     omega2 = tools.find_omega(gvec, tth)
     Om2 = []
     for i in range(len(omega2)):
         Om2.append(tools.form_omega_mat(omega2[i]))
     #assert
     for i in range(len(omega1)):
         #            print Om1[i]
         #            print Om2[i]
         diff = n.abs(Om1[i] - Om2[i]).sum()
         self.assertAlmostEqual(diff, 0, 9)
Пример #2
0
    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]
Пример #3
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])
Пример #4
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')