Skip to content

Commit

Permalink
refactored io to discourage use of generics
Browse files Browse the repository at this point in the history
  • Loading branch information
wolearyc committed Aug 13, 2024
1 parent 6a92d8b commit 1cbb968
Show file tree
Hide file tree
Showing 19 changed files with 284 additions and 281 deletions.
4 changes: 3 additions & 1 deletion docs/source/dev guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Ramannoodle's documentation is built with `Sphinx <https://www.sphinx-doc.org/en
$ make html
in the docs directory. The resulting html is available in build/html.
from within the docs directory. The resulting html is available in docs/build/html.

Guidelines
----------
Expand All @@ -52,3 +52,5 @@ In no particular order, here are some guidelines that are followed throughout ra
* Unless otherwise noted, fractional coordinates are always used. Variables for cartesian coordinates always have "cartesian\_" appended.

* Use classes widely. Sometimes, a regular function is all that is needed!

* With IO functions, ramannoodle attempts to strike a balance between simplicity and flexibility. `import ramannoodle.io` provides access to generic file readers and writers for a variety of file formats. However, these generic routines do not offer much customization but do offer simplicity. Additional options can be accessed in the code-specific packages, such as `import ramannoodle.io.vasp.poscar`. Use of these is preferred.
74 changes: 46 additions & 28 deletions docs/source/notebooks/Basic tutorial.ipynb

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions docs/source/notebooks/Masking.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ramannoodle/dynamics/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from abc import ABC, abstractmethod

from ramannoodle.spectrum.raman import PhononRamanSpectrum
from ramannoodle.polarizability import PolarizabilityModel
from ramannoodle.polarizability.abstract import PolarizabilityModel


class Dynamics(ABC): # pylint: disable=too-few-public-methods
Expand Down
2 changes: 1 addition & 1 deletion ramannoodle/dynamics/phonon.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from ramannoodle.dynamics.abstract import Dynamics
from ramannoodle.globals import RAMAN_TENSOR_CENTRAL_DIFFERENCE
from ramannoodle.polarizability import PolarizabilityModel
from ramannoodle.polarizability.abstract import PolarizabilityModel
from ramannoodle.spectrum.raman import PhononRamanSpectrum


Expand Down
7 changes: 0 additions & 7 deletions ramannoodle/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@ def __init__(self, reason: str):
pass


class InvalidOptionException(Exception):
"""Raised when an optional argument is not supported."""

def __init__(self, reason: str):
pass


class InvalidDOFException(Exception):
"""Raised when things a degree of freedom is invalid in some way."""

Expand Down
144 changes: 0 additions & 144 deletions ramannoodle/io/__init__.py
Original file line number Diff line number Diff line change
@@ -1,145 +1 @@
"""Routines for interacting with files used and produced by DFT codes."""

from pathlib import Path

import numpy as np
from numpy.typing import NDArray

from ramannoodle.dynamics.phonon import Phonons
from ramannoodle.symmetry.structural import ReferenceStructure
from ramannoodle.io import vasp

# These dictionaries map between file_format's and appropriate loading functions.
_PHONON_READERS = {"outcar": vasp.outcar.read_phonons}
_POSITION_AND_POLARIZABILITY_READERS = {
"outcar": vasp.outcar.read_positions_and_polarizability
}
_REFERENCE_STRUCTURE_READERS = {
"outcar": vasp.outcar.read_ref_structure,
"poscar": vasp.poscar.read_ref_structure,
}


def read_phonons(filepath: str | Path, file_format: str) -> Phonons:
"""Read phonons from a file.
Parameters
----------
filepath
file_format
supports: "outcar"
Returns
-------
:
Raises
------
InvalidFileException
File has unexpected format.
FileNotFoundError
File could not be found.
"""
try:
return _PHONON_READERS[file_format](filepath)
except KeyError as exc:
raise ValueError(f"unsupported format: {file_format}") from exc


def read_positions_and_polarizability(
filepath: str | Path,
file_format: str,
) -> tuple[NDArray[np.float64], NDArray[np.float64]]:
"""Read fractional positions and polarizability from a file.
Parameters
----------
filepath
file_format
supports: "outcar"
Returns
-------
:
2-tuple, whose first element is the fractional positions, a 2D array with shape
(N,3). The second element is the polarizability, a 2D array with shape (3,3).
Raises
------
InvalidFileException
File has unexpected format.
FileNotFoundError
File could not be found.
"""
try:
return _POSITION_AND_POLARIZABILITY_READERS[file_format](filepath)
except KeyError as exc:
raise ValueError(f"unsupported format: {file_format}") from exc


def read_ref_structure(filepath: str | Path, file_format: str) -> ReferenceStructure:
"""Read reference structure from a file.
Parameters
----------
filepath
file_format
supports: "outcar"
Returns
-------
StructuralSymmetry
Raises
------
InvalidFileException
File has unexpected format.
FileNotFoundError
File could not be found.
"""
try:
return _REFERENCE_STRUCTURE_READERS[file_format](filepath)
except KeyError as exc:
raise ValueError(f"unsupported format: {file_format}") from exc


