diff --git a/pymatgen/analysis/chemenv/connectivity/connected_components.py b/pymatgen/analysis/chemenv/connectivity/connected_components.py index d3b929c4632..f993e008935 100644 --- a/pymatgen/analysis/chemenv/connectivity/connected_components.py +++ b/pymatgen/analysis/chemenv/connectivity/connected_components.py @@ -751,7 +751,7 @@ def elastic_centered_graph(self, start_node=None): ) logging.debug( f" Delta image from node {str(node)} to neighbor {str(node_neighbor)} : " - f"({', '.join([str(iii) for iii in myddelta])})" + f"({', '.join(map(str, myddelta))})" ) # Loop on the edges of this neighbor for n1, n2, key, edata in node_neighbor_edges: @@ -905,13 +905,14 @@ def from_graph(cls, g): def description(self, full=False): """ Args: - full (): + full (bool): Whether to return a short or full description. Returns: + str: A description of the connected component. """ out = ["Connected component with environment nodes :"] if not full: - out.extend([str(en) for en in sorted(self.graph.nodes())]) + out.extend(map(str, sorted(self.graph.nodes()))) return "\n".join(out) for en in sorted(self.graph.nodes()): out.append(f"{en}, connected to :") diff --git a/pymatgen/analysis/diffraction/core.py b/pymatgen/analysis/diffraction/core.py index 3f4a43b0ac1..2fe48d72d32 100644 --- a/pymatgen/analysis/diffraction/core.py +++ b/pymatgen/analysis/diffraction/core.py @@ -119,7 +119,7 @@ def get_plot( for two_theta, i, hkls in zip(xrd.x, xrd.y, xrd.hkls): if two_theta_range[0] <= two_theta <= two_theta_range[1]: hkl_tuples = [hkl["hkl"] for hkl in hkls] - label = ", ".join([str(hkl_tuple) for hkl_tuple in hkl_tuples]) # 'full' label + label = ", ".join(map(str, hkl_tuples)) # 'full' label ax.plot([two_theta, two_theta], [0, i], color="k", linewidth=3, label=label) if annotate_peaks == "full": @@ -131,7 +131,7 @@ def get_plot( ) elif annotate_peaks == "compact": if all(all(i < 10 for i in hkl_tuple) for hkl_tuple in hkl_tuples): - label = ",".join(["".join([str(i) for i in hkl_tuple]) for hkl_tuple in hkl_tuples]) + label = ",".join(["".join(map(str, hkl_tuple)) for hkl_tuple in hkl_tuples]) # 'compact' label. Would be unclear for indices >= 10 # It would have more than 3 figures, e.g. 1031 @@ -222,7 +222,6 @@ def get_unique_families(hkls): Returns: {hkl: multiplicity}: A dict with unique hkl and multiplicity. """ - # TODO: Definitely can be sped up. def is_perm(hkl1, hkl2): h1 = np.abs(hkl1) diff --git a/pymatgen/analysis/structure_analyzer.py b/pymatgen/analysis/structure_analyzer.py index ea1f635104d..170eb8b5f6d 100644 --- a/pymatgen/analysis/structure_analyzer.py +++ b/pymatgen/analysis/structure_analyzer.py @@ -274,11 +274,11 @@ def connectivity_array(self): Provides connectivity array. Returns: - connectivity: An array of shape [atomi, atomj, imagej]. atomi is + connectivity: An array of shape [atom_i, atom_j, image_j]. atom_i is the index of the atom in the input structure. Since the second atom can be outside of the unit cell, it must be described by both an atom index and an image index. Array data is the - solid angle of polygon between atomi and imagej of atomj + solid angle of polygon between atom_i and image_j of atom_j """ # shape = [site, axis] cart_coords = np.array(self.s.cart_coords) @@ -290,24 +290,24 @@ def connectivity_array(self): connectivity = np.zeros(cs) vts = np.array(vt.vertices) for (ki, kj), v in vt.ridge_dict.items(): - atomi = ki // n_images - atomj = kj // n_images + atom_i = ki // n_images + atom_j = kj // n_images - imagei = ki % n_images - imagej = kj % n_images + image_i = ki % n_images + image_j = kj % n_images - if imagei != n_images // 2 and imagej != n_images // 2: + if image_i != n_images // 2 and image_j != n_images // 2: continue - if imagei == n_images // 2: - # atomi is in original cell + if image_i == n_images // 2: + # atom_i is in original cell val = solid_angle(vt.points[ki], vts[v]) - connectivity[atomi, atomj, imagej] = val + connectivity[atom_i, atom_j, image_j] = val - if imagej == n_images // 2: - # atomj is in original cell + if image_j == n_images // 2: + # atom_j is in original cell val = solid_angle(vt.points[kj], vts[v]) - connectivity[atomj, atomi, imagei] = val + connectivity[atom_j, atom_i, image_i] = val if -10.101 in vts[v]: warn("Found connectivity with infinite vertex. Cutoff is too low, and results may be incorrect") @@ -327,10 +327,10 @@ def get_connections(self): with their real-space distances. """ con = [] - maxconn = self.max_connectivity - for ii in range(0, maxconn.shape[0]): - for jj in range(0, maxconn.shape[1]): - if maxconn[ii][jj] != 0: + max_conn = self.max_connectivity + for ii in range(0, max_conn.shape[0]): + for jj in range(0, max_conn.shape[1]): + if max_conn[ii][jj] != 0: dist = self.s.get_distance(ii, jj) con.append([ii, jj, dist]) return con @@ -383,7 +383,7 @@ def get_max_bond_lengths(structure, el_radius_updates=None): Args: structure: (structure) - el_radius_updates: (dict) symbol->float to update atomic radii + el_radius_updates: (dict) symbol->float to update atom_ic radii Returns: (dict) - (Element1, Element2) -> float. The two elements are ordered by Z. @@ -488,9 +488,9 @@ def parse_oxide(self) -> tuple[str, int]: is_superoxide = False is_ozonide = True try: - nbonds = len(set(bond_atoms)) + n_bonds = len(set(bond_atoms)) except UnboundLocalError: - nbonds = 0 + n_bonds = 0 if is_ozonide: str_oxide = "ozonide" elif is_superoxide: @@ -500,8 +500,8 @@ def parse_oxide(self) -> tuple[str, int]: else: str_oxide = "oxide" if str_oxide == "oxide": - nbonds = int(comp["O"]) - return str_oxide, nbonds + n_bonds = int(comp["O"]) + return str_oxide, n_bonds def oxide_type( diff --git a/pymatgen/core/trajectory.py b/pymatgen/core/trajectory.py index 8d9d6422cbc..2c176cc8908 100644 --- a/pymatgen/core/trajectory.py +++ b/pymatgen/core/trajectory.py @@ -364,7 +364,7 @@ def write_Xdatcar( syms = [site.specie.symbol for site in self[0]] site_symbols = [a[0] for a in itertools.groupby(syms)] syms = [site.specie.symbol for site in self[0]] - natoms = [len(tuple(a[1])) for a in itertools.groupby(syms)] + n_atoms = [len(tuple(a[1])) for a in itertools.groupby(syms)] for si, frac_coords in enumerate(self.frac_coords): # Only print out the info block if @@ -377,10 +377,10 @@ def write_Xdatcar( _lattice = self.lattice[si] for latt_vec in _lattice: - lines.append(f'{" ".join([str(el) for el in latt_vec])}') + lines.append(f'{" ".join(map(str, latt_vec))}') lines.append(" ".join(site_symbols)) - lines.append(" ".join([str(x) for x in natoms])) + lines.append(" ".join(map(str, n_atoms))) lines.append(f"Direct configuration= {si + 1}") diff --git a/pymatgen/entries/compatibility.py b/pymatgen/entries/compatibility.py index 0bed2f8a0ca..878e70b2080 100644 --- a/pymatgen/entries/compatibility.py +++ b/pymatgen/entries/compatibility.py @@ -818,14 +818,21 @@ def __init__( @cached_class class MaterialsProject2020Compatibility(Compatibility): """ - This class implements the Materials Project 2020 energy correction scheme, - which incorporates uncertainty quantification and allows for mixing of GGA - and GGA+U entries (see References). + This class implements the Materials Project 2020 energy correction scheme, which + incorporates uncertainty quantification and allows for mixing of GGA and GGA+U entries + (see References). Note that this scheme should only be applied to VASP calculations that use the - Materials Project input set parameters (see pymatgen.io.vasp.sets.MPRelaxSet). - Using this compatibility scheme on calculations with different parameters is not - valid. + Materials Project input set parameters (see pymatgen.io.vasp.sets.MPRelaxSet). Using + this compatibility scheme on calculations with different parameters is not valid. + + Note: While the correction scheme is largely composition-based, the energy corrections + applied to ComputedEntry and ComputedStructureEntry can differ for O and S-containing + structures if entry.data['oxidation_states'] is not populated or explicitly set. This + occurs because pymatgen will use atomic distances to classify O and S anions as + superoxide/peroxide/oxide and sulfide/polysulfide, resp. when oxidation states are not + provided. If you want the most accurate corrections possible, supply pre-defined + oxidation states to entry.data or pass ComputedStructureEntry. """ def __init__( diff --git a/pymatgen/io/vasp/inputs.py b/pymatgen/io/vasp/inputs.py index 797d2802f08..475c25b73c6 100644 --- a/pymatgen/io/vasp/inputs.py +++ b/pymatgen/io/vasp/inputs.py @@ -483,7 +483,7 @@ def get_string(self, direct: bool = True, vasp4_compatible: bool = False, signif if self.true_names and not vasp4_compatible: lines.append(" ".join(self.site_symbols)) - lines.append(" ".join([str(x) for x in self.natoms])) + lines.append(" ".join(map(str, self.natoms))) if self.selective_dynamics: lines.append("Selective dynamics") lines.append("direct" if direct else "cartesian") @@ -721,7 +721,7 @@ def get_string(self, sort_keys: bool = False, pretty: bool = False) -> str: lines.append([k, " ".join(value)]) elif isinstance(self[k], list): - lines.append([k, " ".join([str(i) for i in self[k]])]) + lines.append([k, " ".join(map(str, self[k]))]) else: lines.append([k, self[k]]) @@ -1512,17 +1512,17 @@ def __str__(self): style = self.style.name.lower()[0] if style == "l": lines.append(self.coord_type) - for i in range(len(self.kpts)): - lines.append(" ".join([str(x) for x in self.kpts[i]])) + for idx, kpt in enumerate(self.kpts): + lines.append(" ".join(map(str, kpt))) if style == "l": - lines[-1] += " ! " + self.labels[i] - if i % 2 == 1: + lines[-1] += " ! " + self.labels[idx] + if idx % 2 == 1: lines[-1] += "\n" elif self.num_kpts > 0: if self.labels is not None: - lines[-1] += f" {int(self.kpts_weights[i])} {self.labels[i]}" + lines[-1] += f" {int(self.kpts_weights[idx])} {self.labels[idx]}" else: - lines[-1] += f" {int(self.kpts_weights[i])}" + lines[-1] += f" {int(self.kpts_weights[idx])}" # Print tetrahedron parameters if the number of tetrahedrons > 0 if style not in "lagm" and self.tet_number > 0: @@ -1534,7 +1534,7 @@ def __str__(self): # Print shifts for automatic kpoints types if not zero. if self.num_kpts <= 0 and tuple(self.kpts_shift) != (0, 0, 0): - lines.append(" ".join([str(x) for x in self.kpts_shift])) + lines.append(" ".join(map(str, self.kpts_shift))) return "\n".join(lines) + "\n" def as_dict(self): diff --git a/pymatgen/symmetry/tests/test_maggroups.py b/pymatgen/symmetry/tests/test_maggroups.py index 0fa77ef0941..66264929a0b 100644 --- a/pymatgen/symmetry/tests/test_maggroups.py +++ b/pymatgen/symmetry/tests/test_maggroups.py @@ -75,7 +75,7 @@ def test_is_compatible(self): def test_symmetry_ops(self): - msg_1_symmops = "\n".join([str(op) for op in self.msg_1.symmetry_ops]) + msg_1_symmops = "\n".join(map(str, self.msg_1.symmetry_ops)) msg_1_symmops_ref = """x, y, z, +1 -x+3/4, -y+3/4, z, +1 -x, -y, -z, +1 @@ -110,7 +110,7 @@ def test_symmetry_ops(self): x+3/4, -y+1/2, z+1/4, -1""" self.assertStrContentEqual(msg_1_symmops, msg_1_symmops_ref) - msg_2_symmops = "\n".join([str(op) for op in self.msg_2.symmetry_ops]) + msg_2_symmops = "\n".join(map(str, self.msg_2.symmetry_ops)) msg_2_symmops_ref = """x, y, z, +1 -x, y+1/2, -z, +1 -x, -y, -z, +1 @@ -121,7 +121,7 @@ def test_symmetry_ops(self): x+1/2, y, -z+1/2, -1""" self.assertStrContentEqual(msg_2_symmops, msg_2_symmops_ref) - msg_3_symmops = "\n".join([str(op) for op in self.msg_3.symmetry_ops]) + msg_3_symmops = "\n".join(map(str, self.msg_3.symmetry_ops)) msg_3_symmops_ref = """x, y, z, +1 x, -y, -z, +1 -x, y, -z+1/2, +1 @@ -140,7 +140,7 @@ def test_symmetry_ops(self): -x, -y+1/2, z, -1""" assert msg_3_symmops == msg_3_symmops_ref - msg_4_symmops = "\n".join([str(op) for op in self.msg_4.symmetry_ops]) + msg_4_symmops = "\n".join(map(str, self.msg_4.symmetry_ops)) msg_4_symmops_ref = """x, y, z, +1 -x, -y, -z, +1 x+1/2, y, z, -1