def test_operate_on(self): matrix = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) so = SymmetryOperation(matrix) configuration = Configuration([1, 2, 3]) so.operate_on(configuration) np.testing.assert_array_equal( so.operate_on(configuration).vector, np.array([2, 3, 1]))
def test_mul(self): matrix_a = np.array([[0, 1], [1, 0]]) matrix_b = np.array([[1, 0], [0, 1]]) so_a = SymmetryOperation(matrix_a) so_b = SymmetryOperation(matrix_b) np.testing.assert_array_equal((so_a * so_b).matrix, np.array([[0, 1], [1, 0]]))
def test_similarity_transform( self ): matrix_a = np.array( [ [ 0, 1, 0 ], [ 0, 0, 1 ], [ 1, 0, 0 ] ] ) matrix_b = np.array( [ [ 1, 0, 0 ], [ 0, 0, 1 ], [ 0, 1, 0 ] ] ) matrix_c = np.linalg.inv( matrix_a ) so_a = SymmetryOperation( matrix_a ) so_b = SymmetryOperation( matrix_b ) np.testing.assert_array_equal( so_a.similarity_transform( so_b ).matrix, matrix_c )
def test_similarity_transform(self): matrix_a = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) matrix_b = np.array([[1, 0, 0], [0, 0, 1], [0, 1, 0]]) matrix_c = np.linalg.inv(matrix_a) so_a = SymmetryOperation(matrix_a) so_b = SymmetryOperation(matrix_b) np.testing.assert_array_equal( so_a.similarity_transform(so_b).matrix, matrix_c)
def test_similarity_transform_with_label( self ): matrix_a = np.array( [ [ 0, 1, 0 ], [ 0, 0, 1 ], [ 1, 0, 0 ] ] ) matrix_b = np.array( [ [ 1, 0, 0 ], [ 0, 0, 1 ], [ 0, 1, 0 ] ] ) matrix_c = np.linalg.inv( matrix_a ) so_a = SymmetryOperation( matrix_a ) so_b = SymmetryOperation( matrix_b ) label = 'foo' np.testing.assert_array_equal( so_a.similarity_transform( so_b, label=label ).label, label )
def test_similarity_transform_with_label(self): matrix_a = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) matrix_b = np.array([[1, 0, 0], [0, 0, 1], [0, 1, 0]]) matrix_c = np.linalg.inv(matrix_a) so_a = SymmetryOperation(matrix_a) so_b = SymmetryOperation(matrix_b) label = 'foo' np.testing.assert_array_equal( so_a.similarity_transform(so_b, label=label).label, label)
def test_from_vector_with_label(self): vector = [2, 3, 1] label = 'A' so = SymmetryOperation.from_vector(vector, label=label) np.testing.assert_array_equal( so.matrix, np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]])) self.assertEqual(so.label, label)
def read_from_file_with_labels(cls, filename): """ Create a :any:`SymmetryGroup` object from a file, with labelled symmetry operations. The file format should be a series of numerical mappings representing each symmetry operation, prepended with a string that will be used as a label. e.g. for a pair of equivalent sites:: # example input file to define the spacegroup for a pair of equivalent sites E 1 2 C2 2 1 Args: filename (str): Name of the file to be read in. Returns: spacegroup (SymmetryGroup) """ data = np.genfromtxt(filename, dtype=str) labels = [row[0] for row in data] vectors = [[float(s) for s in row[1:]] for row in data] symmetry_operations = [ SymmetryOperation.from_vector(v) for v in vectors ] [so.set_label(l) for (l, so) in zip(labels, symmetry_operations)] return (cls(symmetry_operations=symmetry_operations))
def space_group_from_structure( structure, subset=None, atol=1e-5 ): """ Generates a ``SpaceGroup`` object from a `pymatgen` ``Structure``. Args: structure (pymatgen ``Structure``): structure to be used to define the :any:`SpaceGroup`. subset (Optional [list]): list of atom indices to be used for generating the symmetry operations. atol (Optional [float]): tolerance factor for the ``pymatgen`` `coordinate mapping`_ under each symmetry operation. Returns: a new :any:`SpaceGroup` instance .. _coordinate mapping: http://pymatgen.org/pymatgen.util.coord_utils.html#pymatgen.util.coord_utils.coord_list_mapping_pbc """ mappings = unique_symmetry_operations_as_vectors_from_structure( structure, subset=subset, atol=atol ) symmetry_operations = [ SymmetryOperation.from_vector( m ) for m in mappings ] return SpaceGroup( symmetry_operations=symmetry_operations )
def space_group_from_structure(structure, subset=None, atol=1e-5): """ Generates a ``SpaceGroup`` object from a `pymatgen` ``Structure``. Args: structure (pymatgen ``Structure``): structure to be used to define the :any:`SpaceGroup`. subset (Optional [list]): list of atom indices to be used for generating the symmetry operations. atol (Optional [float]): tolerance factor for the ``pymatgen`` `coordinate mapping`_ under each symmetry operation. Returns: a new :any:`SpaceGroup` instance .. _coordinate mapping: http://pymatgen.org/pymatgen.util.coord_utils.html#pymatgen.util.coord_utils.coord_list_mapping_pbc """ mappings = unique_symmetry_operations_as_vectors_from_structure( structure, subset=subset, atol=atol) symmetry_operations = [SymmetryOperation.from_vector(m) for m in mappings] return SpaceGroup(symmetry_operations=symmetry_operations)
def point_group_from_molecule( molecule, subset=None, atol=1e-5 ): """ Generates a ``PointGroup`` object from a `pymatgen` ``Molecule``. Args: molecule (pymatgen ``Molecule``): molecule to be used to define the :any:`PointGroup`. subset (Optional [list]): list of atom indices to be used for generating the symmetry operations. atol (Optional [float]): tolerance factor for the ``pymatgen`` `coordinate mapping`_ under each symmetry operation. Returns: a new :any:`PointGroup` instance .. _coordinate mapping: http://pymatgen.org/pymatgen.util.coord_utils.html#pymatgen.util.coord_utils.coord_list_mapping """ molecule = Molecule( molecule.species, molecule.cart_coords - molecule.center_of_mass ) mappings = unique_symmetry_operations_as_vectors_from_structure( molecule, subset=subset, atol=atol ) symmetry_operations = [ SymmetryOperation.from_vector( m ) for m in mappings ] return PointGroup( symmetry_operations=symmetry_operations )
def read_from_file( cls, filename ): """ Create a :any:`SymmetryGroup` object from a file. The file format should be a series of numerical mappings representing each symmetry operation. e.g. for a pair of equivalent sites:: # example input file to define the spacegroup for a pair of equivalent sites 1 2 2 1 Args: filename (str): Name of the file to be read in. Returns: spacegroup (SymmetryGroup) """ data = np.loadtxt( filename, dtype=int ) symmetry_operations = [ SymmetryOperation.from_vector( row.tolist() ) for row in data ] return( cls( symmetry_operations = symmetry_operations ) )
def __init__( self, objects, symmetry_group=None ): """ Create a :any:`ConfigurationSpace` object. Args: objects (list): The set of objects that define the vector space of this configuration space. symmetry_group (:any:`SymmetryGroup`): The set of symmetry operations describing the symmetries of this configuration space. Returns: None """ # Check that all properties have compatible dimensions self.dim = len( objects ) self.objects = objects if symmetry_group: for so in symmetry_group.symmetry_operations: if so.matrix.shape[0] != self.dim: raise ValueError self.symmetry_group = symmetry_group else: self.symmetry_group = SymmetryGroup( symmetry_operations=[ SymmetryOperation( np.identity( self.dim, dtype=int ), label='E' ) ] )
def point_group_from_molecule(molecule, subset=None, atol=1e-5): """ Generates a ``PointGroup`` object from a `pymatgen` ``Molecule``. Args: molecule (pymatgen ``Molecule``): molecule to be used to define the :any:`PointGroup`. subset (Optional [list]): list of atom indices to be used for generating the symmetry operations. atol (Optional [float]): tolerance factor for the ``pymatgen`` `coordinate mapping`_ under each symmetry operation. Returns: a new :any:`PointGroup` instance .. _coordinate mapping: http://pymatgen.org/pymatgen.util.coord_utils.html#pymatgen.util.coord_utils.coord_list_mapping """ molecule = Molecule(molecule.species, molecule.cart_coords - molecule.center_of_mass) mappings = unique_symmetry_operations_as_vectors_from_structure( molecule, subset=subset, atol=atol) symmetry_operations = [SymmetryOperation.from_vector(m) for m in mappings] return PointGroup(symmetry_operations=symmetry_operations)
def read_from_file(cls, filename): """ Create a :any:`SymmetryGroup` object from a file. The file format should be a series of numerical mappings representing each symmetry operation. e.g. for a pair of equivalent sites:: # example input file to define the spacegroup for a pair of equivalent sites 1 2 2 1 Args: filename (str): Name of the file to be read in. Returns: spacegroup (SymmetryGroup) """ data = np.loadtxt(filename, dtype=int) symmetry_operations = [ SymmetryOperation.from_vector(row.tolist()) for row in data ] return (cls(symmetry_operations=symmetry_operations))
def read_from_file_with_labels( cls, filename ): """ Create a :any:`SymmetryGroup` object from a file, with labelled symmetry operations. The file format should be a series of numerical mappings representing each symmetry operation, prepended with a string that will be used as a label. e.g. for a pair of equivalent sites:: # example input file to define the spacegroup for a pair of equivalent sites E 1 2 C2 2 1 Args: filename (str): Name of the file to be read in. Returns: spacegroup (SymmetryGroup) """ data = np.genfromtxt( filename, dtype=str ) labels = [ row[0] for row in data ] vectors = [ [ float(s) for s in row[1:] ] for row in data ] symmetry_operations = [ SymmetryOperation.from_vector( v ) for v in vectors ] [ so.set_label( l ) for (l, so) in zip( labels, symmetry_operations ) ] return( cls( symmetry_operations=symmetry_operations ) )
def test_mul_raises_TypeError_with_invalid_type( self ): so = SymmetryOperation.from_vector( [ 2, 3, 1 ] ) with self.assertRaises( TypeError ): new_conf = so * 'foo'
def test_repr( self ): matrix = np.array( [ [ 1, 0 ], [ 0, 1 ] ] ) so = SymmetryOperation( matrix, label='L' ) this_repr = so.__repr__() self.assertNotEqual( this_repr.find( 'L' ), 0 ) self.assertNotEqual( this_repr.find( "[[1, 0],\n[0, 1]]" ), 0 )
def test_se_label( self ): matrix = np.array( [ [ 1, 0 ], [ 0, 1 ] ] ) so = SymmetryOperation( matrix ) so.set_label( 'new_label' ) self.assertEqual( so.label, 'new_label' )
def test_as_vector( self ): matrix = np.array( [ [ 0, 0, 1 ], [ 1, 0, 0 ], [ 0, 1, 0 ] ] ) so = SymmetryOperation( matrix ) self.assertEqual( so.as_vector(), [ 2, 3, 1 ] )
def test_operate_on_raises_TypeError_with_invalid_type( self ): matrix = np.array( [ [ 0, 1, 0 ], [ 0, 0, 1 ], [ 1, 0, 0 ] ] ) so = SymmetryOperation( matrix ) with self.assertRaises( TypeError ): so.operate_on( 'foo' )
def test_pprint(self): matrix = np.matrix([[1, 0], [0, 1]]) so = SymmetryOperation(matrix) with patch('sys.stdout', new=io.StringIO()) as mock_stdout: so.pprint() self.assertEqual(mock_stdout.getvalue(), '--- : 1 2\n')
def test_from_vector(self): vector = [2, 3, 1] so = SymmetryOperation.from_vector(vector) np.testing.assert_array_equal( so.matrix, np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]]))
def test_invert(self): matrix_a = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) matrix_b = np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]]) so = SymmetryOperation(matrix_a) np.testing.assert_array_equal(so.invert().matrix, matrix_b)
def test_invert_sets_label(self): matrix_a = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) so = SymmetryOperation(matrix_a).invert(label='A') self.assertEqual(so.label, 'A')
def test_mul_raises_TypeError_with_invalid_type(self): so = SymmetryOperation.from_vector([2, 3, 1]) with self.assertRaises(TypeError): new_conf = so * 'foo'
def test_mul_with_configuration(self): so = SymmetryOperation.from_vector([2, 3, 1]) conf = Configuration([1, 2, 3]) new_conf = so * conf self.assertEqual(type(new_conf), Configuration) self.assertEqual(new_conf.matches(Configuration([3, 1, 2])), True)
def test_as_vector(self): matrix = np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]]) so = SymmetryOperation(matrix) self.assertEqual(so.as_vector(), [2, 3, 1])
def test_from_vector( self ): vector = [ 2, 3, 1 ] so = SymmetryOperation.from_vector( vector ) np.testing.assert_array_equal( so.matrix, np.array( [ [ 0, 0, 1 ], [ 1, 0, 0 ], [ 0, 1, 0 ] ] ) )
def test_character(self): matrix = np.array([[1, 0], [0, 1]]) so = SymmetryOperation(matrix) self.assertEqual(so.character(), 2)
def test_symmetry_operation_raises_valueerror_for_nonsquare_matrix(self): array = np.array([[1, 0, 0], [0, 0, 1]]) with self.assertRaises(ValueError): SymmetryOperation(array)
def test_symmetry_operation_is_initialised_with_label(self): matrix = np.array([[1, 0], [0, 1]]) label = 'E' so = SymmetryOperation(matrix, label=label) self.assertEqual(so.label, label)
def test_symmetry_operation_is_initialised_from_an_array(self): array = np.array([[1, 0], [0, 1]]) so = SymmetryOperation(array) np.testing.assert_array_equal(so.matrix, np.array(array))
def test_symmetry_operation_is_initialised_from_a_list(self): this_list = [[1, 0], [0, 1]] so = SymmetryOperation(this_list) np.testing.assert_array_equal(so.matrix, np.array(this_list))
def test_operate_on( self ): matrix = np.array( [ [ 0, 1, 0 ], [ 0, 0, 1 ], [ 1, 0, 0 ] ] ) so = SymmetryOperation( matrix ) configuration = Configuration( [ 1, 2, 3 ] ) so.operate_on( configuration ) np.testing.assert_array_equal( so.operate_on( configuration ).vector, np.array( [ 2, 3, 1 ] ) )
def test_operate_on_raises_TypeError_with_invalid_type(self): matrix = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) so = SymmetryOperation(matrix) with self.assertRaises(TypeError): so.operate_on('foo')
def test_character( self ): matrix = np.array( [ [ 1, 0 ], [ 0, 1 ] ] ) so = SymmetryOperation( matrix ) self.assertEqual( so.character(), 2 )
def test_repr(self): matrix = np.array([[1, 0], [0, 1]]) so = SymmetryOperation(matrix, label='L') this_repr = so.__repr__() self.assertNotEqual(this_repr.find('L'), 0) self.assertNotEqual(this_repr.find("[[1, 0],\n[0, 1]]"), 0)
def test_as_vector_counting_from_zero( self ): matrix = np.array( [ [ 1, 0 ], [ 0, 1 ] ] ) so = SymmetryOperation( matrix ) self.assertEqual( so.as_vector( count_from_zero=True ), [ 0, 1 ] )
def test_from_vector_counting_from_zero( self ): vector = [ 1, 2, 0 ] so = SymmetryOperation.from_vector( vector, count_from_zero=True ) np.testing.assert_array_equal( so.matrix, np.array( [ [ 0, 0, 1 ], [ 1, 0, 0 ], [ 0, 1, 0 ] ] ) )
def test_pprint_with_label( self ): matrix = np.array( [ [ 1, 0 ], [ 0, 1 ] ] ) so = SymmetryOperation( matrix, label='L' ) with patch( 'sys.stdout', new=io.StringIO() ) as mock_stdout: so.pprint() self.assertEqual( mock_stdout.getvalue(), 'L : 1 2\n' )
def test_se_label(self): matrix = np.array([[1, 0], [0, 1]]) so = SymmetryOperation(matrix) so.set_label('new_label') self.assertEqual(so.label, 'new_label')
def test_mul_with_configuration( self ): so = SymmetryOperation.from_vector( [ 2, 3, 1 ] ) conf = Configuration( [ 1, 2, 3 ] ) new_conf = so * conf self.assertEqual( type( new_conf ), Configuration ) self.assertEqual( new_conf.matches( Configuration( [ 3, 1, 2 ] ) ), True )
def test_symmetry_operation_is_initialised_from_a_matrix(self): matrix = np.array([[1, 0], [0, 1]]) so = SymmetryOperation(matrix) np.testing.assert_array_equal(so.matrix, matrix)
def test_invert( self ): matrix_a = np.array( [ [ 0, 1, 0 ], [ 0, 0, 1 ], [ 1, 0, 0 ] ] ) matrix_b = np.array( [ [ 0, 0, 1 ], [ 1, 0, 0 ], [ 0, 1, 0 ] ] ) so = SymmetryOperation( matrix_a ) np.testing.assert_array_equal( so.invert().matrix, matrix_b )
def test_pprint_with_label(self): matrix = np.array([[1, 0], [0, 1]]) so = SymmetryOperation(matrix, label='L') with patch('sys.stdout', new=io.StringIO()) as mock_stdout: so.pprint() self.assertEqual(mock_stdout.getvalue(), 'L : 1 2\n')
def test_from_vector_with_label( self ): vector = [ 2, 3, 1 ] label = 'A' so = SymmetryOperation.from_vector( vector, label=label ) np.testing.assert_array_equal( so.matrix, np.array( [ [ 0, 0, 1 ], [ 1, 0, 0 ], [ 0, 1, 0 ] ] ) ) self.assertEqual( so.label, label )
def test_symmetry_operation_raises_typeerror_for_invalid_type(self): objects = ['foo', 1, None] for o in objects: with self.assertRaises(TypeError): SymmetryOperation(o)
def test_from_vector_counting_from_zero(self): vector = [1, 2, 0] so = SymmetryOperation.from_vector(vector, count_from_zero=True) np.testing.assert_array_equal( so.matrix, np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]]))
def test_as_vector_counting_from_zero(self): matrix = np.array([[1, 0], [0, 1]]) so = SymmetryOperation(matrix) self.assertEqual(so.as_vector(count_from_zero=True), [0, 1])