_STRUCTURE_WRITERS = {"poscar": vasp.poscar.write_structure}


def write_structure(
lattice: NDArray[np.float64],
atomic_numbers: list[int],
fractional_positions: NDArray[np.float64],
filepath: str | Path,
file_format: str,
**options: str,
) -> None:
"""Write structure to file.
Parameters
----------
lattice
atomic_numbers
fractional_positions
filepath
file_format
supports: "poscar"
overwrite
options
Additional, file-format-dependent options. See IO.
Raises
------
InvalidFileException
File has unexpected format.
"""
try:
_STRUCTURE_WRITERS[file_format](
lattice,
atomic_numbers,
fractional_positions,
filepath,
**options,
)
except KeyError as exc:
raise ValueError(f"unsupported format: {file_format}") from exc
148 changes: 148 additions & 0 deletions ramannoodle/io/generic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
"""Generic, rather inflexible IO routines.
If more flexibility is needed, the IO routines contained in the code-specific
subpackages should be used.
"""

from pathlib import Path

import numpy as np
from numpy.typing import NDArray
from ramannoodle.dynamics.phonon import Phonons

from ramannoodle.symmetry.structural import ReferenceStructure
import ramannoodle.io.vasp as vasp_io

# These map between file_format's and appropriate reading functions.
_PHONON_READERS = {"outcar": vasp_io.outcar.read_phonons}
_POSITION_AND_POLARIZABILITY_READERS = {
"outcar": vasp_io.outcar.read_positions_and_polarizability
}
_REFERENCE_STRUCTURE_READERS = {
"outcar": vasp_io.outcar.read_ref_structure,
"poscar": vasp_io.poscar.read_ref_structure,
}


def read_phonons(filepath: str | Path, file_format: str) -> Phonons:
"""Read phonons from a file.
Parameters
----------
filepath
file_format
supports: "outcar"
Returns
-------
:
Raises
------
InvalidFileException
File has unexpected format.
FileNotFoundError
File could not be found.
"""
try:
return _PHONON_READERS[file_format](filepath)
except KeyError as exc:
raise ValueError(f"unsupported format: {file_format}") from exc


def read_positions_and_polarizability(
filepath: str | Path,
file_format: str,
) -> tuple[NDArray[np.float64], NDArray[np.float64]]:
"""Read fractional positions and polarizability from a file.
Parameters
----------
filepath
file_format
supports: "outcar"
Returns
-------
:
2-tuple, whose first element is the fractional positions, a 2D array with shape
(N,3). The second element is the polarizability, a 2D array with shape (3,3).
Raises
------
InvalidFileException
File has unexpected format.
FileNotFoundError
File could not be found.
"""
try:
return _POSITION_AND_POLARIZABILITY_READERS[file_format](filepath)
except KeyError as exc:
raise ValueError(f"unsupported format: {file_format}") from exc


def read_ref_structure(filepath: str | Path, file_format: str) -> ReferenceStructure:
"""Read reference structure from a file.
Parameters
----------
filepath
file_format
supports: "outcar", "poscar"
Returns
-------
StructuralSymmetry
Raises
------
InvalidFileException
File has unexpected format.
FileNotFoundError
File could not be found.
"""
try:
return _REFERENCE_STRUCTURE_READERS[file_format](filepath)
except KeyError as exc:
raise ValueError(f"unsupported format: {file_format}") from exc


_STRUCTURE_WRITERS = {"poscar": vasp_io.poscar.write_structure}


def write_structure( # pylint: disable=too-many-arguments
lattice: NDArray[np.float64],
atomic_numbers: list[int],
positions: NDArray[np.float64],
filepath: str | Path,
file_format: str,
overwrite: bool = False,
) -> None:
"""Write structure to file.
Parameters
----------
lattice
atomic_numbers
positions
filepath
file_format
supports: "poscar"
overwrite
Raises
------
InvalidFileException
File has unexpected format.
"""
try:
_STRUCTURE_WRITERS[file_format](
lattice=lattice,
atomic_numbers=atomic_numbers,
positions=positions,
filepath=filepath,
overwrite=overwrite,
)
except KeyError as exc:
raise ValueError(f"unsupported format: {file_format}") from exc
2 changes: 1 addition & 1 deletion ramannoodle/io/vasp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Functions for interacting with VASP input and output files."""
"""Functions for interacting with VASP files."""

# flake8: noqa: F401
from ramannoodle.io.vasp import outcar
Expand Down
3 changes: 1 addition & 2 deletions ramannoodle/io/vasp/outcar.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
from ramannoodle.symmetry.structural import ReferenceStructure


# Utilities for OUTCAR
# These functions partially read files.
# Utilities for OUTCAR. Warning: some of these functions partially read files.
def _get_atomic_symbol_from_potcar_line(line: str) -> str:
"""Extract atomic symbol from a POTCAR line in a VASP OUTCAR file.
Expand Down
Loading

0 comments on commit 1cbb968

Please sign in to comment.