Exemple #1
0
def solve(desiredSetting, VL, orthogMatrices, U0, Goniometer,
                              PG_permutions=[[X,Y,Z]]):
    """ Solve for datum position
    Uses:
        VL              Laboratory vectors to match
        orthogMatrices  Dict containing {'rec':Bm1t, 'dir':B}
        desiredSetting  List of the two vectors defining the desired setting
        U0              Zero-angle setting matrix
        PG_permutions   Point group permutations

    Return:
        datumSolutions (list of datum solutions in degrees)

    Local variables
        U0m1    [U0]**-1
        C       base vectors in crystal frame
        Cm1     [C]**-1
        L       base vectors in laboratory frame
        SL      L matrix with permuted signs
        CU      [C]**-1 [U0]**-1
    """

    # Orthogonalize crystal vectors h -> yv
    # YV crystal frame vectors defining desired setting (orthogonalized)

    YV = []
    for vi in 0, 1:
        # if reciproc: B*vi.vector elif direct: B1mt*vi.vector
        B = orthogMatrices[desiredSetting[vi].space]
        YV.append(B*desiredSetting[vi])

    #  referential_permutations sign permutations for four permutations of
    #        parallel/antiparallel (rotation axis & beam)
    #    y1 // e1, y2 // beamVector;  y1 anti// e1, y2 // beamVector
    #    y1 // e1, y2 anti// beamVector;  y1 anti// e1, y2 anti// beamVector

    referential_permutations = [ ex,  ey,  ez], \
                               [-ex, -ey,  ez], \
                               [ ex, -ey, -ez], \
                               [-ex,  ey, -ez]

    # Construct orthogonal frame in crystal space defined by vectors
    # y1 = yv(,1) and y2 = yv(,2). The base vectors form the COLUMNS
    # of matrix C
    #  - 1st vector along YV1
    #  - 3rd vector perpendicular to YV1 & YV2
    #  - 2nd vector completes the RH set

    C1 = YV[0].normalize()
    C3 = YV[0].cross(YV[1]).normalize()
    C2 = C3.cross(C1).normalize()
    C = mat3(C1, C2, C3)

    # Similarly, construct laboratory frame matrix defined by VL1, VL2
    #  1st vector along VL1
    #  3rd vector perpendicular to VL1 & VL2
    #  2nd vector completes the RH set

    L1 = VL[0].normalize()
    L3 = VL[0].cross(VL[1]).normalize()
    L2 = L3.cross(L1).normalize()
    L = mat3(L1, L2, L3)

    # The matrix which superimposes the two frames is L C**-1. This
    # is then the orientation matrix DU, including the required datum
    # position D.  The datum matrix is then  D = L C**-1 U**-1
    # We need to consider four possible alignments & values of D,
    # corresponding to y1 parallel & antiparallel to vl1, and y2
    # parallel & antiparallel to vl2. To get these, we change
    # the signs of l1 & l2, or l2 & l3, or both, as set out in array LS.

    datumSolutions = []
    independentSolution = []

    # Loop four solutions for D, each with possibly two sets of goniostat
    # angles

    Cm1 = C.inverse()
    B = orthogMatrices['rec']
    UB0 = U0 * B

    # Loop for introducing Point Group permutations:
    for PG_operator in PG_permutions:
        # We use the operator in reciprocal space so it need a transposition.
        PG_operator = mat3T(PG_operator)
        # printmat(B.dot(PG_operator),'B.dot(PG_operator)')

        # The PG operator is applied on the UB0 matrix
        U0perm = UB0 * PG_operator * B.inverse()
        if _debug:
            print
            printmat(PG_operator, 'PG_operator', "%12.6f")
            printmat(U0, 'U0', "%12.6f")
            printmat(U0perm, 'U0perm', "%12.6f")

        if not is_orthogonal(U0perm):
            print "!!!!!!!!!!!!!!! ERROR: Improper U0perm matrice!!"

        #  CU = C**-1 . U**-1
        CU = Cm1 * U0perm.inverse()
        for referential_permut in referential_permutations:

            SL = L * mat3T(referential_permut)
            _DM = SL * CU

            # angles: there are zero or two possible sets of goniostat angles
            # which correspond to D, although one or both may be inaccessible

            try:
                _2s = ThreeAxisRotation2(_DM.mlist,
                                        Goniometer.rotationAxes,
                                        inversAxesOrder=0).getAngles()
                twoSolutions = (_2s[0][2],_2s[0][1],_2s[0][0]), \
                               (_2s[1][2],_2s[1][1],_2s[1][0])

                for oneSolution in twoSolutions:

                    solutionKey = "%6.2f%6.2f%6.2f" % tuple(oneSolution)
                    if solutionKey not in independentSolution:
                        independentSolution.append(solutionKey)
                        datumSolutions.append(map(radian2degree, oneSolution))
                        #print ">>>>>>>>>",solutionKey,"number ",
                        #print len(independentSolution)
                    else:
                        if _debug:
                            print ">>>>>>>>> Redundant solution"
            except ValueError:
                pass

    return datumSolutions
