Skip to content

Commit

Permalink
pyright fixes for `ext/io/phonon/symmetry/transformations/util/vis/…
Browse files Browse the repository at this point in the history
…dev_scripts` and improve `io.lobster` (#3757)

* Add a CI run that only tests non-optional deps (optimistically)

- Hopefully all tests have been written in such a way that they will be
  skipped if the underlying required package is not found

* Install dev deps at least

* Try out pyright config for unbound vars only

* Add pyright to CI

* pyright fix

* pyright fix in vis.structure_vtk

* fix `utils`

* fix `transformations`

* fix `symmetry.kpath`

* finish fixing `symmetry`

* update `pyright`

* suppress `pyright` reportMissingModuleSource warning

* fix `phonon`

* some fixes in `io`

* format tweaks of `io.vasp.outputs`

* fix unit test for `symmetry.kpath`

* fix io.vasp

* fix unit test for io.vasp.inputs

* fix io.qchem

* fix io.pwscf, need input

* replace `match.group(i)` with `match[i]`

* fix missing )

* fix typo

* suppress `reportInvalidTypeForm`

* fix io.nwchem and packmol

* fix io.lobster.inputs and use snake_case

* fix lobsterenv

* fix io.icet

* fix io.lammps

* revert to try/except for speed

* set default coords_are_cartesian for pwscf

* fix io.gaussian

* fix io.fiesta

* fix io.cif

* fix io.babel

* fix io.ase

* fix io.cif tests

* fix io.feff

* fix io.exciting

* fix io.abinit

* fix io.cp2k

* fix io.lobster.outputs

* take some (not all) code rabbit suggestion

* fix ext

* fix dev_scripts

* fix logic error

* simplify checking

* remove some weird constructions in lobster io

* pre-commit auto-fixes

* resolve code rabbit suggestions

* fix more new key issues

* fix new_key problems with code simplification

* make same logic for del

* remove unnecessary `int` before `math.floor/ceil`

* Fix lower vs other

* tweak error type in io.lobster

* fix error type in lobster test

* fix nested if

* pre-commit auto-fixes

* remove DEBUG tag

* comment out pyright until all chunks finished

* replace runtime error with value error

* use walrus op for if match := re.match(...)

* remove unused pyright code until ready to enable

* rename single-letter m->match

* remove unused raw

---------

Signed-off-by: Matthew Evans <7916000+ml-evs@users.noreply.github.com>
Co-authored-by: Matthew Evans <git@ml-evs.science>
Co-authored-by: Matthew Evans <7916000+ml-evs@users.noreply.github.com>
Co-authored-by: JaGeo <janine.george@bam.de>
Co-authored-by: Janosh Riebesell <janosh.riebesell@gmail.com>
  • Loading branch information
5 people authored Apr 15, 2024
1 parent 37d1066 commit 0e57abf
Show file tree
Hide file tree
Showing 59 changed files with 866 additions and 892 deletions.
8 changes: 6 additions & 2 deletions dev_scripts/chemenv/equivalent_indices.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@
# 0. any point
for i0 in range(8):
# 1. point opposite to point 0. in the square face
if i0 in [0, 2]:
if i0 in {0, 2}:
i1 = i0 + 1
elif i0 in [1, 3]:
elif i0 in {1, 3}:
i1 = i0 - 1
elif i0 == 4:
i1 = 7
Expand All @@ -111,10 +111,14 @@
i1 = 5
elif i0 == 7:
i1 = 4
else:
raise RuntimeError("Cannot determine point.")

# 2. one of the two last points in the square face
sfleft = list(sf1) if i0 in sf1 else list(sf2)
sfleft.remove(i0)
sfleft.remove(i1)
i2 = 0
for i2 in sfleft:
sfleft2 = list(sfleft)
sfleft2.remove(i2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,18 @@ def get_structure(self, morphing_factor):

coords = copy.deepcopy(self.abstract_geometry.points_wcs_ctwcc())
bare_points = self.abstract_geometry.bare_points_with_centre
origin = None

for morphing in self.morphing_description:
if morphing["site_type"] == "neighbor":
i_site = morphing["ineighbor"] + 1
if morphing["expansion_origin"] == "central_site":
origin = bare_points[0]
vector = bare_points[i_site] - origin
coords[i_site] += vector * (morphing_factor - 1.0)
else:
if morphing["site_type"] != "neighbor":
raise ValueError(f"Key \"site_type\" is {morphing['site_type']} while it can only be neighbor")

i_site = morphing["ineighbor"] + 1
if morphing["expansion_origin"] == "central_site":
origin = bare_points[0]
vector = bare_points[i_site] - origin
coords[i_site] += vector * (morphing_factor - 1.0)

return Structure(lattice=lattice, species=species, coords=coords, coords_are_cartesian=True)

def estimate_parameters(self, dist_factor_min, dist_factor_max, symmetry_measure_type="csm_wcs_ctwcc"):
Expand Down Expand Up @@ -269,7 +270,7 @@ def get_weights(self, weights_options):
"+-------------------------------------------------------------+\n"
)

