Implements Better Tests and Logging
This commit is contained in:
@@ -69,7 +69,7 @@ def main():
|
||||
except IOError:
|
||||
raise RuntimeError('Invalid or Missing Config File.')
|
||||
|
||||
Log.make_header(__VERSION, data.get('crystal_pol'))
|
||||
Log.make_header(__VERSION, config.to_dict())
|
||||
|
||||
pol = Polarization(args.infile, args.outfile, config)
|
||||
pol.run()
|
||||
|
||||
@@ -81,9 +81,6 @@ class Gaussian:
|
||||
|
||||
with open(file, 'w+') as fh:
|
||||
|
||||
chk_path = file.with_suffix('.chk')
|
||||
fh.write(f"%Chk={chk_path}\n")
|
||||
|
||||
fh.write(f"%Mem={self.config.mem}Gb\n")
|
||||
|
||||
fh.write(f"%Nprocs={self.config.n_procs}\n")
|
||||
@@ -120,13 +117,13 @@ class Gaussian:
|
||||
fh.seek(0)
|
||||
return fh.read()
|
||||
|
||||
def make_gaussian_charges(self, fh: TextIO, crystal: Crystal) -> None:
|
||||
@staticmethod
|
||||
def make_gaussian_charges(fh: TextIO, crystal: Crystal) -> None:
|
||||
|
||||
for index_cell, cell in enumerate(crystal):
|
||||
for index_mol, molecule in enumerate(cell):
|
||||
if (index_cell == 0 and index_mol != 0) or (index_cell != 0):
|
||||
for atom in molecule:
|
||||
symbol = atom_symbol[atom.na]
|
||||
fh.write(
|
||||
f"{float(atom.rx):>10.5f} "
|
||||
f"{float(atom.ry):>10.5f} "
|
||||
@@ -134,8 +131,6 @@ class Gaussian:
|
||||
f"{float(atom.chg):>10.5f}\n"
|
||||
)
|
||||
|
||||
fh.write("\n")
|
||||
|
||||
def read_charges_from_gaussian_output(self, cycle, number_of_charges: int) -> List[float]:
|
||||
step_dir = Path(
|
||||
self.config.simulation_dir,
|
||||
@@ -156,4 +151,4 @@ class Gaussian:
|
||||
|
||||
lines = lines[3:] # Consume 3 more lines
|
||||
|
||||
return list(map(lambda x: float(x.split()[2]), lines[:number_of_charges]))
|
||||
return list(map(lambda x: float(x.split()[2]), lines[:number_of_charges]))
|
||||
|
||||
@@ -33,7 +33,7 @@ class Polarization:
|
||||
|
||||
cycle = 1
|
||||
max_charge_diff = sys.float_info.max
|
||||
while max_charge_diff > self.config.charge_tolerance:
|
||||
while max_charge_diff >= self.config.charge_tolerance:
|
||||
|
||||
max_charge_diff, charge_diff = self.update_crystal_charges(
|
||||
self.gaussian.run(cycle, self.crystal),
|
||||
@@ -41,7 +41,7 @@ class Polarization:
|
||||
|
||||
Log.make_run(
|
||||
cycle,
|
||||
max_charge_diff,
|
||||
max_charge_diff if cycle != 1 else 0,
|
||||
charge_diff,
|
||||
self.crystal
|
||||
)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
from dataclasses import dataclass, field, fields
|
||||
from dataclasses import dataclass, field, fields, asdict
|
||||
|
||||
|
||||
@dataclass
|
||||
class Config:
|
||||
|
||||
mem: int
|
||||
level: str
|
||||
n_atoms: int
|
||||
@@ -31,13 +30,11 @@ class Config:
|
||||
f'Memory must be a integer greater than 0.'
|
||||
)
|
||||
|
||||
if self.level is None:
|
||||
raise ValueError(
|
||||
f'Invalid value for level. Level must not be none.'
|
||||
)
|
||||
|
||||
if self.n_atoms is None or self.n_atoms <= 0:
|
||||
raise ValueError(
|
||||
f'Invalid value for n_atoms: {self.mem},'
|
||||
f'Number of Atoms must be a integer greater than 0.'
|
||||
)
|
||||
|
||||
def to_dict(self):
|
||||
return asdict(self)
|
||||
|
||||
@@ -18,6 +18,7 @@ class Atom:
|
||||
ry: float,
|
||||
rz: float,
|
||||
na: int = None,
|
||||
chg: float = None,
|
||||
symbol: str = None,
|
||||
|
||||
) -> None:
|
||||
@@ -42,5 +43,5 @@ class Atom:
|
||||
self.rx = rx
|
||||
self.ry = ry
|
||||
self.rz = rz
|
||||
self.chg = None
|
||||
self.chg = chg
|
||||
self.mass = atom_mass[self.na]
|
||||
|
||||
@@ -2,4 +2,4 @@ import time
|
||||
|
||||
|
||||
def weekday_date_time():
|
||||
return time.strftime("%A, %d %b %Y at %H:%M:%S")
|
||||
return time.strftime("%A, %d %b %Y at %H:%M:%S")
|
||||
|
||||
@@ -1,45 +1,49 @@
|
||||
import sys
|
||||
|
||||
from crystalpol.shared.config import Config
|
||||
from crystalpol.shared.utils import weekday_date_time
|
||||
|
||||
import logging
|
||||
|
||||
from crystalpol.shared.utils import weekday_date_time
|
||||
import sys
|
||||
|
||||
|
||||
class Log:
|
||||
@staticmethod
|
||||
def make_header(version: str, config_dict: dict):
|
||||
logging.info(
|
||||
def make_header(version: str, config_dict: dict, logger=None):
|
||||
|
||||
if logger is None:
|
||||
logger = logging.getLogger()
|
||||
|
||||
logger.info(
|
||||
f"##########################################################################################\n"
|
||||
f"############## Welcome to CRYSTALPOL version {version} ##############\n"
|
||||
f"##########################################################################################\n"
|
||||
)
|
||||
logging.info(f"Your python version is {sys.version}\n")
|
||||
logging.info(f"Program started on {weekday_date_time()}\n")
|
||||
logger.info(f"Your python version is {sys.version}\n")
|
||||
logger.info(f"Program started on {weekday_date_time()}\n")
|
||||
|
||||
logging.info("------------------------------------------------------------------------------------------")
|
||||
logging.info(" CRYSTALPOL variables being used in this run: ")
|
||||
logging.info("------------------------------------------------------------------------------------------\n")
|
||||
logger.info("------------------------------------------------------------------------------------------")
|
||||
logger.info(" CRYSTALPOL variables being used in this run: ")
|
||||
logger.info("------------------------------------------------------------------------------------------\n")
|
||||
for key, value in config_dict.items():
|
||||
logging.info(f"\t{key} = {(key if key else 'Not set')}")
|
||||
logger.info(f"\t{key} = {(value if value else 'Not set')}")
|
||||
|
||||
logging.info("------------------------------------------------------------------------------------------")
|
||||
logging.info(f" RUN Results: ")
|
||||
logging.info("------------------------------------------------------------------------------------------\n")
|
||||
logger.info("------------------------------------------------------------------------------------------")
|
||||
logger.info(f" RUN Results: ")
|
||||
logger.info("------------------------------------------------------------------------------------------\n")
|
||||
|
||||
@staticmethod
|
||||
def make_run(cycle, max_charge_diff, charge_diff, crystal):
|
||||
logging.info(f"cycle: {cycle}")
|
||||
logging.info(f"\nMax charge diff: {max_charge_diff}")
|
||||
logging.info(f"Charge Diff: {charge_diff}\n")
|
||||
def make_run(cycle, max_charge_diff, charge_diff, crystal, logger=None):
|
||||
|
||||
logging.info("------------------------------------------------------------------------------------------")
|
||||
logging.info(f" S rx ry rz chg ")
|
||||
logging.info("------------------------------------------------------------------------------------------")
|
||||
if logger is None:
|
||||
logger = logging.getLogger()
|
||||
|
||||
logger.info(f"cycle: {cycle}")
|
||||
logger.info(f"\nMax charge diff: {max_charge_diff:.5f}")
|
||||
logger.info(f"Charge Diff: {charge_diff}\n")
|
||||
|
||||
logger.info(f"------------------------------------------------------------------------------------------")
|
||||
logger.info(f" S rx ry rz chg ")
|
||||
logger.info(f"------------------------------------------------------------------------------------------")
|
||||
for atom in crystal[0][0]:
|
||||
logging.info(f" {atom.symbol} {atom.rx} {atom.ry} {atom.rz} {atom.chg} ")
|
||||
|
||||
logging.info("\n------------------------------------------------------------------------------------------\n")
|
||||
|
||||
logger.info(
|
||||
f" {atom.symbol.rjust(2)} {float(atom.rx):.6f} {float(atom.ry):.6f} {float(atom.rz):.6f} {float(atom.chg):.6f} ")
|
||||
|
||||
logger.info("\n------------------------------------------------------------------------------------------\n")
|
||||
|
||||
Reference in New Issue
Block a user