def get_real_space_primitive_matrix(lattice, matrix, wd = None): '''Get the primitive real space vectors for the unit cell and lattice type. Note that the resulting matrix will need to be scaled by a factor equal to the wavelength in Angstroms.''' # parse the orientation matrix cell, a, u = parse_matrix(matrix) # generate other possibilities o = _Othercell() if wd: o.set_working_directory(wd) auto_logfiler(o) o.set_cell(cell) o.set_lattice(lattice) o.generate() # transform the possibly centred cell to the primitive setting new_cell = o.get_cell('aP') op = symop_to_mat(o.get_reindex_op('aP')) primitive_a = matmul(invert(op), a) # then convert to real space real_a = invert(primitive_a) return real_a[0:3], real_a[3:6], real_a[6:9]
def get_reciprocal_space_primitive_matrix(lattice, matrix, wd = None): '''Get the primitive reciprocal space vectors for this matrix.''' # parse the orientation matrix cell, a, u = parse_matrix(matrix) # generate other possibilities o = _Othercell() if wd: o.set_working_directory(wd) auto_logfiler(o) o.set_cell(cell) o.set_lattice(lattice) o.generate() # transform the possibly centred cell to the primitive setting new_cell = o.get_cell('aP') op = symop_to_mat(o.get_reindex_op('aP')) primitive_a = matmul(invert(op), a) return mat2vec(primitive_a)
def get_reciprocal_space_primitive_matrix(lattice, matrix, wd=None): """Get the primitive reciprocal space vectors for this matrix.""" # parse the orientation matrix cell, a, u = parse_matrix(matrix) # generate other possibilities o = _Othercell() if wd: o.set_working_directory(wd) auto_logfiler(o) o.set_cell(cell) o.set_lattice(lattice) o.generate() # transform the possibly centred cell to the primitive setting op = symop_to_mat(o.get_reindex_op("aP")) primitive_a = matmul(invert(op), a) return mat2vec(primitive_a)
def get_real_space_primitive_matrix(lattice, matrix, wd=None): """Get the primitive real space vectors for the unit cell and lattice type. Note that the resulting matrix will need to be scaled by a factor equal to the wavelength in Angstroms.""" # parse the orientation matrix cell, a, u = parse_matrix(matrix) # generate other possibilities o = _Othercell() if wd: o.set_working_directory(wd) auto_logfiler(o) o.set_cell(cell) o.set_lattice(lattice) o.generate() # transform the possibly centred cell to the primitive setting op = symop_to_mat(o.get_reindex_op("aP")) primitive_a = matmul(invert(op), a) # then convert to real space real_a = invert(primitive_a) return real_a[0:3], real_a[3:6], real_a[6:9]
def transmogrify_matrix(lattice, matrix, target_lattice, wavelength, wd = None): '''Transmogrify a matrix for lattice X into a matrix for lattice Y. This should work find for Mosflm... Will also return the new unit cell.''' cell, a, u = parse_matrix(matrix) o = _Othercell() if wd: o.set_working_directory(wd) auto_logfiler(o) o.set_cell(cell) o.set_lattice(lattice) o.generate() new_cell = o.get_cell(target_lattice) op = symop_to_mat(o.get_reindex_op(target_lattice)) # HACK! again - bug # 3193 if 'lattice_symmetry' in o.get_executable(): op = transpose(op) # why is only one of the matrices inverted?! a = matmul(invert(op), a) u = matmul(op, u) # in here test that the given unit cell corresponds to the # one calculated from the A matrix. anew = matscl(a, 1.0 / wavelength) reala = transpose(invert(anew)) _a, _b, _c = mat2vec(reala) la = math.sqrt(dot(_a, _a)) lb = math.sqrt(dot(_b, _b)) lc = math.sqrt(dot(_c, _c)) if math.fabs(la - new_cell[0]) / new_cell[0] > 0.01: raise RuntimeError, 'cell check failed (wavelength != %f)' % \ wavelength if math.fabs(lb - new_cell[1]) / new_cell[1] > 0.01: raise RuntimeError, 'cell check failed (wavelength != %f)' % \ wavelength if math.fabs(lc - new_cell[2]) / new_cell[2] > 0.01: raise RuntimeError, 'cell check failed (wavelength != %f)' % \ wavelength return format_matrix(new_cell, a, u)
def transmogrify_matrix(lattice, matrix, target_lattice, wavelength, wd=None): """Transmogrify a matrix for lattice X into a matrix for lattice Y. This should work find for Mosflm... Will also return the new unit cell.""" cell, a, u = parse_matrix(matrix) o = _Othercell() if wd: o.set_working_directory(wd) auto_logfiler(o) o.set_cell(cell) o.set_lattice(lattice) o.generate() new_cell = o.get_cell(target_lattice) op = symop_to_mat(o.get_reindex_op(target_lattice)) # HACK! again - bug # 3193 if "lattice_symmetry" in o.get_executable(): op = transpose(op) # why is only one of the matrices inverted?! a = matmul(invert(op), a) u = matmul(op, u) # in here test that the given unit cell corresponds to the # one calculated from the A matrix. anew = matscl(a, 1.0 / wavelength) reala = transpose(invert(anew)) _a, _b, _c = mat2vec(reala) la = math.sqrt(dot(_a, _a)) lb = math.sqrt(dot(_b, _b)) lc = math.sqrt(dot(_c, _c)) if ( math.fabs(la - new_cell[0]) / new_cell[0] > 0.01 or math.fabs(lb - new_cell[1]) / new_cell[1] > 0.01 or math.fabs(lc - new_cell[2]) / new_cell[2] > 0.01 ): raise RuntimeError("cell check failed (wavelength != %f)" % wavelength) return format_matrix(new_cell, a, u)
def set_integrater_reindex_operator(self, reindex_operator, compose=True, reason=None): '''Assign a symmetry operator to the reflections - note that this is cumulative...''' reindex_operator = reindex_operator.lower().strip() # see if we really need to do anything if reindex_operator == 'h,k,l' and \ self._intgr_reindex_operator == 'h,k,l': return # ok we need to do something - either just record the new # operation or compose it with the existing operation self.set_integrater_finish_done(False) if reason: Debug.write('Reindexing to %s (compose=%s) because %s' % (reindex_operator, compose, reason)) if self._intgr_reindex_operator is None or not compose: self._intgr_reindex_operator = reindex_operator else: old_operator = self._intgr_reindex_operator self._intgr_reindex_operator = compose_symops( reindex_operator, old_operator) Debug.write('Composing %s and %s -> %s' % \ (old_operator, reindex_operator, self._intgr_reindex_operator)) # convert this to a 3x3 matrix form for e.g. XDS CORRECT self._intgr_reindex_matrix = symop_to_mat( self._intgr_reindex_operator) self._set_integrater_reindex_operator_callback() return
def set_integrater_reindex_operator(self, reindex_operator, compose=True, reason=None): '''Assign a symmetry operator to the reflections - note that this is cumulative...''' reindex_operator = reindex_operator.lower().strip() # see if we really need to do anything if reindex_operator == 'h,k,l' and \ self._intgr_reindex_operator == 'h,k,l': return # ok we need to do something - either just record the new # operation or compose it with the existing operation self.set_integrater_finish_done(False) if reason: Debug.write('Reindexing to %s (compose=%s) because %s' % (reindex_operator, compose, reason)) if self._intgr_reindex_operator is None or not compose: self._intgr_reindex_operator = reindex_operator else: old_operator = self._intgr_reindex_operator self._intgr_reindex_operator = compose_symops( reindex_operator, old_operator) Debug.write('Composing %s and %s -> %s' % \ (old_operator, reindex_operator, self._intgr_reindex_operator)) # convert this to a 3x3 matrix form for e.g. XDS CORRECT self._intgr_reindex_matrix = symop_to_mat(self._intgr_reindex_operator) self._set_integrater_reindex_operator_callback()
def mosflm_a_matrix_to_real_space(wavelength, lattice, matrix): '''Given a Mosflm A matrix and the associated spacegroup (think of this Bravais lattice (which will be converted to a spacegroup for the benefit of the CCTBX program lattice_symmetry) return the real space primative crystal lattice vectors in the xia2 reference frame. This reference frame corresponds to that defined for imgCIF.''' # convert the lattice to a spacegroup - not needed, see below # spacegroup_number = lattice_to_spacegroup(lattice) # spacegroup = Syminfo.spacegroup_name_to_number(spacegroup_number) # get the a, u, matrices and the unit cell cell, a, u = parse_matrix(matrix) # use iotbx.latice_symmetry to obtain the reindexing operator to # a primative triclinic lattice - this should not be specific to # using iotbx - othercell should be optionally supported too... ls = _Othercell() ls.set_cell(cell) ls.set_lattice(lattice) # ls.set_spacegroup(spacegroup) # cell, reindex = ls.generate_primative_reindex() ls.generate() cell = ls.get_cell('aP') reindex = ls.get_reindex_op('aP') reindex_matrix = symop_to_mat(reindex) # grim hack warning! - this is because for some reason (probably to # do with LS getting the inverse operation) othercell is returning # the transpose of the operator or something... FIXME bug # 3193 if 'othercell' in ls.get_executable(): reindex_matrix = transpose(reindex_matrix) # scale the a matrix a = matscl(a, 1.0 / wavelength) # convert to real space (invert) and apply this reindex operator to the a # matrix to get the primative real space triclinic cell axes real_a = matmul(reindex_matrix, transpose(invert(a))) # convert these to the xia2 reference frame a, b, c = mat2vec(real_a) ax = mosflm_to_xia2(a) bx = mosflm_to_xia2(b) cx = mosflm_to_xia2(c) # FIXME in here add check that the unit cell lengths are within 1% of # the correct value - if they are not, raise an exception as the wavelength # provided is probably wrong... la = math.sqrt(dot(ax, ax)) lb = math.sqrt(dot(bx, bx)) lc = math.sqrt(dot(cx, cx)) # print out values - the cell may have been reindexed. Debug.write('Reindexed cell lengths: %.3f %.3f %.3f' % \ (cell[0], cell[1], cell[2])) Debug.write('Calculated from matrix: %.3f %.3f %.3f' % \ (la, lb, lc)) if math.fabs(la - cell[0]) / cell[0] > 0.01: raise RuntimeError, 'cell check failed (wavelength != %f)' % \ wavelength if math.fabs(lb - cell[1]) / cell[1] > 0.01: raise RuntimeError, 'cell check failed (wavelength != %f)' % \ wavelength if math.fabs(lc - cell[2]) / cell[2] > 0.01: raise RuntimeError, 'cell check failed (wavelength != %f)' % \ wavelength # return these vectors return ax, bx, cx
def mosflm_a_matrix_to_real_space(wavelength, lattice, matrix): """Given a Mosflm A matrix and the associated spacegroup (think of this Bravais lattice (which will be converted to a spacegroup for the benefit of the CCTBX program lattice_symmetry) return the real space primative crystal lattice vectors in the xia2 reference frame. This reference frame corresponds to that defined for imgCIF.""" # get the a, u, matrices and the unit cell cell, a, u = parse_matrix(matrix) # use iotbx.latice_symmetry to obtain the reindexing operator to # a primative triclinic lattice - this should not be specific to # using iotbx - othercell should be optionally supported too... ls = _Othercell() ls.set_cell(cell) ls.set_lattice(lattice) ls.generate() cell = ls.get_cell("aP") reindex = ls.get_reindex_op("aP") reindex_matrix = symop_to_mat(reindex) # grim hack warning! - this is because for some reason (probably to # do with LS getting the inverse operation) othercell is returning # the transpose of the operator or something... FIXME bug # 3193 if "othercell" in ls.get_executable(): reindex_matrix = transpose(reindex_matrix) # scale the a matrix a = matscl(a, 1.0 / wavelength) # convert to real space (invert) and apply this reindex operator to the a # matrix to get the primative real space triclinic cell axes real_a = matmul(reindex_matrix, transpose(invert(a))) # convert these to the xia2 reference frame a, b, c = mat2vec(real_a) ax = mosflm_to_xia2(a) bx = mosflm_to_xia2(b) cx = mosflm_to_xia2(c) # FIXME in here add check that the unit cell lengths are within 1% of # the correct value - if they are not, raise an exception as the wavelength # provided is probably wrong... la = math.sqrt(dot(ax, ax)) lb = math.sqrt(dot(bx, bx)) lc = math.sqrt(dot(cx, cx)) # print out values - the cell may have been reindexed. Debug.write("Reindexed cell lengths: %.3f %.3f %.3f" % (cell[0], cell[1], cell[2])) Debug.write("Calculated from matrix: %.3f %.3f %.3f" % (la, lb, lc)) if ( math.fabs(la - cell[0]) / cell[0] > 0.01 or math.fabs(lb - cell[1]) / cell[1] > 0.01 or math.fabs(lc - cell[2]) / cell[2] > 0.01 ): raise RuntimeError("cell check failed (wavelength != %f)" % wavelength) # return these vectors return ax, bx, cx