Example #1
0
    def test_get_bond_distance_summary(self):
        """Test getting the bond distance summary"""
        sa = SiteAnalyzer(self.tin_dioxide)
        data = sa.get_bond_distance_summary(0)

        self.assertEqual(len(data[2]), 6)
        self.assertAlmostEqual(data[2][0], 2.0922101061490546)
Example #2
0
    def test_init(self):
        """Test to check SiteDescriber can be initialised"""
        sa = SiteAnalyzer(self.tin_dioxide)
        self.assertNotEqual(sa, None, msg="tin dioxide site analyzer could not be init")

        # check different structure
        sa = SiteAnalyzer(self.ba_n)
        self.assertNotEqual(sa, None, msg="BaN2 site analyzer could not be initialized")
Example #3
0
    def test_connectivity_angle_summary(self):
        """Test getting the connectivity angle summary"""
        sa = SiteAnalyzer(self.tin_dioxide)
        data = sa.get_connectivity_angle_summary(0)

        self.assertEqual(len(data[0]['corner']), 8)
        self.assertEqual(len(data[0]['edge']), 4)
        self.assertAlmostEqual(data[0]['edge'][0], 101.62287790513848)
Example #4
0
    def test_nnn_distance_summary(self):
        """Test getting the nnn distance summary"""
        sa = SiteAnalyzer(self.tin_dioxide)
        data = sa.get_nnn_distance_summary(0)

        self.assertEqual(len(data[0]['corner']), 8)
        self.assertEqual(len(data[0]['edge']), 2)
        self.assertAlmostEqual(data[0]['edge'][0], 3.24322132)
Example #5
0
    def test_geometries_match(self):
        """Test geometry matching function."""
        sa = SiteAnalyzer(self.tin_dioxide, use_symmetry_equivalent_sites=False)
        geom_a = sa.get_site_geometry(0)
        geom_b = sa.get_site_geometry(1)
        geom_c = sa.get_site_geometry(4)

        self.assertTrue(geometries_match(geom_a, geom_b))
        self.assertFalse(geometries_match(geom_a, geom_c))
Example #6
0
 def test_get_site_summary(self):
     """Test getting the site summary"""
     sa = SiteAnalyzer(self.tin_dioxide)
     data = sa.get_site_summary(0)
     self.assertEqual(data["element"], "Sn4+")
     self.assertEqual(data["geometry"]["type"], "octahedral")
     self.assertAlmostEqual(data["geometry"]["likeness"], 0.9349776258427136)
     self.assertEqual(len(data["nn"]), 6)
     self.assertEqual(len(data["nnn"]["corner"]), 8)
     self.assertEqual(len(data["nnn"]["edge"]), 2)
     self.assertEqual(data["poly_formula"], "O6")
     self.assertEqual(data["sym_labels"], (1,))
Example #7
0
    def test_equivalent_sites(self):
        """Check equivalent sites instance variable set correctly."""
        sa = SiteAnalyzer(self.ba_n, use_symmetry_equivalent_sites=False)
        self.assertEqual(sa.equivalent_sites, [0, 0, 0, 0, 4, 4])

        # test using symmetry to determine equivalent sites
        sa = SiteAnalyzer(self.ba_n, use_symmetry_equivalent_sites=True)
        self.assertIsInstance(sa.equivalent_sites, list)
        self.assertEqual(sa.equivalent_sites, [0, 0, 0, 0, 4, 4])

        # test symprec option works
        sa = SiteAnalyzer(self.ba_n, use_symmetry_equivalent_sites=True, symprec=0.0001)
        self.assertEqual(sa.equivalent_sites, [0, 1, 1, 0, 4, 4])
Example #8
0
 def test_get_site_summary(self):
     """Test getting the site summary"""
     sa = SiteAnalyzer(self.tin_dioxide)
     data = sa.get_site_summary(0)
     self.assertEqual(data['element'], 'Sn4+')
     self.assertEqual(data['geometry']['type'], 'octahedral')
     self.assertAlmostEqual(data['geometry']['likeness'],
                            0.9349776258427136)
     self.assertEqual(len(data['nn']), 6)
     self.assertEqual(len(data['nnn']['corner']), 8)
     self.assertEqual(len(data['nnn']['edge']), 2)
     self.assertEqual(data['poly_formula'], 'O6')
     self.assertEqual(data['sym_labels'], (1, ))