with open("ce_pairs.json") as file:
with open("ce_pairs.json", encoding="utf-8") as file:
ce_pairs = json.load(file)
self_weight_max_csms: dict[str, list[float]] = {}
self_weight_max_csms_per_cn: dict[str, list[float]] = {}
Expand Down
1 change: 1 addition & 0 deletions dev_scripts/chemenv/view_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
print()
# Visualize the separation plane of a given algorithm
sep_plane = False
algo = None
if any(algo.algorithm_type == SEPARATION_PLANE for algo in cg.algorithms):
test = input("Enter index of the algorithm for which you want to visualize the plane : ")
if test != "":
Expand Down
5 changes: 4 additions & 1 deletion dev_scripts/update_pt_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,10 @@ def parse_shannon_radii():
from openpyxl import load_workbook

wb = load_workbook("Shannon Radii.xlsx")
print(wb.get_sheet_names())
print(wb.sheetnames())
sheet = wb["Sheet1"]
i = 2
el = charge = cn = None
radii = collections.defaultdict(dict)
while sheet[f"E{i}"].value:
if sheet[f"A{i}"].value:
Expand Down Expand Up @@ -235,6 +236,7 @@ def add_electron_affinities():

req = requests.get("https://wikipedia.org/wiki/Electron_affinity_(data_page)")
soup = BeautifulSoup(req.text, "html.parser")
table = None
for table in soup.find_all("table"):
if "Hydrogen" in table.text:
break
Expand Down Expand Up @@ -271,6 +273,7 @@ def add_ionization_energies():

with open("NIST Atomic Ionization Energies Output.html") as file:
soup = BeautifulSoup(file.read(), "html.parser")
table = None
for table in soup.find_all("table"):
if "Hydrogen" in table.text:
break
Expand Down
3 changes: 1 addition & 2 deletions pymatgen/analysis/ewald.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,7 @@ def _calc_recip(self):

for g, g2, gr, exp_val, s_real, s_imag in zip(gs, g2s, grs, exp_vals, s_reals, s_imags):
# Uses the identity sin(x)+cos(x) = 2**0.5 sin(x + pi/4)
m = (gr[None, :] + pi / 4) - gr[:, None]
np.sin(m, m)
m = np.sin((gr[None, :] + pi / 4) - gr[:, None])
m *= exp_val / g2

e_recip += m
Expand Down
8 changes: 4 additions & 4 deletions pymatgen/analysis/local_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -4164,10 +4164,10 @@ def _get_radius(site):
return el.ionic_radii[oxi]

# e.g., oxi = 2.667, average together 2+ and 3+ radii
if int(math.floor(oxi)) in el.ionic_radii and int(math.ceil(oxi)) in el.ionic_radii:
oxi_low = el.ionic_radii[int(math.floor(oxi))]
oxi_high = el.ionic_radii[int(math.ceil(oxi))]
x = oxi - int(math.floor(oxi))
if math.floor(oxi) in el.ionic_radii and math.ceil(oxi) in el.ionic_radii:
oxi_low = el.ionic_radii[math.floor(oxi)]
oxi_high = el.ionic_radii[math.ceil(oxi)]
x = oxi - math.floor(oxi)
return (1 - x) * oxi_low + x * oxi_high

if oxi > 0 and el.average_cationic_radius > 0:
Expand Down
4 changes: 2 additions & 2 deletions pymatgen/command_line/enumlib_caller.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def get_sg_info(ss):
# enumeration. See Cu7Te5.cif test file.
base *= 10

