Ejemplo n.º 1
0
def quatOfExpMap(expMap):
    """
    """
    angles = columnNorm(expMap)
    axes   = unitVector(expMap)

    quats = quatOfAngleAxis(angles, axes)
    return quats
Ejemplo n.º 2
0
def rotMatOfExpMap_orig(expMap):
    """Original rotMatOfExpMap, used for comparison to optimized version
    """
    if isinstance(expMap, ndarray):
        if expMap.ndim != 2:
            if expMap.ndim == 1 and len(expMap) == 3:
                numObjs = 1
                expMap = expMap.reshape(3, 1)
            else:
                raise RuntimeError, "input is the wrong dimensionality"
        elif expMap.shape[0] != 3:
            raise RuntimeError(
                "input is the wrong shape along the 0-axis.  Yours is %d when is should be 3" % (expMap.shape[0])
            )
        else:
            numObjs = expMap.shape[1]
    elif isinstance(expMap, list) or isinstance(expMap, tuple):
        if len(expMap) != 3:
            raise RuntimeError, "for list/tuple input only one exponential map vector is allowed"
        else:
            if not isscalar(expMap[0]) or not isscalar(expMap[1]) or not isscalar(expMap[2]):
                raise RuntimeError, "for list/tuple input only one exponential map vector is allowed"
            else:
                numObjs = 1
                expMap = asarray(expMap).reshape(3, 1)

    phi = columnNorm(expMap)  # angles of rotation from exponential maps
    W = skewMatrixOfVector(expMap)  # skew matrices of exponential maps

    # Find tiny angles to avoid divide-by-zero and apply limits in expressions
    zeroIndex = phi < tinyRotAng
    phi[zeroIndex] = 1

    # first term
    C1 = sin(phi) / phi
    C1[zeroIndex] = 1

    # second term
    C2 = (1 - cos(phi)) / phi ** 2
    C2[zeroIndex] = 1

    if numObjs == 1:
        rmat = I3 + C1 * W + C2 * dot(W, W)
    else:
        rmat = zeros((numObjs, 3, 3))
        for i in range(numObjs):
            rmat[i, :, :] = I3 + C1[i] * W[i, :, :] + C2[i] * dot(W[i, :, :], W[i, :, :])

    return rmat
Ejemplo n.º 3
0
def rotMatOfExpMap_opt(expMap):
    """Optimized version of rotMatOfExpMap
    """
    if expMap.ndim == 1:
        expMap = expMap.reshape(3, 1)
    phi = atleast_1d(columnNorm(expMap)) # angles of rotation from exponential maps
    W   = skewMatrixOfVector(expMap)     # skew matrices of exponential maps

    # Find tiny angles to avoid divide-by-zero and apply limits in expressions
    zeroIndex = phi < tinyRotAng
    phi[zeroIndex] = 1


    # first term
    C1 = sin(phi) / phi
    C1[zeroIndex] = 1  # is this right?  might be OK since C1 multiplies W

    # second term
    C2 = (1 - cos(phi)) / phi**2
    C2[zeroIndex] = 0.5 # won't matter because W^2 is small

    numObjs = expMap.shape[1]
    if numObjs == 1: # case of single point
        W = numpy.reshape(W, [1, 3, 3])
        pass

    C1 = numpy.tile(numpy.reshape(C1, [numObjs, 1]), [1, 9]).reshape([numObjs,3,3])
    C2 = numpy.tile(numpy.reshape(C2, [numObjs, 1]), [1, 9]).reshape([numObjs,3,3])

    W2 = numpy.zeros([numObjs, 3, 3])

    for i in range(3):
        for j in range(3):
            W2[:, i, j] = numpy.sum(W[:, i, :]*W[:, :, j], 1)
            pass
        pass

    rmat = C1*W + C2 * W2
    rmat[:, 0, 0] += 1.
    rmat[:, 1, 1] += 1.
    rmat[:, 2, 2] += 1.

    return rmat.squeeze()
Ejemplo n.º 4
0
def assemble_grain_data(grain_data_list,pos_offset=None,rotation_offset=None):
    num_grain_files=len(grain_data_list)    
    
    num_grains_list=[None]*num_grain_files
    
    for i in np.arange(num_grain_files):
        num_grains_list[i]=grain_data_list[i].shape[0]
        
    num_grains=np.sum(num_grains_list)  
    
    grain_data=np.zeros([num_grains,grain_data_list[0].shape[1]])    
    
    for i in np.arange(num_grain_files):
        
        tmp=copy.copy(grain_data_list[i])
        
        if pos_offset is not None:
            pos_tile=np.tile(pos_offset[:,i],[num_grains_list[i],1])
            tmp[:,6:9]=tmp[:,6:9]+pos_tile
        #Needs Testing    
        if rotation_offset is not None:  
            rot_tile=np.tile(np.atleast_2d(rotation_offset[:,i]).T,[1,num_grains_list[i]])
            quat_tile=rot.quatOfExpMap(rot_tile)
            grain_quats=rot.quatOfExpMap(tmp[:,3:6].T)
            new_quats=rot.quatProduct(grain_quats,quat_tile)
            
            sinang = mutil.columnNorm(new_quats[1:,:])
            ang=2.*np.arcsin(sinang)
            axis   = mutil.unitVector(new_quats[1:,:])
            tmp[:,3:6]=np.tile(np.atleast_2d(ang).T,[1,3])*axis.T

            
        grain_data[int(np.sum(num_grains_list[:i])):int(np.sum(num_grains_list[:(i+1)])),:]=tmp
        

    old_grain_numbers=copy.copy(grain_data[:,0])
    grain_data[:,0]=np.arange(num_grains)    
    return grain_data,old_grain_numbers
Ejemplo n.º 5
0
def discreteFiber(c, s, B=I3, ndiv=120, invert=False, csym=None, ssym=None):
    """
    """
    import symmetry as S

    ztol = 1.e-8

    # arg handling for c
    if hasattr(c, '__len__'):
        if hasattr(c, 'shape'):
            assert c.shape[0] == 3, \
                   'scattering vector must be 3-d; yours is %d-d' \
                   % (c.shape[0])
            if len(c.shape) == 1:
                c = c.reshape(3, 1)
            elif len(c.shape) > 2:
                raise RuntimeError, \
                      'incorrect arg shape; must be 1-d or 2-d, yours is %d-d' \
                      % (len(c.shape))
        else:
            # convert list input to array and transpose
            if len(c) == 3 and isscalar(c[0]):
                c = asarray(c).reshape(3, 1)
            else:
                c = asarray(c).T
    else:
        raise RuntimeError, 'input must be array-like'

    # arg handling for s
    if hasattr(s, '__len__'):
        if hasattr(s, 'shape'):
            assert s.shape[0] == 3, \
                   'scattering vector must be 3-d; yours is %d-d' \
                   % (s.shape[0])
            if len(s.shape) == 1:
                s = s.reshape(3, 1)
            elif len(s.shape) > 2:
                raise RuntimeError, \
                      'incorrect arg shape; must be 1-d or 2-d, yours is %d-d' \
                      % (len(s.shape))
        else:
            # convert list input to array and transpose
            if len(s) == 3 and isscalar(s[0]):
                s = asarray(s).reshape(3, 1)
            else:
                s = asarray(s).T
    else:
        raise RuntimeError, 'input must be array-like'

    nptc = c.shape[1]
    npts = s.shape[1]

    c = unitVector(dot(B, c))        # turn c hkls into unit vector in crys frame
    s = unitVector(s)                # convert s to unit vector in samp frame

    retval = []
    for i_c in range(nptc):
        dupl_c = tile(c[:, i_c], (npts, 1)).T

        ax   = s + dupl_c
        anrm = columnNorm(ax).squeeze() # should be 1-d

        okay = anrm > ztol
        nokay = okay.sum()
        if nokay == npts:
            ax = ax / tile(anrm, (3, 1))
        else:
            nspace = nullSpace(c[:, i_c].reshape(3, 1))
            hperp = nspace[:, 0].reshape(3, 1)
            if nokay == 0:
                ax = tile(hperp, (1, npts))
            else:
                ax[:,     okay] = ax[:, okay] / tile(anrm[okay], (3, 1))
                ax[:, not okay] = tile(hperp, (1, npts - nokay))

        q0 = vstack( [ zeros(npts), ax ] )

        # find rotations
        # note: the following line fixes bug with use of arange with float increments
        phi = arange(0, ndiv) * (2*pi/float(ndiv))
        qh  = quatOfAngleAxis(phi, tile(c[:, i_c], (ndiv, 1)).T)

        # the fibers, arraged as (npts, 4, ndiv)
        qfib = dot( quatProductMatrix(qh, mult='right'), q0 ).transpose(2, 1, 0)
        if csym is not None:
            retval.append(S.toFundamentalRegion(qfib.squeeze(),
                                                crysSym=csym,
                                                sampSym=ssym))
        else:
            retval.append(fixQuat(qfib).squeeze())
    return retval
Ejemplo n.º 6
0
    def simulateLauePattern(self, planeData, minEnergy=5, maxEnergy=25, rMat_s=np.eye(3), rMat=None, vInv=None, doGnomonic=False):
        
        multipleEnergyRanges = False
        if hasattr(maxEnergy, '__len__'):
            assert len(maxEnergy) == len(minEnergy), 'energy cutoff ranges must have the same length'
            multipleEnergyRanges = True; lmin = []; lmax = []
            for i in range(len(maxEnergy)):
                lmin.append(processWavelength(maxEnergy[i]))
                lmax.append(processWavelength(minEnergy[i]))                
        else:
            lmin = processWavelength(maxEnergy)
            lmax = processWavelength(minEnergy)
        
        gvec_c = planeData.getPlaneNormals()
        hkls   = planeData.getSymHKLs() 
        dsp    = planeData.getPlaneSpacings()
        
        if rMat is None:
            rMat = [np.eye(3),]
        if vInv is None:
            vInv = [vInv_ref,]
        
        # rMult     = planeData.getMultiplicity()
        # nHKLs_tot = rMult.sum()
        # rMask     = np.ones(nHKLs_tot, dtype=bool)
        
        retval = []
        for iG in range(len(rMat)):
            tmp = {'detXY':[], 'gnoXY':[], 'angles':[], 'dspacing':[], 'hkl':[], 'energy':[]}
            for iHKL in range(planeData.nHKLs):                
                # stretch them: V^(-1) * R * Gc
                gvec_s_str = mutil.unitVector(
                    np.dot( vInv[iG], np.dot( rMat[iG], gvec_c[iHKL] ) ) )
                gvec_c_str = np.dot(rMat[iG].T, gvec_s_str)
                gvec_l_str = np.dot(rMat_s, gvec_s_str)
                #
                # dpts  = self.gVecToDet(gvec_c_str, rMat=rMat[iG], rMat_s=rMat_s)
                # gpts  = self.gVecToDet(gvec_c_str, rMat=rMat[iG], rMat_s=rMat_s, doGnomonic=True)
                dpts  = self.gVecToDet(gvec_c_str, rMat=rMat[iG], rMat_s=rMat_s)
                gpts  = self.gVecToDet(gvec_c_str, rMat=rMat[iG], rMat_s=rMat_s, doGnomonic=True)
                canIntersect = -np.isnan(dpts[0, :])
                npts_in = sum(canIntersect)
                if np.any(canIntersect):
                    dpts = dpts[:, canIntersect].reshape(3, npts_in)
                    dhkl = hkls[iHKL][:, canIntersect].reshape(3, npts_in)

                    gvl_hat = gvec_l_str[:, canIntersect].reshape(3, npts_in)
                    gvl_xy  = gvec_l_str[:2, canIntersect].reshape(2, npts_in)
                    
                    # dot with the beam
                    dotWbeam = np.dot(Z_ref.T, gvl_hat).flatten()

                    # angles
                    theta = piby2 - rot.arccosSafe( dotWbeam )
                    wlen  = 2*dsp[iHKL]*np.sin(theta)
                    eta   = np.arccos(gvl_xy[0, :])
                    
                    # find on spatial extent of detector
                    # for corner # xTest = np.logical_and(dpts[0, :] > 0, dpts[0, :] < self.cdim)
                    # for corner # yTest = np.logical_and(dpts[1, :] > 0, dpts[1, :] < self.rdim)
                    xTest = np.logical_and(dpts[0, :] > -0.5 * self.cdim, dpts[0, :] < 0.5 * self.cdim)
                    yTest = np.logical_and(dpts[1, :] > -0.5 * self.rdim, dpts[1, :] < 0.5 * self.rdim)
                    
                    onDetector  = np.logical_and(xTest, yTest)
                    if multipleEnergyRanges:
                        validEnergy = np.zeros(len(wlen), dtype=bool)
                        for i in range(len(lmin)):
                            validEnergy = validEnergy | np.logical_and(wlen >= lmin[i], wlen <= lmax[i])
                            pass
                    else:
                        validEnergy = np.logical_and(wlen >= lmin, wlen <= lmax)
                        pass
                    
                    keepers = np.logical_and(onDetector, validEnergy)

                    dsp_this = 1. / mutil.columnNorm(np.dot(planeData.latVecOps['B'], dhkl[:, keepers]))
                    
                    tmp['detXY'].append(dpts[:2, keepers])
                    tmp['gnoXY'].append(gpts[:2, keepers])
                    tmp['angles'].append(np.vstack([2*theta[keepers]*r2d, eta[keepers]*r2d]))
                    tmp['hkl'].append(dhkl[:, keepers])
                    tmp['dspacing'].append(dsp_this)
                    tmp['energy'].append(processWavelength(wlen[keepers]))
                else:
                    tmp['detXY'].append(np.empty((2, 0)))
                    tmp['gnoXY'].append(np.empty((2, 0)))
                    tmp['angles'].append(np.empty((2, 0)))
                    tmp['hkl'].append(np.empty((3, 0)))
                    tmp['dspacing'].append(np.empty(0))
                    tmp['energy'].append(np.empty(0))
                    pass
                pass
            retval.append(tmp)
        return retval
Ejemplo n.º 7
0
    def oe_pfig(self):
        """Make an omega-eta polefigure"""
        # some constants

        deg2rad = numpy.pi /180.0
        radius = numpy.sqrt(2)
        offset = 2.5*radius
        nocolor = 'none'
        pdir_cho = 'X'  # to come from choice interactor

        # parent window and data

        exp = wx.GetApp().ws
        p = self.GetParent()
        ome_eta = p.data
        hkldata = ome_eta.getData(self.idata)

        # axes/figure

        p.figure.delaxes(p.axes)
        p.axes = p.figure.gca()
        p.axes.set_autoscale_on(True)
        p.axes.set_aspect('equal')
        p.axes.axis([-2.0, offset+2.0, -1.5, 1.5])

        # outlines for pole figure

        C1 = Circle((0,0), radius)
        C2 = Circle((offset,0), radius)
        outline_circles = [C1, C2]
        pc_outl = PatchCollection(outline_circles, facecolors=nocolor)
        p.axes.add_collection(pc_outl)

        # build the rectangles

        pf_rects = []

        tTh = exp.activeMaterial.planeData.getTTh()[self.idata]

        etas  = ome_eta.etaEdges
        netas = len(etas) - 1
        deta = abs(etas[1] - etas[0])

        omes  = ome_eta.omeEdges
        nomes = len(omes) - 1
        dome = abs(omes[1] - omes[0])

        if pdir_cho == 'X':
            pdir = numpy.c_[1, 0, 0].T  # X
        elif pdir_cho == 'Y':
            pdir = numpy.c_[0, 1, 0].T  # X
        elif pdir_cho == 'Z':
            pdir = numpy.c_[0, 0, 1].T  # X
            pass

        ii = 0
        for i in range(nomes):
            for j in range(netas):
                qc = makeMSV(tTh, etas[j] + 0.5*deta, omes[i] + 0.5*dome)

                qll = makeMSV(tTh,        etas[j],        omes[i])
                qlr = makeMSV(tTh, etas[j] + deta,        omes[i])
                qur = makeMSV(tTh, etas[j] + deta, omes[i] + dome)
                qul = makeMSV(tTh,        etas[j], omes[i] + dome)

                pdot_p = numpy.dot(qll.T, pdir) >= 0 \
                    and numpy.dot(qlr.T, pdir) >= 0 \
                    and numpy.dot(qur.T, pdir) >= 0 \
                    and numpy.dot(qul.T, pdir) >= 0

                pdot_m = numpy.dot(qll.T, pdir) < 0 \
                    and numpy.dot(qlr.T, pdir) < 0 \
                    and numpy.dot(qur.T, pdir) < 0 \
                    and numpy.dot(qul.T, pdir) < 0

                if pdot_p:
                    sgn = 1.0
                    ii += 1
                elif pdot_m:
                    sgn = -1.0
                    ii += 1
                elif not pdot_p and not pdot_m:
                    continue

                # the vertex chords
                qll = makeMSV(tTh,        etas[j],        omes[i]) - sgn * pdir
                qlr = makeMSV(tTh, etas[j] + deta,        omes[i]) - sgn * pdir
                qur = makeMSV(tTh, etas[j] + deta, omes[i] + dome) - sgn * pdir
                qul = makeMSV(tTh,        etas[j], omes[i] + dome) - sgn * pdir

                nll = columnNorm(qll)
                nlr = columnNorm(qlr)
                nur = columnNorm(qur)
                nul = columnNorm(qul)

                if pdir_cho == 'X':
                    pqll = nll*unitVector(qll[[1, 2]].reshape(2, 1))
                    pqlr = nlr*unitVector(qlr[[1, 2]].reshape(2, 1))
                    pqur = nur*unitVector(qur[[1, 2]].reshape(2, 1))
                    pqul = nul*unitVector(qul[[1, 2]].reshape(2, 1))
                elif pdir_cho == 'Y':
                    pqll = nll*unitVector(qll[[0, 2]].reshape(2, 1))
                    pqlr = nlr*unitVector(qlr[[0, 2]].reshape(2, 1))
                    pqur = nur*unitVector(qur[[0, 2]].reshape(2, 1))
                    pqul = nul*unitVector(qul[[0, 2]].reshape(2, 1))
                elif pdir_cho == 'Z':
                    pqll = nll*unitVector(qll[[0, 1]].reshape(2, 1))
                    pqlr = nlr*unitVector(qlr[[0, 1]].reshape(2, 1))
                    pqur = nur*unitVector(qur[[0, 1]].reshape(2, 1))
                    pqul = nul*unitVector(qul[[0, 1]].reshape(2, 1))

                xy = numpy.hstack([pqll, pqlr, pqur, pqul]).T
                if sgn == -1:
                    xy[:, 0] = xy[:, 0] + offset
                pf_rects.append(Polygon(xy, aa=False))
                pass
            pass

        cmap=matplotlib.cm.jet
        pf_coll = PatchCollection(pf_rects, cmap=cmap, edgecolors='None')
        pf_coll.set_array(numpy.array(hkldata.T.flatten()))
        p.axes.add_collection(pf_coll)

        p.canvas.draw()
        p.axes.axis('off')
        return
