diff --git a/ThermoScreening/__init__.py b/ThermoScreening/__init__.py index 1598152..8cc958f 100644 --- a/ThermoScreening/__init__.py +++ b/ThermoScreening/__init__.py @@ -1,3 +1,5 @@ +"""ThermoScreening: DFTB+ thermochemistry screening package.""" + import logging import os import time diff --git a/ThermoScreening/calculator/__init__.py b/ThermoScreening/calculator/__init__.py index ef8e7f7..88a1e7a 100644 --- a/ThermoScreening/calculator/__init__.py +++ b/ThermoScreening/calculator/__init__.py @@ -1 +1,3 @@ -from .dftbplus import Geoopt, Hessian, Modes \ No newline at end of file +"""Calculator backends for ThermoScreening.""" + +from .dftbplus import Geoopt, Hessian, Modes diff --git a/ThermoScreening/calculator/dftbplus.py b/ThermoScreening/calculator/dftbplus.py index 8bc2e4f..e08f22f 100644 --- a/ThermoScreening/calculator/dftbplus.py +++ b/ThermoScreening/calculator/dftbplus.py @@ -1,3 +1,5 @@ +"""DFTB+ calculators: geometry optimisation, Hessian, and vibrational modes.""" + import os import shutil import subprocess @@ -121,7 +123,6 @@ def __init__( self.calculate(atoms) - return None def potential_energy(self): """ @@ -221,7 +222,6 @@ def __init__( self.calculate(atoms) - return None def read(self): """ @@ -278,7 +278,6 @@ def __init__(self, geometry="geo_opt.gen", hessian="hessian.out"): # read the vibrational modes self.wave_numbers = self.read() - return None def write(self): """ @@ -304,7 +303,6 @@ def write(self): with open("modes_in.hsd", "w") as f: f.write(string) - return None def calculate(self): """ @@ -328,7 +326,6 @@ def calculate(self): with open("modes.out", "w") as output: subprocess.run(["modes"], stdout=output, check=True) - return None def read(self): """ diff --git a/ThermoScreening/cli/__init__.py b/ThermoScreening/cli/__init__.py index b0e83cd..6794e2f 100644 --- a/ThermoScreening/cli/__init__.py +++ b/ThermoScreening/cli/__init__.py @@ -1,4 +1,6 @@ +"""Command-line interface for ThermoScreening.""" + from .thermo import main from ..utils import print_header -print_header() \ No newline at end of file +print_header() diff --git a/ThermoScreening/cli/thermo.py b/ThermoScreening/cli/thermo.py index 51acb5d..751facf 100644 --- a/ThermoScreening/cli/thermo.py +++ b/ThermoScreening/cli/thermo.py @@ -1,3 +1,5 @@ +"""The ``thermo`` command-line entry point.""" + from argparse import ArgumentParser import sys import time diff --git a/ThermoScreening/exceptions.py b/ThermoScreening/exceptions.py index 290df65..e0842bf 100644 --- a/ThermoScreening/exceptions.py +++ b/ThermoScreening/exceptions.py @@ -4,9 +4,9 @@ class ThermoScreeningException(Exception): """Base class for exceptions in this package.""" - + class TSValueError(ThermoScreeningException): """Exception raised for errors in the input value.""" - + class TSNotImplementedError(ThermoScreeningException): """Exception raised for not implemented methods.""" diff --git a/ThermoScreening/thermo/__init__.py b/ThermoScreening/thermo/__init__.py index 4eef94a..6308869 100644 --- a/ThermoScreening/thermo/__init__.py +++ b/ThermoScreening/thermo/__init__.py @@ -1,7 +1,9 @@ +"""Thermochemistry API for ThermoScreening.""" + from .api import read_xyz, read_gen, read_vib_file, read_coord, read_vibrational, unit_length, unit_energy, unit_mass, run_thermo, execute from .atoms import Atom from .cell import Cell from .inputFileReader import InputFileReader from .system import System from .thermo import Thermo -from .screening import screen \ No newline at end of file +from .screening import screen diff --git a/ThermoScreening/thermo/api.py b/ThermoScreening/thermo/api.py index 7ed2afc..76f6426 100644 --- a/ThermoScreening/thermo/api.py +++ b/ThermoScreening/thermo/api.py @@ -1,3 +1,5 @@ +"""High-level thermochemistry functions: coordinate/frequency I/O and run helpers.""" + import logging import os from contextlib import contextmanager @@ -181,14 +183,13 @@ def read_coord(coord_file: str, engine: str): if coord_file.endswith(".xyz"): data_N, data_atoms, data_xyz, cell, pbc = read_xyz(coord_file) return data_N, data_atoms, data_xyz, cell, pbc - elif coord_file.endswith(".gen"): + if coord_file.endswith(".gen"): data_N, data_atoms, data_xyz, cell_vectors, pbc = read_gen(coord_file) return data_N, data_atoms, data_xyz, cell_vectors, pbc - else: - logger.error( - "The input file is not supported.", - exception=TSNotImplementedError - ) + logger.error( + "The input file is not supported.", + exception=TSNotImplementedError + ) else: logger.error( @@ -251,11 +252,10 @@ def unit_length(engine: str): """ if engine == "dftb+": return "Angstrom" - else: - logger.error( - "The engine is not supported.", - exception=TSNotImplementedError - ) + logger.error( + "The engine is not supported.", + exception=TSNotImplementedError + ) def unit_energy(engine: str): @@ -279,11 +279,10 @@ def unit_energy(engine: str): """ if engine == "dftb+": return "Hartree" - else: - logger.error( - "The engine is not supported.", - exception=TSNotImplementedError - ) + logger.error( + "The engine is not supported.", + exception=TSNotImplementedError + ) def unit_mass(engine: str): @@ -307,11 +306,10 @@ def unit_mass(engine: str): """ if engine == "dftb+": return "amu" - else: - logger.error( - "The engine is not supported.", - exception=TSNotImplementedError - ) + logger.error( + "The engine is not supported.", + exception=TSNotImplementedError + ) def unit_frequency(engine: str): @@ -335,11 +333,10 @@ def unit_frequency(engine: str): """ if engine == "dftb+": return "cm^-1" - else: - logger.error( - "The engine is not supported.", - exception=TSNotImplementedError - ) + logger.error( + "The engine is not supported.", + exception=TSNotImplementedError + ) def _atoms_from_ase(atoms): diff --git a/ThermoScreening/thermo/atoms.py b/ThermoScreening/thermo/atoms.py index 4f4d8ef..5a6ecc1 100644 --- a/ThermoScreening/thermo/atoms.py +++ b/ThermoScreening/thermo/atoms.py @@ -1,3 +1,5 @@ +"""Atom representation and element reference data.""" + import logging import numpy as np @@ -45,7 +47,7 @@ class Atom: >>> atom.position array([0., 0., 0.]) """ - + logger = logging.getLogger(__package_name__).getChild(__qualname__) logger = setup_logger(logger) @@ -96,7 +98,7 @@ def __init__( self._symbol = atomic_Symbol[int(number)].capitalize() except: self.logger.error( - "The atomic number %s is not known." % number, + f"The atomic number {number} is not known.", exception=TSValueError ) self._mass = atomicMasses[self._symbol.lower()] @@ -107,7 +109,7 @@ def __init__( self._number = atomicNumbers[symbol.lower()] except: self.logger.error( - "The chemical symbol %s is not known." % symbol, + f"The chemical symbol {symbol} is not known.", exception=TSValueError ) self._mass = atomicMasses[symbol.lower()] @@ -225,7 +227,7 @@ def change_atom( self._number = atomicNumbers[self._symbol.lower()] except: self.logger.error( - "The chemical symbol %s is not known." % symbol, + f"The chemical symbol {symbol} is not known.", exception=TSValueError ) @@ -238,14 +240,14 @@ def change_atom( self._symbol = atomic_Symbol[int(number)].capitalize() except: self.logger.error( - "The atomic number %s is not known." % number, + f"The atomic number {number} is not known.", exception=TSValueError ) self._mass = atomicMasses[self._symbol.lower()] self._configuration = atomicElectronConfigurations[self._symbol.lower()] if position is not None: - - self.position = position + + self.position = position atomic_Symbol = atomicNumbersReverse diff --git a/ThermoScreening/thermo/cell.py b/ThermoScreening/thermo/cell.py index 98e2ef8..3754424 100644 --- a/ThermoScreening/thermo/cell.py +++ b/ThermoScreening/thermo/cell.py @@ -1,3 +1,5 @@ +"""Periodic cell helpers.""" + import numpy as np diff --git a/ThermoScreening/thermo/inputFileReader.py b/ThermoScreening/thermo/inputFileReader.py index 1e33e15..3eacad8 100644 --- a/ThermoScreening/thermo/inputFileReader.py +++ b/ThermoScreening/thermo/inputFileReader.py @@ -1,3 +1,5 @@ +"""Reader for ThermoScreening key=value input files.""" + import logging from ThermoScreening.exceptions import TSValueError @@ -14,7 +16,7 @@ class InputFileReader: The input file. """ - + logger = logging.getLogger(__package_name__).getChild(__qualname__) logger = setup_logger(logger) @@ -58,7 +60,6 @@ def __init__( self._read() self._check() - return None def _read(self): """ @@ -84,7 +85,6 @@ def _read(self): key, value = line.split("=", maxsplit=1) self._dictionary[key.strip()] = value.strip() - return None def _check(self): """ @@ -101,8 +101,7 @@ def _check(self): """ self._check_required_keys() self._check_known_keys() - - return None + def _check_required_keys(self): """ @@ -120,11 +119,10 @@ def _check_required_keys(self): for key in self.required_keys: if key not in self._dictionary.keys(): self.logger.error( - "The key {} is not set in the input file.".format(key), + f"The key {key} is not set in the input file.", exception=TSValueError ) - - return None + def _check_known_keys(self): """ @@ -142,8 +140,7 @@ def _check_known_keys(self): for key in self._dictionary.keys(): if key not in self.required_keys: self.logger.error( - "The key {} is not known.".format(key), + f"The key {key} is not known.", exception=TSValueError ) - return None diff --git a/ThermoScreening/thermo/system.py b/ThermoScreening/thermo/system.py index e0ed902..eaf892a 100644 --- a/ThermoScreening/thermo/system.py +++ b/ThermoScreening/thermo/system.py @@ -1,3 +1,5 @@ +"""Molecular system model with symmetry and degree-of-freedom analysis.""" + import logging import warnings import numpy as np @@ -159,13 +161,13 @@ def dimensionality(atoms: List[Atom]) -> int: or (np.array_equal(x, zero_array) and np.array_equal(y, zero_array)) ): return 1 - elif ( + if ( np.array_equal(z, zero_array) or np.array_equal(y, zero_array) or np.array_equal(x, zero_array) ): return 2 - elif ( + if ( np.array_equal(z, zero_array) and np.array_equal(y, zero_array) and np.array_equal(x, zero_array) @@ -197,13 +199,12 @@ def dim(atoms: List[Atom]) -> int: number_of_atoms = len(atoms) if number_of_atoms == 1: return 1 - elif number_of_atoms > 1: + if number_of_atoms > 1: return dimensionality(atoms) - else: - System.logger.error( - "The number of atoms must be greater than 0.", - exception=TSValueError - ) + System.logger.error( + "The number of atoms must be greater than 0.", + exception=TSValueError + ) def dof(atoms: List[Atom]) -> int: @@ -229,15 +230,14 @@ def dof(atoms: List[Atom]) -> int: number_of_atoms = len(atoms) if number_of_atoms == 1: return 3 - elif number_of_atoms > 1: + if number_of_atoms > 1: return ( (3 * number_of_atoms - 5) if linearity(atoms) else (3 * number_of_atoms - 6) ) - else: - System.logger.error( - "The number of atoms must be greater than 0.", - exception=TSValueError - ) + System.logger.error( + "The number of atoms must be greater than 0.", + exception=TSValueError + ) def spin(charge: float) -> float: @@ -255,8 +255,7 @@ def spin(charge: float) -> float: if (charge % 2.0) == 0: return 0.0 - else: - return 0.5 + return 0.5 def rotational_symmetry_number(atoms: List[Atom]) -> int: @@ -580,7 +579,7 @@ class System: >>> system.atoms [Atom(symbol='H', position=[0.0, 0.0, 0.0], mass=1.0), Atom(symbol='H', position=[0.0, 0.0, 1.0], mass=1.0)] """ - + logger = logging.getLogger(__package_name__).getChild(__name__) logger = setup_logger(logger) @@ -627,19 +626,19 @@ def __init__( If the number of atoms is less than 1. If the vibrational frequencies are not provided. """ - + if atoms is None: self.logger.error( "Atoms must be provided.", exception=TSValueError ) - + if len(atoms) == 0: self.logger.error( "The number of atoms must be greater than 0.", exception=TSValueError ) - + if vibrational_frequencies is None: self.logger.error( "Vibrational frequencies must be provided.", diff --git a/ThermoScreening/thermo/thermo.py b/ThermoScreening/thermo/thermo.py index ab5c1db..8cecd3e 100644 --- a/ThermoScreening/thermo/thermo.py +++ b/ThermoScreening/thermo/thermo.py @@ -1,3 +1,5 @@ +"""Rigid-rotor/harmonic-oscillator thermochemistry calculation.""" + import numpy as np import logging @@ -43,7 +45,7 @@ class Thermo: run() Calculates the thermochemical properties of the system. """ - + logger = logging.getLogger(__package_name__).getChild(__name__) logger = setup_logger(logger) @@ -79,22 +81,22 @@ def __init__( ------- None """ - if pressure == None: + if pressure is None: self.logger.error( "The pressure is not given.", exception=TSValueError ) - if temperature == None: + if temperature is None: self.logger.error( "The temperature is not given.", exception=TSValueError ) - if system == None: + if system is None: self.logger.error( "The system is not given.", exception=TSValueError ) - if engine == None: + if engine is None: self.logger.error( "The engine is not given.", exception=TSValueError @@ -124,7 +126,6 @@ def __init__( self._reloc_coord = None self._atomic_masses = self._system.atomic_masses() - return None def run(self): """ @@ -143,7 +144,6 @@ def run(self): self._compute_thermochemical_properties() self._summary() - return None def _transform_units(self): """ @@ -180,7 +180,6 @@ def _transform_units(self): exception=TSValueError ) - return None def _relocate_to_cm(self): """ @@ -194,7 +193,6 @@ def _relocate_to_cm(self): self._reloc_coord = self._system.coord() self._reloc_coord -= self._system.center_of_mass - return None def _compute_inertia_tensor(self): """ @@ -223,7 +221,6 @@ def _compute_inertia_tensor(self): self._inertia_tensor[1, 2] = -np.sum(m * y * z) self._inertia_tensor[2, 1] = self._inertia_tensor[1, 2] - return None def _compute_rotational_partition_function(self): """ @@ -260,7 +257,6 @@ def _compute_rotational_partition_function(self): / (np.power(self._rotational_temperature_xyz, 1 / 2)) ) - return None def _compute_rotational_entropy(self): """ @@ -276,7 +272,6 @@ def _compute_rotational_entropy(self): / PhysicalConstants["cal"] ) - return None def _compute_rotational_energy(self): """ @@ -298,7 +293,6 @@ def _compute_rotational_heat_capacity(self): (3 / 2) * PhysicalConstants["R"] / PhysicalConstants["cal"] ) - return None def _rotational_contribution(self): """ @@ -317,7 +311,6 @@ def _rotational_contribution(self): self._compute_rotational_energy() self._compute_rotational_heat_capacity() - return None def _compute_vibrational_partition_function(self): """ @@ -342,7 +335,6 @@ def _compute_vibrational_partition_function(self): / (1 - np.exp(-self._vib_temp_K / self._temperature)) ) - return None def _compute_vibrational_entropy(self): """ @@ -367,7 +359,6 @@ def _compute_vibrational_entropy(self): / PhysicalConstants["cal"] ) - return None def _compute_vibrational_energy(self): """ @@ -406,7 +397,6 @@ def _compute_vibrational_energy(self): / PhysicalConstants["cal"] ) - return None def _compute_vibrational_heat_capacity(self): """ @@ -428,7 +418,6 @@ def _compute_vibrational_heat_capacity(self): ) / PhysicalConstants["cal"] ) - return None def _vibrational_contribution(self): """ @@ -455,7 +444,6 @@ def _compute_electronic_partition_function(self): self._electronic_partition_function = 2 * self._system._spin + 1 - return None def _compute_electronic_entropy(self): """ @@ -471,7 +459,6 @@ def _compute_electronic_entropy(self): * np.log(self._electronic_partition_function) / PhysicalConstants["cal"] ) - return None def _compute_electronic_energy(self): """ @@ -484,7 +471,6 @@ def _compute_electronic_energy(self): self._electronic_energy = 0 / PhysicalConstants["cal"] - return None def _compute_electronic_heat_capacity(self): """ @@ -497,7 +483,6 @@ def _compute_electronic_heat_capacity(self): self._electronic_heat_capacity = 0 / PhysicalConstants["cal"] - return None def _electronic_contribution(self): """ @@ -513,7 +498,6 @@ def _electronic_contribution(self): self._compute_electronic_energy() self._compute_electronic_heat_capacity() - return None def _compute_translational_partition_function(self): """ @@ -532,7 +516,6 @@ def _compute_translational_partition_function(self): (3 / 2), ) * (PhysicalConstants["kB"] * self._temperature / self._pressure) - return None def _compute_translational_entropy(self): """ @@ -549,7 +532,6 @@ def _compute_translational_entropy(self): / PhysicalConstants["cal"] ) - return None def _compute_translational_energy(self): """ @@ -568,7 +550,6 @@ def _compute_translational_energy(self): / PhysicalConstants["cal"] ) - return None def _compute_translational_heat_capacity(self): """ @@ -583,7 +564,6 @@ def _compute_translational_heat_capacity(self): 3 / 2 * PhysicalConstants["R"] / PhysicalConstants["cal"] ) - return None def _translational_contribution(self): """ @@ -598,7 +578,6 @@ def _translational_contribution(self): self._compute_translational_energy() self._compute_translational_heat_capacity() - return None def _compute_thermochemical_properties(self): """ @@ -666,7 +645,6 @@ def _compute_thermochemical_properties(self): + self._translational_heat_capacity ) - return None def _summary(self): """ @@ -703,7 +681,6 @@ def _summary(self): + self._total_gibbs_free_energy_Hartree_per_mol ) - return None def total_energy(self, unit: str) -> float: """ @@ -727,15 +704,14 @@ def total_energy(self, unit: str) -> float: if unit == "H": return _real_scalar(self._total_energy_Hartree_per_mol) - elif unit == "kcal": + if unit == "kcal": return _real_scalar(self._total_energy_kcal) - elif unit == "cal": + if unit == "cal": return _real_scalar(self._total_energy) - else: - self.logger.error( - "The unit is not supported.", - exception=TSValueError - ) + self.logger.error( + "The unit is not supported.", + exception=TSValueError + ) def total_enthalpy(self, unit: str) -> float: """ @@ -759,15 +735,14 @@ def total_enthalpy(self, unit: str) -> float: if unit == "H": return _real_scalar(self._total_enthalpy_Hartree_per_mol) - elif unit == "kcal": + if unit == "kcal": return _real_scalar(self._total_enthalpy_kcal) - elif unit == "cal": + if unit == "cal": return _real_scalar(self._total_enthalpy) - else: - self.logger.error( - "The unit is not supported.", - exception=TSValueError - ) + self.logger.error( + "The unit is not supported.", + exception=TSValueError + ) def total_entropy(self, unit: str) -> float: """ @@ -791,13 +766,12 @@ def total_entropy(self, unit: str) -> float: if unit == "H/T": return _real_scalar(self._total_entropy_Hartree_per_mol) - elif unit == "cal/(mol*K)": + if unit == "cal/(mol*K)": return _real_scalar(self._total_entropy) - else: - self.logger.error( - "The unit is not supported.", - exception=TSValueError - ) + self.logger.error( + "The unit is not supported.", + exception=TSValueError + ) def total_gibbs_free_energy(self, unit: str) -> float: """ @@ -821,15 +795,14 @@ def total_gibbs_free_energy(self, unit: str) -> float: if unit == "H": return _real_scalar(self._total_gibbs_free_energy_Hartree_per_mol) - elif unit == "kcal": + if unit == "kcal": return _real_scalar(self._total_gibbs_free_energy_kcal) - elif unit == "cal": + if unit == "cal": return _real_scalar(self._total_gibbs_free_energy) - else: - self.logger.error( - "The unit is not supported.", - exception=TSValueError - ) + self.logger.error( + "The unit is not supported.", + exception=TSValueError + ) def total_heat_capacity(self, unit: str) -> float: """ @@ -853,18 +826,17 @@ def total_heat_capacity(self, unit: str) -> float: if unit == "cal/(mol*K)": return _real_scalar(self._total_heatcapacity) - elif unit == "H/T": + if unit == "H/T": return _real_scalar( self._total_heatcapacity * PhysicalConstants["cal"] / PhysicalConstants["H"] / PhysicalConstants["N_A"] ) - else: - self.logger.error( - "The unit is not supported.", - exception=TSValueError - ) + self.logger.error( + "The unit is not supported.", + exception=TSValueError + ) def total_EeZPE(self) -> float: """ diff --git a/ThermoScreening/utils/__init__.py b/ThermoScreening/utils/__init__.py index d69f064..a81035a 100644 --- a/ThermoScreening/utils/__init__.py +++ b/ThermoScreening/utils/__init__.py @@ -1,2 +1,4 @@ +"""Utility helpers for ThermoScreening.""" + from .header import print_header -from .physicalConstants import PhysicalConstants \ No newline at end of file +from .physicalConstants import PhysicalConstants diff --git a/ThermoScreening/utils/header.py b/ThermoScreening/utils/header.py index 406f071..4ad3e43 100644 --- a/ThermoScreening/utils/header.py +++ b/ThermoScreening/utils/header.py @@ -1,3 +1,5 @@ +"""Program header/banner.""" + import sys from beartype.typing import Any diff --git a/ThermoScreening/utils/physicalConstants.py b/ThermoScreening/utils/physicalConstants.py index 58fec6b..1d36630 100644 --- a/ThermoScreening/utils/physicalConstants.py +++ b/ThermoScreening/utils/physicalConstants.py @@ -1,3 +1,5 @@ +"""Physical constants and unit conversions.""" + import numpy as np """ Physical constants and conversion factors that is used in the program. @@ -20,16 +22,16 @@ "c": 299792458, # m/s "kB": 1.380649 * 10**(-23), # J K^-1 "R": 8.314462618, # J mol^-1 K^-1 - "N_A": 6.02214076 * 10**(23), # mol^-1 + "N_A": 6.02214076 * 10**(23), # mol^-1 "u": 1.66053906660 * 10**(-27), # kg "H": 4.3597447222071 * 10**(-18), # J "cal": 4.184, # J "A": 10**(-10), # m "HztoGHz": 10**(-9), # GHz - "eV": 1.602176634 * 10**(-19), # J + "eV": 1.602176634 * 10**(-19), # J # NOT USED: - # "pi": 3.14159265358979323846, - # "kcal": 4184, # J + # "pi": 3.14159265358979323846, + # "kcal": 4184, # J # "angstrom": 10**(-10), # m # "bohr_radius": 5.29177210903 * 10**(-11), # m } diff --git a/ThermoScreening/version.py b/ThermoScreening/version.py index e990cd6..7fb742c 100644 --- a/ThermoScreening/version.py +++ b/ThermoScreening/version.py @@ -1,3 +1,5 @@ +"""Package version helpers.""" + from importlib.metadata import PackageNotFoundError, version