stko.XTB

class stko.XTB(xtb_path, gfn_version=2, output_dir=None, opt_level='normal', max_runs=2, calculate_hessian=True, num_cores=1, electronic_temperature=300, solvent_model='gbsa', solvent=None, solvent_grid='normal', charge=0, num_unpaired_electrons=0, unlimited_memory=False, write_sasa_info=False)[source]

Bases: Optimizer

Uses GFN-xTB to optimize molecules.

Notes

When running optimize(), this calculator changes the present working directory with os.chdir(). The original working directory will be restored even if an error is raised, so unless multi-threading is being used this implementation detail should not matter.

Furthermore, optimize() will check that the structure is adequately optimized by checking for negative frequencies after a Hessian calculation. max_runs can be provided to the initializer to set the maximum number of optimizations which will be attempted at the given opt_level to obtain an optimized structure. However, we outline in the examples how to iterate over opt_levels to increase convergence criteria and hopefully obtain an optimized structure. The presence of negative frequencies can occur even when the optimization has converged based on the given opt_level.

We thank Andrew Tarzia and Alejandro Santana-Bonilla for their contributions to this code.

Parameters:
  • xtb_path (Path | str) – The path to the xTB executable.

  • gfn_version (int) – Parameterization of GFN to use in xTB. For details see https://xtb-docs.readthedocs.io/en/latest/basics.html.

  • output_dir (Path | str | None) – The name of the directory into which files generated during the optimization are written, if None then uuid.uuid4() is used.

  • opt_level (str) – Optimization level to use. Can be one of 'crude', 'sloppy', 'loose', 'lax', 'normal', 'tight', 'vtight' or 'extreme'. For details see https://xtb-docs.readthedocs.io/en/latest/optimization.html .

  • max_runs (int) – Maximum number of optimizations to attempt in a row.

  • calculate_hessian (bool) – Toggle calculation of the hessian and vibrational frequencies after optimization. True is required to check that the structure is completely optimized. False will drastically speed up the calculation but potentially provide incomplete optimizations and forces max_runs to be 1.

  • num_cores (int) – The number of cores xTB should use.

  • electronic_temperature (float) – Electronic temperature in Kelvin.

  • solvent_model (str) – Solvent model to use out of older gbsa and newer alpb. gbsa is default for backwards compatability, but alpb is recommended. For details see https://xtb-docs.readthedocs.io/en/latest/gbsa.html.

  • solvent (str | None) – Solvent to use in GBSA implicit solvation method. For details see https://xtb-docs.readthedocs.io/en/latest/gbsa.html.

  • solvent_grid (str) – Grid level to use in SASA calculations for GBSA implicit solvent. Can be one of 'normal', 'tight', 'verytight' or 'extreme'. For details see https://xtb-docs.readthedocs.io/en/latest/gbsa.html.

  • charge (int) – Formal molecular charge.

  • num_unpaired_electrons (int) – Number of unpaired electrons.

  • unlimited_memory (bool) – If True optimize() will be run without constraints on the stack size. If memory issues are encountered, this should be True, however this may raise issues on clusters.

  • write_sasa_info (bool) – If True, the detailed info input will request gbsa=True and output SASA information from xtb. Requires a solvent model to be used.

Examples

Note that for ConstructedMolecule objects constructed by stk, XTB should usually be used in a OptimizerSequence. This is because xTB only uses xyz coordinates as input and so will not recognize the long bonds created during construction. An optimizer which can minimize these bonds should be used before XTB.

import stk
import stko

bb1 = stk.BuildingBlock('NCCNCCN', [stk.PrimaryAminoFactory()])
bb2 = stk.BuildingBlock('O=CCCC=O', [stk.AldehydeFactory()])
polymer = stk.ConstructedMolecule(
    stk.polymer.Linear(
        building_blocks=(bb1, bb2),
        repeating_unit="AB",
        orientations=[0, 0],
        num_repeating_units=1
    )
)

xtb = stko.OptimizerSequence(
    stko.UFF(),
    stko.XTB(xtb_path='/opt/gfnxtb/xtb', unlimited_memory=True)
)
polymer = xtb.optimize(polymer)

By default, all optimizations with xTB are performed using the --ohess flag, which forces the calculation of a numerical Hessian, thermodynamic properties and vibrational frequencies. optimize() will check that the structure is appropriately optimized (i.e. convergence is obtained and no negative vibrational frequencies are present) and continue optimizing a structure (up to max_runs times) until this is achieved. This loop, by default, will be performed at the same opt_level. The following example shows how a user may optimize structures with tigher convergence criteria (i.e. different opt_level) until the structure is sufficiently optimized. Furthermore, the calculation of the Hessian can be turned off using max_runs to 1 and calculate_hessian to False.

# Use crude optimization with max_runs=1 because this will
# not achieve optimization and rerunning it is unproductive.
xtb_crude = stko.XTB(
    xtb_path='/opt/gfnxtb/xtb',
    output_dir='xtb_crude',
    unlimited_memory=True,
    opt_level='crude',
    max_runs=1,
    calculate_hessian=True
)
# Use normal optimization with max_runs == 2.
xtb_normal = stko.XTB(
    xtb_path='/opt/gfnxtb/xtb',
    output_dir='xtb_normal',
    unlimited_memory=True,
    opt_level='normal',
    max_runs=2
)
# Use vtight optimization with max_runs == 2, which should
# achieve sufficient optimization.
xtb_vtight = stko.XTB(
    xtb_path='/opt/gfnxtb/xtb',
    output_dir='xtb_vtight',
    unlimited_memory=True,
    opt_level='vtight',
    max_runs=2
)

optimizers = [xtb_crude, xtb_normal, xtb_vtight]
for optimizer in optimizers:
    polymer = optimizer.optimize(polymer)
    if polymer not in optimizer.incomplete:
        break

Attributes

incomplete

Molecules passed to optimize() whose optimzation was incomplete.

Methods

optimize

Optimize mol.

optimize(mol)[source]

Optimize mol.

Parameters:

mol (MoleculeT) – The molecule to be optimized.

Returns:

The optimized molecule.

Return type:

MoleculeT

incomplete: set[Molecule]

Molecules passed to optimize() whose optimzation was incomplete.