Example #9
0
    def test_get_next_nearest_neighbors(self):
        """Check getting next nearest neighbors."""
        sa = SiteAnalyzer(self.tin_dioxide)
        info = sa.get_next_nearest_neighbors(5)

        self.assertEqual(len(info), 14)
        self.assertEqual(info[0]["element"], "O2-")
        self.assertEqual(info[0]["connectivity"], "edge")
        self.assertEqual(info[0]["geometry"]["type"], "trigonal planar")
        self.assertEqual(info[0]["inequiv_index"], 2)

        info = sa.get_next_nearest_neighbors(0,
                                             inc_inequivalent_site_index=False)
        self.assertTrue('inequiv_index' not in info[0])

        info = sa.get_next_nearest_neighbors(0)
        self.assertEqual(info[0]["element"], 'Sn4+')
        self.assertEqual(info[0]["connectivity"], "edge")
        self.assertEqual(info[0]["geometry"]["type"], "octahedral")
        self.assertEqual(len(info[0]['angles']), 2)
        self.assertAlmostEqual(info[0]['angles'][0], 101.62287790513848)

        # check different structure without oxi state
        sa = SiteAnalyzer(self.ba_n)
        info = sa.get_next_nearest_neighbors(0)
        self.assertEqual(len(info), 36)
        self.assertEqual(info[5]["element"], "N")
        self.assertEqual(info[5]["connectivity"], "edge")
        self.assertEqual(info[5]["geometry"]["type"], "6-coordinate")
        self.assertEqual(len(info[5]['angles']), 2)
        self.assertAlmostEqual(info[5]['angles'][0], 83.91397867959587)
Example #10
0
    def test_get_next_nearest_neighbors(self):
        """Check getting next nearest neighbors."""
        sa = SiteAnalyzer(self.tin_dioxide)
        info = sa.get_next_nearest_neighbors(5)

        self.assertEqual(len(info), 14)
        idx = [i for i, s in enumerate(info) if s["connectivity"] == "edge"][0]
        self.assertEqual(info[idx]["element"], "O2-")
        self.assertEqual(info[idx]["connectivity"], "edge")
        self.assertEqual(info[idx]["geometry"]["type"], "trigonal planar")
        self.assertEqual(info[idx]["inequiv_index"], 2)

        info = sa.get_next_nearest_neighbors(0, inc_inequivalent_site_index=False)
        self.assertTrue("inequiv_index" not in info[0])

        info = sa.get_next_nearest_neighbors(0)
        self.assertEqual(info[0]["element"], "Sn4+")
        self.assertEqual(info[0]["connectivity"], "edge")
        self.assertEqual(info[0]["geometry"]["type"], "octahedral")
        self.assertEqual(len(info[0]["angles"]), 2)
        self.assertAlmostEqual(info[0]["angles"][0], 101.62287790513848)
        self.assertAlmostEqual(info[0]["distance"], 3.24322132)

        # check different structure without oxi state
        sa = SiteAnalyzer(self.ba_n)
        info = sa.get_next_nearest_neighbors(0)
        self.assertEqual(len(info), 36)
        self.assertEqual(info[5]["element"], "N")
        self.assertEqual(info[5]["connectivity"], "edge")
        self.assertEqual(info[5]["geometry"]["type"], "6-coordinate")
        self.assertEqual(len(info[5]["angles"]), 2)
        self.assertAlmostEqual(info[5]["angles"][0], 83.91397867959587)
        self.assertAlmostEqual(info[5]["distance"], 3.549136232944574)
Example #11
0
    def test_nnn_summaries_match(self):
        """Test nearest neighbour summary matching function."""
        sa = SiteAnalyzer(self.ba_n, use_symmetry_equivalent_sites=True)
        nnn_a = sa.get_next_nearest_neighbors(0)
        nnn_b = sa.get_next_nearest_neighbors(3)
        nnn_c = sa.get_next_nearest_neighbors(4)

        self.assertTrue(nnn_summaries_match(nnn_a, nnn_b))
        self.assertFalse(nnn_summaries_match(nnn_a, nnn_c))

        # test not matching bond angles
        self.assertTrue(
            nnn_summaries_match(nnn_a,
                                nnn_b,
                                bond_angle_tol=1e-10,
                                match_bond_angles=False))
