예제 #1
0
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
예제 #2
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()
예제 #3
0
    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()
예제 #4
0
 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())
예제 #5
0
 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])
예제 #6
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]
예제 #7
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')
예제 #8
0
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