def write(self, directory: str) -> None: with open(mtr.expand(pathlib.Path(directory, "INCAR")), "w") as f: f.write(_incar_str(self.settings["INCAR"])) with open(mtr.expand(pathlib.Path(directory, "POSCAR")), "w") as f: f.write(_poscar_str(self.settings["POSCAR"])) with open(mtr.expand(pathlib.Path(directory, "KPOINTS")), "w") as f: f.write(_kpoints_str(self.settings["KPOINTS"])) with open(mtr.expand(pathlib.Path(directory, "POTCAR")), "w") as f: f.write(_potcar_str(self.settings["POTCAR"]))
def compute( self, solute: mtr.Molecule, solvent: mtr.Molecule, shells: int, tolerance: float, solvent_density: mtr.Quantity, ) -> mtr.Molecule: if solvent_density.dimension == mtr.Dimension(M=1, L=-3): number_density = solvent_density / solvent.mass else: number_density = solvent_density n, sphere_radius = self._packing_params(shells=shells, number_density=number_density) with self.io() as io: inp = mtr.PackmolInput( tolerance=tolerance, filetype="xyz", output_name=mtr.expand(path="packed", dir=io.work_dir), ) if isinstance(solute, str): solute_cm = contextlib.nullcontext(solute) else: solute_cm = solute.tempfile(suffix=".xyz", dir=io.work_dir) if isinstance(solvent, str): solvent_cm = contextlib.nullcontext(solvent) else: solvent_cm = solvent.tempfile(suffix=".xyz", dir=io.work_dir) with solute_cm as f, solvent_cm as g: inp.add_structure( structure_filepath=mtr.expand( path=f.name if hasattr(f, "name") else f, dir=io.work_dir), number=1, instructions=["fixed 0. 0. 0. 0. 0. 0."], ) r = sphere_radius.convert(mtr.angstrom).value inp.add_structure( structure_filepath=mtr.expand( path=g.name if hasattr(g, "name") else g, dir=io.work_dir), number=n - 1, instructions=[f"inside sphere 0. 0. 0. {r}"], ) inp.write(io.inp) self.engine.execute(self.io) return mtr.Molecule( mtr.expand(path="packed.xyz", dir=io.work_dir))
def __init__( self, ccdc_root: str, num_processors: Optional[int] = None, num_threads: Optional[int] = None, arguments: Optional[Iterable[str]] = None, ) -> None: self.ccdc_root = mtr.expand(ccdc_root) # FIXME: generalize past 2019 version of CCDC code executable = mtr.expand( pathlib.Path(self.ccdc_root, "Python_API_2019", "miniconda", "bin", "python")) super().__init__(executable, num_processors, num_threads, arguments)
def write(self, file: Union[str, IO], overwrite: Optional[bool] = False) -> None: """Write structure to a file. Parameters ---------- file : Union[str, IO] Path to file to which the structure will be written. Can be an absolute or a relative path. overwrite : Optional[bool], optional If true, overwrite `filepath` if it already exists. Ignored if `file` is a file-like object, by default False Raises ------ ValueError Raised if file extension is not recognized """ open_code = "w" if overwrite else "x" with open(mtr.expand(file), open_code) if isinstance( file, str) else contextlib.nullcontext(file) as f: if f.name.endswith(".xyz"): s = self.to_xyz() else: raise ValueError("Cannot write to file with given extension.") try: f.write(s) except TypeError: f.write(s.encode()) f.flush()
def execute(self, coord: str, io: mtr.IO, arguments: Optional[Iterable[str]] = None) -> str: with io() as _io: cmd = self.command(_io.out, _io.work_dir, mtr.expand(coord), arguments) with open(_io.out, "w") as out: env = self.env() if env is None: subprocess.call(cmd, stdout=out, stderr=subprocess.STDOUT, cwd=io.work_dir) else: subprocess.call( cmd, stdout=out, stderr=subprocess.STDOUT, env=self.env(), cwd=io.work_dir, ) with open(_io.out, "r") as f: return "".join(f.readlines())
def commands(self, excitation_filepath: str, work_dir: str) -> Tuple[Union[str, int, float]]: return ( 18, *(a for i in range(40) for a in [6] + ([excitation_filepath] if i == 0 else []) + [i + 1, 2, mtr.expand(f"{work_dir}/S{i+1}.fch")]), 0, )
def compute(self, filepath: str) -> Any: inp = mtr.MultiwfnInput(mtr.expand(filepath), *self.commands(), -10) with self.io() as io: inp.write(io.inp) self.engine.execute(self.io) return self.parse(io.out)
def __init__(self, filepath: str) -> None: """ Args: filepath: Path to file from which output will be read. Can be an absolute or a relative path. """ raise NotImplementedError # FIXME: implement self.filepath = mtr.expand(filepath)
def tempfile(self, suffix: str, dir: Optional[str] = None): with tempfile.NamedTemporaryFile( dir=mtr.expand(dir) if dir is not None else None, suffix=suffix) as fp: try: self.write(file=fp) yield fp finally: pass
def save(self, filepath: str) -> None: """ Pickle molecule to a given save file. Args: filepath: Path to file in which the molecule will be pickled. Can be an absolute or a relative path. """ with open(mtr.expand(filepath), "wb") as f: pickle.dump(obj=self, file=f)
def write(self, filepath: str) -> None: """ Write Multiwfn input to a file. Args: filepath: Path to file to which the input will be written. Can be an absolute or a relative path. """ with open(mtr.expand(filepath), "w") as f: f.write(str(self))
def compute(self, filepath: str, excitation_filepath: str) -> Any: with self.io() as io: inp = mtr.MultiwfnInput( mtr.expand(filepath), *self.commands(excitation_filepath, io.work_dir), -10, ) inp.write(io.inp) self.engine.execute(self.io) return self.parse(io.out)
def __init__( self, executable: Optional[str] = "qchem", scratch_dir: Optional[str] = None, qcenv: Optional[str] = None, num_processors: Optional[int] = None, num_threads: Optional[int] = None, arguments: Optional[Iterable[str]] = None, save: Optional[bool] = False, savename: Optional[str] = None, ) -> None: self.scratch_dir = mtr.expand( scratch_dir) if scratch_dir is not None else None self.qcenv = shlex.quote( mtr.expand(qcenv)) if qcenv is not None else None self.save = save self.savename = savename super().__init__( executable=executable, num_processors=num_processors, num_threads=num_threads, arguments=arguments, )
def load(filepath: str) -> Molecule: """ Load molecule from a pickle file. Args: filepath: Path to pickle file from which the molecule will be loaded. Can be an absolute or a relative path. Returns: Molecule retrieved from pickle file. """ with open(mtr.expand(filepath), "rb") as f: mol = pickle.load(file=f) return mol
def _read_xyz(filepath: str, coordinate_unit: str = "angstrom") -> Structure: with open(mtr.expand(filepath), "r") as f: atom_data = np.atleast_2d( np.loadtxt( fname=f, usecols=(0, 1, 2, 3), skiprows=1, max_rows=int(next(f)), dtype=str, )) atomic_symbols = atom_data[:, 0] atomic_positions = (np.asarray(p, dtype="float64") * getattr(mtr, coordinate_unit) for p in atom_data[:, 1:]) atoms = (mtr.Atom(element=symbol, position=position) for symbol, position in zip(atomic_symbols, atomic_positions)) return Structure(*atoms)
def env(self) -> Dict[str, str]: if self.scratch_dir is None and self.qcenv is None: return None if self.qcenv is not None: # FIXME: shell=True needs to be avoided!! d = ast.literal_eval( re.match( r"environ\((.*)\)", subprocess.check_output( f". {self.qcenv}; python -c 'import os; print(os.environ)'", shell=True, ).decode().strip(), ).group(1)) else: d = {} if self.scratch_dir is not None: d["QCSCRATCH"] = mtr.expand(self.scratch_dir) return d
def _objective(omega: float, _alpha: float) -> float: beta = 1 / epsilon - _alpha s = mtr.Settings() if settings is None else copy.deepcopy(settings) s = self.defaults(s) s["rem", "hf_sr"] = int(round(1000 * _alpha)) s["rem", "hf_lr"] = int(1000 / epsilon) s["xc_functional"] = ( ("X", "HF", _alpha), ("X", "wPBE", beta), ("X", "PBE", 1 - _alpha - beta), ("C", "PBE", 1.0), ) omega = int(round(1000 * omega)) s["rem", "omega"] = s["rem", "omega2"] = omega wd = mtr.expand(f"{io.work_dir}/{omega}") gs_io = mtr.IO("gs.in", "gs.out", wd) cation_io = mtr.IO("cation.in", "cation.out", wd) anion_io = mtr.IO("anion.in", "anion.out", wd) ke = self.engine.koopman_error(gs_io, cation_io, anion_io) return ke.compute(molecule, s).value
def env(self) -> Dict[str, str]: # FIXME: generalize past 2019 version of CCDC code return { "CSDHOME": mtr.expand(pathlib.Path(self.ccdc_root, "CSD_2019")) }
def write(self, filepath: str) -> None: with open(mtr.expand(filepath), "w") as f: f.write(str(self))
def __init__(self, filepath: str) -> None: self.filepath = mtr.expand(filepath)
def __init__(self, filepath: str, *commands: str) -> None: self.commands = tuple((mtr.expand(filepath), *commands))