# base = n_disordered # 10 ** int(math.ceil(math.log10(n_disordered)))
# base = n_disordered # 10 ** math.ceil(math.log10(n_disordered))
# To get a reasonable number of structures, we fix concentrations to the
# range expected in the original structure.
total_amounts = sum(index_amounts)
Expand All @@ -266,7 +266,7 @@ def get_sg_info(ss):
if abs(conc * base - round(conc * base)) < 1e-5:
output.append(f"{int(round(conc * base))} {int(round(conc * base))} {base}")
else:
min_conc = int(math.floor(conc * base))
min_conc = math.floor(conc * base)
output.append(f"{min_conc - 1} {min_conc + 1} {base}")
output.append("")
logger.debug("Generated input file:\n" + "\n".join(output))
Expand Down
54 changes: 26 additions & 28 deletions pymatgen/command_line/vampire_caller.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ def __init__(
stdout = stdout.decode()

if stderr:
vanhelsing = stderr.decode()
if len(vanhelsing) > 27: # Suppress blank warning msg
logging.warning(vanhelsing)
van_helsing = stderr.decode()
if len(van_helsing) > 27: # Suppress blank warning msg
logging.warning(van_helsing)

if process.returncode != 0:
raise RuntimeError(f"Vampire exited with return code {process.returncode}.")
Expand All @@ -146,9 +146,9 @@ def __init__(
self._stderr = stderr

# Process output
nmats = max(self.mat_id_dict.values())
parsed_out, critical_temp = VampireCaller.parse_stdout("output", nmats)
self.output = VampireOutput(parsed_out, nmats, critical_temp)
n_mats = max(self.mat_id_dict.values())
parsed_out, critical_temp = VampireCaller.parse_stdout("output", n_mats)
self.output = VampireOutput(parsed_out, n_mats, critical_temp)

def _create_mat(self):
structure = self.structure
Expand All @@ -158,43 +158,41 @@ def _create_mat(self):
# Maps sites to material id for vampire inputs
mat_id_dict = {}

nmats = 0
n_mats = 0
for key in self.unique_site_ids:
spin_up, spin_down = False, False
nmats += 1 # at least 1 mat for each unique site
n_mats += 1 # at least 1 mat for each unique site

# Check which spin sublattices exist for this site id
for site in key:
m = magmoms[site]
if m > 0:
if magmoms[site] > 0:
spin_up = True
if m < 0:
if magmoms[site] < 0:
spin_down = True

# Assign material id for each site
for site in key:
m = magmoms[site]
if spin_up and not spin_down:
mat_id_dict[site] = nmats
mat_id_dict[site] = n_mats
if spin_down and not spin_up:
mat_id_dict[site] = nmats
mat_id_dict[site] = n_mats
if spin_up and spin_down:
# Check if spin up or down shows up first
m0 = magmoms[key[0]]
if m > 0 and m0 > 0:
mat_id_dict[site] = nmats
if m < 0 and m0 < 0:
mat_id_dict[site] = nmats
if m > 0 > m0:
mat_id_dict[site] = nmats + 1
if m < 0 < m0:
mat_id_dict[site] = nmats + 1
if magmoms[site] > 0 and m0 > 0:
mat_id_dict[site] = n_mats
if magmoms[site] < 0 and m0 < 0:
mat_id_dict[site] = n_mats
if magmoms[site] > 0 > m0:
mat_id_dict[site] = n_mats + 1
if magmoms[site] < 0 < m0:
mat_id_dict[site] = n_mats + 1

# Increment index if two sublattices
if spin_up and spin_down:
nmats += 1
n_mats += 1

mat_file = [f"material:num-materials={nmats}"]
mat_file = [f"material:num-materials={n_mats}"]

for key in self.unique_site_ids:
i = self.unique_site_ids[key] # unique site id
Expand Down Expand Up @@ -230,7 +228,7 @@ def _create_mat(self):

def _create_input(self):
structure = self.structure
mcbs = self.mc_box_size
mc_box_size = self.mc_box_size
equil_timesteps = self.equil_timesteps
mc_timesteps = self.mc_timesteps
mat_name = self.mat_name
Expand All @@ -255,9 +253,9 @@ def _create_input(self):

# System size in nm
input_script += [
f"dimensions:system-size-x = {mcbs:.1f} !nm",
f"dimensions:system-size-y = {mcbs:.1f} !nm",
f"dimensions:system-size-z = {mcbs:.1f} !nm",
f"dimensions:system-size-x = {mc_box_size:.1f} !nm",
f"dimensions:system-size-y = {mc_box_size:.1f} !nm",
f"dimensions:system-size-z = {mc_box_size:.1f} !nm",
]

# Critical temperature Monte Carlo calculation
Expand Down
19 changes: 8 additions & 11 deletions pymatgen/core/ion.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,12 @@ def from_formula(cls, formula: str) -> Self:
Ion
"""
charge = 0.0
f = formula
# strip (aq), if present
m = re.search(r"\(aq\)", f)
if m:
f = f.replace(m.group(), "", 1)
if match := re.search(r"\(aq\)", formula):
formula = formula.replace(match.group(), "", 1)
# check for charge in brackets
m = re.search(r"\[([^\[\]]+)\]", f)
if m:
m_chg = re.search(r"([\.\d]*)([+-]*)([\.\d]*)", m.group(1))
if match := re.search(r"\[([^\[\]]+)\]", formula):
m_chg = re.search(r"([\.\d]*)([+-]*)([\.\d]*)", match.group(1))
if m_chg:
if m_chg.group(1) != "":
if m_chg.group(3) != "":
Expand All @@ -65,18 +62,18 @@ def from_formula(cls, formula: str) -> Self:
for i in re.findall("[+-]", m_chg.group(2)):
charge += float(i + "1")

f = f.replace(m.group(), "", 1)
formula = formula.replace(match.group(), "", 1)

# if no brackets, parse trailing +/-
for m_chg in re.finditer(r"([+-])([\.\d]*)", f):
for m_chg in re.finditer(r"([+-])([\.\d]*)", formula):
sign = m_chg.group(1)
sgn = float(str(sign + "1"))
if m_chg.group(2).strip() != "":
charge += float(m_chg.group(2)) * sgn
else:
charge += sgn
f = f.replace(m_chg.group(), "", 1)
composition = Composition(f)
formula = formula.replace(m_chg.group(), "", 1)
composition = Composition(formula)
return cls(composition, charge)

@property
Expand Down
37 changes: 18 additions & 19 deletions pymatgen/core/periodic_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,15 @@ def __getattr__(self, item: str) -> Any:
except ValueError:
# Ignore error. val will just remain a string.
pass
if item in ("refractive_index", "melting_point") and isinstance(val, str):
# Final attempt to parse a float.
m = re.findall(r"[\.\d]+", val)
if m:
warnings.warn(
f"Ambiguous values ({val}) for {item} of {self.symbol}. Returning first float value."
)
return float(m[0])
if (
item in ("refractive_index", "melting_point")
and isinstance(val, str)
and (match := re.findall(r"[\.\d]+", val))
):
warnings.warn(
f"Ambiguous values ({val}) for {item} of {self.symbol}. Returning first float value."
)
return float(match[0])
return val
raise AttributeError(f"Element has no attribute {item}!")

Expand Down Expand Up @@ -385,9 +386,8 @@ def full_electronic_structure(self) -> list[tuple[int, str, int]]:
e_str = self.electronic_structure

def parse_orbital(orb_str):
m = re.match(r"(\d+)([spdfg]+)(\d+)", orb_str)
if m:
return int(m.group(1)), m.group(2), int(m.group(3))
if match := re.match(r"(\d+)([spdfg]+)(\d+)", orb_str):
return int(match.group(1)), match.group(2), int(match.group(3))
return orb_str

data = [parse_orbital(s) for s in e_str.split(".")]
Expand Down Expand Up @@ -1382,17 +1382,16 @@ def from_str(cls, species_string: str) -> Self:
Raises:
ValueError if species_string cannot be interpreted.
"""
m = re.search(r"([A-ZAa-z]*)([0-9.]*)([+\-]*)(.*)", species_string)
if m:
sym = m.group(1)
if m.group(2) == m.group(3) == "":
if match := re.search(r"([A-ZAa-z]*)([0-9.]*)([+\-]*)(.*)", species_string):
sym = match.group(1)
if match.group(2) == match.group(3) == "":
oxi = 0.0
else:
oxi = 1.0 if m.group(2) == "" else float(m.group(2))
oxi = -oxi if m.group(3) == "-" else oxi
oxi = 1.0 if match.group(2) == "" else float(match.group(2))
oxi = -oxi if match.group(3) == "-" else oxi
properties = {}
if m.group(4): # has Spin property
tokens = m.group(4).split("=")
if match.group(4): # has Spin property
tokens = match.group(4).split("=")
properties = {tokens[0]: float(tokens[1])}
return cls(sym, oxi, **properties)
raise ValueError("Invalid DummySpecies String")
Expand Down
4 changes: 2 additions & 2 deletions pymatgen/electronic_structure/boltztrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def write_energy(self, output_file) -> None:
# use 90% of bottom bands since highest eigenvalues
# are usually incorrect
# ask Geoffroy Hautier for more details
nb_bands = int(math.floor(self._bs.nb_bands * (1 - self.cb_cut)))
nb_bands = math.floor(self._bs.nb_bands * (1 - self.cb_cut))
for j in range(nb_bands):
eigs.append(
Energy(
Expand Down Expand Up @@ -384,7 +384,7 @@ def write_proj(self, output_file_proj: str, output_file_def: str) -> None:
file.write(str(len(self._bs.kpoints)) + "\n")
for i, kpt in enumerate(self._bs.kpoints):
tmp_proj = []
for j in range(int(math.floor(self._bs.nb_bands * (1 - self.cb_cut)))):
for j in range(math.floor(self._bs.nb_bands * (1 - self.cb_cut))):
tmp_proj.append(self._bs.projections[Spin(self.spin)][j][i][oi][site_nb])
# TODO deal with the sorting going on at
# the energy level!!!
Expand Down
Loading

0 comments on commit 0e57abf

Please sign in to comment.