From c4dae5e8d1dc4c4417fba73740c85605eac4f3ee Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Sun, 11 Jun 2023 16:04:25 -0300 Subject: [PATCH] Adds Formatter to Project --- diceplayer/__init__.py | 1 - diceplayer/__main__.py | 16 +- diceplayer/player.py | 156 ++++----- diceplayer/shared/config/dice_config.py | 19 +- diceplayer/shared/config/gaussian_config.py | 14 +- diceplayer/shared/config/player_config.py | 30 +- diceplayer/shared/environment/atom.py | 18 +- diceplayer/shared/environment/molecule.py | 32 +- diceplayer/shared/environment/system.py | 36 +- diceplayer/shared/interface/__interface.py | 5 +- diceplayer/shared/interface/dice_interface.py | 82 ++--- .../shared/interface/gaussian_interface.py | 151 ++++----- diceplayer/shared/utils/dataclass_protocol.py | 2 +- diceplayer/shared/utils/logger.py | 11 +- diceplayer/shared/utils/misc.py | 5 +- diceplayer/shared/utils/ptable.py | 244 ++++++++++++-- poetry.lock | 133 +++++++- pyproject.toml | 2 + tests/mocks/mock_proc.py | 6 +- tests/shared/config/test_dice_dto.py | 60 ++-- tests/shared/config/test_gaussian_dto.py | 24 +- tests/shared/config/test_player_dto.py | 54 ++- tests/shared/environment/test_atom.py | 2 +- tests/shared/environment/test_molecule.py | 88 +++-- tests/shared/environment/test_system.py | 9 +- tests/shared/interface/test_dice_interface.py | 317 ++++++++++++------ .../interface/test_gaussian_interface.py | 42 +-- tests/shared/utils/test_logger.py | 83 +++-- tests/test_player.py | 230 ++++++++----- 29 files changed, 1151 insertions(+), 721 deletions(-) diff --git a/diceplayer/__init__.py b/diceplayer/__init__.py index b2344e9..b8fea4a 100644 --- a/diceplayer/__init__.py +++ b/diceplayer/__init__.py @@ -1,4 +1,3 @@ from diceplayer.shared.utils.logger import Logger - logger = Logger(__name__) diff --git a/diceplayer/__main__.py b/diceplayer/__main__.py index 1e4fa0e..d07ccac 100644 --- a/diceplayer/__main__.py +++ b/diceplayer/__main__.py @@ -1,12 +1,12 @@ -from diceplayer.shared.interface.dice_interface import DiceInterface -from diceplayer.player import Player from diceplayer import logger +from diceplayer.player import Player +from diceplayer.shared.interface.dice_interface import DiceInterface -from pathlib import Path import argparse import logging import pickle import sys +from pathlib import Path __VERSION = "v0.0.1" @@ -25,18 +25,20 @@ def main(): "-v", "--version", action="version", version="diceplayer-" + __VERSION ) parser.add_argument( - "-i", "--input", + "-i", + "--input", dest="infile", default="control.yml", metavar="INFILE", - help="input file of diceplayer [default = control.in]" + help="input file of diceplayer [default = control.in]", ) parser.add_argument( - "-o", "--output", + "-o", + "--output", dest="outfile", default="run.log", metavar="OUTFILE", - help="output file of diceplayer [default = run.log]" + help="output file of diceplayer [default = run.log]", ) args = parser.parse_args() diff --git a/diceplayer/player.py b/diceplayer/player.py index a7aa562..021202e 100644 --- a/diceplayer/player.py +++ b/diceplayer/player.py @@ -1,24 +1,24 @@ -from diceplayer.shared.interface.gaussian_interface import GaussianInterface -from diceplayer.shared.interface.dice_interface import DiceInterface -from diceplayer.shared.utils.dataclass_protocol import Dataclass +from diceplayer import logger +from diceplayer.shared.config.dice_config import DiceConfig from diceplayer.shared.config.gaussian_config import GaussianDTO from diceplayer.shared.config.player_config import PlayerConfig -from diceplayer.shared.config.dice_config import DiceConfig -from diceplayer.shared.utils.misc import weekday_date_time +from diceplayer.shared.environment.atom import Atom from diceplayer.shared.environment.molecule import Molecule from diceplayer.shared.environment.system import System -from diceplayer.shared.environment.atom import Atom +from diceplayer.shared.interface.dice_interface import DiceInterface +from diceplayer.shared.interface.gaussian_interface import GaussianInterface +from diceplayer.shared.utils.dataclass_protocol import Dataclass +from diceplayer.shared.utils.misc import weekday_date_time from diceplayer.shared.utils.ptable import atomsymb -from diceplayer import logger -from dataclasses import fields -from typing import Type, Tuple -from pathlib import Path -import pickle import yaml -import sys -import os +import os +import pickle +import sys +from dataclasses import fields +from pathlib import Path +from typing import Tuple, Type ENV = ["OMP_STACKSIZE"] @@ -29,9 +29,7 @@ class Player: raise ValueError("Must specify either infile or optimization") elif infile is not None: - self.config = self.set_config( - self.read_keywords(infile) - ) + self.config = self.set_config(self.read_keywords(infile)) self.system = System() @@ -60,7 +58,6 @@ class Player: ) for cycle in range(self.initial_cycle, self.initial_cycle + self.config.maxcyc): - logger.info( f"------------------------------------------------------------------------------------------\n" f" Step # {cycle}\n" @@ -78,9 +75,7 @@ class Player: def prepare_system(self): for i, mol in enumerate(self.system.molecule): - logger.info( - f"Molecule {i + 1} - {mol.molname}" - ) + logger.info(f"Molecule {i + 1} - {mol.molname}") mol.print_mol_info() logger.info( @@ -113,7 +108,6 @@ class Player: geoms_file_path.touch() def print_keywords(self) -> None: - def log_keywords(config: Dataclass, dto: Type[Dataclass]): for key in sorted(list(map(lambda f: f.name, fields(dto)))): if getattr(config, key) is not None: @@ -162,9 +156,7 @@ class Player: with open(self.config.dice.ljname) as file: ljc_data = file.readlines() else: - raise RuntimeError( - f"Potential file {self.config.dice.ljname} not found." - ) + raise RuntimeError(f"Potential file {self.config.dice.ljname} not found.") combrule = ljc_data.pop(0).split()[0] if combrule not in ("*", "+"): @@ -191,7 +183,6 @@ class Player: ) for i in range(ntypes): - try: nsites, molname = ljc_data.pop(0).split()[:2] except ValueError: @@ -209,10 +200,7 @@ class Player: atom_fields = ["lbl", "na", "rx", "ry", "rz", "chg", "eps", "sig"] for j in range(nsites): - new_atom = dict(zip( - atom_fields, - ljc_data.pop(0).split() - )) + new_atom = dict(zip(atom_fields, ljc_data.pop(0).split())) self.system.molecule[i].add_atom( Atom(**self.validate_atom_dict(i, j, new_atom)) ) @@ -227,16 +215,12 @@ class Player: ) logger.info(f"Combination rule: {self.config.dice.combrule}") - logger.info( - f"Types of molecules: {len(self.system.molecule)}\n" - ) + logger.info(f"Types of molecules: {len(self.system.molecule)}\n") i = 0 for mol in self.system.molecule: i += 1 - logger.info( - "{} atoms in molecule type {}:".format(len(mol.atom), i) - ) + logger.info("{} atoms in molecule type {}:".format(len(mol.atom), i)) logger.info( "---------------------------------------------------------------------------------" ) @@ -285,42 +269,37 @@ class Player: self.gaussian_interface.reset() if self.config.opt: - if 'position' not in result: - raise RuntimeError( - 'Optimization failed. No position found in result.' - ) + if "position" not in result: + raise RuntimeError("Optimization failed. No position found in result.") - self.system.update_molecule(result['position']) + self.system.update_molecule(result["position"]) else: - if 'charges' not in result: + if "charges" not in result: raise RuntimeError( - 'Charges optimization failed. No charges found in result.' + "Charges optimization failed. No charges found in result." ) - diff = self.system.molecule[0] \ - .update_charges(result['charges']) + diff = self.system.molecule[0].update_charges(result["charges"]) self.system.print_charges_and_dipole(cycle) self.print_geoms(cycle) if diff < self.config.gaussian.chg_tol: - logger.info( - f'Charges converged after {cycle} cycles.' - ) + logger.info(f"Charges converged after {cycle} cycles.") raise StopIteration() def print_geoms(self, cycle: int): - with open(self.config.geoms_file, 'a') as file: - file.write(f'Cycle # {cycle}\n') + with open(self.config.geoms_file, "a") as file: + file.write(f"Cycle # {cycle}\n") for atom in self.system.molecule[0].atom: symbol = atomsymb[atom.na] file.write( - f'{symbol:<2s} {atom.rx:>10.6f} {atom.ry:>10.6f} {atom.rz:>10.6f}\n' + f"{symbol:<2s} {atom.rx:>10.6f} {atom.ry:>10.6f} {atom.rz:>10.6f}\n" ) - file.write('\n') + file.write("\n") @staticmethod def validate_atom_dict(molecule_type, molecule_site, atom_dict: dict) -> dict: @@ -329,69 +308,69 @@ class Player: if len(atom_dict) < 8: raise ValueError( - f'Invalid number of fields for site {molecule_site} for molecule type {molecule_type}.' + f"Invalid number of fields for site {molecule_site} for molecule type {molecule_type}." ) try: - atom_dict['lbl'] = int(atom_dict['lbl']) + atom_dict["lbl"] = int(atom_dict["lbl"]) except Exception: raise ValueError( - f'Invalid lbl fields for site {molecule_site} for molecule type {molecule_type}.' + f"Invalid lbl fields for site {molecule_site} for molecule type {molecule_type}." ) try: - atom_dict['na'] = int(atom_dict['na']) + atom_dict["na"] = int(atom_dict["na"]) except Exception: raise ValueError( - f'Invalid na fields for site {molecule_site} for molecule type {molecule_type}.' + f"Invalid na fields for site {molecule_site} for molecule type {molecule_type}." ) try: - atom_dict['rx'] = float(atom_dict['rx']) + atom_dict["rx"] = float(atom_dict["rx"]) except Exception: raise ValueError( - f'Invalid rx fields for site {molecule_site} for molecule type {molecule_type}. ' - f'Value must be a float.' + f"Invalid rx fields for site {molecule_site} for molecule type {molecule_type}. " + f"Value must be a float." ) try: - atom_dict['ry'] = float(atom_dict['ry']) + atom_dict["ry"] = float(atom_dict["ry"]) except Exception: raise ValueError( - f'Invalid ry fields for site {molecule_site} for molecule type {molecule_type}. ' - f'Value must be a float.' + f"Invalid ry fields for site {molecule_site} for molecule type {molecule_type}. " + f"Value must be a float." ) try: - atom_dict['rz'] = float(atom_dict['rz']) + atom_dict["rz"] = float(atom_dict["rz"]) except Exception: raise ValueError( - f'Invalid rz fields for site {molecule_site} for molecule type {molecule_type}. ' - f'Value must be a float.' + f"Invalid rz fields for site {molecule_site} for molecule type {molecule_type}. " + f"Value must be a float." ) try: - atom_dict['chg'] = float(atom_dict['chg']) + atom_dict["chg"] = float(atom_dict["chg"]) except Exception: raise ValueError( - f'Invalid chg fields for site {molecule_site} for molecule type {molecule_type}. ' - f'Value must be a float.' + f"Invalid chg fields for site {molecule_site} for molecule type {molecule_type}. " + f"Value must be a float." ) try: - atom_dict['eps'] = float(atom_dict['eps']) + atom_dict["eps"] = float(atom_dict["eps"]) except Exception: raise ValueError( - f'Invalid eps fields for site {molecule_site} for molecule type {molecule_type}. ' - f'Value must be a float.' + f"Invalid eps fields for site {molecule_site} for molecule type {molecule_type}. " + f"Value must be a float." ) try: - atom_dict['sig'] = float(atom_dict['sig']) + atom_dict["sig"] = float(atom_dict["sig"]) except Exception: raise ValueError( - f'Invalid sig fields for site {molecule_site} for molecule type {molecule_type}. ' - f'Value must be a float.' + f"Invalid sig fields for site {molecule_site} for molecule type {molecule_type}. " + f"Value must be a float." ) return atom_dict @@ -400,9 +379,7 @@ class Player: formatstr = "{:<3d} {:>3d} {:>10.5f} {:>10.5f} {:>10.5f} {:>10.6f} {:>9.5f} {:>7.4f} {:>9.4f}" mol = self.system.molecule[0] - logger.info( - "{} atoms in molecule type {}:".format(len(mol.atom), 1) - ) + logger.info("{} atoms in molecule type {}:".format(len(mol.atom), 1)) logger.info( "---------------------------------------------------------------------------------" ) @@ -432,28 +409,21 @@ class Player: def save_run_in_pickle(self, cycle): try: - with open('latest-step.pkl', 'wb') as pickle_file: - pickle.dump( - (self.config, self.system, cycle), - pickle_file - ) + with open("latest-step.pkl", "wb") as pickle_file: + pickle.dump((self.config, self.system, cycle), pickle_file) except Exception: - raise RuntimeError( - f'Could not save pickle file latest-step.pkl.' - ) + raise RuntimeError(f"Could not save pickle file latest-step.pkl.") @staticmethod def load_run_from_pickle() -> Tuple[PlayerConfig, System, int]: pickle_path = Path("latest-step.pkl") try: - with open(pickle_path, 'rb') as pickle_file: + with open(pickle_path, "rb") as pickle_file: save = pickle.load(pickle_file) return save[0], save[1], save[2] + 1 except Exception: - raise RuntimeError( - f'Could not load pickle file {pickle_path}.' - ) + raise RuntimeError(f"Could not load pickle file {pickle_path}.") @staticmethod def set_config(data: dict) -> PlayerConfig: @@ -461,18 +431,16 @@ class Player: @staticmethod def read_keywords(infile) -> dict: - with open(infile, 'r') as yml_file: + with open(infile, "r") as yml_file: config = yaml.load(yml_file, Loader=yaml.SafeLoader) if "diceplayer" in config: return config.get("diceplayer") - raise RuntimeError( - f'Could not find diceplayer section in {infile}.' - ) + raise RuntimeError(f"Could not find diceplayer section in {infile}.") @classmethod - def from_file(cls, infile: str) -> 'Player': + def from_file(cls, infile: str) -> "Player": return cls(infile=infile) @classmethod diff --git a/diceplayer/shared/config/dice_config.py b/diceplayer/shared/config/dice_config.py index b2a5b66..e74605b 100644 --- a/diceplayer/shared/config/dice_config.py +++ b/diceplayer/shared/config/dice_config.py @@ -1,7 +1,8 @@ from diceplayer.shared.utils.dataclass_protocol import Dataclass -from dataclasses import dataclass from dacite import from_dict + +from dataclasses import dataclass from typing import List @@ -10,6 +11,7 @@ class DiceConfig(Dataclass): """ Data Transfer Object for the Dice configuration. """ + ljname: str outname: str dens: float @@ -22,24 +24,17 @@ class DiceConfig(Dataclass): press: float = 1.0 temp: float = 300.0 progname: str = "dice" - randominit: str = 'first' + randominit: str = "first" def __post_init__(self): - if not isinstance(self.ljname, str): - raise ValueError( - "Error: 'ljname' keyword not specified in config file" - ) + raise ValueError("Error: 'ljname' keyword not specified in config file") if not isinstance(self.outname, str): - raise ValueError( - "Error: 'outname' keyword not specified in config file" - ) + raise ValueError("Error: 'outname' keyword not specified in config file") if not isinstance(self.dens, float): - raise ValueError( - "Error: 'dens' keyword not specified in config file" - ) + raise ValueError("Error: 'dens' keyword not specified in config file") if not isinstance(self.nmol, list): raise ValueError( diff --git a/diceplayer/shared/config/gaussian_config.py b/diceplayer/shared/config/gaussian_config.py index b5b24ce..930afc2 100644 --- a/diceplayer/shared/config/gaussian_config.py +++ b/diceplayer/shared/config/gaussian_config.py @@ -1,31 +1,29 @@ from diceplayer.shared.utils.dataclass_protocol import Dataclass -from dataclasses import dataclass from dacite import from_dict +from dataclasses import dataclass + @dataclass class GaussianDTO(Dataclass): """ Data Transfer Object for the Gaussian configuration. """ + level: str qmprog: str chgmult = [0, 1] - pop: str = 'chelpg' + pop: str = "chelpg" chg_tol: float = 0.01 keywords: str = None def __post_init__(self): if self.qmprog not in ("g03", "g09", "g16"): - raise ValueError( - "Error: invalid qmprog value." - ) + raise ValueError("Error: invalid qmprog value.") if self.level is None: - raise ValueError( - "Error: 'level' keyword not specified in config file." - ) + raise ValueError("Error: 'level' keyword not specified in config file.") @classmethod def from_dict(cls, param: dict): diff --git a/diceplayer/shared/config/player_config.py b/diceplayer/shared/config/player_config.py index ce1f7d9..6cac4d2 100644 --- a/diceplayer/shared/config/player_config.py +++ b/diceplayer/shared/config/player_config.py @@ -1,9 +1,10 @@ -from diceplayer.shared.utils.dataclass_protocol import Dataclass -from diceplayer.shared.config.gaussian_config import GaussianDTO from diceplayer.shared.config.dice_config import DiceConfig +from diceplayer.shared.config.gaussian_config import GaussianDTO +from diceplayer.shared.utils.dataclass_protocol import Dataclass + +from dacite import from_dict from dataclasses import dataclass -from dacite import from_dict @dataclass @@ -11,6 +12,7 @@ class PlayerConfig(Dataclass): """ Data Transfer Object for the player configuration. """ + opt: bool maxcyc: int nprocs: int @@ -21,10 +23,10 @@ class PlayerConfig(Dataclass): mem: int = None switchcyc: int = 3 - qmprog: str = 'g16' + qmprog: str = "g16" altsteps: int = 20000 - geoms_file = 'geoms.xyz' - simulation_dir = 'simfiles' + geoms_file = "geoms.xyz" + simulation_dir = "simfiles" def __post_init__(self): MIN_STEP = 20000 @@ -33,16 +35,12 @@ class PlayerConfig(Dataclass): @classmethod def from_dict(cls, param: dict): - if param['dice'] is None: - raise ValueError( - "Error: 'dice' keyword not specified in config file." - ) - param['dice'] = DiceConfig.from_dict(param['dice']) + if param["dice"] is None: + raise ValueError("Error: 'dice' keyword not specified in config file.") + param["dice"] = DiceConfig.from_dict(param["dice"]) - if param['gaussian'] is None: - raise ValueError( - "Error: 'gaussian' keyword not specified in config file." - ) - param['gaussian'] = GaussianDTO.from_dict(param['gaussian']) + if param["gaussian"] is None: + raise ValueError("Error: 'gaussian' keyword not specified in config file.") + param["gaussian"] = GaussianDTO.from_dict(param["gaussian"]) return from_dict(PlayerConfig, param) diff --git a/diceplayer/shared/environment/atom.py b/diceplayer/shared/environment/atom.py index f093ee5..2f0e40d 100644 --- a/diceplayer/shared/environment/atom.py +++ b/diceplayer/shared/environment/atom.py @@ -17,15 +17,15 @@ class Atom: """ def __init__( - self, - lbl: int, - na: int, - rx: float, - ry: float, - rz: float, - chg: float, - eps: float, - sig: float, + self, + lbl: int, + na: int, + rx: float, + ry: float, + rz: float, + chg: float, + eps: float, + sig: float, ) -> None: """ The constructor function __init__ is used to create new instances of the Atom class. diff --git a/diceplayer/shared/environment/molecule.py b/diceplayer/shared/environment/molecule.py index 6b89278..61dd8c2 100644 --- a/diceplayer/shared/environment/molecule.py +++ b/diceplayer/shared/environment/molecule.py @@ -1,18 +1,18 @@ from __future__ import annotations -from diceplayer.shared.utils.ptable import ghost_number +from diceplayer import logger from diceplayer.shared.environment.atom import Atom from diceplayer.shared.utils.misc import BOHR2ANG -from diceplayer import logger +from diceplayer.shared.utils.ptable import ghost_number -from nptyping import NDArray, Shape, Float -from numpy.linalg import linalg import numpy as np +from nptyping import Float, NDArray, Shape +from numpy.linalg import linalg -from typing import List, Any, Tuple, Union -from copy import deepcopy import logging import math +from copy import deepcopy +from typing import Any, List, Tuple, Union class Molecule: @@ -127,9 +127,9 @@ class Molecule: dx = atom1.rx - atom2.rx dy = atom1.ry - atom2.ry dz = atom1.rz - atom2.rz - distances.append(math.sqrt(dx ** 2 + dy ** 2 + dz ** 2)) + distances.append(math.sqrt(dx**2 + dy**2 + dz**2)) - return np.array(distances).reshape(dim, dim-1) + return np.array(distances).reshape(dim, dim - 1) def inertia_tensor(self) -> NDArray[Shape["3, 3"], Float]: """ @@ -147,9 +147,9 @@ class Molecule: dy = atom.ry - self.com[1] dz = atom.rz - self.com[2] - Ixx += atom.mass * (dy ** 2 + dz ** 2) - Iyy += atom.mass * (dz ** 2 + dx ** 2) - Izz += atom.mass * (dx ** 2 + dy ** 2) + Ixx += atom.mass * (dy**2 + dz**2) + Iyy += atom.mass * (dz**2 + dx**2) + Izz += atom.mass * (dx**2 + dy**2) Ixy += atom.mass * dx * dy * -1 Ixz += atom.mass * dx * dz * -1 @@ -169,7 +169,9 @@ class Molecule: try: evals, evecs = linalg.eigh(self.inertia_tensor()) except ValueError: - raise RuntimeError("Error: diagonalization of inertia tensor did not converge") + raise RuntimeError( + "Error: diagonalization of inertia tensor did not converge" + ) return evals, evecs @@ -355,7 +357,7 @@ class Molecule: ) ) - def minimum_distance(self, molec: 'Molecule') -> float: + def minimum_distance(self, molec: "Molecule") -> float: """ Return the minimum distance between two molecules @@ -374,6 +376,6 @@ class Molecule: dx = atom1.rx - atom2.rx dy = atom1.ry - atom2.ry dz = atom1.rz - atom2.rz - distances.append(math.sqrt(dx ** 2 + dy ** 2 + dz ** 2)) + distances.append(math.sqrt(dx**2 + dy**2 + dz**2)) - return min(distances) \ No newline at end of file + return min(distances) diff --git a/diceplayer/shared/environment/system.py b/diceplayer/shared/environment/system.py index 8034877..f8e5dd8 100644 --- a/diceplayer/shared/environment/system.py +++ b/diceplayer/shared/environment/system.py @@ -1,13 +1,14 @@ -from diceplayer.shared.environment.molecule import Molecule -from diceplayer.shared.utils.ptable import atomsymb -from diceplayer.shared.utils.misc import BOHR2ANG from diceplayer import logger +from diceplayer.shared.environment.molecule import Molecule +from diceplayer.shared.utils.misc import BOHR2ANG +from diceplayer.shared.utils.ptable import atomsymb -from typing import List, Tuple, TextIO -from copy import deepcopy -from numpy import linalg import numpy as np +from numpy import linalg + import math +from copy import deepcopy +from typing import List, TextIO, Tuple class System: @@ -59,7 +60,6 @@ class System: logger.info(f"RMSD = {rmsd:>8.5f} Angstrom") def rmsd_fit(self, p_index: int, r_index: int) -> Tuple[float, Molecule]: - projecting_mol = self.molecule[p_index] reference_mol = self.molecule[r_index] @@ -117,9 +117,9 @@ class System: rmsd = 0 for i in range(dim): rmsd += ( - (x[i, 0] - y[i, 0]) ** 2 - + (x[i, 1] - y[i, 1]) ** 2 - + (x[i, 2] - y[i, 2]) ** 2 + (x[i, 0] - y[i, 0]) ** 2 + + (x[i, 1] - y[i, 1]) ** 2 + + (x[i, 2] - y[i, 2]) ** 2 ) rmsd = math.sqrt(rmsd / dim) @@ -214,12 +214,12 @@ class System: # def print_charges_and_dipole(self, cycle: int) -> None: """ - Print the charges and dipole of the molecule in the Output file + Print the charges and dipole of the molecule in the Output file - Args: - cycle (int): Number of the cycle - fh (TextIO): Output file - """ + Args: + cycle (int): Number of the cycle + fh (TextIO): Output file + """ logger.info("Cycle # {}\n".format(cycle)) logger.info("Number of site: {}\n".format(len(self.molecule[0].atom))) @@ -228,6 +228,10 @@ class System: logger.info( "{:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f}\n".format( - chargesAndDipole[0], chargesAndDipole[1], chargesAndDipole[2], chargesAndDipole[3], chargesAndDipole[4] + chargesAndDipole[0], + chargesAndDipole[1], + chargesAndDipole[2], + chargesAndDipole[3], + chargesAndDipole[4], ) ) diff --git a/diceplayer/shared/interface/__interface.py b/diceplayer/shared/interface/__interface.py index bede652..89a06e3 100644 --- a/diceplayer/shared/interface/__interface.py +++ b/diceplayer/shared/interface/__interface.py @@ -7,10 +7,7 @@ from abc import ABC, abstractmethod class Interface(ABC): - __slots__ = [ - 'step', - 'system' - ] + __slots__ = ["step", "system"] def __init__(self): self.system: System | None = None diff --git a/diceplayer/shared/interface/dice_interface.py b/diceplayer/shared/interface/dice_interface.py index 4b28774..db97999 100644 --- a/diceplayer/shared/interface/dice_interface.py +++ b/diceplayer/shared/interface/dice_interface.py @@ -1,20 +1,21 @@ from __future__ import annotations +from diceplayer import logger from diceplayer.shared.config.player_config import PlayerConfig from diceplayer.shared.environment.system import System from diceplayer.shared.interface import Interface -from diceplayer import logger -from multiprocessing import Process, connection from setproctitle import setproctitle -from typing import Final, TextIO -from pathlib import Path -import subprocess -import shutil -import random -import time -import sys + import os +import random +import shutil +import subprocess +import sys +import time +from multiprocessing import Process, connection +from pathlib import Path +from typing import Final, TextIO DICE_END_FLAG: Final[str] = "End of simulation" DICE_FLAG_LINE: Final[int] = -2 @@ -74,19 +75,11 @@ class DiceInterface(Interface): if not simulation_dir.exists(): simulation_dir.mkdir(parents=True) - proc_dir = Path( - simulation_dir, - f"step{cycle:02d}", - f"p{proc:02d}" - ) + proc_dir = Path(simulation_dir, f"step{cycle:02d}", f"p{proc:02d}") proc_dir.mkdir(parents=True, exist_ok=True) def _make_dice_inputs(self, cycle, proc): - proc_dir = Path( - self.step.simulation_dir, - f"step{cycle:02d}", - f"p{proc:02d}" - ) + proc_dir = Path(self.step.simulation_dir, f"step{cycle:02d}", f"p{proc:02d}") self._make_potentials(proc_dir) @@ -94,17 +87,17 @@ class DiceInterface(Interface): # This is logic is used to make the initial configuration file # for the next cycle using the last.xyz file from the previous cycle. - if self.step.dice.randominit == 'first' and cycle > 1: + if self.step.dice.randominit == "first" and cycle > 1: last_xyz = Path( self.step.simulation_dir, f"step{(cycle - 1):02d}", f"p{proc:02d}", - "last.xyz" + "last.xyz", ) if not last_xyz.exists(): raise FileNotFoundError(f"File {last_xyz} not found.") - with open(last_xyz, 'r') as last_xyz_file: + with open(last_xyz, "r") as last_xyz_file: self._make_init_file(proc_dir, last_xyz_file) last_xyz_file.seek(0) self.step.dice.dens = self._new_density(last_xyz_file) @@ -122,11 +115,7 @@ class DiceInterface(Interface): def _run_dice(self, cycle: int, proc: int): working_dir = os.getcwd() - proc_dir = Path( - self.step.simulation_dir, - f"step{cycle:02d}", - f"p{proc:02d}" - ) + proc_dir = Path(self.step.simulation_dir, f"step{cycle:02d}", f"p{proc:02d}") logger.info( f"Simulation process {str(proc_dir)} initiated with pid {os.getpid()}" @@ -134,7 +123,7 @@ class DiceInterface(Interface): os.chdir(proc_dir) - if not (self.step.dice.randominit == 'first' and cycle > 1): + if not (self.step.dice.randominit == "first" and cycle > 1): self.run_dice_file(cycle, proc, "NVT.ter") if len(self.step.dice.nstep) == 2: @@ -168,17 +157,16 @@ class DiceInterface(Interface): SECONDARY_MOLECULE_LENGTH = 0 for i in range(1, len(self.step.dice.nmol)): - SECONDARY_MOLECULE_LENGTH += self.step.dice.nmol[i] * len(self.system.molecule[i].atom) + SECONDARY_MOLECULE_LENGTH += self.step.dice.nmol[i] * len( + self.system.molecule[i].atom + ) xyz_lines = xyz_lines[-SECONDARY_MOLECULE_LENGTH:] input_file = Path(proc_dir, self.step.dice.outname + ".xy") - with open(input_file, 'w') as f: - + with open(input_file, "w") as f: for atom in self.system.molecule[0].atom: - f.write( - f"{atom.rx:>10.6f} {atom.ry:>10.6f} {atom.rz:>10.6f}\n" - ) + f.write(f"{atom.rx:>10.6f} {atom.ry:>10.6f} {atom.rz:>10.6f}\n") for line in xyz_lines: atom = line.split() @@ -205,7 +193,7 @@ class DiceInterface(Interface): def _make_nvt_ter(self, cycle, proc_dir): file = Path(proc_dir, "NVT.ter") - with open(file, 'w') as f: + with open(file, "w") as f: f.write(f"title = {self.title} - NVT Thermalization\n") f.write(f"ncores = {self.step.ncores}\n") f.write(f"ljname = {self.step.dice.ljname}\n") @@ -236,9 +224,8 @@ class DiceInterface(Interface): f.write(f"upbuf = {self.step.dice.upbuf}") def _make_nvt_eq(self, cycle, proc_dir): - file = Path(proc_dir, "NVT.eq") - with open(file, 'w') as f: + with open(file, "w") as f: f.write(f"title = {self.title} - NVT Production\n") f.write(f"ncores = {self.step.ncores}\n") f.write(f"ljname = {self.step.dice.ljname}\n") @@ -269,9 +256,8 @@ class DiceInterface(Interface): f.write("seed = {}\n".format(seed)) def _make_npt_ter(self, cycle, proc_dir): - file = Path(proc_dir, "NPT.ter") - with open(file, 'w') as f: + with open(file, "w") as f: f.write(f"title = {self.title} - NPT Thermalization\n") f.write(f"ncores = {self.step.ncores}\n") f.write(f"ljname = {self.step.dice.ljname}\n") @@ -303,7 +289,7 @@ class DiceInterface(Interface): def _make_npt_eq(self, proc_dir): file = Path(proc_dir, "NPT.eq") - with open(file, 'w') as f: + with open(file, "w") as f: f.write(f"title = {self.title} - NPT Production\n") f.write(f"ncores = {self.step.ncores}\n") f.write(f"ljname = {self.step.dice.ljname}\n") @@ -332,7 +318,7 @@ class DiceInterface(Interface): fstr = "{:<3d} {:>3d} {:>10.5f} {:>10.5f} {:>10.5f} {:>10.6f} {:>9.5f} {:>7.4f}\n" file = Path(proc_dir, self.step.dice.ljname) - with open(file, 'w') as f: + with open(file, "w") as f: f.write(f"{self.step.dice.combrule}\n") f.write(f"{len(self.step.dice.nmol)}\n") @@ -370,7 +356,9 @@ class DiceInterface(Interface): ) def run_dice_file(self, cycle: int, proc: int, file_name: str): - with open(Path(file_name), 'r') as infile, open(Path(file_name + ".out"), 'w') as outfile: + with open(Path(file_name), "r") as infile, open( + Path(file_name + ".out"), "w" + ) as outfile: if shutil.which("bash") is not None: exit_status = subprocess.call( [ @@ -385,11 +373,15 @@ class DiceInterface(Interface): ) if exit_status != 0: - raise RuntimeError(f"Dice process step{cycle:02d}-p{proc:02d} did not exit properly") + raise RuntimeError( + f"Dice process step{cycle:02d}-p{proc:02d} did not exit properly" + ) - with open(Path(file_name + ".out"), 'r') as outfile: + with open(Path(file_name + ".out"), "r") as outfile: flag = outfile.readlines()[DICE_FLAG_LINE].strip() if flag != DICE_END_FLAG: - raise RuntimeError(f"Dice process step{cycle:02d}-p{proc:02d} did not exit properly") + raise RuntimeError( + f"Dice process step{cycle:02d}-p{proc:02d} did not exit properly" + ) logger.info(f"Dice {file_name} - step{cycle:02d}-p{proc:02d} exited properly") diff --git a/diceplayer/shared/interface/gaussian_interface.py b/diceplayer/shared/interface/gaussian_interface.py index ee9dc00..1dd69bb 100644 --- a/diceplayer/shared/interface/gaussian_interface.py +++ b/diceplayer/shared/interface/gaussian_interface.py @@ -1,24 +1,23 @@ from __future__ import annotations +from diceplayer import logger from diceplayer.shared.config.player_config import PlayerConfig +from diceplayer.shared.environment.atom import Atom from diceplayer.shared.environment.molecule import Molecule from diceplayer.shared.environment.system import System -from diceplayer.shared.environment.atom import Atom +from diceplayer.shared.interface import Interface from diceplayer.shared.utils.misc import date_time from diceplayer.shared.utils.ptable import atomsymb -from diceplayer.shared.interface import Interface -from diceplayer import logger -from typing import Tuple, List, Dict, Any - -from nptyping import NDArray import numpy as np +from nptyping import NDArray -from pathlib import Path +import os +import shutil import subprocess import textwrap -import shutil -import os +from pathlib import Path +from typing import Any, Dict, List, Tuple class GaussianInterface(Interface): @@ -33,10 +32,7 @@ class GaussianInterface(Interface): self._copy_chk_file_from_previous_step(cycle) asec_charges = self.populate_asec_vdw(cycle) - self._make_gaussian_input_file( - cycle, - asec_charges - ) + self._make_gaussian_input_file(cycle, asec_charges) self._run_gaussian(cycle) self._run_formchk(cycle) @@ -49,9 +45,7 @@ class GaussianInterface(Interface): raise NotImplementedError("Optimization not implemented yet.") else: - return_value['charges'] = np.array( - self._read_charges_from_fchk(cycle) - ) + return_value["charges"] = np.array(self._read_charges_from_fchk(cycle)) return return_value @@ -60,36 +54,22 @@ class GaussianInterface(Interface): del self.system def _make_qm_dir(self, cycle: int): - qm_dir_path = Path( - self.step.simulation_dir, - f"step{cycle:02d}", - "qm" - ) + qm_dir_path = Path(self.step.simulation_dir, f"step{cycle:02d}", "qm") if not qm_dir_path.exists(): qm_dir_path.mkdir() def _copy_chk_file_from_previous_step(self, cycle: int): current_chk_file_path = Path( - self.step.simulation_dir, - f"step{cycle:02d}", - "qm", - f"asec.chk" + self.step.simulation_dir, f"step{cycle:02d}", "qm", f"asec.chk" ) if current_chk_file_path.exists(): - raise FileExistsError( - f"File {current_chk_file_path} already exists." - ) + raise FileExistsError(f"File {current_chk_file_path} already exists.") previous_chk_file_path = Path( - self.step.simulation_dir, - f"step{(cycle - 1):02d}", - "qm", - f"asec.chk" + self.step.simulation_dir, f"step{(cycle - 1):02d}", "qm", f"asec.chk" ) if not previous_chk_file_path.exists(): - raise FileNotFoundError( - f"File {previous_chk_file_path} does not exist." - ) + raise FileNotFoundError(f"File {previous_chk_file_path} does not exist.") shutil.copy(previous_chk_file_path, current_chk_file_path) @@ -104,17 +84,19 @@ class GaussianInterface(Interface): for proc in range(1, self.step.nprocs + 1): proc_charges.append(self._read_charges_from_last_step(cycle, proc)) - asec_charges, thickness, picked_mols = \ - self._evaluate_proc_charges(nsites_total, proc_charges) + asec_charges, thickness, picked_mols = self._evaluate_proc_charges( + nsites_total, proc_charges + ) - logger.info(f"In average, {(sum(picked_mols) / norm_factor):^7.2f} molecules\n" - f"were selected from each of the {len(picked_mols)} configurations\n" - f"of the production simulations to form the ASEC, comprising a shell with\n" - f"minimum thickness of {(sum(thickness) / norm_factor):>6.2f} Angstrom\n" - ) + logger.info( + f"In average, {(sum(picked_mols) / norm_factor):^7.2f} molecules\n" + f"were selected from each of the {len(picked_mols)} configurations\n" + f"of the production simulations to form the ASEC, comprising a shell with\n" + f"minimum thickness of {(sum(thickness) / norm_factor):>6.2f} Angstrom\n" + ) for charge in asec_charges: - charge['chg'] = charge['chg'] / norm_factor + charge["chg"] = charge["chg"] / norm_factor return asec_charges @@ -135,23 +117,19 @@ class GaussianInterface(Interface): def _read_charges_from_last_step(self, cycle: int, proc: int) -> list[str]: last_xyz_file_path = Path( - self.step.simulation_dir, - f"step{cycle:02d}", - f"p{proc:02d}", - "last.xyz" + self.step.simulation_dir, f"step{cycle:02d}", f"p{proc:02d}", "last.xyz" ) if not last_xyz_file_path.exists(): - raise FileNotFoundError( - f"File {last_xyz_file_path} does not exist." - ) + raise FileNotFoundError(f"File {last_xyz_file_path} does not exist.") - with open(last_xyz_file_path, 'r') as last_xyz_file: + with open(last_xyz_file_path, "r") as last_xyz_file: lines = last_xyz_file.readlines() return lines - def _evaluate_proc_charges(self, total_nsites: int, proc_charges: list[list[str]]) -> Tuple[ - List[Dict[str, float | Any]], List[float], List[int]]: + def _evaluate_proc_charges( + self, total_nsites: int, proc_charges: list[list[str]] + ) -> Tuple[List[Dict[str, float | Any]], List[float], List[int]]: asec_charges = [] thickness = [] @@ -164,9 +142,7 @@ class GaussianInterface(Interface): f"Number of sites does not match total number of sites." ) - thickness.append( - self._calculate_proc_thickness(charges) - ) + thickness.append(self._calculate_proc_thickness(charges)) nsites_ref_mol = len(self.system.molecule[0].atom) charges = charges[nsites_ref_mol:] @@ -183,7 +159,12 @@ class GaussianInterface(Interface): for site in range(len(self.system.molecule[type].atom)): line = charges.pop(0).split() - if line[0].title() != atomsymb[self.system.molecule[type].atom[site].na].strip(): + if ( + line[0].title() + != atomsymb[ + self.system.molecule[type].atom[site].na + ].strip() + ): raise SyntaxError( f"Error: Invalid Dice Output. Atom type does not match." ) @@ -201,13 +182,18 @@ class GaussianInterface(Interface): ) ) - distance = self.system.molecule[0] \ - .minimum_distance(new_molecule) + distance = self.system.molecule[0].minimum_distance(new_molecule) if distance < thickness[-1]: for atom in new_molecule.atom: asec_charges.append( - {"lbl": atomsymb[atom.na], "rx": atom.rx, "ry": atom.ry, "rz": atom.rz, "chg": atom.chg} + { + "lbl": atomsymb[atom.na], + "rx": atom.rx, + "ry": atom.ry, + "rz": atom.rz, + "chg": atom.chg, + } ) mol_count += 1 @@ -230,18 +216,17 @@ class GaussianInterface(Interface): def _make_gaussian_input_file(self, cycle: int, asec_charges: list[dict]) -> None: gaussian_input_file_path = Path( - self.step.simulation_dir, - f"step{cycle:02d}", - "qm", - f"asec.gjf" + self.step.simulation_dir, f"step{cycle:02d}", "qm", f"asec.gjf" ) - with open(gaussian_input_file_path, 'w') as gaussian_input_file: + with open(gaussian_input_file_path, "w") as gaussian_input_file: gaussian_input_file.writelines( self._generate_gaussian_input(cycle, asec_charges) ) - def _generate_gaussian_input(self, cycle: int, asec_charges: list[dict]) -> list[str]: + def _generate_gaussian_input( + self, cycle: int, asec_charges: list[dict] + ) -> list[str]: gaussian_input = ["%Chk=asec.chk\n"] if self.step.mem is not None: @@ -268,7 +253,9 @@ class GaussianInterface(Interface): gaussian_input.append("\nForce calculation - Cycle number {}\n".format(cycle)) gaussian_input.append("\n") - gaussian_input.append(f"{self.step.gaussian.chgmult[0]},{self.step.gaussian.chgmult[1]}\n") + gaussian_input.append( + f"{self.step.gaussian.chgmult[0]},{self.step.gaussian.chgmult[1]}\n" + ) for atom in self.system.molecule[0].atom: symbol = atomsymb[atom.na] @@ -283,7 +270,7 @@ class GaussianInterface(Interface): for charge in asec_charges: gaussian_input.append( "{:>10.5f} {:>10.5f} {:>10.5f} {:>11.8f}\n".format( - charge['rx'], charge['ry'], charge['rz'], charge['chg'] + charge["rx"], charge["ry"], charge["rz"], charge["chg"] ) ) @@ -292,11 +279,7 @@ class GaussianInterface(Interface): return gaussian_input def _run_gaussian(self, cycle: int) -> None: - qm_dir = Path( - self.step.simulation_dir, - f"step{(cycle):02d}", - "qm" - ) + qm_dir = Path(self.step.simulation_dir, f"step{(cycle):02d}", "qm") working_dir = os.getcwd() os.chdir(qm_dir) @@ -319,7 +302,10 @@ class GaussianInterface(Interface): "bash", "-c", "exec -a {}-step{} {} {}".format( - self.step.gaussian.qmprog, cycle, self.step.gaussian.qmprog, infile + self.step.gaussian.qmprog, + cycle, + self.step.gaussian.qmprog, + infile, ), ] ) @@ -334,18 +320,16 @@ class GaussianInterface(Interface): os.chdir(working_dir) def _run_formchk(self, cycle: int): - qm_dir = Path( - self.step.simulation_dir, - f"step{(cycle):02d}", - "qm" - ) + qm_dir = Path(self.step.simulation_dir, f"step{(cycle):02d}", "qm") work_dir = os.getcwd() os.chdir(qm_dir) logger.info("Formatting the checkpoint file... \n") - exit_status = subprocess.call(["formchk", "asec.chk"], stdout=subprocess.DEVNULL) + exit_status = subprocess.call( + ["formchk", "asec.chk"], stdout=subprocess.DEVNULL + ) if exit_status != 0: raise SystemError("Formchk process did not exit properly") @@ -355,12 +339,7 @@ class GaussianInterface(Interface): os.chdir(work_dir) def _read_charges_from_fchk(self, cycle: int): - fchk_file_path = Path( - "simfiles", - f"step{cycle:02d}", - "qm", - "asec.fchk" - ) + fchk_file_path = Path("simfiles", f"step{cycle:02d}", "qm", "asec.fchk") with open(fchk_file_path) as fchk: fchkfile = fchk.readlines() diff --git a/diceplayer/shared/utils/dataclass_protocol.py b/diceplayer/shared/utils/dataclass_protocol.py index b3b3dbd..7d7c4da 100644 --- a/diceplayer/shared/utils/dataclass_protocol.py +++ b/diceplayer/shared/utils/dataclass_protocol.py @@ -1,4 +1,4 @@ -from typing import runtime_checkable, Protocol +from typing import Protocol, runtime_checkable @runtime_checkable diff --git a/diceplayer/shared/utils/logger.py b/diceplayer/shared/utils/logger.py index 2404f20..4d4806a 100644 --- a/diceplayer/shared/utils/logger.py +++ b/diceplayer/shared/utils/logger.py @@ -1,12 +1,11 @@ -from pathlib import Path import logging +from pathlib import Path def valid_logger(func): def wrapper(*args, **kwargs): logger = args[0] - assert logger._was_set, \ - "Logger is not set. Please call set_logger() first." + assert logger._was_set, "Logger is not set. Please call set_logger() first." return func(*args, **kwargs) @@ -24,7 +23,7 @@ class Logger: if self._logger is None: self._logger = logging.getLogger(logger_name) - def set_logger(self, outfile='run.log', level=logging.INFO, stream=None): + def set_logger(self, outfile="run.log", level=logging.INFO, stream=None): outfile_path = None if outfile is not None and stream is None: outfile_path = Path(outfile) @@ -57,14 +56,14 @@ class Logger: def _create_handlers(self, outfile_path: Path, stream): handlers = [] if outfile_path is not None: - handlers.append(logging.FileHandler(outfile_path, mode='a+')) + handlers.append(logging.FileHandler(outfile_path, mode="a+")) elif stream is not None: handlers.append(logging.StreamHandler(stream)) else: handlers.append(logging.StreamHandler()) for handler in handlers: - handler.setFormatter(logging.Formatter('%(message)s')) + handler.setFormatter(logging.Formatter("%(message)s")) self._logger.addHandler(handler) def close(self): diff --git a/diceplayer/shared/utils/misc.py b/diceplayer/shared/utils/misc.py index 9e54a1f..af2ac13 100644 --- a/diceplayer/shared/utils/misc.py +++ b/diceplayer/shared/utils/misc.py @@ -14,6 +14,7 @@ ANG2BOHR: Final[float] = 1 / BOHR2ANG ####################################### functions ###################################### + def weekday_date_time(): return time.strftime("%A, %d %b %Y at %H:%M:%S") @@ -31,8 +32,8 @@ def compress_files_1mb(path): if os.path.getsize(file) > 1024 * 1024: ## If bigger than 1MB filegz = file + ".gz" try: - with open(file, 'rb') as f_in: - with gzip.open(filegz, 'wb') as f_out: + with open(file, "rb") as f_in: + with gzip.open(filegz, "wb") as f_out: shutil.copyfileobj(f_in, f_out) except: sys.exit("Error: cannot compress file {}".format(file)) diff --git a/diceplayer/shared/utils/ptable.py b/diceplayer/shared/utils/ptable.py index fe6762d..158bfdb 100644 --- a/diceplayer/shared/utils/ptable.py +++ b/diceplayer/shared/utils/ptable.py @@ -2,34 +2,222 @@ dice_ghost_label = "Xx" #### Tuple of atom symbols -atomsymb = ( "00", +atomsymb = ( + "00", + "H ", + "He", + "Li", + "Be", + "B ", + "C ", + "N ", + "O ", + "F ", + "Ne", + "Na", + "Mg", + "Al", + "Si", + "P ", + "S ", + "Cl", + "Ar", + "K ", + "Ca", + "Sc", + "Ti", + "V ", + "Cr", + "Mn", + "Fe", + "Co", + "Ni", + "Cu", + "Zn", + "Ga", + "Ge", + "As", + "Se", + "Br", + "Kr", + "Rb", + "Sr", + "Y ", + "Zr", + "Nb", + "Mo", + "Tc", + "Ru", + "Rh", + "Pd", + "Ag", + "Cd", + "In", + "Sn", + "Sb", + "Te", + "I ", + "Xe", + "Cs", + "Ba", + "La", + "Ce", + "Pr", + "Nd", + "Pm", + "Sm", + "Eu", + "Gd", + "Tb", + "Dy", + "Ho", + "Er", + "Tm", + "Yb", + "Lu", + "Hf", + "Ta", + "W ", + "Re", + "Os", + "Ir", + "Pt", + "Au", + "Hg", + "Ti", + "Pb", + "Bi", + "Po", + "At", + "Rn", + "Fr", + "Ra", + "Ac", + "Th", + "Pa", + "U ", + "Np", + "Pu", + "Am", + "Cm", + "Bk", + "Cf", + "Es", + "Fm", + "Md", + "No", + "Lr", + dice_ghost_label, +) -"H ", "He", -"Li","Be", "B ","C ","N ","O ","F ","Ne", -"Na","Mg", "Al","Si","P ","S ","Cl","Ar", -"K ","Ca","Sc","Ti","V ","Cr","Mn","Fe","Co","Ni","Cu","Zn","Ga","Ge","As","Se","Br","Kr", -"Rb","Sr","Y ","Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn","Sb","Te","I ","Xe", -"Cs","Ba", - "La","Ce","Pr","Nd","Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm","Yb","Lu", - "Hf","Ta","W ","Re","Os","Ir","Pt","Au","Hg","Ti","Pb","Bi","Po","At","Rn", -"Fr","Ra", - "Ac","Th","Pa","U ","Np","Pu","Am","Cm","Bk","Cf","Es","Fm","Md","No","Lr", - dice_ghost_label ) - -#### Tuple of atom masses -atommass = ( 0.0, - -1.0079, 4.0026, -6.9410,9.0122, 10.811,12.011,14.007,15.999,18.998,20.180, -22.990,24.305, 26.982,28.086,30.974,32.065,35.453,39.948, -39.098,40.078,44.956,47.867,50.942,51.996,54.938,55.845,58.933,58.693,63.546,65.409,69.723,72.640,74.922,78.960,79.904,83.798, -85.468,87.620,88.906,91.224,92.906,95.940,98.000,101.07,102.91,106.42,107.87,112.41,114.82,118.71,121.76,127.60,126.90,131.29, -132.91,137.33, - 138.91,140.12,140.91,144.24,145.00,150.36,151.96,157.25,158.93,162.50,164.93,167.26,168.93,173.04,174.97, - 178.49,180.95,183.84,186.21,190.23,192.22,195.08,196.97,200.59,204.38,207.20,208.98,209.00,210.00,222.00, -223.00,226.00, - 227.00,232.04,231.04,238.03,237.00,244.00,243.00,247.00,247.00,251.00,252.00,257.00,258.00,259.00,262.00, - 0.000 ) +#### Tuple of atom masses +atommass = ( + 0.0, + 1.0079, + 4.0026, + 6.9410, + 9.0122, + 10.811, + 12.011, + 14.007, + 15.999, + 18.998, + 20.180, + 22.990, + 24.305, + 26.982, + 28.086, + 30.974, + 32.065, + 35.453, + 39.948, + 39.098, + 40.078, + 44.956, + 47.867, + 50.942, + 51.996, + 54.938, + 55.845, + 58.933, + 58.693, + 63.546, + 65.409, + 69.723, + 72.640, + 74.922, + 78.960, + 79.904, + 83.798, + 85.468, + 87.620, + 88.906, + 91.224, + 92.906, + 95.940, + 98.000, + 101.07, + 102.91, + 106.42, + 107.87, + 112.41, + 114.82, + 118.71, + 121.76, + 127.60, + 126.90, + 131.29, + 132.91, + 137.33, + 138.91, + 140.12, + 140.91, + 144.24, + 145.00, + 150.36, + 151.96, + 157.25, + 158.93, + 162.50, + 164.93, + 167.26, + 168.93, + 173.04, + 174.97, + 178.49, + 180.95, + 183.84, + 186.21, + 190.23, + 192.22, + 195.08, + 196.97, + 200.59, + 204.38, + 207.20, + 208.98, + 209.00, + 210.00, + 222.00, + 223.00, + 226.00, + 227.00, + 232.04, + 231.04, + 238.03, + 237.00, + 244.00, + 243.00, + 247.00, + 247.00, + 251.00, + 252.00, + 257.00, + 258.00, + 259.00, + 262.00, + 0.000, +) #### Number of the ghost atom -ghost_number = len(atomsymb) - 1 \ No newline at end of file +ghost_number = len(atomsymb) - 1 diff --git a/poetry.lock b/poetry.lock index 074bc30..6275797 100644 --- a/poetry.lock +++ b/poetry.lock @@ -12,6 +12,56 @@ files = [ {file = "argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4"}, ] +[[package]] +name = "black" +version = "23.3.0" +description = "The uncompromising code formatter." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, + {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, + {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, + {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, + {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, + {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, + {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, + {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, + {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, + {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, + {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, + {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, + {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, + {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + [[package]] name = "cfgv" version = "3.3.1" @@ -24,6 +74,33 @@ files = [ {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, ] +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + [[package]] name = "coverage" version = "7.2.7" @@ -154,6 +231,36 @@ files = [ [package.extras] license = ["ukkonen"] +[[package]] +name = "isort" +version = "5.12.0" +description = "A Python utility / library to sort Python imports." +category = "main" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] + +[package.extras] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +category = "main" +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + [[package]] name = "nodeenv" version = "1.8.0" @@ -230,6 +337,18 @@ files = [ {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, ] +[[package]] +name = "packaging" +version = "23.1" +description = "Core utilities for Python packages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, +] + [[package]] name = "pastel" version = "0.2.1" @@ -242,6 +361,18 @@ files = [ {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, ] +[[package]] +name = "pathspec" +version = "0.11.1" +description = "Utility library for gitignore style pattern matching of file paths." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, + {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, +] + [[package]] name = "platformdirs" version = "3.5.3" @@ -496,4 +627,4 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "360a82468f029af7e8a41fdc2ddc321aea6fc9753cc6e9eddb84d07c8b377a2d" +content-hash = "2527f460007c57ea9d99659a7dce34657b4cdbd8c9d05bcd3deb822474ae79c6" diff --git a/pyproject.toml b/pyproject.toml index 496f4fc..73740ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,8 @@ dacite = "^1.8.1" nptyping = "^2.5.0" poethepoet = "^0.20.0" pre-commit = "^3.3.2" +isort = "^5.12.0" +black = "^23.3.0" [tool.poetry.scripts] diceplayer = "diceplayer.__main__:main" diff --git a/tests/mocks/mock_proc.py b/tests/mocks/mock_proc.py index 1319766..3c6310f 100644 --- a/tests/mocks/mock_proc.py +++ b/tests/mocks/mock_proc.py @@ -1,5 +1,5 @@ -from typing import List import itertools +from typing import List class MockProc: @@ -8,8 +8,8 @@ class MockProc: def __init__(self, *args, **kwargs): self.pid = next(MockProc.pid_counter) - if 'exitcode' in kwargs: - self.exitcode = kwargs['exitcode'] + if "exitcode" in kwargs: + self.exitcode = kwargs["exitcode"] else: self.exitcode = 0 diff --git a/tests/shared/config/test_dice_dto.py b/tests/shared/config/test_dice_dto.py index 9117e46..0793582 100644 --- a/tests/shared/config/test_dice_dto.py +++ b/tests/shared/config/test_dice_dto.py @@ -6,8 +6,8 @@ import unittest class TestDiceDto(unittest.TestCase): def test_class_instantiation(self): dice_dto = DiceConfig( - ljname='test', - outname='test', + ljname="test", + outname="test", dens=1.0, nmol=[1], nstep=[1, 1], @@ -19,64 +19,78 @@ class TestDiceDto(unittest.TestCase): with self.assertRaises(ValueError) as ex: DiceConfig( ljname=None, - outname='test', + outname="test", dens=1.0, nmol=[1], nstep=[1, 1], ) - self.assertEqual(ex.exception, "Error: 'ljname' keyword not specified in config file") + self.assertEqual( + ex.exception, "Error: 'ljname' keyword not specified in config file" + ) def test_validate_outname(self): with self.assertRaises(ValueError) as ex: DiceConfig( - ljname='test', + ljname="test", outname=None, dens=1.0, nmol=[1], nstep=[1, 1], ) - self.assertEqual(ex.exception, "Error: 'outname' keyword not specified in config file") + self.assertEqual( + ex.exception, "Error: 'outname' keyword not specified in config file" + ) def test_validate_dens(self): with self.assertRaises(ValueError) as ex: DiceConfig( - ljname='test', - outname='test', + ljname="test", + outname="test", dens=None, nmol=[1], nstep=[1, 1], ) - self.assertEqual(ex.exception, "Error: 'dens' keyword not specified in config file") + self.assertEqual( + ex.exception, "Error: 'dens' keyword not specified in config file" + ) def test_validate_nmol(self): with self.assertRaises(ValueError) as ex: DiceConfig( - ljname='test', - outname='test', + ljname="test", + outname="test", dens=1.0, nmol=0, nstep=[1, 1], ) - self.assertEqual(ex.exception, "Error: 'nmol' keyword not defined appropriately in config file") + self.assertEqual( + ex.exception, + "Error: 'nmol' keyword not defined appropriately in config file", + ) def test_validate_nstep(self): with self.assertRaises(ValueError) as ex: DiceConfig( - ljname='test', - outname='test', + ljname="test", + outname="test", dens=1.0, nmol=[1], nstep=0, ) - self.assertEqual(ex.exception, "Error: 'nstep' keyword not defined appropriately in config file") + self.assertEqual( + ex.exception, + "Error: 'nstep' keyword not defined appropriately in config file", + ) def test_from_dict(self): - dice_dto = DiceConfig.from_dict({ - 'ljname': 'test', - 'outname': 'test', - 'dens': 1.0, - 'nmol': [1], - 'nstep': [1, 1], - }) + dice_dto = DiceConfig.from_dict( + { + "ljname": "test", + "outname": "test", + "dens": 1.0, + "nmol": [1], + "nstep": [1, 1], + } + ) - self.assertIsInstance(dice_dto, DiceConfig) \ No newline at end of file + self.assertIsInstance(dice_dto, DiceConfig) diff --git a/tests/shared/config/test_gaussian_dto.py b/tests/shared/config/test_gaussian_dto.py index e719786..f8d7745 100644 --- a/tests/shared/config/test_gaussian_dto.py +++ b/tests/shared/config/test_gaussian_dto.py @@ -6,9 +6,9 @@ import unittest class TestGaussianDTO(unittest.TestCase): def test_class_instantiation(self): gaussian_dto = GaussianDTO( - level='test', - qmprog='g16', - keywords='test', + level="test", + qmprog="g16", + keywords="test", ) self.assertIsInstance(gaussian_dto, GaussianDTO) @@ -16,30 +16,30 @@ class TestGaussianDTO(unittest.TestCase): def test_is_valid_qmprog(self): with self.assertRaises(ValueError): gaussian_dto = GaussianDTO( - level='test', - qmprog='test', - keywords='test', + level="test", + qmprog="test", + keywords="test", ) def test_is_valid_level(self): with self.assertRaises(ValueError): gaussian_dto = GaussianDTO( level=None, - qmprog='g16', - keywords='test', + qmprog="g16", + keywords="test", ) def test_from_dict(self): gaussian_dto = GaussianDTO.from_dict( { - 'level': 'test', - 'qmprog': 'g16', - 'keywords': 'test', + "level": "test", + "qmprog": "g16", + "keywords": "test", } ) self.assertIsInstance(gaussian_dto, GaussianDTO) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/shared/config/test_player_dto.py b/tests/shared/config/test_player_dto.py index 909e5fd..2c3121c 100644 --- a/tests/shared/config/test_player_dto.py +++ b/tests/shared/config/test_player_dto.py @@ -1,45 +1,45 @@ +from diceplayer.shared.config.dice_config import DiceConfig from diceplayer.shared.config.gaussian_config import GaussianDTO from diceplayer.shared.config.player_config import PlayerConfig -from diceplayer.shared.config.dice_config import DiceConfig import unittest def get_config_dict(): return { - 'opt': True, - 'mem': 12, - 'maxcyc': 100, - 'nprocs': 4, - 'ncores': 4, - 'dice': { - 'ljname': 'test', - 'outname': 'test', - 'dens': 1.0, - 'nmol': [1], - 'nstep': [1, 1], + "opt": True, + "mem": 12, + "maxcyc": 100, + "nprocs": 4, + "ncores": 4, + "dice": { + "ljname": "test", + "outname": "test", + "dens": 1.0, + "nmol": [1], + "nstep": [1, 1], + }, + "gaussian": { + "level": "test", + "qmprog": "g16", + "keywords": "test", }, - 'gaussian': { - 'level': 'test', - 'qmprog': 'g16', - 'keywords': 'test', - } } class TestPlayerDTO(unittest.TestCase): def setUp(self) -> None: self.dice_dto = DiceConfig( - ljname='test', - outname='test', + ljname="test", + outname="test", dens=1.0, nmol=[1], nstep=[1, 1], ) self.gaussian_dto = GaussianDTO( - level='test', - qmprog='g16', - keywords='test', + level="test", + qmprog="g16", + keywords="test", ) def test_class_instantiation(self): @@ -50,7 +50,7 @@ class TestPlayerDTO(unittest.TestCase): nprocs=4, ncores=4, dice=self.dice_dto, - gaussian=self.gaussian_dto + gaussian=self.gaussian_dto, ) self.assertIsInstance(player_dto, PlayerConfig) @@ -66,20 +66,18 @@ class TestPlayerDTO(unittest.TestCase): ncores=4, altsteps=100, dice=self.dice_dto, - gaussian=self.gaussian_dto + gaussian=self.gaussian_dto, ) self.assertEqual(player_dto.altsteps, 20000) def test_from_dict(self): - player_dto = PlayerConfig.from_dict( - get_config_dict() - ) + player_dto = PlayerConfig.from_dict(get_config_dict()) self.assertIsInstance(player_dto, PlayerConfig) self.assertIsInstance(player_dto.dice, DiceConfig) self.assertIsInstance(player_dto.gaussian, GaussianDTO) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/shared/environment/test_atom.py b/tests/shared/environment/test_atom.py index fa6de06..78e7fa5 100644 --- a/tests/shared/environment/test_atom.py +++ b/tests/shared/environment/test_atom.py @@ -16,4 +16,4 @@ class TestAtom(unittest.TestCase): sig=1.0, ) - self.assertIsInstance(atom, Atom) \ No newline at end of file + self.assertIsInstance(atom, Atom) diff --git a/tests/shared/environment/test_molecule.py b/tests/shared/environment/test_molecule.py index 5a65815..9bcf59a 100644 --- a/tests/shared/environment/test_molecule.py +++ b/tests/shared/environment/test_molecule.py @@ -1,30 +1,30 @@ -import numpy as np - -from diceplayer.shared.environment.molecule import Molecule from diceplayer.shared.environment.atom import Atom +from diceplayer.shared.environment.molecule import Molecule +import numpy as np import numpy.testing as npt + import unittest class TestMolecule(unittest.TestCase): def test_class_instantiation(self): - mol = Molecule('test') + mol = Molecule("test") self.assertIsInstance(mol, Molecule) def test_add_atom(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=1.0, ry=1.0, rz=1.0, chg=1.0, eps=1.0, sig=1.0) ) self.assertEqual(len(mol.atom), 1) - npt.assert_equal(mol.com, [1., 1., 1.]) + npt.assert_equal(mol.com, [1.0, 1.0, 1.0]) def test_center_of_mass(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=1.0, ry=1.0, rz=1.0, chg=1.0, eps=1.0, sig=1.0) @@ -33,10 +33,10 @@ class TestMolecule(unittest.TestCase): Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) ) - npt.assert_equal(mol.com, [.5, .5, .5]) + npt.assert_equal(mol.com, [0.5, 0.5, 0.5]) def test_center_of_mass_to_origin(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=1.0, ry=1.0, rz=1.0, chg=1.0, eps=1.0, sig=1.0) @@ -47,7 +47,7 @@ class TestMolecule(unittest.TestCase): npt.assert_equal(mol.com, [0, 0, 0]) def test_charges_and_dipole(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) @@ -57,13 +57,10 @@ class TestMolecule(unittest.TestCase): expected_charge_dipole_array = [1.0, 0.0, 0.0, 0.0, 0.0] - npt.assert_equal( - actual_charge_dipole_array, - expected_charge_dipole_array - ) + npt.assert_equal(actual_charge_dipole_array, expected_charge_dipole_array) def test_distances_between_atoms(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) @@ -76,12 +73,11 @@ class TestMolecule(unittest.TestCase): actual_distance_between_atoms = mol.distances_between_atoms() npt.assert_almost_equal( - expected_distance_between_atoms, - actual_distance_between_atoms + expected_distance_between_atoms, actual_distance_between_atoms ) def test_inertia_tensor(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) @@ -90,25 +86,28 @@ class TestMolecule(unittest.TestCase): Atom(lbl=1, na=1, rx=1.0, ry=1.0, rz=1.0, chg=1.0, eps=1.0, sig=1.0) ) - expected_inertia_tensor = [[1.00790, -0.50395, -0.50395], - [-0.50395, 1.0079, -0.50395], - [-0.50395, -0.50395, 1.0079]] + expected_inertia_tensor = [ + [1.00790, -0.50395, -0.50395], + [-0.50395, 1.0079, -0.50395], + [-0.50395, -0.50395, 1.0079], + ] actual_inertia_tensor = mol.inertia_tensor() - npt.assert_equal( - expected_inertia_tensor, - actual_inertia_tensor - ) + npt.assert_equal(expected_inertia_tensor, actual_inertia_tensor) def test_principal_axes(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) ) - expected_evals, expected_evecs = [0., 0., 0.], [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]] + expected_evals, expected_evecs = [0.0, 0.0, 0.0], [ + [1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + ] evals, evecs = mol.principal_axes() @@ -116,7 +115,7 @@ class TestMolecule(unittest.TestCase): npt.assert_equal(expected_evecs, evecs) def test_read_position(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) @@ -126,30 +125,24 @@ class TestMolecule(unittest.TestCase): actual_position = mol.read_position() - npt.assert_equal( - expected_position, - actual_position - ) + npt.assert_equal(expected_position, actual_position) def test_update_charges(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) ) - expected_charges = [2.] + expected_charges = [2.0] mol.update_charges(expected_charges) actual_charges = list(map(lambda a: a.chg, mol.atom)) - npt.assert_equal( - expected_charges, - actual_charges - ) + npt.assert_equal(expected_charges, actual_charges) def test_sizes_of_molecule(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) @@ -162,7 +155,7 @@ class TestMolecule(unittest.TestCase): npt.assert_equal(sizes, expected_sizes) def test_standard_orientation(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=1.0, ry=1.0, rz=1.0, chg=1.0, eps=1.0, sig=1.0) @@ -175,7 +168,7 @@ class TestMolecule(unittest.TestCase): self.assertEqual(mol.read_position().tolist(), expected_position) def test_translate(self): - mol = Molecule('test') + mol = Molecule("test") mol.add_atom( Atom(lbl=1, na=1, rx=1.0, ry=1.0, rz=1.0, chg=1.0, eps=1.0, sig=1.0) @@ -185,18 +178,15 @@ class TestMolecule(unittest.TestCase): expected_position = [0.0, 0.0, 0.0] - self.assertEqual( - new_mol.read_position().tolist(), - expected_position - ) + self.assertEqual(new_mol.read_position().tolist(), expected_position) def test_minimum_distance(self): - mol1 = Molecule('test1') + mol1 = Molecule("test1") mol1.add_atom( Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) ) - mol2 = Molecule('test2') + mol2 = Molecule("test2") mol2.add_atom( Atom(lbl=1, na=1, rx=1.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0) ) @@ -208,5 +198,5 @@ class TestMolecule(unittest.TestCase): self.assertEqual(expected_distance, actual_distance) -if __name__ == '__main__': - unittest.main() \ No newline at end of file +if __name__ == "__main__": + unittest.main() diff --git a/tests/shared/environment/test_system.py b/tests/shared/environment/test_system.py index 8fad46c..09282e6 100644 --- a/tests/shared/environment/test_system.py +++ b/tests/shared/environment/test_system.py @@ -13,15 +13,14 @@ class TestSystem(unittest.TestCase): def test_add_type(self): system = System() - system.add_type(Molecule('test')) + system.add_type(Molecule("test")) self.assertIsInstance(system.molecule, list) with self.assertRaises(TypeError) as ex: - system.add_type('test') - self.assertEqual(ex.exception, 'Error: molecule is not a Molecule instance') + system.add_type("test") + self.assertEqual(ex.exception, "Error: molecule is not a Molecule instance") - -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/shared/interface/test_dice_interface.py b/tests/shared/interface/test_dice_interface.py index 0c5b931..c182149 100644 --- a/tests/shared/interface/test_dice_interface.py +++ b/tests/shared/interface/test_dice_interface.py @@ -1,18 +1,17 @@ -from diceplayer.shared.interface.dice_interface import DiceInterface +from diceplayer import logger from diceplayer.shared.config.player_config import PlayerConfig +from diceplayer.shared.environment.atom import Atom from diceplayer.shared.environment.molecule import Molecule from diceplayer.shared.environment.system import System -from diceplayer.shared.environment.atom import Atom -from diceplayer import logger - -import yaml -import io - +from diceplayer.shared.interface.dice_interface import DiceInterface from tests.mocks.mock_inputs import get_config_example from tests.mocks.mock_proc import MockConnection, MockProc -from unittest import mock +import yaml + +import io import unittest +from unittest import mock class TestDiceInterface(unittest.TestCase): @@ -20,7 +19,7 @@ class TestDiceInterface(unittest.TestCase): logger.set_logger(stream=io.StringIO()) config = yaml.load(get_config_example(), Loader=yaml.Loader) - self.config = PlayerConfig.from_dict(config['diceplayer']) + self.config = PlayerConfig.from_dict(config["diceplayer"]) def test_class_instantiation(self): dice = DiceInterface() @@ -44,24 +43,26 @@ class TestDiceInterface(unittest.TestCase): dice.configure(self.config, System()) - self.assertTrue(hasattr(dice, 'step')) - self.assertTrue(hasattr(dice, 'system')) + self.assertTrue(hasattr(dice, "step")) + self.assertTrue(hasattr(dice, "system")) dice.reset() - self.assertFalse(hasattr(dice, 'step')) - self.assertFalse(hasattr(dice, 'system')) + self.assertFalse(hasattr(dice, "step")) + self.assertFalse(hasattr(dice, "system")) - @mock.patch('diceplayer.shared.interface.dice_interface.Process', MockProc()) - @mock.patch('diceplayer.shared.interface.dice_interface.connection', MockConnection) + @mock.patch("diceplayer.shared.interface.dice_interface.Process", MockProc()) + @mock.patch("diceplayer.shared.interface.dice_interface.connection", MockConnection) def test_start(self): dice = DiceInterface() dice.configure(self.config, System()) dice.start(1) - @mock.patch('diceplayer.shared.interface.dice_interface.connection', MockConnection) - @mock.patch('diceplayer.shared.interface.dice_interface.Process', MockProc(exitcode=1)) + @mock.patch("diceplayer.shared.interface.dice_interface.connection", MockConnection) + @mock.patch( + "diceplayer.shared.interface.dice_interface.Process", MockProc(exitcode=1) + ) def test_start_with_process_error(self): dice = DiceInterface() dice.configure(self.config, System()) @@ -75,10 +76,16 @@ class TestDiceInterface(unittest.TestCase): with self.assertRaises(SystemExit): dice._simulation_process(1, 1) - @mock.patch('diceplayer.shared.interface.dice_interface.DiceInterface._make_proc_dir') - @mock.patch('diceplayer.shared.interface.dice_interface.DiceInterface._make_dice_inputs') - @mock.patch('diceplayer.shared.interface.dice_interface.DiceInterface._run_dice') - def test_simulation_process(self, mock_run_dice, mock_make_dice_inputs, mock_make_proc_dir): + @mock.patch( + "diceplayer.shared.interface.dice_interface.DiceInterface._make_proc_dir" + ) + @mock.patch( + "diceplayer.shared.interface.dice_interface.DiceInterface._make_dice_inputs" + ) + @mock.patch("diceplayer.shared.interface.dice_interface.DiceInterface._run_dice") + def test_simulation_process( + self, mock_run_dice, mock_make_dice_inputs, mock_make_proc_dir + ): dice = DiceInterface() dice._simulation_process(1, 1) @@ -87,8 +94,8 @@ class TestDiceInterface(unittest.TestCase): self.assertTrue(dice._make_dice_inputs.called) self.assertTrue(dice._run_dice.called) - @mock.patch('diceplayer.shared.interface.dice_interface.Path.mkdir') - @mock.patch('diceplayer.shared.interface.dice_interface.Path.exists') + @mock.patch("diceplayer.shared.interface.dice_interface.Path.mkdir") + @mock.patch("diceplayer.shared.interface.dice_interface.Path.exists") def test_make_proc_dir_if_simdir_exists(self, mock_path_exists, mock_path_mkdir): dice = DiceInterface() dice.configure(self.config, System()) @@ -99,9 +106,11 @@ class TestDiceInterface(unittest.TestCase): self.assertEqual(mock_path_mkdir.call_count, 2) - @mock.patch('diceplayer.shared.interface.dice_interface.Path.mkdir') - @mock.patch('diceplayer.shared.interface.dice_interface.Path.exists') - def test_make_proc_dir_if_simdir_doesnt_exists(self, mock_path_exists, mock_path_mkdir): + @mock.patch("diceplayer.shared.interface.dice_interface.Path.mkdir") + @mock.patch("diceplayer.shared.interface.dice_interface.Path.exists") + def test_make_proc_dir_if_simdir_doesnt_exists( + self, mock_path_exists, mock_path_mkdir + ): dice = DiceInterface() dice.configure(self.config, System()) @@ -145,9 +154,13 @@ class TestDiceInterface(unittest.TestCase): self.assertFalse(dice._make_npt_ter.called) self.assertFalse(dice._make_npt_eq.called) - @mock.patch('builtins.open', new_callable=mock.mock_open, read_data='test') - @mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=True) - def test_make_dice_inputs_nstep_len_two_with_randoninit_first_cycle_two(self, mock_path_exists, mock_open): + @mock.patch("builtins.open", new_callable=mock.mock_open, read_data="test") + @mock.patch( + "diceplayer.shared.interface.dice_interface.Path.exists", return_value=True + ) + def test_make_dice_inputs_nstep_len_two_with_randoninit_first_cycle_two( + self, mock_path_exists, mock_open + ): dice = DiceInterface() dice.configure(self.config, System()) @@ -176,8 +189,12 @@ class TestDiceInterface(unittest.TestCase): self.assertFalse(dice._make_npt_ter.called) self.assertFalse(dice._make_npt_eq.called) - @mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=False) - def test_make_dice_inputs_raises_exception_on_last_not_found(self, mock_path_exists): + @mock.patch( + "diceplayer.shared.interface.dice_interface.Path.exists", return_value=False + ) + def test_make_dice_inputs_raises_exception_on_last_not_found( + self, mock_path_exists + ): dice = DiceInterface() dice.configure(self.config, System()) @@ -223,10 +240,14 @@ class TestDiceInterface(unittest.TestCase): self.assertTrue(dice._make_npt_ter.called) self.assertTrue(dice._make_npt_eq.called) - @mock.patch('diceplayer.shared.interface.dice_interface.os') - @mock.patch('diceplayer.shared.interface.dice_interface.shutil') - @mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=True) - def test_run_dice_on_first_cycle_run_successful(self, mock_path_exists, mock_shutils, mock_os): + @mock.patch("diceplayer.shared.interface.dice_interface.os") + @mock.patch("diceplayer.shared.interface.dice_interface.shutil") + @mock.patch( + "diceplayer.shared.interface.dice_interface.Path.exists", return_value=True + ) + def test_run_dice_on_first_cycle_run_successful( + self, mock_path_exists, mock_shutils, mock_os + ): dice = DiceInterface() dice.configure(self.config, System()) @@ -257,10 +278,14 @@ class TestDiceInterface(unittest.TestCase): self.assertEqual(dice.run_dice_file.call_count, 2) self.assertTrue(mock_shutils.copy.called) - @mock.patch('diceplayer.shared.interface.dice_interface.os') - @mock.patch('diceplayer.shared.interface.dice_interface.shutil') - @mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=True) - def test_run_dice_on_second_cycle_run_successful(self, mock_path_exists, mock_shutils, mock_os): + @mock.patch("diceplayer.shared.interface.dice_interface.os") + @mock.patch("diceplayer.shared.interface.dice_interface.shutil") + @mock.patch( + "diceplayer.shared.interface.dice_interface.Path.exists", return_value=True + ) + def test_run_dice_on_second_cycle_run_successful( + self, mock_path_exists, mock_shutils, mock_os + ): dice = DiceInterface() dice.configure(self.config, System()) @@ -287,10 +312,14 @@ class TestDiceInterface(unittest.TestCase): self.assertEqual(dice.run_dice_file.call_count, 1) self.assertTrue(mock_shutils.copy.called) - @mock.patch('diceplayer.shared.interface.dice_interface.os') - @mock.patch('diceplayer.shared.interface.dice_interface.shutil') - @mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=False) - def test_run_dice_on_second_cycle_run_successful(self, mock_path_exists, mock_shutils, mock_os): + @mock.patch("diceplayer.shared.interface.dice_interface.os") + @mock.patch("diceplayer.shared.interface.dice_interface.shutil") + @mock.patch( + "diceplayer.shared.interface.dice_interface.Path.exists", return_value=False + ) + def test_run_dice_on_second_cycle_run_successful( + self, mock_path_exists, mock_shutils, mock_os + ): dice = DiceInterface() dice.configure(self.config, System()) @@ -299,7 +328,7 @@ class TestDiceInterface(unittest.TestCase): with self.assertRaises(FileNotFoundError): dice._run_dice(1, 1) - @mock.patch('builtins.open', new_callable=mock.mock_open) + @mock.patch("builtins.open", new_callable=mock.mock_open) def test_make_init_file(self, mock_open): example_atom = Atom( lbl=1, @@ -312,10 +341,10 @@ class TestDiceInterface(unittest.TestCase): sig=1.0, ) - main_molecule = Molecule('main_molecule') + main_molecule = Molecule("main_molecule") main_molecule.add_atom(example_atom) - secondary_molecule = Molecule('secondary_molecule') + secondary_molecule = Molecule("secondary_molecule") secondary_molecule.add_atom(example_atom) system = System() @@ -328,15 +357,17 @@ class TestDiceInterface(unittest.TestCase): dice.step.dice.nmol = [1, 1] last_xyz_file = io.StringIO() - last_xyz_file.writelines([ - ' TEST\n', - ' Configuration number : TEST = TEST TEST TEST\n', - ' H 1.00000 1.00000 1.00000\n', - ' H 1.00000 1.00000 1.00000\n', - ]) + last_xyz_file.writelines( + [ + " TEST\n", + " Configuration number : TEST = TEST TEST TEST\n", + " H 1.00000 1.00000 1.00000\n", + " H 1.00000 1.00000 1.00000\n", + ] + ) last_xyz_file.seek(0) - dice._make_init_file('test', last_xyz_file) + dice._make_init_file("test", last_xyz_file) mock_handler = mock_open() calls = mock_handler.write.call_args_list @@ -344,14 +375,14 @@ class TestDiceInterface(unittest.TestCase): lines = list(map(lambda x: x[0][0], calls)) expected_lines = [ - ' 1.000000 1.000000 1.000000\n', - ' 1.000000 1.000000 1.000000\n', - '$end' + " 1.000000 1.000000 1.000000\n", + " 1.000000 1.000000 1.000000\n", + "$end", ] self.assertEqual(lines, expected_lines) - @mock.patch('builtins.open', new_callable=mock.mock_open) + @mock.patch("builtins.open", new_callable=mock.mock_open) def test_new_density(self, mock_open): example_atom = Atom( lbl=1, @@ -364,10 +395,10 @@ class TestDiceInterface(unittest.TestCase): sig=1.0, ) - main_molecule = Molecule('main_molecule') + main_molecule = Molecule("main_molecule") main_molecule.add_atom(example_atom) - secondary_molecule = Molecule('secondary_molecule') + secondary_molecule = Molecule("secondary_molecule") secondary_molecule.add_atom(example_atom) system = System() @@ -378,95 +409,166 @@ class TestDiceInterface(unittest.TestCase): dice.configure(self.config, system) last_xyz_file = io.StringIO() - last_xyz_file.writelines([ - ' TEST\n', - ' Configuration number : TEST = 1 1 1\n', - ' H 1.00000 1.00000 1.00000\n', - ' H 1.00000 1.00000 1.00000\n', - ]) + last_xyz_file.writelines( + [ + " TEST\n", + " Configuration number : TEST = 1 1 1\n", + " H 1.00000 1.00000 1.00000\n", + " H 1.00000 1.00000 1.00000\n", + ] + ) last_xyz_file.seek(0) density = dice._new_density(last_xyz_file) self.assertEqual(density, 85.35451545000001) - @mock.patch('builtins.open', new_callable=mock.mock_open) - @mock.patch('diceplayer.shared.interface.dice_interface.random') + @mock.patch("builtins.open", new_callable=mock.mock_open) + @mock.patch("diceplayer.shared.interface.dice_interface.random") def test_make_nvt_ter(self, mock_random, mock_open): mock_random.random.return_value = 1 dice = DiceInterface() dice.configure(self.config, System()) - dice._make_nvt_ter(1, 'test') + dice._make_nvt_ter(1, "test") mock_handler = mock_open() calls = mock_handler.write.call_args_list lines = list(map(lambda x: x[0][0], calls)) - expected_lines = ['title = Diceplayer run - NVT Thermalization\n', 'ncores = 4\n', 'ljname = phb.ljc\n', 'outname = phb\n', 'nmol = 1 50\n', 'dens = 0.75\n', 'temp = 300.0\n', 'init = yes\n', 'nstep = 2000\n', 'vstep = 0\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 0\n', 'irdf = 0\n', 'seed = 1000000\n', 'upbuf = 360'] + expected_lines = [ + "title = Diceplayer run - NVT Thermalization\n", + "ncores = 4\n", + "ljname = phb.ljc\n", + "outname = phb\n", + "nmol = 1 50\n", + "dens = 0.75\n", + "temp = 300.0\n", + "init = yes\n", + "nstep = 2000\n", + "vstep = 0\n", + "mstop = 1\n", + "accum = no\n", + "iprint = 1\n", + "isave = 0\n", + "irdf = 0\n", + "seed = 1000000\n", + "upbuf = 360", + ] self.assertEqual(lines, expected_lines) - @mock.patch('builtins.open', new_callable=mock.mock_open) - @mock.patch('diceplayer.shared.interface.dice_interface.random') + @mock.patch("builtins.open", new_callable=mock.mock_open) + @mock.patch("diceplayer.shared.interface.dice_interface.random") def test_make_nvt_eq(self, mock_random, mock_open): mock_random.random.return_value = 1 dice = DiceInterface() dice.configure(self.config, System()) - dice._make_nvt_eq(1, 'test') + dice._make_nvt_eq(1, "test") mock_handler = mock_open() calls = mock_handler.write.call_args_list lines = list(map(lambda x: x[0][0], calls)) - expected_lines = ['title = Diceplayer run - NVT Production\n', 'ncores = 4\n', 'ljname = phb.ljc\n', 'outname = phb\n', 'nmol = 1 50\n', 'dens = 0.75\n', 'temp = 300.0\n', 'init = no\n', 'nstep = 3000\n', 'vstep = 0\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 1000\n', 'irdf = 40\n', 'seed = 1000000\n'] + expected_lines = [ + "title = Diceplayer run - NVT Production\n", + "ncores = 4\n", + "ljname = phb.ljc\n", + "outname = phb\n", + "nmol = 1 50\n", + "dens = 0.75\n", + "temp = 300.0\n", + "init = no\n", + "nstep = 3000\n", + "vstep = 0\n", + "mstop = 1\n", + "accum = no\n", + "iprint = 1\n", + "isave = 1000\n", + "irdf = 40\n", + "seed = 1000000\n", + ] self.assertEqual(lines, expected_lines) - @mock.patch('builtins.open', new_callable=mock.mock_open) - @mock.patch('diceplayer.shared.interface.dice_interface.random') + @mock.patch("builtins.open", new_callable=mock.mock_open) + @mock.patch("diceplayer.shared.interface.dice_interface.random") def test_make_npt_ter(self, mock_random, mock_open): mock_random.random.return_value = 1 dice = DiceInterface() dice.configure(self.config, System()) - dice._make_npt_ter(1, 'test') + dice._make_npt_ter(1, "test") mock_handler = mock_open() calls = mock_handler.write.call_args_list lines = list(map(lambda x: x[0][0], calls)) - expected_lines = ['title = Diceplayer run - NPT Thermalization\n', 'ncores = 4\n', 'ljname = phb.ljc\n', 'outname = phb\n', 'nmol = 1 50\n', 'press = 1.0\n', 'temp = 300.0\n', 'init = no\n', 'vstep = 600\n', 'nstep = 5\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 0\n', 'irdf = 0\n', 'seed = 1000000\n'] + expected_lines = [ + "title = Diceplayer run - NPT Thermalization\n", + "ncores = 4\n", + "ljname = phb.ljc\n", + "outname = phb\n", + "nmol = 1 50\n", + "press = 1.0\n", + "temp = 300.0\n", + "init = no\n", + "vstep = 600\n", + "nstep = 5\n", + "mstop = 1\n", + "accum = no\n", + "iprint = 1\n", + "isave = 0\n", + "irdf = 0\n", + "seed = 1000000\n", + ] self.assertEqual(lines, expected_lines) - @mock.patch('builtins.open', new_callable=mock.mock_open) - @mock.patch('diceplayer.shared.interface.dice_interface.random') + @mock.patch("builtins.open", new_callable=mock.mock_open) + @mock.patch("diceplayer.shared.interface.dice_interface.random") def test_make_npt_eq(self, mock_random, mock_open): mock_random.random.return_value = 1 dice = DiceInterface() dice.configure(self.config, System()) - dice._make_npt_eq('test') + dice._make_npt_eq("test") mock_handler = mock_open() calls = mock_handler.write.call_args_list lines = list(map(lambda x: x[0][0], calls)) - expected_lines = ['title = Diceplayer run - NPT Production\n', 'ncores = 4\n', 'ljname = phb.ljc\n', 'outname = phb\n', 'nmol = 1 50\n', 'press = 1.0\n', 'temp = 300.0\n', 'nstep = 5\n', 'vstep = 800\n', 'init = no\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 1000\n', 'irdf = 40\n', 'seed = 1000000\n'] + expected_lines = [ + "title = Diceplayer run - NPT Production\n", + "ncores = 4\n", + "ljname = phb.ljc\n", + "outname = phb\n", + "nmol = 1 50\n", + "press = 1.0\n", + "temp = 300.0\n", + "nstep = 5\n", + "vstep = 800\n", + "init = no\n", + "mstop = 1\n", + "accum = no\n", + "iprint = 1\n", + "isave = 1000\n", + "irdf = 40\n", + "seed = 1000000\n", + ] self.assertEqual(lines, expected_lines) - @mock.patch('builtins.open', new_callable=mock.mock_open) + @mock.patch("builtins.open", new_callable=mock.mock_open) def test_make_potentials(self, mock_open): example_atom = Atom( lbl=1, @@ -479,10 +581,10 @@ class TestDiceInterface(unittest.TestCase): sig=1.0, ) - main_molecule = Molecule('main_molecule') + main_molecule = Molecule("main_molecule") main_molecule.add_atom(example_atom) - secondary_molecule = Molecule('secondary_molecule') + secondary_molecule = Molecule("secondary_molecule") secondary_molecule.add_atom(example_atom) system = System() @@ -492,49 +594,68 @@ class TestDiceInterface(unittest.TestCase): dice = DiceInterface() dice.configure(self.config, system) - dice._make_potentials('test') + dice._make_potentials("test") mock_handler = mock_open() calls = mock_handler.write.call_args_list lines = list(map(lambda x: x[0][0], calls)) - expected_lines = ['*\n', '2\n', '1 main_molecule\n', '1 1 1.00000 1.00000 1.00000 1.000000 1.00000 1.0000\n', '1 secondary_molecule\n', '1 1 1.00000 1.00000 1.00000 1.000000 1.00000 1.0000\n'] + expected_lines = [ + "*\n", + "2\n", + "1 main_molecule\n", + "1 1 1.00000 1.00000 1.00000 1.000000 1.00000 1.0000\n", + "1 secondary_molecule\n", + "1 1 1.00000 1.00000 1.00000 1.000000 1.00000 1.0000\n", + ] self.assertEqual(lines, expected_lines) - @mock.patch('diceplayer.shared.interface.dice_interface.subprocess') - @mock.patch('builtins.open', new_callable=mock.mock_open, read_data='End of simulation\nBLABLA') + @mock.patch("diceplayer.shared.interface.dice_interface.subprocess") + @mock.patch( + "builtins.open", + new_callable=mock.mock_open, + read_data="End of simulation\nBLABLA", + ) def test_run_dice_file(self, mock_open, mock_subprocess): mock_subprocess.call.return_value = 0 dice = DiceInterface() dice.configure(self.config, System()) - dice.run_dice_file(1, 1, 'test') + dice.run_dice_file(1, 1, "test") self.assertTrue(mock_subprocess.call.called) self.assertTrue(mock_open.called) - @mock.patch('diceplayer.shared.interface.dice_interface.subprocess') - @mock.patch('builtins.open', new_callable=mock.mock_open, read_data='Error\nBLABLA') - def test_run_dice_file_raises_runtime_error_on_dice_file(self, mock_open, mock_subprocess): + @mock.patch("diceplayer.shared.interface.dice_interface.subprocess") + @mock.patch("builtins.open", new_callable=mock.mock_open, read_data="Error\nBLABLA") + def test_run_dice_file_raises_runtime_error_on_dice_file( + self, mock_open, mock_subprocess + ): mock_subprocess.call.return_value = 0 dice = DiceInterface() dice.configure(self.config, System()) with self.assertRaises(RuntimeError): - dice.run_dice_file(1, 1, 'test') + dice.run_dice_file(1, 1, "test") - @mock.patch('diceplayer.shared.interface.dice_interface.subprocess') - @mock.patch('builtins.open', new_callable=mock.mock_open, read_data='End of simulation\nBLABLA') - def test_run_dice_file_raises_runtime_error_of_dice_exit_code(self, mock_open, mock_subprocess): + @mock.patch("diceplayer.shared.interface.dice_interface.subprocess") + @mock.patch( + "builtins.open", + new_callable=mock.mock_open, + read_data="End of simulation\nBLABLA", + ) + def test_run_dice_file_raises_runtime_error_of_dice_exit_code( + self, mock_open, mock_subprocess + ): mock_subprocess.call.return_value = 1 dice = DiceInterface() dice.configure(self.config, System()) with self.assertRaises(RuntimeError): - dice.run_dice_file(1, 1, 'test') + dice.run_dice_file(1, 1, "test") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/shared/interface/test_gaussian_interface.py b/tests/shared/interface/test_gaussian_interface.py index b59cd93..4e6e12f 100644 --- a/tests/shared/interface/test_gaussian_interface.py +++ b/tests/shared/interface/test_gaussian_interface.py @@ -1,16 +1,14 @@ -from diceplayer.shared.interface.gaussian_interface import GaussianInterface +from diceplayer import logger from diceplayer.shared.config.player_config import PlayerConfig from diceplayer.shared.environment.system import System -from diceplayer import logger - +from diceplayer.shared.interface.gaussian_interface import GaussianInterface from tests.mocks.mock_inputs import get_config_example import yaml + import io - - -from unittest import mock import unittest +from unittest import mock class TestGaussianInterface(unittest.TestCase): @@ -18,7 +16,7 @@ class TestGaussianInterface(unittest.TestCase): logger.set_logger(stream=io.StringIO()) config = yaml.load(get_config_example(), Loader=yaml.Loader) - self.config = PlayerConfig.from_dict(config['diceplayer']) + self.config = PlayerConfig.from_dict(config["diceplayer"]) def test_class_instantiation(self): gaussian_interface = GaussianInterface() @@ -45,11 +43,11 @@ class TestGaussianInterface(unittest.TestCase): gaussian_interface.reset() - self.assertFalse(hasattr(gaussian_interface, 'step')) - self.assertFalse(hasattr(gaussian_interface, 'system')) + self.assertFalse(hasattr(gaussian_interface, "step")) + self.assertFalse(hasattr(gaussian_interface, "system")) - @mock.patch('diceplayer.shared.interface.gaussian_interface.Path.mkdir') - @mock.patch('diceplayer.shared.interface.gaussian_interface.Path.exists') + @mock.patch("diceplayer.shared.interface.gaussian_interface.Path.mkdir") + @mock.patch("diceplayer.shared.interface.gaussian_interface.Path.exists") def test_make_qm_dir(self, mock_exists, mock_mkdir): mock_exists.return_value = False @@ -61,8 +59,8 @@ class TestGaussianInterface(unittest.TestCase): mock_exists.assert_called_once() mock_mkdir.assert_called_once() - @mock.patch('diceplayer.shared.interface.gaussian_interface.shutil.copy') - @mock.patch('diceplayer.shared.interface.gaussian_interface.Path.exists') + @mock.patch("diceplayer.shared.interface.gaussian_interface.shutil.copy") + @mock.patch("diceplayer.shared.interface.gaussian_interface.Path.exists") def test_copy_chk_file_from_previous_step(self, mock_exists, mock_copy): gaussian_interface = GaussianInterface() gaussian_interface.configure(self.config, System()) @@ -74,9 +72,11 @@ class TestGaussianInterface(unittest.TestCase): self.assertTrue(mock_exists.called) self.assertTrue(mock_copy.called) - @mock.patch('diceplayer.shared.interface.gaussian_interface.shutil.copy') - @mock.patch('diceplayer.shared.interface.gaussian_interface.Path.exists') - def test_copy_chk_file_from_previous_step_no_previous_step(self, mock_exists, mock_copy): + @mock.patch("diceplayer.shared.interface.gaussian_interface.shutil.copy") + @mock.patch("diceplayer.shared.interface.gaussian_interface.Path.exists") + def test_copy_chk_file_from_previous_step_no_previous_step( + self, mock_exists, mock_copy + ): gaussian_interface = GaussianInterface() gaussian_interface.configure(self.config, System()) @@ -85,9 +85,11 @@ class TestGaussianInterface(unittest.TestCase): with self.assertRaises(FileNotFoundError): gaussian_interface._copy_chk_file_from_previous_step(2) - @mock.patch('diceplayer.shared.interface.gaussian_interface.shutil.copy') - @mock.patch('diceplayer.shared.interface.gaussian_interface.Path.exists') - def test_copy_chk_file_from_previous_step_current_exists(self, mock_exists, mock_copy): + @mock.patch("diceplayer.shared.interface.gaussian_interface.shutil.copy") + @mock.patch("diceplayer.shared.interface.gaussian_interface.Path.exists") + def test_copy_chk_file_from_previous_step_current_exists( + self, mock_exists, mock_copy + ): gaussian_interface = GaussianInterface() gaussian_interface.configure(self.config, System()) @@ -109,5 +111,5 @@ class TestGaussianInterface(unittest.TestCase): # gaussian_interface._copy_chk_file_from_previous_step.assert_called_once_with(2) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/shared/utils/test_logger.py b/tests/shared/utils/test_logger.py index abe41a8..2fd776f 100644 --- a/tests/shared/utils/test_logger.py +++ b/tests/shared/utils/test_logger.py @@ -1,10 +1,9 @@ from diceplayer.shared.utils.logger import Logger, valid_logger -import logging import io - -from unittest import mock +import logging import unittest +from unittest import mock class TestValidateLogger(unittest.TestCase): @@ -32,102 +31,102 @@ class TestValidateLogger(unittest.TestCase): class TestLogger(unittest.TestCase): def test_class_instantiation(self): - logger = Logger('test') + logger = Logger("test") self.assertIsInstance(logger, Logger) - @mock.patch('builtins.open', mock.mock_open()) + @mock.patch("builtins.open", mock.mock_open()) def test_set_logger_to_file(self): - logger = Logger('test') + logger = Logger("test") logger.set_logger(stream=io.StringIO()) self.assertIsNotNone(logger._logger) - self.assertEqual(logger._logger.name, 'test') + self.assertEqual(logger._logger.name, "test") def test_set_logger_to_stream(self): - logger = Logger('test') + logger = Logger("test") logger.set_logger(stream=io.StringIO()) self.assertIsNotNone(logger._logger) - self.assertEqual(logger._logger.name, 'test') + self.assertEqual(logger._logger.name, "test") - @mock.patch('builtins.open', mock.mock_open()) - @mock.patch('diceplayer.shared.utils.logger.Path.exists') - @mock.patch('diceplayer.shared.utils.logger.Path.rename') + @mock.patch("builtins.open", mock.mock_open()) + @mock.patch("diceplayer.shared.utils.logger.Path.exists") + @mock.patch("diceplayer.shared.utils.logger.Path.rename") def test_set_logger_if_file_exists(self, mock_rename, mock_exists): - logger = Logger('test') + logger = Logger("test") mock_exists.return_value = True logger.set_logger() self.assertTrue(mock_rename.called) self.assertIsNotNone(logger._logger) - self.assertEqual(logger._logger.name, 'test') + self.assertEqual(logger._logger.name, "test") - @mock.patch('builtins.open', mock.mock_open()) - @mock.patch('diceplayer.shared.utils.logger.Path.exists') - @mock.patch('diceplayer.shared.utils.logger.Path.rename') + @mock.patch("builtins.open", mock.mock_open()) + @mock.patch("diceplayer.shared.utils.logger.Path.exists") + @mock.patch("diceplayer.shared.utils.logger.Path.rename") def test_set_logger_if_file_not_exists(self, mock_rename, mock_exists): - logger = Logger('test') + logger = Logger("test") mock_exists.return_value = False logger.set_logger() self.assertFalse(mock_rename.called) self.assertIsNotNone(logger._logger) - self.assertEqual(logger._logger.name, 'test') + self.assertEqual(logger._logger.name, "test") - @mock.patch('builtins.open', mock.mock_open()) + @mock.patch("builtins.open", mock.mock_open()) def test_close(self): - logger = Logger('test') + logger = Logger("test") logger.set_logger() logger.close() self.assertEqual(len(logger._logger.handlers), 0) - @mock.patch('builtins.open', mock.mock_open()) + @mock.patch("builtins.open", mock.mock_open()) def test_info(self): - logger = Logger('test') + logger = Logger("test") logger.set_logger(stream=io.StringIO()) - with self.assertLogs(level='INFO') as cm: - logger.info('test') + with self.assertLogs(level="INFO") as cm: + logger.info("test") - self.assertEqual(cm.output, ['INFO:test:test']) + self.assertEqual(cm.output, ["INFO:test:test"]) - @mock.patch('builtins.open', mock.mock_open()) + @mock.patch("builtins.open", mock.mock_open()) def test_debug(self): - logger = Logger('test') + logger = Logger("test") logger.set_logger(stream=io.StringIO(), level=logging.DEBUG) - with self.assertLogs(level='DEBUG') as cm: - logger.debug('test') + with self.assertLogs(level="DEBUG") as cm: + logger.debug("test") - self.assertEqual(cm.output, ['DEBUG:test:test']) + self.assertEqual(cm.output, ["DEBUG:test:test"]) - @mock.patch('builtins.open', mock.mock_open()) + @mock.patch("builtins.open", mock.mock_open()) def test_warning(self): - logger = Logger('test') + logger = Logger("test") logger.set_logger(stream=io.StringIO()) - with self.assertLogs(level='WARNING') as cm: - logger.warning('test') + with self.assertLogs(level="WARNING") as cm: + logger.warning("test") - self.assertEqual(cm.output, ['WARNING:test:test']) + self.assertEqual(cm.output, ["WARNING:test:test"]) - @mock.patch('builtins.open', mock.mock_open()) + @mock.patch("builtins.open", mock.mock_open()) def test_error(self): - logger = Logger('test') + logger = Logger("test") logger.set_logger(stream=io.StringIO()) - with self.assertLogs(level='ERROR') as cm: - logger.error('test') + with self.assertLogs(level="ERROR") as cm: + logger.error("test") - self.assertEqual(cm.output, ['ERROR:test:test']) + self.assertEqual(cm.output, ["ERROR:test:test"]) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_player.py b/tests/test_player.py index f6071a0..c793767 100644 --- a/tests/test_player.py +++ b/tests/test_player.py @@ -1,12 +1,10 @@ -from diceplayer.player import Player from diceplayer import logger - -import io - +from diceplayer.player import Player from tests.mocks.mock_inputs import mock_open -from unittest import mock +import io import unittest +from unittest import mock class TestPlayer(unittest.TestCase): @@ -59,36 +57,36 @@ class TestPlayer(unittest.TestCase): def test_print_keywords(self, mock_date_func, mock_sys): player = Player("control.test.yml") - mock_sys.version = 'TEST' - mock_date_func.return_value = '00 Test 0000 at 00:00:00' + mock_sys.version = "TEST" + mock_date_func.return_value = "00 Test 0000 at 00:00:00" with self.assertLogs() as cm: player.print_keywords() expected_output = [ - 'INFO:diceplayer:##########################################################################################\n############# Welcome to DICEPLAYER version 1.0 #############\n##########################################################################################\n', - 'INFO:diceplayer:Your python version is TEST\n', - 'INFO:diceplayer:Program started on 00 Test 0000 at 00:00:00\n', - 'INFO:diceplayer:Environment variables:', - 'INFO:diceplayer:OMP_STACKSIZE = Not set\n', - 'INFO:diceplayer:------------------------------------------------------------------------------------------\n DICE variables being used in this run:\n------------------------------------------------------------------------------------------\n', - 'INFO:diceplayer:dens = 0.75', - 'INFO:diceplayer:isave = 1000', - 'INFO:diceplayer:ljname = phb.ljc', - 'INFO:diceplayer:nmol = [ 1 50 ]', - 'INFO:diceplayer:nstep = [ 2000 3000 4000 ]', - 'INFO:diceplayer:outname = phb', - 'INFO:diceplayer:press = 1.0', - 'INFO:diceplayer:progname = ~/.local/bin/dice', - 'INFO:diceplayer:randominit = first', - 'INFO:diceplayer:temp = 300.0', - 'INFO:diceplayer:------------------------------------------------------------------------------------------\n GAUSSIAN variables being used in this run:\n------------------------------------------------------------------------------------------\n', - 'INFO:diceplayer:chg_tol = 0.01', - 'INFO:diceplayer:keywords = freq', - 'INFO:diceplayer:level = MP2/aug-cc-pVDZ', - 'INFO:diceplayer:pop = chelpg', - 'INFO:diceplayer:qmprog = g16', - 'INFO:diceplayer:\n' + "INFO:diceplayer:##########################################################################################\n############# Welcome to DICEPLAYER version 1.0 #############\n##########################################################################################\n", + "INFO:diceplayer:Your python version is TEST\n", + "INFO:diceplayer:Program started on 00 Test 0000 at 00:00:00\n", + "INFO:diceplayer:Environment variables:", + "INFO:diceplayer:OMP_STACKSIZE = Not set\n", + "INFO:diceplayer:------------------------------------------------------------------------------------------\n DICE variables being used in this run:\n------------------------------------------------------------------------------------------\n", + "INFO:diceplayer:dens = 0.75", + "INFO:diceplayer:isave = 1000", + "INFO:diceplayer:ljname = phb.ljc", + "INFO:diceplayer:nmol = [ 1 50 ]", + "INFO:diceplayer:nstep = [ 2000 3000 4000 ]", + "INFO:diceplayer:outname = phb", + "INFO:diceplayer:press = 1.0", + "INFO:diceplayer:progname = ~/.local/bin/dice", + "INFO:diceplayer:randominit = first", + "INFO:diceplayer:temp = 300.0", + "INFO:diceplayer:------------------------------------------------------------------------------------------\n GAUSSIAN variables being used in this run:\n------------------------------------------------------------------------------------------\n", + "INFO:diceplayer:chg_tol = 0.01", + "INFO:diceplayer:keywords = freq", + "INFO:diceplayer:level = MP2/aug-cc-pVDZ", + "INFO:diceplayer:pop = chelpg", + "INFO:diceplayer:qmprog = g16", + "INFO:diceplayer:\n", ] self.assertEqual(cm.output, expected_output) @@ -99,12 +97,18 @@ class TestPlayer(unittest.TestCase): molecule_type=0, molecule_site=0, atom_dict={ - "lbl": 0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0 - } + "lbl": 0, + "na": 1, + "rx": 1.0, + "ry": 1.0, + "rz": 1.0, + "chg": 1.0, + "eps": 1.0, + }, ) self.assertEqual( str(context.exception), - "Invalid number of fields for site 1 for molecule type 1." + "Invalid number of fields for site 1 for molecule type 1.", ) with self.assertRaises(ValueError) as context: @@ -112,12 +116,18 @@ class TestPlayer(unittest.TestCase): molecule_type=0, molecule_site=0, atom_dict={ - "lbl": '', "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": 1.0 - } + "lbl": "", + "na": 1, + "rx": 1.0, + "ry": 1.0, + "rz": 1.0, + "chg": 1.0, + "eps": 1.0, + "sig": 1.0, + }, ) self.assertEqual( - str(context.exception), - "Invalid lbl fields for site 1 for molecule type 1." + str(context.exception), "Invalid lbl fields for site 1 for molecule type 1." ) with self.assertRaises(ValueError) as context: @@ -125,12 +135,18 @@ class TestPlayer(unittest.TestCase): molecule_type=0, molecule_site=0, atom_dict={ - "lbl": 1.0, "na": '', "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": 1.0 - } + "lbl": 1.0, + "na": "", + "rx": 1.0, + "ry": 1.0, + "rz": 1.0, + "chg": 1.0, + "eps": 1.0, + "sig": 1.0, + }, ) self.assertEqual( - str(context.exception), - "Invalid na fields for site 1 for molecule type 1." + str(context.exception), "Invalid na fields for site 1 for molecule type 1." ) with self.assertRaises(ValueError) as context: @@ -138,12 +154,19 @@ class TestPlayer(unittest.TestCase): molecule_type=0, molecule_site=0, atom_dict={ - "lbl": 1.0, "na": 1, "rx": '', "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": 1.0 - } + "lbl": 1.0, + "na": 1, + "rx": "", + "ry": 1.0, + "rz": 1.0, + "chg": 1.0, + "eps": 1.0, + "sig": 1.0, + }, ) self.assertEqual( str(context.exception), - "Invalid rx fields for site 1 for molecule type 1. Value must be a float." + "Invalid rx fields for site 1 for molecule type 1. Value must be a float.", ) with self.assertRaises(ValueError) as context: @@ -151,12 +174,19 @@ class TestPlayer(unittest.TestCase): molecule_type=0, molecule_site=0, atom_dict={ - "lbl": 1.0, "na": 1, "rx": 1.0, "ry": '', "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": 1.0 - } + "lbl": 1.0, + "na": 1, + "rx": 1.0, + "ry": "", + "rz": 1.0, + "chg": 1.0, + "eps": 1.0, + "sig": 1.0, + }, ) self.assertEqual( str(context.exception), - "Invalid ry fields for site 1 for molecule type 1. Value must be a float." + "Invalid ry fields for site 1 for molecule type 1. Value must be a float.", ) with self.assertRaises(ValueError) as context: @@ -164,12 +194,19 @@ class TestPlayer(unittest.TestCase): molecule_type=0, molecule_site=0, atom_dict={ - "lbl": 1.0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": '', "chg": 1.0, "eps": 1.0, "sig": 1.0 - } + "lbl": 1.0, + "na": 1, + "rx": 1.0, + "ry": 1.0, + "rz": "", + "chg": 1.0, + "eps": 1.0, + "sig": 1.0, + }, ) self.assertEqual( str(context.exception), - "Invalid rz fields for site 1 for molecule type 1. Value must be a float." + "Invalid rz fields for site 1 for molecule type 1. Value must be a float.", ) with self.assertRaises(ValueError) as context: @@ -177,12 +214,19 @@ class TestPlayer(unittest.TestCase): molecule_type=0, molecule_site=0, atom_dict={ - "lbl": 1.0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": '', "eps": 1.0, "sig": 1.0 - } + "lbl": 1.0, + "na": 1, + "rx": 1.0, + "ry": 1.0, + "rz": 1.0, + "chg": "", + "eps": 1.0, + "sig": 1.0, + }, ) self.assertEqual( str(context.exception), - "Invalid chg fields for site 1 for molecule type 1. Value must be a float." + "Invalid chg fields for site 1 for molecule type 1. Value must be a float.", ) with self.assertRaises(ValueError) as context: @@ -190,12 +234,19 @@ class TestPlayer(unittest.TestCase): molecule_type=0, molecule_site=0, atom_dict={ - "lbl": 1.0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": '', "sig": 1.0 - } + "lbl": 1.0, + "na": 1, + "rx": 1.0, + "ry": 1.0, + "rz": 1.0, + "chg": 1.0, + "eps": "", + "sig": 1.0, + }, ) self.assertEqual( str(context.exception), - "Invalid eps fields for site 1 for molecule type 1. Value must be a float." + "Invalid eps fields for site 1 for molecule type 1. Value must be a float.", ) with self.assertRaises(ValueError) as context: @@ -203,12 +254,19 @@ class TestPlayer(unittest.TestCase): molecule_type=0, molecule_site=0, atom_dict={ - "lbl": 1.0, "na": 1, "rx": 1.0, "ry": 1.0, "rz": 1.0, "chg": 1.0, "eps": 1.0, "sig": '' - } + "lbl": 1.0, + "na": 1, + "rx": 1.0, + "ry": 1.0, + "rz": 1.0, + "chg": 1.0, + "eps": 1.0, + "sig": "", + }, ) self.assertEqual( str(context.exception), - "Invalid sig fields for site 1 for molecule type 1. Value must be a float." + "Invalid sig fields for site 1 for molecule type 1. Value must be a float.", ) @mock.patch("builtins.open", mock_open) @@ -234,10 +292,7 @@ class TestPlayer(unittest.TestCase): with self.assertRaises(RuntimeError) as context: player.read_potentials() - self.assertEqual( - str(context.exception), - "Potential file phb.ljc not found." - ) + self.assertEqual(str(context.exception), "Potential file phb.ljc not found.") # Enabling file found for next tests mock_path_exists.return_value = True @@ -249,7 +304,7 @@ class TestPlayer(unittest.TestCase): self.assertEqual( str(context.exception), - "Error: expected a '*' or a '+' sign in 1st line of file phb.error.combrule.ljc" + "Error: expected a '*' or a '+' sign in 1st line of file phb.error.combrule.ljc", ) # Testing ntypes error @@ -259,7 +314,7 @@ class TestPlayer(unittest.TestCase): self.assertEqual( str(context.exception), - "Error: expected an integer in the 2nd line of file phb.error.ntypes.ljc" + "Error: expected an integer in the 2nd line of file phb.error.ntypes.ljc", ) # Testing ntypes error on config @@ -270,7 +325,7 @@ class TestPlayer(unittest.TestCase): self.assertEqual( str(context.exception), "Error: number of molecule types in file phb.error.ntypes.config.ljc " - "must match that of 'nmol' keyword in config file" + "must match that of 'nmol' keyword in config file", ) # Testing nsite error @@ -280,7 +335,7 @@ class TestPlayer(unittest.TestCase): self.assertEqual( str(context.exception), - "Error: expected nsites to be an integer for molecule type 1" + "Error: expected nsites to be an integer for molecule type 1", ) # Testing molname error @@ -290,7 +345,7 @@ class TestPlayer(unittest.TestCase): self.assertEqual( str(context.exception), - "Error: expected nsites and molname for the molecule type 1" + "Error: expected nsites and molname for the molecule type 1", ) @mock.patch("builtins.open", mock_open) @@ -299,31 +354,28 @@ class TestPlayer(unittest.TestCase): player = Player("control.test.yml") player.read_potentials() - with self.assertLogs(level='INFO') as context: + with self.assertLogs(level="INFO") as context: player.print_potentials() expected_output = [ - 'INFO:diceplayer:==========================================================================================\n Potential parameters from file phb.ljc:\n------------------------------------------------------------------------------------------\n', - 'INFO:diceplayer:Combination rule: *', - 'INFO:diceplayer:Types of molecules: 2\n', - 'INFO:diceplayer:1 atoms in molecule type 1:', - 'INFO:diceplayer:---------------------------------------------------------------------------------', - 'INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass', - 'INFO:diceplayer:---------------------------------------------------------------------------------', - 'INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079', - 'INFO:diceplayer:\n', - 'INFO:diceplayer:1 atoms in molecule type 2:', - 'INFO:diceplayer:---------------------------------------------------------------------------------', - 'INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass', - 'INFO:diceplayer:---------------------------------------------------------------------------------', - 'INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079', - 'INFO:diceplayer:\n' + "INFO:diceplayer:==========================================================================================\n Potential parameters from file phb.ljc:\n------------------------------------------------------------------------------------------\n", + "INFO:diceplayer:Combination rule: *", + "INFO:diceplayer:Types of molecules: 2\n", + "INFO:diceplayer:1 atoms in molecule type 1:", + "INFO:diceplayer:---------------------------------------------------------------------------------", + "INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass", + "INFO:diceplayer:---------------------------------------------------------------------------------", + "INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079", + "INFO:diceplayer:\n", + "INFO:diceplayer:1 atoms in molecule type 2:", + "INFO:diceplayer:---------------------------------------------------------------------------------", + "INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass", + "INFO:diceplayer:---------------------------------------------------------------------------------", + "INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079", + "INFO:diceplayer:\n", ] - self.assertEqual( - context.output, - expected_output - ) + self.assertEqual(context.output, expected_output) @mock.patch("builtins.open", mock_open) def test_dice_start(self): @@ -336,5 +388,5 @@ class TestPlayer(unittest.TestCase): player.dice_interface.start.assert_called_once() -if __name__ == '__main__': +if __name__ == "__main__": unittest.main()