Skip to content

vasppy v1.0#31

Merged
bjmorgan merged 83 commits into
mainfrom
v1.0
Mar 28, 2026
Merged

vasppy v1.0#31
bjmorgan merged 83 commits into
mainfrom
v1.0

Conversation

@bjmorgan

Copy link
Copy Markdown
Owner

Summary

  • Removes the custom Poscar class in favour of pymatgen Structure throughout
  • Migrates all CLI scripts and modules to the new Structure-based API
  • Fixes accumulated bugs: bitwise operator in Band.__eq__, PROCAR k-point regex, KPoint equality, RDF initialisation, file handle leaks, bare except in summary.py
  • Adds type hints, Google-style docstrings, and f-strings across all modules
  • Resolves all 26 mypy strict-mode errors
  • Code quality improvements: cached_property for lazy loading in Vasprun, guard-clause and normalise-then-act patterns in doscar.py, vectorised mask construction in utils.py, module-level compiled regex constants in outcar.py, ClassVar annotations for class-level constants
  • Bumps version to 1.0.0

bjmorgan added 30 commits March 27, 2026 21:26
Design and development docs are local only, not tracked.
- Raise minimum Python version to 3.11
- Remove fortranformat dependency (unused)
- Remove entry points for scripts being deleted
- Align ruff and mypy targets with new minimum version
- Drop Python 3.10 from CI matrix
Delete pimaim.py (dead format), polyhedron.py (unused),
xdatcar.py (no remaining consumers), and associated scripts
(pimaim_to_poscar, pimaim_to_xtl, poscar_to_pimaim,
xdatcar_to_disp, xdatcar_to_poscart, xdatcar_to_rdf).
- Fix bitwise operator precedence bug in read_atomic_dos_as_df
- Fix DataFrame.drop() result not being assigned in read_total_dos
- Replace deprecated delim_whitespace with sep parameter
- Remove no-op bare except clause
- Resolve TODO comments in pdos_select channel indexing
- Handle DOSCAR files without projected DOS data (fixes #14)
Replace & with logical and to avoid operator precedence issues.
- Replace bitwise & with logical and in KPoint.__eq__
- Make k-point regex less strict to handle variant VASP
  output formatting (fixes #11)
Use context managers for all file operations.
- Remove bare except clause (redundant re-raise) in parse_vasprun
- Change potcar_spec() to return paired lists instead of dict,
  correctly handling duplicate species (fixes #15)
- Fix docstring parameter name mismatch (return_hash -> return_hashes)
- Update all callers to work with the new return type
Convert numpy array inputs to lists to avoid ambiguous
truth value errors (fixes #29).
Replace custom Poscar class usage with direct
Structure.from_file() calls.
Use Structure.from_file() for I/O, retain cell.Cell.rotate()
for lattice rotation.
Replace custom Poscar scaling factor access with
pymatgen Structure volume calculation.
Replace custom Poscar replicate, scaling normalisation,
bohr conversion, and output with pymatgen equivalents.
Replace custom Poscar API with pymatgen Structure operations
and cell.py utilities for lattice rotation.
- proc_poscar: simplify coordinate type lookup, use
  itertools.groupby, f-strings, direct property access
- check_species: use dict.fromkeys for unique ordered
  species, f-strings, remove typing import
- poscar_to_xtl: f-strings
Replace all Poscar class usage with pymatgen Structure.
Remove stdout redirection in favour of direct file writing.
Fix spacing not being updated when grid dimensions are read.
All consumers have been migrated to pymatgen Structure.
Add SIGPIPE handler to scripts that produce stdout output.
….py and atom.py

Add a module-level docstring to units.py and annotate the module-level
constants. Rewrite atom.py with Google-style docstring, remove the
redundant Returns section for __init__, and add a module docstring.
…kpoints.py

Add a module-level docstring. Replace the bare `raise ValueError` in
AutoKPoints.__init__ with a descriptive message identifying the
unrecognised grid-centering value.
…odernise docstrings

Replace `assert type(matrix) is np.ndarray` and `assert matrix.shape == (3, 3)`
in Cell.__init__ with isinstance checks and descriptive ValueError raises.
Add a module docstring, Google-style docstrings throughout, modern type hints,
and fix the typo "corredponding" -> "corresponding".
…on.py and vaspmeta.py

Add full type annotations to all functions and __init__ methods.
Convert .format() call to f-string in delta_E. Simplify delta_stoichiometry
return with a dict comprehension. Add module-level docstrings.
Expand Google-style docstrings with Raises sections where appropriate.
…to utils.py

Add type hints to validate_checksum, match_filename, and cd. Convert
.format() calls to f-strings in match_filename and validate_checksum.
Rename the shadowed local variable in validate_checksum to actual_filename.
Add a module-level docstring and docstrings to cd and validate_checksum.
Rename the local dr_ij array to avoid shadowing the function name.
- Add return-type annotations and modernise parameter types on all
  seven public functions (str | float | list[float] | np.ndarray).
- Rewrite all docstrings in Google style with British English.
- Rename recLat variable to rec_lat to follow snake_case convention.
- fermi_energy_from_outcar now raises ValueError when E-fermi line is
  absent rather than silently failing with an AttributeError.
- Add tests for reciprocal_lattice_from_outcar, fermi_energy_from_outcar,
  vasp_version_from_outcar, and coords_from_outcar (14 tests total, all
  passing; covers the four functions that previously had no test coverage).
…strings

- Remove 'from typing import List, Union, Optional, Any, Dict' and replace
  all occurrences with builtin equivalents (list, dict, X | None).
- Fix typo in structures property docstring: "attribut" -> "attribute".
- Rewrite all docstrings in Google style with British English.
- Remove redundant 'Args: None' sections from properties and methods that
  take no arguments.
- Use dict[str, object] for parse_structure return type instead of
  Dict[str, Any].
…d tests

- Add type annotations to all five functions: matrix_eigvals, to_matrix,
  plot_dielectric_functions, parse_dielectric_data, and
  absorption_coefficient.
- Rewrite module docstring and all function docstrings in Google style.
- Add explicit matplotlib type hints (Axes | None, Figure | None) to
  plot_dielectric_functions.
- Expand test suite from 3 to 10 tests, adding coverage for
  absorption_coefficient (4 tests including a numerical regression test)
  and plot_dielectric_functions (3 tests).
- Add return type annotations and parameter type hints to
  handle_occupancy and Band.__init__.
- Add __eq__ type signature with NotImplemented guard for non-Band
  comparisons.
- Replace .format() call with an f-string in handle_occupancy.
- Rewrite all docstrings in Google style with British English.
- Add class-level Attributes docstring to Band.
- Band remains a regular class rather than a frozen dataclass because
  handle_occupancy can mutate the occupancy field to 0.0.
…tests

- Add missing -> None return type annotation to VanHoveAnalysis.__init__.
- Remove duplicate 'rho' assignment in VanHoveAnalysis.__init__.
- Rewrite all docstrings in Google style with British English.
- Expand test suite from 5 to 19 tests, adding:
  - TestShellVolumes: 4 tests covering single-shell volume, positivity,
    monotonicity, and total volume.
  - smeared_rdf: 2 tests (correct shape, peak broadening).
  - from_species_strings classmethod: 3 tests (missing species errors and
    successful construction).
  - VanHoveAnalysis: 6 tests covering shape, metadata, self/distinct
    accessors with and without Gaussian smearing.
- atom_names and structures now use @cached_property
- Removes _atom_names, _structures sentinels and guard checks
- Update tests to check behaviour (parsed once) not implementation
- summary.py: replace bare raise (ValueError) with informative message
- outcar.py: add bounds checks before [-1] indexing on findall results
- rdf.py: use explicit None checks for weights and indices_j
- rdf.py: set self_reference before overwriting indices_j
- rdf.py: fix from_species_strings spurious raise when species_j not requested
@coveralls

coveralls commented Mar 28, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 75.013% (+31.6%) from 43.4%
when pulling 4df7d15 on v1.0
into a659a25 on main.

mypy now runs once in a dedicated typecheck job rather than
redundantly across the full Python version matrix. pylint is
removed as ruff covers the same checks.
Restrict push trigger to main; pull_request handles all
branch CI, so pushes to feature branches no longer run twice.
np.ma.make_mask has an ambiguous return type in the numpy stubs.
Replace with np.ones(..., dtype=bool) which is clearer in intent
and has a precise return type.
- doscar.py: fix read_total_dos return type (-> None), remove stale
  comments, rename colors parameter to colours
- optics.py: fix swapped xz/yz order in docstrings
- vasprun.py: fix selective_dynamics type in docstring
- procar.py: fix exception type in docstring (AttributeError -> ValueError),
  replace Unicode Angstrom symbol, add KPoint.__eq__ docstring,
  remove commented-out write_file code
- convergence_testing.py: add missing ClassVar annotation
- kpoints.py: standardise docstring format, fix "miniumum" typo
- rdf.py: remove dead self.self_reference attribute
- murnfit.py: narrow except Exception to ET.ParseError and
  FileNotFoundError with warning; remove global warning filter
- summary.py: warn when vasprun.xml cannot be parsed
- outcar.py: raise ValueError when no EATOM values found,
  consistent with other outcar functions
- vasprun.py: add None checks for truncated XML elements

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Release-focused refactor to vasppy v1.0.0 that removes the internal POSCAR/XDATCAR abstractions in favor of pymatgen Structure, migrates CLI/scripts to the new API, and tightens correctness via type hints, docstrings, and expanded tests/CI.

Changes:

  • Replace/retire the custom Poscar-based API across modules and scripts, standardizing on pymatgen Structure.
  • Improve robustness and quality: typed APIs, clearer errors, regex/constants cleanups, and small algorithmic/IO improvements.
  • Expand/modernize test suite and CI (pytest coverage, mypy job, Ruff config), and bump version to 1.0.0.

Reviewed changes

Copilot reviewed 72 out of 73 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
vasppy/xdatcar.py Removes custom XDATCAR parsing implementation.
vasppy/version.py Bumps library version to 1.0.0.
vasppy/vasprun.py Adds typing + cached properties; refactors XML parsing helpers.
vasppy/vaspmeta.py Adds typing/docstrings; simplifies YAML loading into VASPMeta.
vasppy/utils.py Adds typing/docstrings; improves checksum validation and distance masking.
vasppy/units.py Adds module docstring and type annotations for constants.
vasppy/scripts/xdatcar_to_rdf.py Removes deprecated XDATCAR→RDF CLI script.
vasppy/scripts/xdatcar_to_disp.py Removes deprecated XDATCAR displacement CLI script.
vasppy/scripts/vasp_summary.py Docstrings/typing; SIGPIPE handling; small refactors for output/Pool usage.
vasppy/scripts/vasp_grid.py Migrates to Grid.from_file + Structure-based lattice lengths.
vasppy/scripts/spacegroup.py Migrates POSCAR reading to Structure.from_file; improves help text.
vasppy/scripts/rotate_poscar.py Migrates POSCAR reading/writing to pymatgen; rotates via Cell.
vasppy/scripts/r2r2_expansion.py Migrates to pymatgen Structure; refactors expansion logic and output.
vasppy/scripts/proc_poscar.py Reimplements POSCAR manipulation around pymatgen Structure/Poscar.
vasppy/scripts/potcar_spec.py Updates CLI for new potcar_spec return shape; adds doc/SIGPIPE.
vasppy/scripts/poscar_to_xtl.py Replaces custom POSCAR writer with pymatgen-based XTL output helper.
vasppy/scripts/poscar_to_cif.py Replaces custom POSCAR writer with pymatgen CifWriter.
vasppy/scripts/murnfit.py Updates POSCAR handling to pymatgen; improves error handling + typing/tests.
vasppy/scripts/fat_bands.py CLI hardening + docstrings; uses Procar.from_file.
vasppy/scripts/effective_mass.py CLI hardening + docstrings; uses Procar.from_file and arg typing.
vasppy/scripts/convergence_testing.py Refactors with typing/dataclass cleanups + Path usage + clearer IO flow.
vasppy/scripts/checkforce.py Adds SIGPIPE handling + iterator typing for multi-step force parsing.
vasppy/scripts/check_species.py Migrates POSCAR parsing to Structure; improves CLI/docstrings.
vasppy/rdf.py Type/doc updates; fixes numpy-array indices handling; improves validations.
vasppy/poscar.py Removes legacy custom Poscar implementation.
vasppy/polyhedron.py Removes unused Polyhedron module.
vasppy/pimaim.py Removes legacy PIMAIM interop module.
vasppy/outcar.py Adds compiled regex constants; improves parsing errors and typing.
vasppy/optics.py Adds typing/docstrings; minor API cleanup + plotting helpers.
vasppy/neighbour_list.py Adds module docstring/typing; minor cleanups and clearer errors.
vasppy/kpoints.py Adds module docstring/typing; improves error messages + kspacing helpers.
vasppy/cell.py Adds typing/docstrings; improves validation and return types.
vasppy/calculation.py Adds typing/docstrings; improves errors and small logic simplifications.
vasppy/band.py Adds typing/docstrings; fixes equality logic and occupancy handling docs.
vasppy/atom.py Removes legacy Atom class.
tests/test_xdatcar.py Removes XDATCAR tests tied to removed Poscar/Xdatcar.
tests/test_vasprun.py Updates tests for cached_property-based caching semantics.
tests/test_vaspmeta.py Updates constructor expectations (track param).
tests/test_utils.py Adds checksum-not-found test + keeps distance tests updated.
tests/test_summary.py Updates potcar_spec tests to new tuple return; adds more Summary method tests.
tests/test_scripts_r2r2_expansion.py Adds characterization tests for r2r2 expansion behavior.
tests/test_scripts_poscar_to_xtl.py Adds integration tests for XTL output helper.
tests/test_scripts_murnfit.py Adds unit tests for Murnaghan fit helpers.
tests/test_scripts_check_species.py Adds integration tests for Structure-based species extraction.
tests/test_rdf.py Adds tests for shell volumes, RDF numpy indices, and Van Hove analysis.
tests/test_procar.py Expands regression/behavior tests; updates loading helpers.
tests/test_poscar.py Removes tests tied to deleted legacy Poscar.
tests/test_outcar.py Expands tests to cover additional OUTCAR parsing helpers.
tests/test_optics.py Expands tests to cover absorption coefficient + plotting behavior.
tests/test_grid.py Adds comprehensive Grid tests + minimal CHGCAR fixture coverage.
tests/test_data/POSCAR_NaCl Adds POSCAR fixture for script/integration tests.
tests/test_data/CHGCAR_minimal Adds minimal CHGCAR fixture for Grid parsing tests.
tests/test_calculation.py Adds test coverage for new error behavior and Mapping stoichiometry.
tests/test_band.py Adds equality regression test.
tests/test_atom.py Removes tests tied to deleted legacy Atom.
tests/scripts/test_spacegroup.py Adds characterization tests for spacegroup CLI.
tests/scripts/test_rotate_poscar.py Adds characterization tests for rotate_poscar CLI.
tests/scripts/test_proc_poscar.py Adds subprocess-based characterization tests for proc_poscar CLI.
tests/scripts/test_poscar_to_cif.py Adds characterization tests for poscar_to_cif CLI.
tests/scripts/test_convergence_testing.py Updates tests to Path-based implementation details.
pyproject.toml Updates version, Python requirement, dependencies, and entry points.
.ruff.toml Updates Ruff config structure + target-version alignment.
.gitignore Adjusts ignored docs/markdown patterns.
.github/workflows/ruff.yml Restricts push trigger to main while retaining PR checks.
.github/workflows/build.yml Drops 3.10, adds 3.14, adds mypy job, adjusts Coveralls finalization.
Comments suppressed due to low confidence (1)

vasppy/vasprun.py:168

  • In parse_structures, elem = child.find("structure") can be None (e.g., truncated XML or unexpected vasprun variants), but it's passed straight into parse_structure, which expects an etree.Element. Add an explicit None check here and raise a helpful ValueError (ideally including which <calculation> index/path failed) rather than letting an AttributeError occur later.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread vasppy/scripts/checkforce.py
Comment thread vasppy/vasprun.py
Comment thread vasppy/vaspmeta.py
Comment thread vasppy/scripts/proc_poscar.py
Comment thread vasppy/scripts/proc_poscar.py Outdated
- checkforce.py: use explicit is None check for convergence parameter
- vasprun.py: add None check for crystal varray in truncated XML
- vaspmeta.py: validate yaml data is a dict before accessing keys
- proc_poscar.py: raise ValueError instead of bare Exception
- checkforce.py: use explicit is None check for convergence parameter
- vasprun.py: add None check for crystal varray in truncated XML
- vaspmeta.py: validate yaml data is a dict before accessing keys
- proc_poscar.py: raise ValueError instead of bare Exception;
  remove --scale flag (pymatgen always folds the scaling factor
  into the lattice on read, so --scale is now the default behaviour)
pymatgen always folds the POSCAR scaling factor into the lattice
on read, so scaling is always 1.0. Remove the --scale flag and
the scaling parameter from _output_header and _convert_to_bohr.
The chequerboard sublattice grouping feature relied on arbitrary
species labels which are not supported by pymatgen Structure.
The use case was niche and undocumented.
@bjmorgan

Copy link
Copy Markdown
Owner Author

The low-confidence parse_structures comment from the Copilot review has also been addressed — added a None check with a descriptive ValueError including the calculation index, in 6de0034.

This comment was marked as resolved.

The previous intersect1d check would trigger masking for any
partial overlap between indices_i and indices_j, which could
produce an inconsistent reshape when rows lost different numbers
of entries. Restrict masking to the self-referencing case where
the two index lists are identical.
@bjmorgan bjmorgan merged commit 381a359 into main Mar 28, 2026
12 checks passed
@bjmorgan bjmorgan deleted the v1.0 branch March 28, 2026 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants