# 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# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# 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 <http://www.gnu.org/licenses/># --"""Orca output file format."""fromtypingimportTextIOimportnumpyasnpfromnumpy.typingimportNDArrayfrom..docstringsimportdocument_load_onefrom..utilsimportLineIterator__all__=()PATTERNS=["*.out"]
[docs]@document_load_one("Orca output",["atcoords","atnums","energy","moments","extra"])defload_one(lit:LineIterator)->dict:"""Do not edit this docstring. It will be overwritten."""result={}whileTrue:try:line=next(lit)exceptStopIteration:# Read until the end of the file.break# Get the total number of atomsifline.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 runifline.startswith("CARTESIAN COORDINATES (A.U.)"):result["atnums"],result["atcoords"]=_helper_geometry(lit,natom)# Read the energies of each SCF cycle in iodata.extraifline.startswith("SCF ITERATIONS"):scf_energies=_helper_scf_energies(lit)result["extra"]={"scf_energies":scf_energies}# The final SCF energy is obtainedifline.startswith("FINAL SINGLE POINT ENERGY"):words=line.split()result["energy"]=float(words[4])# Read also the dipole momentifline.startswith("Total Dipole Moment"):words=line.split()dipole=np.array([float(words[4]),float(words[5]),float(words[6])])result["moments"]={(1,"c"):dipole}returnresult
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 linenext(lit)natom=0# Add until an empty line is foundwhilenext(lit).strip()!="":natom+=1returnnatomdef_helper_geometry(lit:TextIO,natom:int)->tuple[NDArray[int],NDArray[float]]:"""Load coordinates form a ORCA output file format. Parameters ---------- lit The line iterator to read the data from. Returns ------- atnums The atomic numbers. atcoords The atcoords in an array with shape ``(natom, 3)``. """atcoords=np.zeros((natom,3))atnums=np.zeros(natom)# skip the dashed linenext(lit)# skip the titles in tablenext(lit)# read in the atomic number and coordinates in a.u.foriinrange(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])returnatnums,atcoordsdef_helper_scf_energies(lit:TextIO)->NDArray[float]:"""Load energies from each SCF cycle from a ORCA output file format. Parameters ---------- lit The line iterator to read the data from. Returns ------- energies The energies of each scf cycle in 1D-array. """energies=[]line=next(lit)# read the next line until blank linewhileline.strip()!="":words=line.split()ifwords[0].isdigit():energies.append(float(words[1]))line=next(lit)returnnp.asarray(energies)