diff --git a/pymatgen/analysis/local_env.py b/pymatgen/analysis/local_env.py index f95ad5a36f4..8196cf52b0a 100644 --- a/pymatgen/analysis/local_env.py +++ b/pymatgen/analysis/local_env.py @@ -68,7 +68,7 @@ class ValenceIonicRadiusEvaluator: def __init__(self, structure: Structure) -> None: """ Args: - structure: pymatgen.core.structure.Structure. + structure: pymatgen Structure. """ self._structure = structure.copy() self._valences = self._get_valences() diff --git a/pymatgen/analysis/structure_analyzer.py b/pymatgen/analysis/structure_analyzer.py index d918f35a989..82ef3812ca7 100644 --- a/pymatgen/analysis/structure_analyzer.py +++ b/pymatgen/analysis/structure_analyzer.py @@ -518,8 +518,7 @@ def sulfide_type(structure): Returns: (str) sulfide/polysulfide or None if structure is a sulfate. """ - structure = structure.copy() - structure.remove_oxidation_states() + structure = structure.copy().remove_oxidation_states() sulphur = Element("S") comp = structure.composition if comp.is_element or sulphur not in comp: diff --git a/pymatgen/command_line/gulp_caller.py b/pymatgen/command_line/gulp_caller.py index cda6871e71f..634b45a5f86 100644 --- a/pymatgen/command_line/gulp_caller.py +++ b/pymatgen/command_line/gulp_caller.py @@ -317,7 +317,7 @@ def specie_potential_lines(structure, potential, **kwargs): structure. Args: - structure: pymatgen.core.structure.Structure object + structure: pymatgen Structure object potential: String specifying the type of potential used kwargs: Additional parameters related to potential. For potential == "buckingham", @@ -375,7 +375,7 @@ def buckingham_input(self, structure: Structure, keywords, library=None, uc=True from library. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure keywords: GULP first line keywords. library (Default=None): File containing the species and potential. uc (Default=True): Unit Cell Flag. @@ -401,7 +401,7 @@ def buckingham_potential(structure, val_dict=None): J. Mater Chem., 4, 831-837 (1994) Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure val_dict (Needed if structure is not charge neutral): {El:valence} dict, where El is element. """ @@ -462,7 +462,7 @@ def tersoff_input(self, structure: Structure, periodic=False, uc=True, *keywords """Gets a GULP input with Tersoff potential for an oxide structure. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure periodic (Default=False): Flag denoting whether periodic boundary conditions are used library (Default=None): File containing the species and potential. @@ -487,7 +487,7 @@ def tersoff_potential(structure): """Generate the species, Tersoff potential lines for an oxide structure. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure """ bv = BVAnalyzer() el = [site.specie.symbol for site in structure] @@ -702,7 +702,7 @@ def get_energy_tersoff(structure, gulp_cmd="gulp"): """Compute the energy of a structure using Tersoff potential. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure gulp_cmd: GULP command if not in standard place """ gio = GulpIO() @@ -716,7 +716,7 @@ def get_energy_buckingham(structure, gulp_cmd="gulp", keywords=("optimise", "con """Compute the energy of a structure using Buckingham potential. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure gulp_cmd: GULP command if not in standard place keywords: GULP first line keywords valence_dict: {El: valence}. Needed if the structure is not charge @@ -733,7 +733,7 @@ def get_energy_relax_structure_buckingham(structure, gulp_cmd="gulp", keywords=( """Relax a structure and compute the energy using Buckingham potential. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure gulp_cmd: GULP command if not in standard place keywords: GULP first line keywords valence_dict: {El: valence}. Needed if the structure is not charge diff --git a/pymatgen/core/interface.py b/pymatgen/core/interface.py index 4377d6981eb..ff53ca2eb37 100644 --- a/pymatgen/core/interface.py +++ b/pymatgen/core/interface.py @@ -19,7 +19,7 @@ class Interface(Structure): """This class stores data for defining an interface between two structures. - It is a subclass of pymatgen.core.structure.Structure. + It is a subclass of pymatgen Structure. """ def __init__( diff --git a/pymatgen/core/structure.py b/pymatgen/core/structure.py index 86656dc012d..6b16571772f 100644 --- a/pymatgen/core/structure.py +++ b/pymatgen/core/structure.py @@ -578,7 +578,7 @@ def add_oxidation_state_by_site(self, oxidation_states: list[float]) -> None: new_sp[Species(sym, ox)] = occu site.species = Composition(new_sp) - def remove_oxidation_states(self) -> None: + def remove_oxidation_states(self) -> SiteCollection: """Removes oxidation states from a structure.""" for site in self: new_sp: dict[Element, float] = collections.defaultdict(float) @@ -587,7 +587,9 @@ def remove_oxidation_states(self) -> None: new_sp[Element(sym)] += occu site.species = Composition(new_sp) - def add_oxidation_state_by_guess(self, **kwargs) -> None: + return self + + def add_oxidation_state_by_guess(self, **kwargs) -> SiteCollection: """Decorates the structure with oxidation state, guessing using Composition.oxi_state_guesses(). If multiple guesses are found we take the first one. @@ -599,7 +601,9 @@ def add_oxidation_state_by_guess(self, **kwargs) -> None: oxi_guess = oxi_guess or [{e.symbol: 0 for e in self.composition}] self.add_oxidation_state_by_element(oxi_guess[0]) - def add_spin_by_element(self, spins: dict[str, float]) -> None: + return self + + def add_spin_by_element(self, spins: dict[str, float]) -> SiteCollection: """Add spin states to structure. Args: @@ -615,7 +619,9 @@ def add_spin_by_element(self, spins: dict[str, float]) -> None: new_species[species] = occu site.species = Composition(new_species) - def add_spin_by_site(self, spins: Sequence[float]) -> None: + return self + + def add_spin_by_site(self, spins: Sequence[float]) -> SiteCollection: """Add spin states to structure by site. Args: @@ -632,7 +638,9 @@ def add_spin_by_site(self, spins: Sequence[float]) -> None: new_species[Species(sym, oxidation_state=oxi_state, spin=spin)] = occu site.species = Composition(new_species) - def remove_spin(self) -> None: + return self + + def remove_spin(self) -> SiteCollection: """Remove spin states from structure.""" for site in self: new_sp: dict[Element, float] = collections.defaultdict(float) @@ -641,6 +649,8 @@ def remove_spin(self) -> None: new_sp[Species(sp.symbol, oxidation_state=oxi_state)] += occu site.species = Composition(new_sp) + return self + def extract_cluster(self, target_sites: list[Site], **kwargs) -> list[Site]: """Extracts a cluster of atoms based on bond lengths. diff --git a/pymatgen/ext/cod.py b/pymatgen/ext/cod.py index ac8684afabe..9e4d55a31e3 100644 --- a/pymatgen/ext/cod.py +++ b/pymatgen/ext/cod.py @@ -52,8 +52,8 @@ def query(self, sql: str) -> str: Returns: Response from SQL query. """ - r = subprocess.check_output(["mysql", "-u", "cod_reader", "-h", self.url, "-e", sql, "cod"]) - return r.decode("utf-8") + resp = subprocess.check_output(["mysql", "-u", "cod_reader", "-h", self.url, "-e", sql, "cod"]) + return resp.decode("utf-8") @requires(which("mysql"), "mysql must be installed to use this query.") def get_cod_ids(self, formula): @@ -84,8 +84,7 @@ def get_structure_by_id(self, cod_id, **kwargs): Args: cod_id (int): COD id. - kwargs: All kwargs supported by - :func:`pymatgen.core.structure.Structure.from_str`. + kwargs: All kwargs supported by Structure.from_str. Returns: A Structure. @@ -100,8 +99,7 @@ def get_structure_by_formula(self, formula: str, **kwargs) -> list[dict[str, str Args: formula (str): Chemical formula. - kwargs: All kwargs supported by - :func:`pymatgen.core.structure.Structure.from_str`. + kwargs: All kwargs supported by Structure.from_str. Returns: A list of dict of the format [{"structure": Structure, "cod_id": int, "sg": "P n m a"}] diff --git a/pymatgen/io/ase.py b/pymatgen/io/ase.py index e1e32348344..4516ee04542 100644 --- a/pymatgen/io/ase.py +++ b/pymatgen/io/ase.py @@ -183,7 +183,7 @@ def get_structure(atoms: Atoms, cls: type[Structure] = Structure, **cls_kwargs) **cls_kwargs: Any additional kwargs to pass to the cls Returns: - Equivalent pymatgen.core.structure.Structure + Structure: Equivalent pymatgen Structure """ symbols = atoms.get_chemical_symbols() positions = atoms.get_positions() diff --git a/pymatgen/io/cp2k/utils.py b/pymatgen/io/cp2k/utils.py index e12710e55f3..2d90630fdc3 100644 --- a/pymatgen/io/cp2k/utils.py +++ b/pymatgen/io/cp2k/utils.py @@ -120,7 +120,7 @@ def atoi(t): return [atoi(c) for c in re.split(r"_(\d+)", text)] -def get_unique_site_indices(structure: Structure | Molecule): +def get_unique_site_indices(struct: Structure | Molecule): """ Get unique site indices for a structure according to site properties. Whatever site-property has the most unique values is used for indexing. @@ -147,31 +147,27 @@ def get_unique_site_indices(structure: Structure | Molecule): "aux_basis", } - for site in structure: + for site in struct: for sp in site.species: oxi_states.append(getattr(sp, "oxi_state", 0)) spins.append(getattr(sp, "_properties", {}).get("spin", 0)) - structure.add_site_property("oxi_state", oxi_states) - structure.add_site_property("spin", spins) - structure.remove_oxidation_states() + struct.add_site_property("oxi_state", oxi_states) + struct.add_site_property("spin", spins) + struct.remove_oxidation_states() items = [ ( site.species_string, - *[ - structure.site_properties[k][i] - for k in structure.site_properties - if k.lower() in parsable_site_properties - ], + *[struct.site_properties[k][i] for k in struct.site_properties if k.lower() in parsable_site_properties], ) - for i, site in enumerate(structure) + for i, site in enumerate(struct) ] unique_itms = list(set(items)) _sites: dict[tuple, list] = {u: [] for u in unique_itms} for i, itm in enumerate(items): _sites[itm].append(i) sites = {} - nums = {s: 1 for s in structure.symbol_set} + nums = {s: 1 for s in struct.symbol_set} for s in _sites: sites[f"{s[0]}_{nums[s[0]]}"] = _sites[s] nums[s[0]] += 1 diff --git a/pymatgen/io/jarvis.py b/pymatgen/io/jarvis.py index 0330452a428..2ace4819445 100644 --- a/pymatgen/io/jarvis.py +++ b/pymatgen/io/jarvis.py @@ -22,7 +22,7 @@ def get_atoms(structure): Returns JARVIS Atoms object from pymatgen structure. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure Returns: JARVIS Atoms object @@ -49,7 +49,7 @@ def get_structure(atoms): atoms: JARVIS Atoms object Returns: - Equivalent pymatgen.core.structure.Structure + Equivalent pymatgen Structure """ return Structure( lattice=atoms.lattice_mat, species=atoms.elements, coords=atoms.frac_coords, coords_are_cartesian=False diff --git a/pymatgen/io/zeopp.py b/pymatgen/io/zeopp.py index 0d69c17a036..ddc2543e2e4 100644 --- a/pymatgen/io/zeopp.py +++ b/pymatgen/io/zeopp.py @@ -219,7 +219,7 @@ def get_voronoi_nodes(structure, rad_dict=None, probe_rad=0.1): Calls Zeo++ for Voronoi decomposition. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure rad_dict (optional): Dictionary of radii of elements in structure. If not given, Zeo++ default values are used. Note: Zeo++ uses atomic radii of elements. @@ -228,10 +228,9 @@ def get_voronoi_nodes(structure, rad_dict=None, probe_rad=0.1): 0.1 A Returns: - voronoi nodes as pymatgen.core.structure.Structure within the - unit cell defined by the lattice of input structure - voronoi face centers as pymatgen.core.structure.Structure within the - unit cell defined by the lattice of input structure + voronoi nodes as pymatgen Structure within the unit cell defined by the lattice of + input structure voronoi face centers as pymatgen Structure within the unit cell + defined by the lattice of input structure """ with ScratchDir("."): name = "temp_zeo1" @@ -306,7 +305,7 @@ def get_high_accuracy_voronoi_nodes(structure, rad_dict, probe_rad=0.1): Calls Zeo++ for Voronoi decomposition. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure rad_dict (optional): Dictionary of radii of elements in structure. If not given, Zeo++ default values are used. Note: Zeo++ uses atomic radii of elements. @@ -315,9 +314,9 @@ def get_high_accuracy_voronoi_nodes(structure, rad_dict, probe_rad=0.1): Default is 0.1 A Returns: - voronoi nodes as pymatgen.core.structure.Structure within the + voronoi nodes as pymatgen Structure within the unit cell defined by the lattice of input structure - voronoi face centers as pymatgen.core.structure.Structure within the + voronoi face centers as pymatgen Structure within the unit cell defined by the lattice of input structure """ with ScratchDir("."): @@ -368,7 +367,7 @@ def get_free_sphere_params(structure, rad_dict=None, probe_rad=0.1): Calls Zeo++ for Voronoi decomposition. Args: - structure: pymatgen.core.structure.Structure + structure: pymatgen Structure rad_dict (optional): Dictionary of radii of elements in structure. If not given, Zeo++ default values are used. Note: Zeo++ uses atomic radii of elements. @@ -377,9 +376,9 @@ def get_free_sphere_params(structure, rad_dict=None, probe_rad=0.1): 0.1 A Returns: - voronoi nodes as pymatgen.core.structure.Structure within the + voronoi nodes as pymatgen Structure within the unit cell defined by the lattice of input structure - voronoi face centers as pymatgen.core.structure.Structure within the + voronoi face centers as pymatgen Structure within the unit cell defined by the lattice of input structure """ with ScratchDir("."): diff --git a/pymatgen/symmetry/analyzer.py b/pymatgen/symmetry/analyzer.py index ddf3a3ce425..59e7947827d 100644 --- a/pymatgen/symmetry/analyzer.py +++ b/pymatgen/symmetry/analyzer.py @@ -56,7 +56,7 @@ def _get_symmetry_dataset(cell, symprec, angle_tolerance): class SpacegroupAnalyzer: - """Takes a pymatgen.core.structure.Structure object and a symprec. + """Takes a pymatgen Structure object and a symprec. Uses spglib to perform various symmetry finding operations. """ diff --git a/pymatgen/transformations/standard_transformations.py b/pymatgen/transformations/standard_transformations.py index 9be374a5e97..060ac67aeef 100644 --- a/pymatgen/transformations/standard_transformations.py +++ b/pymatgen/transformations/standard_transformations.py @@ -181,9 +181,7 @@ def apply_transformation(self, structure): Returns: Non-oxidation state decorated Structure. """ - struct = structure.copy() - struct.remove_oxidation_states() - return struct + return structure.copy().remove_oxidation_states() @property def inverse(self): @@ -611,7 +609,7 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool | num_atoms = sum(structure.composition.values()) for output in ewald_m.output_lists: - s_copy = struct.copy() + struct_copy = struct.copy() # do deletions afterwards because they screw up the indices of the # structure del_indices = [] @@ -619,17 +617,17 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool | if manipulation[1] is None: del_indices.append(manipulation[0]) else: - s_copy[manipulation[0]] = manipulation[1] - s_copy.remove_sites(del_indices) + struct_copy[manipulation[0]] = manipulation[1] + struct_copy.remove_sites(del_indices) if self.no_oxi_states: - s_copy.remove_oxidation_states() + struct_copy.remove_oxidation_states() self._all_structures.append( { "energy": output[0], "energy_above_minimum": (output[0] - lowest_energy) / num_atoms, - "structure": s_copy.get_sorted_structure(), + "structure": struct_copy.get_sorted_structure(), } ) diff --git a/tests/analysis/test_local_env.py b/tests/analysis/test_local_env.py index 8660bcc682a..9665d1908ea 100644 --- a/tests/analysis/test_local_env.py +++ b/tests/analysis/test_local_env.py @@ -1226,10 +1226,9 @@ def test_weighted_cn_no_oxid(self): 3.3897, 3.2589, 3.1207, 3.1924, 3.1915, 3.1207, 3.2598, 3.3897, ] # fmt: on - s = self.lifepo4.copy() - s.remove_oxidation_states() - for idx in range(len(s)): - cn_array.append(cnn.get_cn(s, idx, use_weights=True)) + struct = self.lifepo4.copy().remove_oxidation_states() + for idx in range(len(struct)): + cn_array.append(cnn.get_cn(struct, idx, use_weights=True)) assert_allclose(expected_array, cn_array, 2) diff --git a/tests/core/test_structure.py b/tests/core/test_structure.py index 864cf460992..6acbcf6591a 100644 --- a/tests/core/test_structure.py +++ b/tests/core/test_structure.py @@ -1099,14 +1099,16 @@ def test_remove_oxidation_states(self): o_specie = Species("O", -2) coords = [[0, 0, 0], [0.75, 0.5, 0.75]] lattice = Lattice.cubic(10) - s_elem = Structure(lattice, [co_elem, o_elem], coords) - s_specie = Structure(lattice, [co_specie, o_specie], coords) - s_specie.remove_oxidation_states() - assert s_elem == s_specie, "Oxidation state remover failed" + struct_elem = Structure(lattice, [co_elem, o_elem], coords) + struct_specie = Structure(lattice, [co_specie, o_specie], coords) + struct_out = struct_specie.remove_oxidation_states() + assert struct_out is struct_specie + assert struct_elem == struct_specie, "Oxidation state remover failed" def test_add_oxidation_states_by_guess(self): struct = PymatgenTest.get_structure("Li2O") - struct.add_oxidation_state_by_guess() + struct_with_oxi = struct.add_oxidation_state_by_guess() + assert struct_with_oxi is struct expected = [Species("Li", 1), Species("O", -2)] for site in struct: assert site.specie in expected @@ -1118,17 +1120,21 @@ def test_add_remove_spin_states(self): nio = Structure.from_spacegroup(225, latt, species, coords) # should do nothing, but not fail - nio.remove_spin() + nio1 = nio.remove_spin() + assert nio1 is nio spins = {"Ni": 5} - nio.add_spin_by_element(spins) + nio2 = nio.add_spin_by_element(spins) + assert nio2 is nio assert nio[0].specie.spin == 5, "Failed to add spin states" - nio.remove_spin() + nio3 = nio.remove_spin() + assert nio3 is nio assert nio[0].specie.spin is None spins = [5, -5, -5, 5, 0, 0, 0, 0] # AFM on (001) - nio.add_spin_by_site(spins) + nio4 = nio.add_spin_by_site(spins) + assert nio4 is nio assert nio[1].specie.spin == -5, "Failed to add spin states" def test_apply_operation(self): diff --git a/tests/transformations/test_advanced_transformations.py b/tests/transformations/test_advanced_transformations.py index a878ecc621c..b76b3fd4a6a 100644 --- a/tests/transformations/test_advanced_transformations.py +++ b/tests/transformations/test_advanced_transformations.py @@ -294,8 +294,7 @@ def setUp(self): trans = AutoOxiStateDecorationTransformation() self.Fe3O4_oxi = trans.apply_transformation(self.Fe3O4) - self.Li8Fe2NiCoO8 = Structure.from_file(f"{TEST_FILES_DIR}/Li8Fe2NiCoO8.cif") - self.Li8Fe2NiCoO8.remove_oxidation_states() + self.Li8Fe2NiCoO8 = Structure.from_file(f"{TEST_FILES_DIR}/Li8Fe2NiCoO8.cif").remove_oxidation_states() def test_apply_transformation(self): trans = MagOrderingTransformation({"Fe": 5})