Ejemplo n.º 8
0
    def makeScatteringVectors(hkls, rMat_c, bMat, wavelength, chiTilt=None):
        """
        modeled after QFromU.m
        """

        # basis vectors
        bHat_l = num.c_[ 0.,  0., -1.].T
        eHat_l = num.c_[ 1.,  0.,  0.].T

        zTol = 1.0e-7                       # zero tolerance for checking vectors

        gVec_s = []
        oangs0 = []
        oangs1 = []

        # these are the reciprocal lattice vectors in the CRYSTAL FRAME
        # ** NOTE **
        #   if strained, assumes that you handed it a bMat calculated from
        #   strained [a, b, c]
        gVec_c = num.dot( bMat, hkls )
        gHat_c = unitVector(gVec_c)

        dim0, nRefl = gVec_c.shape
        assert dim0 == 3, "Looks like something is wrong with your lattice plane normals son!"

        # extract 1/dspacing and sin of bragg angle
        dSpacingi = columnNorm(gVec_c).flatten()
        sintht    = 0.5 * wavelength * dSpacingi

        # move reciprocal lattice vectors to sample frame
        gHat_s = num.dot(rMat_c.squeeze(), gHat_c)

        if chiTilt is None:
            cchi = 1.
            schi = 0.
            rchi = num.eye(3)
        else:
            cchi = num.cos(chiTilt)
            schi = num.sin(chiTilt)
            rchi = num.array([[   1.,    0.,    0.],
                              [   0.,  cchi, -schi],
                              [   0.,  schi,  cchi]])
            pass

        a =  cchi * gHat_s[0, :]
        b = -cchi * gHat_s[2, :]
        c =  schi * gHat_s[1, :] - sintht

        # form solution
        abMag    = num.sqrt(a*a + b*b); assert num.all(abMag > 0), "Beam vector specification is infealible!"
        phaseAng = num.arctan2(b, a)
        rhs      = c / abMag; rhs[abs(rhs) > 1.] = num.nan
        rhsAng   = num.arcsin(rhs)

        # write ome angle output arrays (NaNs persist here)
        ome0 =          rhsAng - phaseAng
        ome1 = num.pi - rhsAng - phaseAng

        goodOnes_s = -num.isnan(ome0)

        eta0 = num.nan * num.ones_like(ome0)
        eta1 = num.nan * num.ones_like(ome1)

        # mark feasible reflections
        goodOnes   = num.tile(goodOnes_s, (1, 2)).flatten()

        numGood_s  = sum(goodOnes_s)
        numGood    = 2 * numGood_s
        tmp_eta    = num.empty(numGood)
        tmp_gvec   = num.tile(gHat_c, (1, 2))[:, goodOnes]
        allome     = num.hstack([ome0, ome1])

        for i in range(numGood):
            come = num.cos(allome[goodOnes][i])
            some = num.sin(allome[goodOnes][i])
            rome = num.array([[ come,    0.,  some],
                              [   0.,    1.,    0.],
                              [-some,    0.,  come]])
            rMat_s = num.dot(rchi, rome)
    	    gVec_l = num.dot(rMat_s,
                       num.dot(rMat_c, tmp_gvec[:, i].reshape(3, 1)
                       ) )
            tmp_eta[i] = num.arctan2(gVec_l[1], gVec_l[0])
            pass
        eta0[goodOnes_s] = tmp_eta[:numGood_s]
        eta1[goodOnes_s] = tmp_eta[numGood_s:]

        # make assoc tTh array
        tTh  = 2.*num.arcsin(sintht).flatten()
        tTh0 = tTh; tTh0[-goodOnes_s] = num.nan

        gVec_s = num.tile(dSpacingi, (3, 1)) * gHat_s
        oangs0 = num.vstack([tTh0.flatten(), eta0.flatten(), ome0.flatten()])
        oangs1 = num.vstack([tTh0.flatten(), eta1.flatten(), ome1.flatten()])

        return gVec_s, oangs0, oangs1