Source code for iodata.formats.orcalog

# IODATA is an input and output module for quantum chemistry.
# Copyright (C) 2011-2019 The IODATA Development Team
# This file is part of IODATA.
# IODATA is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
# IODATA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <>
# --
"""Orca output file format."""

from typing import TextIO, Tuple

import numpy as np

from ..docstrings import document_load_one
from ..utils import LineIterator

__all__ = []

PATTERNS = ['*.out']

[docs]@document_load_one("Orca output", ['atcoords', 'atnums', 'energy', 'moments', 'extra']) def load_one(lit: LineIterator) -> dict: """Do not edit this docstring. It will be overwritten.""" result = {} while True: try: line = next(lit) except StopIteration: # Read until the end of the file. break # Get the total number of atoms if line.startswith('CARTESIAN COORDINATES (ANGSTROEM)'): natom = _helper_number_atoms(lit) # Every Cartesian coordinates found are replaced with the old ones # to maintain the ones from the final SCF iteration in e.g. optimization run if line.startswith('CARTESIAN COORDINATES (A.U.)'): result['atnums'], result['atcoords'] = _helper_geometry(lit, natom) # Read the energies of each SCF cycle in iodata.extra if line.startswith('SCF ITERATIONS'): scf_energies = _helper_scf_energies(lit) result['extra'] = {'scf_energies': scf_energies} # The final SCF energy is obtained if line.startswith('FINAL SINGLE POINT ENERGY'): words = line.split() result['energy'] = float(words[4]) # Read also the dipole moment if line.startswith('Total Dipole Moment'): words = line.split() dipole = np.array([float(words[4]), float(words[5]), float(words[6])]) result['moments'] = {(1, 'c'): dipole} return result
def _helper_number_atoms(lit: LineIterator) -> int: """Load list of coordinates from an ORCA output file format. Parameters ---------- lit The line iterator to read the data from. Returns ------- natom: int Total number of atoms. """ # skip the dashed line next(lit) natom = 0 # Add until an empty line is found while next(lit).strip() != '': natom += 1 return natom def _helper_geometry(lit: TextIO, natom: int) -> Tuple[np.ndarray, np.ndarray]: """Load coordinates form a ORCA output file format. Parameters ---------- lit The line iterator to read the data from. Returns ------- atnums: int The atomic numbers. atcoords: array_like The atcoords in an array of size (natom, 3). """ atcoords = np.zeros((natom, 3)) atnums = np.zeros(natom) # skip the dashed line next(lit) # skip the titles in table next(lit) # read in the atomic number and coordinates in a.u. for i in range(natom): words = next(lit).split() atnums[i] = int(float(words[2])) atcoords[i, 0] = float(words[5]) atcoords[i, 1] = float(words[6]) atcoords[i, 2] = float(words[7]) return atnums, atcoords def _helper_scf_energies(lit: TextIO) -> Tuple[np.ndarray, np.ndarray]: """Load energies from each SCF cycle from a ORCA output file format. Parameters ---------- lit The line iterator to read the data from. Returns ------- energies: array_like The energies of each scf cycle in 1D-array. """ energies = [] line = next(lit) # read the next line until blank line while line.strip() != '': words = line.split() if words[0].isdigit(): energies.append(float(words[1])) line = next(lit) return np.asarray(energies)