class TestCoordinationPolyhedron(unittest.TestCase): def setUp(self): mock_central_atom = Mock(spec=Atom) mock_central_atom.in_polyhedra = [] mock_central_atom.index = 0 mock_central_atom.label = 'A' mock_central_atom.__eq__ = mock_atom_eq mock_vertices = [Mock(spec=Atom) for i in range(6)] for i, v in enumerate(mock_vertices, 1): v._neighbours = {} v.index = i v.__lt__ = mock_atom_lt v.__eq__ = mock_atom_eq v.in_polyhedra = [] self.coordination_polyhedron = CoordinationPolyhedron( central_atom=mock_central_atom, vertices=mock_vertices) def test_equal_members(self): other_coordination_polyhedron = copy.deepcopy( self.coordination_polyhedron) other_coordination_polyhedron.vertices[0].neighbours = {0: [1, 2, 3]} other_coordination_polyhedron.vertices[4].neighbours = {4: [1, 3, 5]} self.assertTrue( self.coordination_polyhedron.equal_members( other_coordination_polyhedron)) def test_vertex_vectors(self): vectors = [np.array([1.0, 0.0, 0.0]), np.array([0.0, 1.0, 2.0])] self.coordination_polyhedron._abstract_geometry = Mock( spec=AbstractGeometry) self.coordination_polyhedron.abstract_geometry.points_wocs_ctwocc.return_value = vectors returned_vectors = self.coordination_polyhedron.vertex_vectors for v1, v2 in zip(vectors, returned_vectors): np.testing.assert_equal(v1, v2) def test_angles(self): vertex_vectors = np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, -1.0, 0.0]]) with patch( 'polyhedral_analysis.coordination_polyhedron.CoordinationPolyhedron.vertex_vectors', new_callable=PropertyMock) as mock_vertex_vectors: mock_vertex_vectors.return_value = vertex_vectors angles = self.coordination_polyhedron.angles() np.testing.assert_equal(angles, [90.0, 90.0, 180.0]) def test_vertex_distances(self): mock_vertex_distances = [2.0, 1.0, 1.0, 1.0, 1.0, 1.5] self.coordination_polyhedron.central_atom.distance = \ Mock(side_effect=mock_vertex_distances) vertex_distances = self.coordination_polyhedron.vertex_distances() np.testing.assert_equal(vertex_distances, mock_vertex_distances) def test_vertex_distances_and_labels(self): mock_vertex_distances = (2.0, 1.0, 1.0, 1.0, 1.0, 1.5) mock_labels = ['O', 'O', 'F', 'F', 'F', 'F'] self.coordination_polyhedron.central_atom = Mock(spec=Atom) self.coordination_polyhedron.vertex_distances = \ Mock(return_value=mock_vertex_distances) with patch( 'polyhedral_analysis.coordination_polyhedron.CoordinationPolyhedron.vertex_labels', new_callable=PropertyMock) as mock_vertex_labels: mock_vertex_labels.__get__ = Mock(return_value=mock_labels) output = self.coordination_polyhedron.vertex_distances_and_labels() np.testing.assert_equal(output, list(zip(mock_vertex_distances, mock_labels))) def test_update_vertex_neighbours(self): with patch( 'polyhedral_analysis.coordination_polyhedron.CoordinationPolyhedron.edge_graph', new_callable=PropertyMock) as mock_edge_graph: edge_graph = { 1: [2, 3, 4, 5], 2: [1, 3, 5, 6], 3: [1, 2, 4, 6], 4: [1, 3, 5, 6], 5: [1, 2, 4, 6], 6: [2, 3, 4, 5] } mock_edge_graph.return_value = edge_graph self.coordination_polyhedron.update_vertex_neighbours() for v, n in zip(self.coordination_polyhedron.vertices, edge_graph.values()): self.assertEqual( v._neighbours[self.coordination_polyhedron.index], n) def test_vertices_by_indices(self): vertices = self.coordination_polyhedron.vertices_by_indices([2, 4]) self.assertEqual(sorted([v.index for v in vertices]), [2, 4]) def test_vertex_indices(self): self.assertEqual(self.coordination_polyhedron.vertex_indices, [1, 2, 3, 4, 5, 6]) def test_vertex_coords(self): coords = np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]]) for v, c in zip(self.coordination_polyhedron.vertices, coords): v.coords = c np.testing.assert_array_equal( self.coordination_polyhedron.vertex_coords, coords) def test_vertex_labels(self): labels = ['A', 'B', 'C', 'D', 'E', 'F'] for v, l in zip(self.coordination_polyhedron.vertices, labels): v.label = l self.assertEqual(self.coordination_polyhedron.vertex_labels, labels) def test_coordination_number(self): self.assertEqual(self.coordination_polyhedron.coordination_number, len(self.coordination_polyhedron.vertices)) def test_index(self): self.assertEqual(self.coordination_polyhedron.index, self.coordination_polyhedron.central_atom.index) def test_edge_graph_if_cached(self): edge_graph = { 1: [2, 3, 4, 5], 2: [1, 3, 5, 6], 3: [1, 2, 4, 6], 4: [1, 3, 5, 6], 5: [1, 2, 4, 6], 6: [2, 3, 4, 5] } self.coordination_polyhedron._edge_graph = edge_graph self.assertEqual(self.coordination_polyhedron.edge_graph, edge_graph) def test_edge_graph_if_not_cached(self): edge_graph = { 1: [2, 3, 4, 5], 2: [1, 3, 5, 6], 3: [1, 2, 4, 6], 4: [1, 3, 5, 6], 5: [1, 2, 4, 6], 6: [2, 3, 4, 5] } self.coordination_polyhedron.construct_edge_graph = Mock( return_value=edge_graph) self.coordination_polyhedron.update_vertex_neighbours = Mock() self.assertEqual(self.coordination_polyhedron.edge_graph, edge_graph) self.assertEqual( self.coordination_polyhedron.update_vertex_neighbours.call_count, 1) self.assertEqual( self.coordination_polyhedron.construct_edge_graph.call_count, 1) def test_abstract_geometry_if_cached(self): abstract_geometry = Mock(spec=AbstractGeometry) self.coordination_polyhedron._abstract_geometry = abstract_geometry self.assertEqual(self.coordination_polyhedron.abstract_geometry, abstract_geometry) def test_abstract_geometry_if_not_cached(self): abstract_geometry = Mock(spec=AbstractGeometry) self.coordination_polyhedron.construct_abstract_geometry = Mock( return_value=abstract_geometry) self.assertEqual(self.coordination_polyhedron.abstract_geometry, abstract_geometry) self.assertEqual( self.coordination_polyhedron.construct_abstract_geometry. call_count, 1) def test_construct_abstract_geometry(self): polyhedron = self.coordination_polyhedron polyhedron.central_atom.coords = np.array([1.0, 2.0, 3.0]) polyhedron.minimum_image_vertex_coordinates = Mock(return_value='foo') abstract_geometry = Mock(spec=AbstractGeometry) with patch( f'polyhedral_analysis.coordination_polyhedron.AbstractGeometry' ) as mock_abstract_geometry: mock_abstract_geometry.return_value = abstract_geometry ag = polyhedron.construct_abstract_geometry() self.assertEqual(ag, abstract_geometry) mock_abstract_geometry.assert_called_with( central_site=polyhedron.central_atom.coords, bare_coords='foo', include_central_site_in_centroid=False) def test_faces(self): polyhedron = self.coordination_polyhedron polyhedron.convex_hull = Mock(return_value=Mock(spec=ConvexHull)) returned_vertex_indices = [1, 2, 3, 4, 5, 6] with patch(f'{module_str}.vertex_indices', new_callable=PropertyMock) as mock_vertex_indices: mock_vertex_indices.return_value = returned_vertex_indices simplices = [ np.array([0, 3, 1]), np.array([0, 3, 4]), np.array([5, 3, 1]), np.array([5, 3, 4]), np.array([2, 0, 4]), np.array([2, 0, 1]), np.array([2, 5, 4]), np.array([2, 5, 1]) ] with patch( 'polyhedral_analysis.coordination_polyhedron.merge_coplanar_simplices' ) as mock_merge_coplanar_simplices: mock_merge_coplanar_simplices.return_value = simplices faces = polyhedron.faces() self.assertEqual(faces, ((1, 2, 4), (1, 4, 5), (2, 4, 6), (4, 5, 6), (1, 3, 5), (1, 2, 3), (3, 5, 6), (2, 3, 6))) def test_neighbours(self): mock_central_atom_i = Mock(spec=Atom) mock_central_atom_i.in_polyhedra = [] mock_central_atom_i.index = 3 mock_central_atom_i.label = 'Li' mock_central_atom_j = Mock(spec=Atom) mock_central_atom_j.in_polyhedra = [] mock_central_atom_j.index = 7 mock_central_atom_j.label = 'Li' mock_vertices = [Mock(spec=Atom) for i in range(10)] for i, v in enumerate(mock_vertices, 1): v.neighbours = None v.__lt__ = mock_atom_lt v.index = i v.in_polyhedra = [] polyhedron_i = CoordinationPolyhedron(central_atom=mock_central_atom_i, vertices=mock_vertices[:6]) polyhedron_j = CoordinationPolyhedron(central_atom=mock_central_atom_j, vertices=mock_vertices[-6:]) polyhedron_i._edge_graph = Mock() polyhedron_j._edge_graph = Mock() self.assertEqual(polyhedron_i.neighbours(), (polyhedron_j, )) self.assertEqual(polyhedron_j.neighbours(), (polyhedron_i, )) def test_interection(self): mock_central_atom_i = Mock(spec=Atom) mock_central_atom_i.in_polyhedra = [] mock_central_atom_i.index = 3 mock_central_atom_i.label = 'Li' mock_central_atom_j = Mock(spec=Atom) mock_central_atom_j.in_polyhedra = [] mock_central_atom_j.index = 7 mock_central_atom_j.label = 'Li' mock_vertices = [Mock(spec=Atom) for i in range(10)] for i, v in enumerate(mock_vertices, 1): v.neighbours = None v.__lt__ = mock_atom_lt v.index = i v.in_polyhedra = [] polyhedron_i = CoordinationPolyhedron(central_atom=mock_central_atom_i, vertices=mock_vertices[:6]) polyhedron_j = CoordinationPolyhedron(central_atom=mock_central_atom_j, vertices=mock_vertices[-6:]) self.assertEqual(polyhedron_i.intersection(polyhedron_j), (5, 6)) self.assertEqual(polyhedron_j.intersection(polyhedron_i), (5, 6)) def test_neighbours_by_index_and_shared_vertices(self): polyhedron_i = self.coordination_polyhedron polyhedron_j = copy.deepcopy(polyhedron_i) polyhedron_i.neighbours = Mock(return_value=(polyhedron_j, )) polyhedron_j.neighbours = Mock(return_value=(polyhedron_i, )) polyhedron_i.intersection = Mock(return_value=(5, 6)) polyhedron_j.intersection = Mock(return_value=(5, 6)) self.assertEqual( polyhedron_i.neighbours_by_index_and_shared_vertices(), {polyhedron_j.index: (5, 6)}) self.assertEqual( polyhedron_j.neighbours_by_index_and_shared_vertices(), {polyhedron_i.index: (5, 6)})
class TestCoordinationPolyhedron(unittest.TestCase): def setUp(self): mock_central_atom = Mock(spec=Atom) mock_central_atom.in_polyhedra = [] mock_central_atom.index = 0 mock_central_atom.label = 'A' mock_central_atom.__eq__ = mock_atom_eq mock_vertices = [Mock(spec=Atom) for i in range(6)] for i, v in enumerate(mock_vertices, 1): v.neighbours = None v.index = i v.__lt__ = mock_atom_lt v.__eq__ = mock_atom_eq v.in_polyhedra = [] with patch( 'polyhedral_analysis.coordination_polyhedron.CoordinationPolyhedron.construct_edge_graph' ) as mock_construct_edge_graph: mock_construct_edge_graph.return_value = { 0: [1, 2, 3, 4], 1: [0, 2, 3, 5], 2: [0, 1, 3, 5], 3: [0, 2, 4, 5], 4: [0, 1, 3, 5], 5: [1, 2, 3, 4] } with patch( 'polyhedral_analysis.coordination_polyhedron.CoordinationPolyhedron.construct_abstract_geometry' ) as mock_construct_abstract_geometry: mock_construct_abstract_geometry.return_value = Mock( spec=AbstractGeometry) self.coordination_polyhedron = CoordinationPolyhedron( central_atom=mock_central_atom, vertices=mock_vertices) def test_equal_members(self): other_coordination_polyhedron = copy.deepcopy( self.coordination_polyhedron) other_coordination_polyhedron.vertices[0].neighbours = {0: [1, 2, 3]} other_coordination_polyhedron.vertices[4].neighbours = {4: [1, 3, 5]} self.assertTrue( self.coordination_polyhedron.equal_members( other_coordination_polyhedron)) def test_vertex_vectors(self): vectors = [np.array([1.0, 0.0, 0.0]), np.array([0.0, 1.0, 2.0])] self.coordination_polyhedron.abstract_geometry.points_wocs_ctwocc.return_value = vectors returned_vectors = self.coordination_polyhedron.vertex_vectors for v1, v2 in zip(vectors, returned_vectors): np.testing.assert_equal(v1, v2) def test_angles(self): vertex_vectors = np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, -1.0, 0.0]]) with patch( 'polyhedral_analysis.coordination_polyhedron.CoordinationPolyhedron.vertex_vectors', new_callable=PropertyMock) as mock_vertex_vectors: mock_vertex_vectors.return_value = vertex_vectors angles = self.coordination_polyhedron.angles() np.testing.assert_equal(angles, [90.0, 90.0, 180.0]) def test_vertex_distances(self): mock_vertex_distances = [2.0, 1.0, 1.0, 1.0, 1.0, 1.5] self.coordination_polyhedron.central_atom.site = Mock(spec=Site) self.coordination_polyhedron.central_atom.site.distance = \ Mock( side_effect=mock_vertex_distances ) for v in self.coordination_polyhedron.vertices: v.site = Mock(spec=Site) vertex_distances = self.coordination_polyhedron.vertex_distances() np.testing.assert_equal(vertex_distances, mock_vertex_distances) def test_vertex_distances_with_vertex_labels(self): mock_vertex_distances = [2.0, 1.0, 1.0, 1.0, 1.0, 1.5] mock_labels = ['O', 'O', 'F', 'F', 'F', 'F'] self.coordination_polyhedron.central_atom.site = Mock(spec=Site) self.coordination_polyhedron.central_atom.site.distance = \ Mock( side_effect=mock_vertex_distances ) for v, mock_label in zip(self.coordination_polyhedron.vertices, mock_labels): v.site = Mock(spec=Site) v.label = mock_label vertex_distances = self.coordination_polyhedron.vertex_distances( vertex_labels=True) np.testing.assert_equal(vertex_distances, list(zip(mock_vertex_distances, mock_labels)))