Merge pull request #4 from HideyoshiNakazone/devel

Devel - v0.0.2
This commit is contained in:
2023-06-11 16:08:07 -03:00
committed by GitHub
30 changed files with 1382 additions and 721 deletions

13
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,13 @@
repos:
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
args: [--config=pyproject.toml]
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
files: "\\.(py)$"
args: [--settings-path=pyproject.toml]

View File

@@ -1,4 +1,3 @@
from diceplayer.shared.utils.logger import Logger
logger = Logger(__name__)

View File

@@ -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()

View File

@@ -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

View File

@@ -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(

View File

@@ -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):

View File

@@ -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)

View File

@@ -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.

View File

@@ -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)
return min(distances)

View File

@@ -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],
)
)

View File

@@ -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

View File

@@ -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")

View File

@@ -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()

View File

@@ -1,4 +1,4 @@
from typing import runtime_checkable, Protocol
from typing import Protocol, runtime_checkable
@runtime_checkable

View File

@@ -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):

View File

@@ -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))

View File

@@ -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
ghost_number = len(atomsymb) - 1

319
poetry.lock generated
View File

@@ -12,6 +12,95 @@ 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"
description = "Validate configuration and produce human readable error messages."
category = "main"
optional = false
python-versions = ">=3.6.1"
files = [
{file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
{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"
@@ -99,6 +188,94 @@ files = [
[package.extras]
dev = ["black", "coveralls", "mypy", "pre-commit", "pylint", "pytest (>=5)", "pytest-benchmark", "pytest-cov"]
[[package]]
name = "distlib"
version = "0.3.6"
description = "Distribution utilities"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"},
{file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
]
[[package]]
name = "filelock"
version = "3.12.1"
description = "A platform independent file lock."
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "filelock-3.12.1-py3-none-any.whl", hash = "sha256:42f1e4ff2b497311213d61ad7aac5fed9050608e5309573f101eefa94143134a"},
{file = "filelock-3.12.1.tar.gz", hash = "sha256:82b1f7da46f0ae42abf1bc78e548667f484ac59d2bcec38c713cee7e2eb51e83"},
]
[package.extras]
docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"]
[[package]]
name = "identify"
version = "2.5.24"
description = "File identification library for Python"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "identify-2.5.24-py2.py3-none-any.whl", hash = "sha256:986dbfb38b1140e763e413e6feb44cd731faf72d1909543178aa79b0e258265d"},
{file = "identify-2.5.24.tar.gz", hash = "sha256:0aac67d5b4812498056d28a9a512a483f5085cc28640b02b258a59dac34301d4"},
]
[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"
description = "Node.js virtual environment builder"
category = "main"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
files = [
{file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"},
{file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"},
]
[package.dependencies]
setuptools = "*"
[[package]]
name = "nptyping"
version = "2.5.0"
@@ -160,6 +337,96 @@ 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"
description = "Bring colors to your terminal."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = [
{file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"},
{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"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "platformdirs-3.5.3-py3-none-any.whl", hash = "sha256:0ade98a4895e87dc51d47151f7d2ec290365a585151d97b4d8d6312ed6132fed"},
{file = "platformdirs-3.5.3.tar.gz", hash = "sha256:e48fabd87db8f3a7df7150a4a5ea22c546ee8bc39bc2473244730d4b56d2cc4e"},
]
[package.extras]
docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"]
[[package]]
name = "poethepoet"
version = "0.20.0"
description = "A task runner that works well with poetry."
category = "main"
optional = false
python-versions = ">=3.8"
files = [
{file = "poethepoet-0.20.0-py3-none-any.whl", hash = "sha256:cb37be15f3895ccc65ddf188c2e3d8fb79e26cc9d469a6098cb1c6f994659f6f"},
{file = "poethepoet-0.20.0.tar.gz", hash = "sha256:ca5a2a955f52dfb0a53fad3c989ef0b69ce3d5ec0f6bfa9b1da1f9e32d262e20"},
]
[package.dependencies]
pastel = ">=0.2.1,<0.3.0"
tomli = ">=1.2.2"
[package.extras]
poetry-plugin = ["poetry (>=1.0,<2.0)"]
[[package]]
name = "pre-commit"
version = "3.3.2"
description = "A framework for managing and maintaining multi-language pre-commit hooks."
category = "main"
optional = false
python-versions = ">=3.8"
files = [
{file = "pre_commit-3.3.2-py2.py3-none-any.whl", hash = "sha256:8056bc52181efadf4aac792b1f4f255dfd2fb5a350ded7335d251a68561e8cb6"},
{file = "pre_commit-3.3.2.tar.gz", hash = "sha256:66e37bec2d882de1f17f88075047ef8962581f83c234ac08da21a0c58953d1f0"},
]
[package.dependencies]
cfgv = ">=2.0.0"
identify = ">=1.0.0"
nodeenv = ">=0.11.1"
pyyaml = ">=5.1"
virtualenv = ">=20.10.0"
[[package]]
name = "pyyaml"
version = "6.0"
@@ -295,6 +562,35 @@ files = [
[package.extras]
test = ["pytest"]
[[package]]
name = "setuptools"
version = "67.8.0"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "setuptools-67.8.0-py3-none-any.whl", hash = "sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f"},
{file = "setuptools-67.8.0.tar.gz", hash = "sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"},
]
[package.extras]
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
[[package]]
name = "typing-extensions"
version = "4.6.3"
@@ -307,7 +603,28 @@ files = [
{file = "typing_extensions-4.6.3.tar.gz", hash = "sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"},
]
[[package]]
name = "virtualenv"
version = "20.23.0"
description = "Virtual Python Environment builder"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "virtualenv-20.23.0-py3-none-any.whl", hash = "sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e"},
{file = "virtualenv-20.23.0.tar.gz", hash = "sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924"},
]
[package.dependencies]
distlib = ">=0.3.6,<1"
filelock = ">=3.11,<4"
platformdirs = ">=3.2,<4"
[package.extras]
docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"]
test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.7.1)", "time-machine (>=2.9)"]
[metadata]
lock-version = "2.0"
python-versions = "^3.8"
content-hash = "5767445dc10a28eeb01ba23bfbf781b68d8c158df80be696d53cb0c962d409ab"
content-hash = "2527f460007c57ea9d99659a7dce34657b4cdbd8c9d05bcd3deb822474ae79c6"

View File

@@ -14,7 +14,13 @@ setproctitle = "^1.3.2"
pyyaml = "^6.0"
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"
[tool.poetry.group.dev.dependencies]
coverage = "^7.2.7"
@@ -22,3 +28,31 @@ coverage = "^7.2.7"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poe.tasks]
hooks = "pre-commit install"
[tool.coverage.run]
omit = [
"mega_conversao/src/utilidades/trata.py",
"mega_conversao/src/modulos/*",
"tests/*",
]
data_file = "coverage/.coverage"
[tool.coverage.html]
directory = "coverage/html"
[tool.coverage.lcov]
output = "coverage/lcov.info"
[tool.isort]
profile = "black"
line_length = 79
sections=[
"FUTURE",
"FIRSTPARTY",
"LOCALFOLDER",
"THIRDPARTY",
"STDLIB",
]

View File

@@ -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

View File

@@ -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)
self.assertIsInstance(dice_dto, DiceConfig)

View File

@@ -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()

View File

@@ -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()

View File

@@ -16,4 +16,4 @@ class TestAtom(unittest.TestCase):
sig=1.0,
)
self.assertIsInstance(atom, Atom)
self.assertIsInstance(atom, Atom)

View File

@@ -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()
if __name__ == "__main__":
unittest.main()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()