Example #12
0
    def test_get_inequivalent_site_indices(self):
        sa = SiteAnalyzer(self.ba_n, use_symmetry_equivalent_sites=False)
        inequiv_indices = sa.get_inequivalent_site_indices(list(range(6)))
        self.assertEqual(inequiv_indices, [0, 0, 0, 0, 4, 4])

        # test using symmetry to determine inequivalent sites.
        sa = SiteAnalyzer(self.ba_n, use_symmetry_equivalent_sites=True)
        inequiv_indices = sa.get_inequivalent_site_indices(list(range(6)))
        self.assertEqual(inequiv_indices, [0, 0, 0, 0, 4, 4])

        # test symprec option
        sa = SiteAnalyzer(self.ba_n,
                          use_symmetry_equivalent_sites=True,
                          symprec=0.000001)
        inequiv_indices = sa.get_inequivalent_site_indices(list(range(6)))
        self.assertEqual(inequiv_indices, [0, 1, 1, 0, 4, 4])
Example #13
0
    def test_get_site_geometry(self):
        """Test site geometry description."""
        sa = SiteAnalyzer(self.tin_dioxide)
        geom_data = sa.get_site_geometry(0)
        self.assertEqual(geom_data['type'], "octahedral")
        self.assertAlmostEqual(geom_data['likeness'], 0.9349776258427136)

        geom_data = sa.get_site_geometry(4)
        self.assertEqual(geom_data['type'], "trigonal planar")
        self.assertAlmostEqual(geom_data['likeness'], 0.6050243049545359)

        # check different structure

        sa = SiteAnalyzer(self.ba_n)
        geom_data = sa.get_site_geometry(0)
        self.assertEqual(geom_data['type'], "6-coordinate")
        self.assertAlmostEqual(geom_data['likeness'], 1)
Example #14
0
    def test_get_nearest_neighbors(self):
        """Check getting nearest neighbors."""
        sa = SiteAnalyzer(self.tin_dioxide)
        info = sa.get_nearest_neighbors(4)

        self.assertEqual(len(info), 3)
        self.assertEqual(info[0]["element"], "Sn4+")
        self.assertEqual(info[0]["inequiv_index"], 0)
        self.assertAlmostEqual(info[0]["dist"], 2.0922101061490546)

        info = sa.get_nearest_neighbors(0, inc_inequivalent_site_index=False)
        self.assertTrue('inequiv_index' not in info[0])

        # check different structure without oxi state
        sa = SiteAnalyzer(self.ba_n)
        info = sa.get_nearest_neighbors(0)
        self.assertEqual(len(info), 6)
        self.assertEqual(info[0]["element"], "N")
        self.assertEqual(info[0]["inequiv_index"], 0)
        self.assertAlmostEqual(info[0]["dist"], 1.2619877178483)
Example #15
0
 def test_symmetry_labels(self):
     """Check equivalent sites instance variable set correctly."""
     sa = SiteAnalyzer(self.ba_n, use_symmetry_equivalent_sites=False)
     self.assertEqual(sa.symmetry_labels, [1, 1, 1, 1, 1, 1])
Example #16
0
 def test_get_all_connectivity_angle_summaries(self):
     sa = SiteAnalyzer(self.tin_dioxide)
     data = sa.get_all_connectivity_angle_summaries()
     self.assertEqual(len(data[0][0]['corner']), 8)
     self.assertEqual(len(data[0][0]['edge']), 4)
     self.assertAlmostEqual(data[0][0]['edge'][0], 101.62287790513848)