Exemple #2
0
def solve(desiredSetting,
          VL,
          orthogMatrices,
          U0,
          Goniometer,
          PG_permutions=[[X, Y, Z]]):
    """ Solve for datum position
    Uses:
        VL              Laboratory vectors to match
        orthogMatrices  Dict containing {'rec':Bm1t, 'dir':B}
        desiredSetting  List of the two vectors defining the desired setting
        U0              Zero-angle setting matrix
        PG_permutions   Point group permutations

    Return:
        datumSolutions (list of datum solutions in degrees)

    Local variables
        U0m1    [U0]**-1
        C       base vectors in crystal frame
        Cm1     [C]**-1
        L       base vectors in laboratory frame
        SL      L matrix with permuted signs
        CU      [C]**-1 [U0]**-1
    """

    # Orthogonalize crystal vectors h -> yv
    # YV crystal frame vectors defining desired setting (orthogonalized)

    YV = []
    for vi in 0, 1:
        # if reciproc: B*vi.vector elif direct: B1mt*vi.vector
        B = orthogMatrices[desiredSetting[vi].space]
        YV.append(B * desiredSetting[vi])

    #  referential_permutations sign permutations for four permutations of
    #        parallel/antiparallel (rotation axis & beam)
    #    y1 // e1, y2 // beamVector;  y1 anti// e1, y2 // beamVector
    #    y1 // e1, y2 anti// beamVector;  y1 anti// e1, y2 anti// beamVector

    referential_permutations = [ ex,  ey,  ez], \
                               [-ex, -ey,  ez], \
                               [ ex, -ey, -ez], \
                               [-ex,  ey, -ez]

    # Construct orthogonal frame in crystal space defined by vectors
    # y1 = yv(,1) and y2 = yv(,2). The base vectors form the COLUMNS
    # of matrix C
    #  - 1st vector along YV1
    #  - 3rd vector perpendicular to YV1 & YV2
    #  - 2nd vector completes the RH set

    C1 = YV[0].normalize()
    C3 = YV[0].cross(YV[1]).normalize()
    C2 = C3.cross(C1).normalize()
    C = mat3(C1, C2, C3)

    # Similarly, construct laboratory frame matrix defined by VL1, VL2
    #  1st vector along VL1
    #  3rd vector perpendicular to VL1 & VL2
    #  2nd vector completes the RH set

    L1 = VL[0].normalize()
    L3 = VL[0].cross(VL[1]).normalize()
    L2 = L3.cross(L1).normalize()
    L = mat3(L1, L2, L3)

    # The matrix which superimposes the two frames is L C**-1. This
    # is then the orientation matrix DU, including the required datum
    # position D.  The datum matrix is then  D = L C**-1 U**-1
    # We need to consider four possible alignments & values of D,
    # corresponding to y1 parallel & antiparallel to vl1, and y2
    # parallel & antiparallel to vl2. To get these, we change
    # the signs of l1 & l2, or l2 & l3, or both, as set out in array LS.

    datumSolutions = []
    independentSolution = []

    # Loop four solutions for D, each with possibly two sets of goniostat
    # angles

    Cm1 = C.inverse()
    B = orthogMatrices['rec']
    UB0 = U0 * B

    # Loop for introducing Point Group permutations:
    for PG_operator in PG_permutions:
        # We use the operator in reciprocal space so it need a transposition.
        PG_operator = mat3T(PG_operator)
        # printmat(B.dot(PG_operator),'B.dot(PG_operator)')

        # The PG operator is applied on the UB0 matrix
        U0perm = UB0 * PG_operator * B.inverse()
        if _debug:
            print
            printmat(PG_operator, 'PG_operator', "%12.6f")
            printmat(U0, 'U0', "%12.6f")
            printmat(U0perm, 'U0perm', "%12.6f")

        if not is_orthogonal(U0perm):
            print "!!!!!!!!!!!!!!! ERROR: Improper U0perm matrice!!"

        #  CU = C**-1 . U**-1
        CU = Cm1 * U0perm.inverse()
        for referential_permut in referential_permutations:

            SL = L * mat3T(referential_permut)
            _DM = SL * CU

            # angles: there are zero or two possible sets of goniostat angles
            # which correspond to D, although one or both may be inaccessible

            try:
                _2s = ThreeAxisRotation2(_DM.mlist,
                                         Goniometer.rotationAxes,
                                         inversAxesOrder=0).getAngles()
                twoSolutions = (_2s[0][2],_2s[0][1],_2s[0][0]), \
                               (_2s[1][2],_2s[1][1],_2s[1][0])

                for oneSolution in twoSolutions:

                    solutionKey = "%6.2f%6.2f%6.2f" % tuple(oneSolution)
                    if solutionKey not in independentSolution:
                        independentSolution.append(solutionKey)
                        datumSolutions.append(map(radian2degree, oneSolution))
                        #print ">>>>>>>>>",solutionKey,"number ",
                        #print len(independentSolution)
                    else:
                        if _debug:
                            print ">>>>>>>>> Redundant solution"
            except ValueError:
                pass

    return datumSolutions
