diff --git a/docs/source/conf.py b/docs/source/conf.py index 20a984c2..239f8847 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -18,8 +18,9 @@ # -- Project information ----------------------------------------------------- -project = "Lobsterpy" -copyright = "2022, Janine George" + +project = "LobsterPy" +copyright = "2022-2023, LobsterPy Development Team" author = "Janine George" @@ -49,6 +50,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. + exclude_patterns = ["../../lobsterpy/test", "../../lobsterpy/cohp/test", "../../lobsterpy/plotting/test", @@ -57,6 +59,7 @@ ".DS_Store", ] + def run_apidoc(_): import subprocess import glob diff --git a/examples/NaCl_comp_range/CHARGE.lobster.gz b/examples/NaCl_comp_range/CHARGE.lobster.gz new file mode 100644 index 00000000..add94b72 Binary files /dev/null and b/examples/NaCl_comp_range/CHARGE.lobster.gz differ diff --git a/examples/NaCl_comp_range/COHPCAR.lobster.gz b/examples/NaCl_comp_range/COHPCAR.lobster.gz new file mode 100644 index 00000000..6a344de2 Binary files /dev/null and b/examples/NaCl_comp_range/COHPCAR.lobster.gz differ diff --git a/examples/NaCl_comp_range/ICOBILIST.lobster.gz b/examples/NaCl_comp_range/ICOBILIST.lobster.gz new file mode 100644 index 00000000..76c121a6 Binary files /dev/null and b/examples/NaCl_comp_range/ICOBILIST.lobster.gz differ diff --git a/examples/NaCl_comp_range/ICOHPLIST.lobster.gz b/examples/NaCl_comp_range/ICOHPLIST.lobster.gz new file mode 100644 index 00000000..9c3ad86a Binary files /dev/null and b/examples/NaCl_comp_range/ICOHPLIST.lobster.gz differ diff --git a/examples/NaCl_comp_range/ICOOPLIST.lobster.gz b/examples/NaCl_comp_range/ICOOPLIST.lobster.gz new file mode 100644 index 00000000..74ba259b Binary files /dev/null and b/examples/NaCl_comp_range/ICOOPLIST.lobster.gz differ diff --git a/examples/NaCl_comp_range/MadelungEnergies.lobster.gz b/examples/NaCl_comp_range/MadelungEnergies.lobster.gz new file mode 100644 index 00000000..24eab851 Binary files /dev/null and b/examples/NaCl_comp_range/MadelungEnergies.lobster.gz differ diff --git a/examples/NaCl_comp_range/POSCAR.gz b/examples/NaCl_comp_range/POSCAR.gz new file mode 100644 index 00000000..1f8eed38 Binary files /dev/null and b/examples/NaCl_comp_range/POSCAR.gz differ diff --git a/examples/example_script_NaCl_Structure_graph.py b/examples/example_script_NaCl_Structure_graph.py new file mode 100644 index 00000000..45f79039 --- /dev/null +++ b/examples/example_script_NaCl_Structure_graph.py @@ -0,0 +1,15 @@ +from lobsterpy.structuregraph.graph import LobsterGraph + +graph_NaCl_all = LobsterGraph( + path_to_poscar="./NaCl_comp_range/POSCAR.gz", + path_to_charge="./NaCl_comp_range/CHARGE.lobster.gz", + path_to_cohpcar="./NaCl_comp_range/COHPCAR.lobster.gz", + path_to_icohplist="./NaCl_comp_range/ICOHPLIST.lobster.gz", + add_additional_data_sg=True, + path_to_icooplist="./NaCl_comp_range/ICOOPLIST.lobster.gz", + path_to_icobilist="./NaCl_comp_range/ICOBILIST.lobster.gz", + path_to_madelung="./NaCl_comp_range/MadelungEnergies.lobster.gz", + which_bonds="all", + start=None, + ) +print(graph_NaCl_all.sg) \ No newline at end of file diff --git a/lobsterpy/TestData/CdF_comp_range/ICOBILIST.lobster.gz b/lobsterpy/TestData/CdF_comp_range/ICOBILIST.lobster.gz old mode 100755 new mode 100644 index a868053b..b023806d Binary files a/lobsterpy/TestData/CdF_comp_range/ICOBILIST.lobster.gz and b/lobsterpy/TestData/CdF_comp_range/ICOBILIST.lobster.gz differ diff --git a/lobsterpy/TestData/CdF_comp_range/ICOOPLIST.lobster.gz b/lobsterpy/TestData/CdF_comp_range/ICOOPLIST.lobster.gz old mode 100755 new mode 100644 index 29a4245d..ffdcef11 Binary files a/lobsterpy/TestData/CdF_comp_range/ICOOPLIST.lobster.gz and b/lobsterpy/TestData/CdF_comp_range/ICOOPLIST.lobster.gz differ diff --git a/lobsterpy/TestData/CdF_comp_range/MadelungEnergies.lobster.gz b/lobsterpy/TestData/CdF_comp_range/MadelungEnergies.lobster.gz new file mode 100644 index 00000000..5828ecae Binary files /dev/null and b/lobsterpy/TestData/CdF_comp_range/MadelungEnergies.lobster.gz differ diff --git a/lobsterpy/TestData/NaCl_comp_range/ICOBILIST.lobster.gz b/lobsterpy/TestData/NaCl_comp_range/ICOBILIST.lobster.gz old mode 100755 new mode 100644 index 5c7c5e49..76c121a6 Binary files a/lobsterpy/TestData/NaCl_comp_range/ICOBILIST.lobster.gz and b/lobsterpy/TestData/NaCl_comp_range/ICOBILIST.lobster.gz differ diff --git a/lobsterpy/TestData/NaCl_comp_range/ICOHPLIST.lobster.gz b/lobsterpy/TestData/NaCl_comp_range/ICOHPLIST.lobster.gz index 1f556b48..9c3ad86a 100755 Binary files a/lobsterpy/TestData/NaCl_comp_range/ICOHPLIST.lobster.gz and b/lobsterpy/TestData/NaCl_comp_range/ICOHPLIST.lobster.gz differ diff --git a/lobsterpy/TestData/NaCl_comp_range/ICOOPLIST.lobster.gz b/lobsterpy/TestData/NaCl_comp_range/ICOOPLIST.lobster.gz old mode 100755 new mode 100644 index 293f736d..74ba259b Binary files a/lobsterpy/TestData/NaCl_comp_range/ICOOPLIST.lobster.gz and b/lobsterpy/TestData/NaCl_comp_range/ICOOPLIST.lobster.gz differ diff --git a/lobsterpy/TestData/NaCl_comp_range/MadelungEnergies.lobster.gz b/lobsterpy/TestData/NaCl_comp_range/MadelungEnergies.lobster.gz new file mode 100644 index 00000000..24eab851 Binary files /dev/null and b/lobsterpy/TestData/NaCl_comp_range/MadelungEnergies.lobster.gz differ diff --git a/lobsterpy/structuregraph/__init__.py b/lobsterpy/structuregraph/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lobsterpy/structuregraph/graph.py b/lobsterpy/structuregraph/graph.py new file mode 100644 index 00000000..3a21343f --- /dev/null +++ b/lobsterpy/structuregraph/graph.py @@ -0,0 +1,178 @@ +# Copyright (c) lobsterpy development team +# Distributed under the terms of a BSD 3-Clause "New" or "Revised" License + +""" +This package provides the modules for generating graph objects using lobsterpy data +""" + +from typing import Optional +from pymatgen.core.structure import Structure +from pymatgen.io.lobster.lobsterenv import LobsterNeighbors +from pymatgen.io.lobster.outputs import Charge +from lobsterpy.cohp.analyze import Analysis + + +class LobsterGraph: + """ + Class to generate structure graph objects with bonding data from Lobster + + Attributes: + sg: return structure_graph object + """ + + def __init__( + self, + path_to_poscar: str, + path_to_charge: str, + path_to_cohpcar: str, + path_to_icohplist: str, + path_to_madelung: str, + add_additional_data_sg=True, + path_to_icooplist: Optional[str] = None, + path_to_icobilist: Optional[str] = None, + which_bonds: str = "all", + cutoff_icohp: float = 0.10, + start: str = None, + ): + """ + This class will return structure graph objects with bonding information from Lobster data. + Mode of automatic bonding analysis can be “cation-anion” or “all” bonds. The strongest bond is + determined based on the ICOHPs. The coordination environments are determined based on + cutoff_icohp *ICOHPs values. If the path of ICOBILIST (ICOOPLIST) is provided, the ICOBI (ICOOP) + values corresponding to relevant bond labels obtained from the ICOHPLIST are also added as edge properties + to the structure graph objects. The Mulliken and Loewdin charges are added as node properties to + the structure graph objects. + + + Args: + path_to_poscar: path to POSCAR (e.g., "POSCAR") + path_to_charge: path to CHARGE.lobster (e.g., "CHARGE.lobster") + path_to_cohpcar: path to COHPCAR.lobster (e.g., "COHPCAR.lobster") + path_to_icohplist: path to ICOHPLIST.lobster (e.g., "ICOHPLIST.lobster") + path_to_icooplist: path to ICOOPLIST.lobster (e.g., "ICOOPLIST.lobster") + path_to_icobilist: path to ICOBILIST.lobster (e.g., "ICOBILIST.lobster") + path_to_madelung: path to MadelungEnergies.lobster (e.g., "MadelungEnergies.lobster") + cutoff_icohp : only bonds that are stronger than cutoff_icohp*strongest ICOHP will be considered + add_additional_data_sg: (bool) if True will add the information from ICOOPLIST.lobster + and ICOBILIST.lobster based on ICOHPLIST.lobster relevant bond + which_bonds: selects which kind of bonds are analyzed. "all" is the default + start: start energy for bonding antibonding percent integration + """ + if add_additional_data_sg: + self.add_additional_data_sg = add_additional_data_sg + if path_to_icooplist is not None and path_to_icobilist is not None: + self.path_to_icooplist = path_to_icooplist + self.path_to_icobilist = path_to_icobilist + else: + raise ValueError( + "add_additional_data_sg is set to True." + "Please provide path_to_icooplist and path_to_icobilist" + ) + else: + self.add_additional_data_sg = add_additional_data_sg + + self.path_to_poscar = path_to_poscar + self.path_to_charge = path_to_charge + self.path_to_cohpcar = path_to_cohpcar + self.path_to_icohplist = path_to_icohplist + self.path_to_madelung = path_to_madelung + self.which_bonds = which_bonds + self.cutoff_icohp = cutoff_icohp + + if self.which_bonds == "all": + self.additional_condition = 0 + elif self.which_bonds == "cation-anion": + self.additional_condition = 1 + else: + raise ValueError( + "Only accepted values are 'all' and 'cation-anion'." + "Please check the input parameters of which_bonds arg" + ) + self.start = start + + self.sg = self.get_decorated_sg() + + def get_decorated_sg(self): + """ + Method to generate graph object decorated with bonding data from lobsterpy + Returns: + structure graph object + """ + if self.add_additional_data_sg: + chemenvlobster = LobsterNeighbors( + are_coops=False, + filename_ICOHP=self.path_to_icohplist, + perc_strength_ICOHP=self.cutoff_icohp, + structure=Structure.from_file(self.path_to_poscar), + additional_condition=self.additional_condition, + filename_CHARGE=self.path_to_charge, + add_additional_data_sg=self.add_additional_data_sg, + filename_blist_sg1=self.path_to_icobilist, + id_blist_sg1="ICOBI", + filename_blist_sg2=self.path_to_icooplist, + id_blist_sg2="ICOOP", + valences_from_charges=True, + adapt_extremum_to_add_cond=True, + ) + + else: + chemenvlobster = LobsterNeighbors( + are_coops=False, + filename_ICOHP=self.path_to_icohplist, + perc_strength_ICOHP=self.cutoff_icohp, + structure=Structure.from_file(self.path_to_poscar), + additional_condition=self.additional_condition, + filename_CHARGE=self.path_to_charge, + add_additional_data_sg=self.add_additional_data_sg, + valences_from_charges=True, + adapt_extremum_to_add_cond=True, + ) + + # Adds Mulliken and Löwdin charges as site properties to structure object (node properties) + decorated_structure = Charge(self.path_to_charge).get_structure_with_charges( + self.path_to_poscar + ) + + # Create the structure graph object decorated with site and edge properties based on ICOHP/ICOBI/ICOOP data + lobster_env = chemenvlobster.get_bonded_structure( + structure=decorated_structure, decorate=True, edge_properties=True + ) + + # Initialize automating bonding analysis from Lobsterpy based on ICOHP + analyze = Analysis( + path_to_charge=self.path_to_charge, + path_to_cohpcar=self.path_to_cohpcar, + path_to_poscar=self.path_to_poscar, + path_to_icohplist=self.path_to_icohplist, + path_to_madelung=self.path_to_madelung, + whichbonds=self.which_bonds, + cutoff_icohp=self.cutoff_icohp, + ) + + # Store the summarized dictionary object containing bonding information + cba = analyze.condensed_bonding_analysis + + # Iterate over sites in the dictionary + for k, v in cba["sites"].items(): + for k2, v2 in lobster_env.graph.nodes.data(): + # Check if ions are same and add its corresponding environment in node properties + if v["ion"] == v2["specie"]: + v2["properties"].update({"env": v["env"]}) + + for ( + edge_prop + ) in lobster_env.graph.edges.data(): # Iterate over structure graph edges + _ab, ab_p, _b, b_p = analyze._integrate_antbdstates_below_efermi( + cohp=analyze.chemenv.completecohp.get_cohp_by_label( + edge_prop[2]["bond_label"] + ), + start=self.start, + ) # Compute bonding- antibonding percentages for each bond in structure graph object + edge_prop[2][ + "ICOHP_bonding_perc" + ] = b_p # Store bonding percentage in edge of graph object + edge_prop[2][ + "ICOHP_antibonding_perc" + ] = ab_p # Store anti-bonding percentage in edge graph object + + return lobster_env diff --git a/lobsterpy/structuregraph/test/__init__.py b/lobsterpy/structuregraph/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lobsterpy/structuregraph/test/test_graph.py b/lobsterpy/structuregraph/test/test_graph.py new file mode 100644 index 00000000..86a8ff73 --- /dev/null +++ b/lobsterpy/structuregraph/test/test_graph.py @@ -0,0 +1,659 @@ +import unittest +from pathlib import Path + +from lobsterpy.structuregraph.graph import LobsterGraph + +CurrentDir = Path(__file__).absolute().parent +TestDir = CurrentDir / "../../" + + +class TestGraph(unittest.TestCase): + def setUp(self): + self.graph_NaCl_all = LobsterGraph( + path_to_poscar=TestDir / "TestData/NaCl_comp_range/POSCAR.gz", + path_to_charge=TestDir / "TestData/NaCl_comp_range/CHARGE.lobster.gz", + path_to_cohpcar=TestDir / "TestData/NaCl_comp_range/COHPCAR.lobster.gz", + path_to_icohplist=TestDir / "TestData/NaCl_comp_range/ICOHPLIST.lobster.gz", + add_additional_data_sg=True, + path_to_icooplist=TestDir / "TestData/NaCl_comp_range/ICOOPLIST.lobster.gz", + path_to_icobilist=TestDir / "TestData/NaCl_comp_range/ICOBILIST.lobster.gz", + path_to_madelung=TestDir + / "TestData/NaCl_comp_range/MadelungEnergies.lobster.gz", + which_bonds="all", + start=None, + ) + + self.graph_NaCl_cation_anion = LobsterGraph( + path_to_poscar=TestDir / "TestData/NaCl_comp_range/POSCAR.gz", + path_to_charge=TestDir / "TestData/NaCl_comp_range/CHARGE.lobster.gz", + path_to_cohpcar=TestDir / "TestData/NaCl_comp_range/COHPCAR.lobster.gz", + path_to_icohplist=TestDir / "TestData/NaCl_comp_range/ICOHPLIST.lobster.gz", + add_additional_data_sg=True, + path_to_icooplist=TestDir / "TestData/NaCl_comp_range/ICOOPLIST.lobster.gz", + path_to_icobilist=TestDir / "TestData/NaCl_comp_range/ICOBILIST.lobster.gz", + path_to_madelung=TestDir + / "TestData/NaCl_comp_range/MadelungEnergies.lobster.gz", + which_bonds="cation-anion", + start=None, + ) + + self.graph_NaCl_without_add_data = LobsterGraph( + path_to_poscar=TestDir / "TestData/NaCl_comp_range/POSCAR.gz", + path_to_charge=TestDir / "TestData/NaCl_comp_range/CHARGE.lobster.gz", + path_to_cohpcar=TestDir / "TestData/NaCl_comp_range/COHPCAR.lobster.gz", + path_to_icohplist=TestDir / "TestData/NaCl_comp_range/ICOHPLIST.lobster.gz", + path_to_madelung=TestDir + / "TestData/NaCl_comp_range/MadelungEnergies.lobster.gz", + add_additional_data_sg=False, + which_bonds="all", + start=None, + ) + + self.graph_NaCl_close_fermi = LobsterGraph( + path_to_poscar=TestDir / "TestData/NaCl_comp_range/POSCAR.gz", + path_to_charge=TestDir / "TestData/NaCl_comp_range/CHARGE.lobster.gz", + path_to_cohpcar=TestDir / "TestData/NaCl_comp_range/COHPCAR.lobster.gz", + path_to_icohplist=TestDir / "TestData/NaCl_comp_range/ICOHPLIST.lobster.gz", + path_to_madelung=TestDir + / "TestData/NaCl_comp_range/MadelungEnergies.lobster.gz", + add_additional_data_sg=False, + which_bonds="all", + start=-4, + ) + + self.graph_CdF_all = LobsterGraph( + path_to_poscar=TestDir / "TestData/CdF_comp_range/POSCAR.gz", + path_to_charge=TestDir / "TestData/CdF_comp_range/CHARGE.lobster.gz", + path_to_cohpcar=TestDir / "TestData/CdF_comp_range/COHPCAR.lobster.gz", + path_to_icohplist=TestDir / "TestData/CdF_comp_range/ICOHPLIST.lobster.gz", + add_additional_data_sg=True, + path_to_icooplist=TestDir / "TestData/CdF_comp_range/ICOOPLIST.lobster.gz", + path_to_icobilist=TestDir / "TestData/CdF_comp_range/ICOBILIST.lobster.gz", + path_to_madelung=TestDir + / "TestData/CdF_comp_range/MadelungEnergies.lobster.gz", + which_bonds="all", + start=None, + ) + + self.graph_CdF_close_fermi = LobsterGraph( + path_to_poscar=TestDir / "TestData/CdF_comp_range/POSCAR.gz", + path_to_charge=TestDir / "TestData/CdF_comp_range/CHARGE.lobster.gz", + path_to_cohpcar=TestDir / "TestData/CdF_comp_range/COHPCAR.lobster.gz", + path_to_icohplist=TestDir / "TestData/CdF_comp_range/ICOHPLIST.lobster.gz", + add_additional_data_sg=True, + path_to_icooplist=TestDir / "TestData/CdF_comp_range/ICOOPLIST.lobster.gz", + path_to_icobilist=TestDir / "TestData/CdF_comp_range/ICOBILIST.lobster.gz", + path_to_madelung=TestDir + / "TestData/CdF_comp_range/MadelungEnergies.lobster.gz", + which_bonds="all", + start=-2, + ) + + def test_graph_NaCl_all(self): + self.assertEqual( + self.graph_NaCl_all.sg.graph.nodes(data=True)[0]["specie"], "Na" + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.nodes(data=True)[0]["coords"].tolist(), + [0.0, 0.0, 0.0], + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.nodes(data=True)[0]["properties"][ + "Mulliken Charges" + ], + 0.78, + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.nodes(data=True)[0]["properties"]["env"], "O:6" + ) + + self.assertEqual( + self.graph_NaCl_all.sg.graph.nodes(data=True)[1]["specie"], "Cl" + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.nodes(data=True)[1]["coords"].tolist(), + [2.845847, 2.845847, 2.845847], + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.nodes(data=True)[1]["properties"][ + "Mulliken Charges" + ], + -0.78, + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.nodes(data=True)[1]["properties"]["env"], "O:6" + ) + + self.assertAlmostEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[0]["ICOHP"], + -0.5661, + delta=0.001, + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[0]["ICOHP_bonding_perc"], + 1, + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_antibonding_perc" + ], + 0, + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[0]["ICOBI"], 0.08484 + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[0]["ICOOP"], 0.02826 + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[0]["bond_label"], "21" + ) + + self.assertAlmostEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[4]["ICOHP"], + -0.5661, + delta=0.001, + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[4]["ICOHP_bonding_perc"], 1 + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[4][ + "ICOHP_antibonding_perc" + ], + 0, + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[4]["ICOBI"], 0.08482 + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[4]["ICOOP"], 0.02824 + ) + self.assertEqual( + self.graph_NaCl_all.sg.graph.get_edge_data(0, 1)[4]["bond_label"], "28" + ) + + def test_graph_NaCl_cation_anion(self): + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.nodes(data=True)[0]["specie"], "Na" + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.nodes(data=True)[0][ + "coords" + ].tolist(), + [0.0, 0.0, 0.0], + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.nodes(data=True)[0]["properties"][ + "Mulliken Charges" + ], + 0.78, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.nodes(data=True)[0]["properties"][ + "env" + ], + "O:6", + ) + + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.nodes(data=True)[1]["specie"], "Cl" + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.nodes(data=True)[1][ + "coords" + ].tolist(), + [2.845847, 2.845847, 2.845847], + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.nodes(data=True)[1]["properties"][ + "Mulliken Charges" + ], + -0.78, + ) + self.assertNotIn( + "env", + self.graph_NaCl_cation_anion.sg.graph.nodes(data=True)[1]["properties"], + ) + + self.assertAlmostEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[0]["ICOHP"], + -0.5661, + delta=0.001, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_bonding_perc" + ], + 1, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_antibonding_perc" + ], + 0, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[0]["ICOBI"], + 0.08484, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[0]["ICOOP"], + 0.02826, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[0]["bond_label"], + "21", + ) + + self.assertAlmostEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[4]["ICOHP"], + -0.56614, + delta=0.001, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[4][ + "ICOHP_bonding_perc" + ], + 1, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[4][ + "ICOHP_antibonding_perc" + ], + 0, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[4]["ICOBI"], + 0.08482, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[4]["ICOOP"], + 0.02824, + ) + self.assertEqual( + self.graph_NaCl_cation_anion.sg.graph.get_edge_data(0, 1)[4]["bond_label"], + "28", + ) + + def test_graph_NaCl_without_add_data(self): + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.nodes(data=True)[0]["specie"], + "Na", + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.nodes(data=True)[0][ + "coords" + ].tolist(), + [0.0, 0.0, 0.0], + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.nodes(data=True)[0]["properties"][ + "Mulliken Charges" + ], + 0.78, + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.nodes(data=True)[0]["properties"][ + "env" + ], + "O:6", + ) + + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.nodes(data=True)[1]["specie"], + "Cl", + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.nodes(data=True)[1][ + "coords" + ].tolist(), + [2.845847, 2.845847, 2.845847], + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.nodes(data=True)[1]["properties"][ + "Mulliken Charges" + ], + -0.78, + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.nodes(data=True)[1]["properties"][ + "env" + ], + "O:6", + ) + + self.assertAlmostEqual( + self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[0]["ICOHP"], + -0.5661, + delta=0.001, + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_bonding_perc" + ], + 1, + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_antibonding_perc" + ], + 0, + ) + self.assertNotIn( + "ICOBI", self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[0] + ) + self.assertNotIn( + "ICOOP", self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[0] + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[0][ + "bond_label" + ], + "21", + ) + + self.assertAlmostEqual( + self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[4]["ICOHP"], + -0.5661, + delta=0.001, + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[4][ + "ICOHP_bonding_perc" + ], + 1, + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[4][ + "ICOHP_antibonding_perc" + ], + 0, + ) + self.assertNotIn( + "ICOBI", self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[4] + ) + self.assertNotIn( + "ICOOP", self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[4] + ) + self.assertEqual( + self.graph_NaCl_without_add_data.sg.graph.get_edge_data(0, 1)[4][ + "bond_label" + ], + "28", + ) + + def test_graph_NaCl_close_fermi(self): + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.nodes(data=True)[0]["specie"], "Na" + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.nodes(data=True)[0]["coords"].tolist(), + [0.0, 0.0, 0.0], + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.nodes(data=True)[0]["properties"][ + "Mulliken Charges" + ], + 0.78, + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.nodes(data=True)[0]["properties"][ + "env" + ], + "O:6", + ) + + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.nodes(data=True)[1]["specie"], "Cl" + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.nodes(data=True)[1]["coords"].tolist(), + [2.845847, 2.845847, 2.845847], + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.nodes(data=True)[1]["properties"][ + "Mulliken Charges" + ], + -0.78, + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.nodes(data=True)[1]["properties"][ + "env" + ], + "O:6", + ) + + self.assertAlmostEqual( + self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[0]["ICOHP"], + -0.5661, + delta=0.001, + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_bonding_perc" + ], + 1, + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_antibonding_perc" + ], + 0, + ) + self.assertNotIn( + "ICOBI", self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[0] + ) + self.assertNotIn( + "ICOOP", self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[0] + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[0]["bond_label"], + "21", + ) + + self.assertAlmostEqual( + self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[4]["ICOHP"], + -0.5661, + delta=0.001, + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[4][ + "ICOHP_bonding_perc" + ], + 1, + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[4][ + "ICOHP_antibonding_perc" + ], + 0, + ) + self.assertNotIn( + "ICOBI", self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[4] + ) + self.assertNotIn( + "ICOOP", self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[4] + ) + self.assertEqual( + self.graph_NaCl_close_fermi.sg.graph.get_edge_data(0, 1)[4]["bond_label"], + "28", + ) + + def test_graph_CdF_all(self): + self.assertEqual( + self.graph_CdF_all.sg.graph.nodes(data=True)[0]["specie"], "Cd" + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.nodes(data=True)[0]["coords"].tolist(), + [0.0, 0.0, 0.0], + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.nodes(data=True)[0]["properties"][ + "Mulliken Charges" + ], + 1.57, + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.nodes(data=True)[0]["properties"]["env"], "C:8" + ) + + self.assertEqual(self.graph_CdF_all.sg.graph.nodes(data=True)[1]["specie"], "F") + self.assertEqual( + self.graph_CdF_all.sg.graph.nodes(data=True)[1]["coords"].tolist(), + [1.37314, 1.37314, 1.37314], + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.nodes(data=True)[1]["properties"][ + "Mulliken Charges" + ], + -0.79, + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.nodes(data=True)[1]["properties"]["env"], "T:4" + ) + + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[0]["ICOHP"], -0.62168 + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[0]["ICOHP_bonding_perc"], + 0.72263, + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_antibonding_perc" + ], + 0.27737, + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[0]["ICOBI"], 0.08932 + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[0]["ICOOP"], 0.0148 + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[0]["bond_label"], "29" + ) + + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[3]["ICOHP"], -0.62168 + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[3]["ICOHP_bonding_perc"], + 0.72263, + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[3][ + "ICOHP_antibonding_perc" + ], + 0.27737, + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[3]["ICOBI"], 0.08932 + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[3]["ICOOP"], 0.0148 + ) + self.assertEqual( + self.graph_CdF_all.sg.graph.get_edge_data(0, 1)[3]["bond_label"], "63" + ) + + def test_graph_CdF_close_fermi(self): + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.nodes(data=True)[0]["specie"], "Cd" + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.nodes(data=True)[0]["coords"].tolist(), + [0.0, 0.0, 0.0], + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.nodes(data=True)[0]["properties"][ + "Mulliken Charges" + ], + 1.57, + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.nodes(data=True)[0]["properties"][ + "env" + ], + "C:8", + ) + + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.nodes(data=True)[1]["specie"], "F" + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.nodes(data=True)[1]["coords"].tolist(), + [1.37314, 1.37314, 1.37314], + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.nodes(data=True)[1]["properties"][ + "Mulliken Charges" + ], + -0.79, + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.nodes(data=True)[1]["properties"][ + "env" + ], + "T:4", + ) + + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[0]["ICOHP"], + -0.62168, + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_bonding_perc" + ], + 0, + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[0][ + "ICOHP_antibonding_perc" + ], + 1, + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[0]["ICOBI"], 0.08932 + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[0]["ICOOP"], 0.0148 + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[0]["bond_label"], + "29", + ) + + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[3]["ICOHP"], + -0.62168, + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[3][ + "ICOHP_bonding_perc" + ], + 0, + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[3][ + "ICOHP_antibonding_perc" + ], + 1, + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[3]["ICOBI"], 0.08932 + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[3]["ICOOP"], 0.0148 + ) + self.assertEqual( + self.graph_CdF_close_fermi.sg.graph.get_edge_data(0, 1)[3]["bond_label"], + "63", + ) + + +if __name__ == "__main__": + unittest.main()