Example #17
0
 def test_get_all_bond_distance_summaries(self):
     sa = SiteAnalyzer(self.tin_dioxide)
     data = sa.get_all_bond_distance_summaries()
     self.assertEqual(len(data[0][2]), 6)
     self.assertEqual(len(data[2][0]), 3)
     self.assertAlmostEqual(data[0][2][0], 2.0922101061490546)
    def condense_structure(self, structure: Structure) -> Dict[str, Any]:
        """Condenses the structure into an intermediate dict representation.

        Args:
            structure: A pymatgen structure object.

        Returns:
            The condensed structure information. The data is formatted as a
            :obj:`dict` with a fixed set of keys. An up-to-date example of the,
            the condensed representation of MoS2 given in the documentation.
            See: ``robocrystallographer/docs_rst/source/format.rst`` or
            https://hackingmaterials.lbl.gov/robocrystallographer/format.html
        """
        # sort so we can give proper symmetry labels
        structure = structure.get_sorted_structure()

        # wrap all site coords into unit cell
        structure.translate_sites(range(structure.num_sites), [1, 1, 1])

        sga = SpacegroupAnalyzer(structure, symprec=self.symprec)
        if self.use_conventional_cell:
            structure = sga.get_conventional_standard_structure()
        else:
            structure = sga.get_symmetrized_structure()

        bonded_structure = self.near_neighbors.get_bonded_structure(structure)

        components = get_structure_components(
            bonded_structure,
            inc_orientation=True,
            inc_site_ids=True,
            inc_molecule_graph=True,
        )

        dimensionality = max(c["dimensionality"] for c in components)
        mineral = self._condense_mineral(structure, components)
        formula = self._condense_formula(structure, components)

        structure_data = {
            "formula": formula,
            "spg_symbol": sga.get_space_group_symbol(),
            "crystal_system": sga.get_crystal_system(),
            "mineral": mineral,
            "dimensionality": dimensionality,
        }

        site_analyzer = SiteAnalyzer(
            bonded_structure,
            symprec=self.symprec,
            use_symmetry_equivalent_sites=self.use_symmetry_equivalent_sites,
        )
        structure_data["sites"] = site_analyzer.get_all_site_summaries()
        structure_data[
            "distances"] = site_analyzer.get_all_bond_distance_summaries()
        structure_data[
            "angles"] = site_analyzer.get_all_connectivity_angle_summaries()
        structure_data[
            "nnn_distances"] = site_analyzer.get_all_nnn_distance_summaries()

        component_summary, component_makeup = self._condense_components(
            components, sga, site_analyzer)
        structure_data["components"] = component_summary
        structure_data["component_makeup"] = component_makeup

        if components_are_vdw_heterostructure(components):
            hs_info = get_vdw_heterostructure_information(
                components,
                use_iupac_formula=self.use_iupac_formula,
                use_common_formulas=self.use_common_formulas,
            )
        else:
            hs_info = None

        structure_data["vdw_heterostructure_info"] = hs_info

        return structure_data
    def _condense_components(
        self,
        components: List[Component],
        spacegroup_analyzer: SpacegroupAnalyzer,
        site_analyzer: SiteAnalyzer,
    ) -> Tuple[Dict[int, Any], List[int]]:
        """Condenses the component data.

        Args:
            components: A list of structure components, generated using
                :obj:`pymatgen.analysis.dimensionality.get_structure_components`
            site_analyzer: A site analyzer object for the structure containing
                the components.
            spacegroup_analyzer: A space group analyzer object for the structure
                containing the components.

        Returns:
            The condensed component data and the component makeup of the
            structure. The condensed components have the form::

                {
                    0: {
                        'formula': 'MoS2',
                        'sites': [0, 2]
                        'dimensionality': 2,
                        'molecule_name': None,
                        'orientation': (0, 0, 1)
                    }
                }

            Where the ``0`` key is the component identifier. The ``sites``
            key gives a :obj:`list` of the indexes of the inequivalent sites
            in the structure. If the component is zero-dimensional and
            is a known molecule, the ``molecule_name`` key will be a :obj:`str`
            with the molecule name. The ``orientation`` key is the miller
            index (for two-dimensional components) or direction of propagation
            (for one-dimensional components).
        """
        if self.use_symmetry_equivalent_sites:
            inequiv_components = get_sym_inequiv_components(
                components, spacegroup_analyzer)
        else:
            inequiv_components = get_structure_inequiv_components(components)

        molecule_namer = MoleculeNamer()

        components = {}
        component_makeup = []
        for i, component in enumerate(inequiv_components):
            formula = get_component_formula(
                component,
                use_iupac_formula=self.use_iupac_formula,
                use_common_formulas=self.use_common_formulas,
            )

            sites = site_analyzer.get_inequivalent_site_indices(
                component["site_ids"])

            if component["dimensionality"] == 0:
                molecule_name = molecule_namer.get_name_from_molecule_graph(
                    component["molecule_graph"])
            else:
                molecule_name = None

            components[i] = {
                "formula": formula,
                "dimensionality": component["dimensionality"],
                "orientation": component["orientation"],
                "molecule_name": molecule_name,
                "sites": sites,
            }
            component_makeup.extend([i] * component["count"])

        return components, component_makeup
Example #20
0
 def test_get_all_nnn_distance_summaries(self):
     sa = SiteAnalyzer(self.tin_dioxide)
     data = sa.get_all_nnn_distance_summaries()
     self.assertEqual(len(data[0][0]['corner']), 8)
     self.assertEqual(len(data[0][0]['edge']), 2)
     self.assertAlmostEqual(data[0][0]['edge'][0], 3.24322132)