Exemple #3
0
""" % _progname

from XOconv import mat3T, printmat, is_orthogonal, spg_num2symb, BusingLevy, \
                   SPGlib, map_r2d, PGequiv, openWriteClose, openReadClose,  \
                   rootSquareSum, random_3axes, kappaVector, SPGlib2
from XOconv import MosflmParser, DenzoParser, XDSParser

VERBOSE = True
r2d = 180/math.pi
radian2degree = lambda a: a*r2d
degree2radian = lambda a: a/r2d

ex, ey, ez = vec3(1,0,0), vec3(0,1,0), vec3(0,0,1)
X, Y, Z = ex, ey, ez
Qdnz2mos = mat3T(ez, ex, ey)

class CrystalVector(vec3):
    """ Define a crystal vector to represent reciprocal or direct space vectors

    NOTE that it can accept fractional coordinates like
         CrystalVector("(1.2 1.22 4.9)")

    NOTE that as it inherit from the Vector class, CrystalVectors support the
    usual arithmetic operations ('v1', 'v2': vectors, 's': scalar):

    -  'v1+v2'           (addition)
    -  'v1-v2'           (subtraction)
    -  'v1*v2'           (scalar product)
    -  's*v1', 'v1*s'    (multiplication with a scalar)
    -  'v1/s'            (division by a scalar)
Exemple #4
0
""" % _progname

from XOconv import mat3T, printmat, is_orthogonal, spg_num2symb, BusingLevy, \
                   SPGlib, map_r2d, PGequiv, openWriteClose, openReadClose,  \
                   rootSquareSum, random_3axes, kappaVector, SPGlib2
from XOconv import MosflmParser, DenzoParser, XDSParser

VERBOSE = True
r2d = 180 / math.pi
radian2degree = lambda a: a * r2d
degree2radian = lambda a: a / r2d

ex, ey, ez = vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1)
X, Y, Z = ex, ey, ez
Qdnz2mos = mat3T(ez, ex, ey)


class CrystalVector(vec3):
    """ Define a crystal vector to represent reciprocal or direct space vectors

    NOTE that it can accept fractional coordinates like
         CrystalVector("(1.2 1.22 4.9)")

    NOTE that as it inherit from the Vector class, CrystalVectors support the
    usual arithmetic operations ('v1', 'v2': vectors, 's': scalar):

    -  'v1+v2'           (addition)
    -  'v1-v2'           (subtraction)
    -  'v1*v2'           (scalar product)
    -  's*v1', 'v1*s'    (multiplication with a scalar)