예제 #1
0
def quatAverageCluster(q_in, qsym):
    """
    """
    from symmetry import toFundamentalRegion

    assert q_in.ndim == 2, "input must be 2-s hstacked quats"

    # renormalize
    q_in = unitVector(q_in)

    # check to see num of quats is > 1
    if q_in.shape[1] < 3:
        if q_in.shape[1] == 1:
            q_bar = q_in
        else:
            ma, mq = misorientation(q_in[:, 0].reshape(4, 1), q_in[:, 1].reshape(4, 1), (qsym,))
            q_bar = quatProduct(q_in[:, 0].reshape(4, 1), quatOfExpMap(0.5 * ma * unitVector(mq[1:].reshape(3, 1))))
    else:
        # use first quat as initial guess
        phi = 2.0 * arccos(q_in[0, 0])
        if phi <= finfo(float).eps:
            x0 = zeros(3)
        else:
            n = unitVector(q_in[1:, 0].reshape(3, 1))
            x0 = phi * n.flatten()

        # first drag to origin using first quat (arb!)
        q0 = q_in[:, 0].reshape(4, 1)
        qrot = dot(quatProductMatrix(invertQuat(q0), mult="right"), q_in)

        # second, re-cast to FR
        qrot = toFundamentalRegion(qrot.squeeze(), crysSym=qsym)

        # compute arithmetic average
        q_bar = unitVector(average(qrot, axis=1).reshape(4, 1))

        # unrotate!
        q_bar = dot(quatProductMatrix(q0, mult="right"), q_bar)

        # re-map
        q_bar = toFundamentalRegion(q_bar, crysSym=qsym)
    return q_bar
예제 #2
0
def quatAverageCluster(q_in, qsym):
    """
    """
    from symmetry import toFundamentalRegion

    assert q_in.ndim == 2, 'input must be 2-s hstacked quats'

    # renormalize
    q_in = unitVector(q_in)

    # check to see num of quats is > 1
    if q_in.shape[1] < 3:
        if q_in.shape[1] == 1:
            q_bar = q_in
        else:
            ma, mq = misorientation(q_in[:, 0].reshape(4, 1),
                                    q_in[:, 1].reshape(4, 1), (qsym,))
            q_bar = quatProduct(
                q_in[:, 0].reshape(4, 1),
                quatOfExpMap(0.5*ma*unitVector(mq[1:].reshape(3, 1)))
            )
    else:
        # first drag to origin using first quat (arb!)
        q0 = q_in[:, 0].reshape(4, 1)
        qrot = dot(
            quatProductMatrix(invertQuat(q0), mult='left'),
            q_in)

        # second, re-cast to FR
        qrot = toFundamentalRegion(qrot.squeeze(), crysSym=qsym)

        # compute arithmetic average
        q_bar = unitVector(average(qrot, axis=1).reshape(4, 1))

        # unrotate!
        q_bar = dot(
            quatProductMatrix(q0, mult='left'),
            q_bar)

        # re-map
        q_bar = toFundamentalRegion(q_bar, crysSym=qsym)
    return q_bar
예제 #3
0
def quatAverageCluster(q_in, qsym):
    """
    """
    from symmetry import toFundamentalRegion

    assert q_in.ndim == 2, 'input must be 2-s hstacked quats'

    # renormalize
    q_in = unitVector(q_in)

    # check to see num of quats is > 1
    if q_in.shape[1] < 3:
        if q_in.shape[1] == 1:
            q_bar = q_in
        else:
            ma, mq = misorientation(q_in[:, 0].reshape(4, 1),
                                    q_in[:, 1].reshape(4, 1), (qsym,))
            q_bar = quatProduct(q_in[:, 0].reshape(4, 1),
                                quatOfExpMap(0.5*ma*unitVector(mq[1:].reshape(3, 1))))
    else:
        # first drag to origin using first quat (arb!)
        q0 = q_in[:, 0].reshape(4, 1)
        qrot = dot(
            quatProductMatrix( invertQuat( q0 ), mult='left' ),
            q_in)

        # second, re-cast to FR
        qrot = toFundamentalRegion(qrot.squeeze(), crysSym=qsym)

        # compute arithmetic average
        q_bar = unitVector(average(qrot, axis=1).reshape(4, 1))

        # unrotate!
        q_bar = dot(
            quatProductMatrix( q0, mult='left' ),
            q_bar)

        # re-map
        q_bar = toFundamentalRegion(q_bar, crysSym=qsym)
    return q_bar
예제 #4
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
예제 #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