AKFReader¶
The AKFReader Python class provides a convenient way to read annotated data from the binary KF files generated by AMS.
Below is an example demonstrating some of the AKFReader class’s functionality
#!/usr/bin/env amspython
from scm.akfreader import AKFReader
# Load a kf file.
akf = AKFReader("test.results/dftb.rkf")
# Print a summary of the content in the kf file:
print(akf.table_of_content())
# Also print comments and extra info for all variables
print(akf.table_of_content(verbose=True))
# Read a specific variable from file.
coordinates = akf.read("Molecule%Coords")
print("Coordinates:")
print(coordinates)
# Coordinates:
# [[-1.65367945e+00 4.59827802e+00 -9.59515212e-09]
# ...
# [-2.21256221e+00 5.05007997e+00 -1.93285786e+00]]
# Retrieve the description, units, and additional information for a variable:
description_dict = akf.description("Molecule%Coords")
print("'Molecule%Coords' description:")
print(description_dict)
# 'Molecule%Coords' description:
# {'_type': 'float_array',
# '_shape': [3, 'nAtoms'],
# '_comment': 'Coordinates of the nuclei (x,y,z)',
# '_unit': 'bohr'}
# Read another variable, and do a unit conversion:
energy_in_eV = akf.read("AMSResults%Energy", units="eV")
print(f"Energy: {energy_in_eV} [eV]")
# Read all variables matching the pattern:
history_energies = akf.read("History%Energy(#)")
print(history_energies)
# [('History%Energy(1)', -5.758015498298242),
# ('History%Energy(2)', -5.765039556660788),
# ('History%Energy(3)', -5.766261662994689),
# ('History%Energy(4)', -5.766288141072665)]
Note
The KFFile Python class can also be used to read KF files. Key differences between the AKFReader and the KFFile:
The
AKFReadercan provide ‘extra information’ on the content of the KF files: it can give descriptions of sections, variables, units, and automatically reshapes matrices to the proper size/shape.The
KFFilecan also be used to write KF files (while theAKFReadercan only read).
See also
A command line utility $AMSBIN/akf (described here) offers an alternative way of using the AKFReader tool.
See also
The list of possible variables for the various kf files can be found in the respective user manuals: ams.rkf, adf.rkf, band.rkf, dftb.rkf
API documentation:
- class AKFReader(path: str, kf_def_path=None, strict=False, verbose=False)¶
A python class for reading AMS binary KF files.
- Parameters:
path (str): the path of the KF file (.rkf) to open. Can be wither relative or absolute path. (the other optional constructor parameters are expert options and are best left untouched)
Example:
from scm.akfreader import AKFReader akf = AKFReader("test.results/dftb.rkf") # <- path to ams .rkf result file print(akf.table_of_content()) coordinates = akf.read("Molecule%Coords") energy = akf.read("AMSResults%Energy", units="eV")
- read(name: str, units=None)¶
Read and return the value of a variable on file.
- Parameters:
name (str): The name of the variable to read. This should be of the form “SectionName%VariableName”, so for example akf.read(“Molecule%Coords”) means “read the variable ‘Coords’ from Section ‘Molecule’)
units (str): the desired output units. See the :Units: class for more info on avaiable units.
- Returns:
The content of the variable. The return type depends on the variable you are reading. So, if the variable is an integer, and int will be return. If it’s an array, a numpy array will be returned.
Example:
>>> energy = akf.read("AMSResults%Energy") >>> energy_in_eV = akf.read("AMSResults%Energy", units="eV")
Note: in case the variable is a “pattern” (i.e. the variable name contains “#” or “*” characters, the result will be a list of tuples of all variables matching the pattern. E.g.: ‘foo(#)’ will return [(‘foo(1)’, value1), (‘foo(2)’, value2)]
- table_of_content(verbose=False) str¶
Returns the table of content of the KF file (i.e. the list of all sections and variables on file) in text format.
- Parameters:
verbose (bool): if verbose is True, the full description of all variables will be included
Example:
>>> print(akf.table_of_content()) Content for KF file: /test/dftb.rkf == AMSResults == - AMSResults%Energy - AMSResults%Gradients - AMSResults%DipoleMoment ... >>> print(akf.table_of_content(verbose=True)) Content for KF file: /test/dftb.rkf == AMSResults == comment : Generic results of the DFTB evaluation. type : section - AMSResults%Energy comment : The energy computed by the engine. type : float unit : hartree - AMSResults%Gradients comment : The nuclear gradients. shape : [3, 'Molecule%nAtoms'] type : float_array unit : hartree/bohr - AMSResults%DipoleMoment comment : Dipole moment vector (x,y,z) shape : [3] type : float_array unit : e*bohr ...
- variables(include_hidden=False) List[str]¶
Returns the list of all variables on the KF file (in the form “section%variable”).
Example:
>>> all_variables = akf.variables() >>> print(all_variables) ['AMSResults%Charges', 'AMSResults%DipoleMoment', ... ... 'Orbitals%Energies(#)' 'Orbitals%Occupations(#)']
- sections() List[str]¶
Returns the list of all sections on the KF file.
Example:
>>> print(akf.sections()) ['General', 'AMSResults', 'Molecule', 'Orbitals', ...]
- variables_in_section(section: str) List[str]¶
Returns the list of all variables in the specified section.
Example:
>>> print(akf.variables_in_section("Molecule")) ['Molecule%AtomMasses', 'Molecule%Coords', 'Molecule%AtomicNumbers', ...] >>> for v in akf.variables_in_section("Molecule"): >>> print(f"{v}: {akf.read(v)}")
- __contains__(name: str)¶
Whether or not ‘name’ is present in the KF file. This can either be a section (e.g. “Molecule”) or a variable (e.g. “Molecule%Coords”) Example:
if "Molecule%Coords" in akf: coords = akf.read("Molecule%Coords") else: print("Variable 'Molecule%Coords' not present of file") print("Is the 'Molecule' section present? ", "Molecule" in akf)
- description(name: str) Dict[str, Any]¶
Return the description (meta-data) of the variable as a dictionary.
- Parameters:
name (str): The name of the variable (this should be in the form “Section%Variable”)
- Returns:
dictionary containing the available meta-data for the entry. Note that not meta-data entries are defined for all variables. For example, if a variable does not have a unit, the “_unit” key will not be present in the resulting dictionary
Example:
>>> d = akf.description("Molecule%Coords") >>> print(type(d)) <class 'dict'> >>> print(d) {'_type': 'float_array', '_shape': [3, 'nAtoms'], '_comment': 'Coordinates of the nuclei (x,y,z)', '_unit': 'bohr'}
- str_description(name: str) str¶
Return the description of the variable as a string.
Example:
>>> print(akf.str_description("Molecule%Coords")) comment : Coordinates of the nuclei (x,y,z) shape : [3, 'nAtoms'] type : float_array unit : bohr
- units(name: str) str | None¶
Return the unit of measurement of the variable if specified, otherwise returns None.