Source code for cctk.si_file

import cctk
from cctk.helper_functions import get_symbol


[docs] class SIFile(cctk.File): """ Class representing Supporting Information files. Attributes: titles (list of str): title of each molecule ensemble (cctk.Ensemble): ``cctk.Ensemble`` of molecules to print """
[docs] def __init__(self, ensemble, titles): if ensemble and isinstance(ensemble, cctk.Ensemble): self.ensemble = ensemble else: raise ValueError(f"invalid ensemble {ensemble}!") assert len(titles) == len(ensemble) self.titles = titles
[docs] def write_file(self, filename, write_xyz=False, write_dir=None): """ Write an SI file. Args: filename (str): path to the new file write_xyz (Bool): whether or not to write ``.xyz`` files for each molecule write_dir (str): where to write them too """ first = True for title, (molecule, properties) in zip(self.titles, self.ensemble.items()): assert isinstance(molecule, cctk.Molecule), "molecule is not a valid Molecule object!" text = f"{title}\n" for key, value in generate_info(molecule, properties).items(): text += f"{key}:\t{value}\n" text += "Cartesian Coordinates (Å):\n" for index, Z in enumerate(molecule.atomic_numbers, start=1): line = molecule.get_vector(index) text += f"{get_symbol(Z):>2} {line[0]:>13.6f} {line[1]:>13.6f} {line[2]:>13.8f}\n" text += "\n" if write_xyz and write_dir is not None: cctk.XYZFile.write_molecule_to_file(f"{write_dir}/{title}.xyz", molecule) if first: super().write_file(filename, text) first = False else: super().append_to_file(filename, text)
def generate_info(molecule, properties): info = { "Number of Atoms": molecule.num_atoms(), "Stoichiometry": molecule.formula(), "Charge": molecule.charge, "Multiplicity": molecule.multiplicity, } # for now manually handling route card and imaginaries, which typically aren't linked to cctk.Molecule. # long-term would be good to manually pass an extra info_dict from the calling environment # to avoid these ad hoc carveouts. ccw 3.8.21 if "route_card" in properties: info["Route Card"] = properties["route_card"] if "imaginaries" in properties: info["Imaginary Frequencies (cm-1)"] = properties["imaginaries"] else: info["Imaginary Frequencies (cm-1)"] = "None" if "energy" in properties: info["Energy"] = properties["energy"] if "enthalpy" in properties: info["Enthalpy"] = properties["enthalpy"] if "gibbs_free_energy" in properties: info["Gibbs Free Energy"] = properties["gibbs_free_energy"] if "quasiharmonic_gibbs_free_energy" in properties: info["Gibbs Free Energy (Quasiharmonic Correction)"] = properties["quasiharmonic_gibbs_free_energy"] if "dipole_moment" in properties: info["Dipole Moment (Debye)"] = properties["dipole_moment"] return info