GBasis Tutorial - Basis Sets#

In gbasis, a basis is defined as a list of GeneralizedContractionShell objects, each one representing a linear combination of primitives. Each GeneralizedContractionShell instances contains information about the angular momentum and center of the shell as well as the exponents and the contraction coefficients of the primitives and their normalization coefficients.

This notebook showcases the different ways to define a basis set for a molecule using gabsis.

1. Building Basis Sets from Basis Set File Formats#

Basis set information is typically accessible in text format, such as those provided by the the Basis Set Exchange. gbasis supports two of the most popular formats: Gaussian94 (.gbs) and NWChem (.nw). The following examples show how to load a basis set from these files, and how to build a basis set instance from them.

1.1. Loading Gaussian94 Basis Set File Formats: parse_gbs#

from gbasis.parsers import parse_gbs

# load hydrogen atom def2-SVP basis set information with the Gaussian94 format
gbs_basis_dict = parse_gbs("hydrogen_def2-svp.1.gbs")

# basis set information is stored as
# {'Atom Symbol': [(Angular Momentum, [Exponents], [Coefficients]), ...]}
print("def2-SVP Basis Set Loaded from Gaussian94 Format:")
for atom in gbs_basis_dict:
    print(f"Atom: {atom}")
    print(f"   Number of shells: {len(gbs_basis_dict[atom])}")
    for i, shell in enumerate(gbs_basis_dict[atom]):
        print(f"   Shell {i} has angular momentum {shell[0]}")
        print(f"   Shell {i} has exponents {shell[1]}")
        print(f"   Shell {i} has coefficients {shell[2].flatten()}")
def2-SVP Basis Set Loaded from Gaussian94 Format:
Atom: H
   Number of shells: 3
   Shell 0 has angular momentum 0
   Shell 0 has exponents [13.010701    1.9622572   0.44453796]
   Shell 0 has coefficients [0.01968216 0.13796524 0.47831935]
   Shell 1 has angular momentum 0
   Shell 1 has exponents [0.12194962]
   Shell 1 has coefficients [1.]
   Shell 2 has angular momentum 1
   Shell 2 has exponents [0.8]
   Shell 2 has coefficients [1.]

1.2. Loading NWChem Basis Set File Formats: parse_nwchem#

Checking that the basis set information loaded from Gaussian and NWChem are the same.

import numpy as np
from gbasis.parsers import parse_nwchem

print("def2-SVP Basis Set Loaded from NwChem Format:")
nw_basis_dict = parse_nwchem("hydrogen_def2-svp.1.nw")

print("\nChecking that the Gaussian94 and NWChem loaded basis sets are the same:")
for atom, value in gbs_basis_dict.items():
    print(f"Atom {atom} exist in NWChem basis: {atom in nw_basis_dict}")
    print(f"Are the number of shells the same? {len(value) == len(nw_basis_dict[atom])}")

    # check that the angular momentum, exponents, and coefficients are the same for each shell
    contractions_pair = enumerate(zip(value, nw_basis_dict[atom]))
    for i, (gb_shell, nw_shell) in contractions_pair:
        print(f"Shell {i} has the same angular momentum: {gb_shell[0] == nw_shell[0]}")
        print(f"Shell {i} has the same exponents: {np.allclose(gb_shell[1], nw_shell[1])}")
        print(f"Shell {i} has the same coefficients: {np.allclose(gb_shell[2], nw_shell[2])}")
        print("")
def2-SVP Basis Set Loaded from NwChem Format:

Checking that the Gaussian94 and NWChem loaded basis sets are the same:
Atom H exist in NWChem basis: True
Are the number of shells the same? True
Shell 0 has the same angular momentum: True
Shell 0 has the same exponents: True
Shell 0 has the same coefficients: True

Shell 1 has the same angular momentum: True
Shell 1 has the same exponents: True
Shell 1 has the same coefficients: True

Shell 2 has the same angular momentum: True
Shell 2 has the same exponents: True
Shell 2 has the same coefficients: True

1.3. Making Contraction Shells: make_contractions#

Once the data for a basis set are loaded as a dictionary, the make_contractions function is used to build the basis set given a list of atoms, their atomic coordinates, and coord_types. The latter specifies the coordinate system for building the contraction shells. Setting the coord_types='cartesian' or coord_types='c' uses a Cartesian coordinate system, and setting coord_types='spherical' or coord_types='p' (for pure), the contraction shells are built in the spherical coordinate system.

The following example shows how to use this function to build a basis set for \(\mathrm{H}_{2}\) with different contraction shells.

Example: Cartesian Contraction Shells#

Setting coord_types='cartesian' or coord_types='c' uses a Cartesian coordinate system for all contraction shells.

import numpy as np
from gbasis.parsers import make_contractions

# Define atomic symbols and coordinates
atoms = ["H", "H"]
atcoords = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]])

# Make contractions at def2-SVP basis set
gbs_basis = make_contractions(gbs_basis_dict, atoms, atcoords, coord_types="cartesian")

print("Number of contracted basis functions:", len(gbs_basis))  # 3 for each H atom
print(f"Types of contractions: {[i.coord_type for i in gbs_basis]}", end="\n\n")
print("Showing the first three contraction shells:\n")
for i, shell in enumerate(gbs_basis[:3]):
    print(f"Contraction shell #{i}")
    print(f"   Center: {shell.coord}")
    print(f"   Angular momentum: {shell.angmom}")
    print(f"   Primitive coefficients {shell.coeffs.T}")
    print(f"   Primitive exponents {shell.exps}")
    print(f"   Primitive normalization constant {shell.norm_cont}")
Number of contracted basis functions: 6
Types of contractions: ['cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian']

Showing the first three contraction shells:

Contraction shell #0
   Center: [0. 0. 0.]
   Angular momentum: 0
   Primitive coefficients [[0.01968216 0.13796524 0.47831935]]
   Primitive exponents [13.010701    1.9622572   0.44453796]
   Primitive normalization constant [[1.70131166]]
Contraction shell #1
   Center: [0. 0. 0.]
   Angular momentum: 0
   Primitive coefficients [[1.]]
   Primitive exponents [0.12194962]
   Primitive normalization constant [[1.]]
Contraction shell #2
   Center: [0. 0. 0.]
   Angular momentum: 1
   Primitive coefficients [[1.]]
   Primitive exponents [0.8]
   Primitive normalization constant [[1. 1. 1.]]

Example: Spherical Contraction Shells#

Setting coord_types='spherical' or coord_types='p' (where "p" stands for pure) uses a Spherical coordinate system for all contraction shells.

# make contractions for the hydrogen def2-SVP basis set
gbs_basis = make_contractions(gbs_basis_dict, atoms, atcoords, coord_types="spherical")

print("Number of contracted basis functions:", len(gbs_basis))  # 3 for each H atom
print(f"Types of contractions: {[i.coord_type for i in gbs_basis]}", end="\n\n")
print("Showing the first three contraction shells:\n")
for i, shell in enumerate(gbs_basis[:3]):
    print(f"Contraction shell #{i}")
    print(f"   Center: {shell.coord}")
    print(f"   Angular momentum: {shell.angmom}")
    print(f"   Primitive coefficients {shell.coeffs.T}")
    print(f"   Primitive exponents {shell.exps}")
    print(f"   Primitive normalization constant {shell.norm_cont}")
Number of contracted basis functions: 6
Types of contractions: ['spherical', 'spherical', 'spherical', 'spherical', 'spherical', 'spherical']

Showing the first three contraction shells:

Contraction shell #0
   Center: [0. 0. 0.]
   Angular momentum: 0
   Primitive coefficients [[0.01968216 0.13796524 0.47831935]]
   Primitive exponents [13.010701    1.9622572   0.44453796]
   Primitive normalization constant [[1.70131166]]
Contraction shell #1
   Center: [0. 0. 0.]
   Angular momentum: 0
   Primitive coefficients [[1.]]
   Primitive exponents [0.12194962]
   Primitive normalization constant [[1.]]
Contraction shell #2
   Center: [0. 0. 0.]
   Angular momentum: 1
   Primitive coefficients [[1.]]
   Primitive exponents [0.8]
   Primitive normalization constant [[1. 1. 1.]]

Example: Mixed Contraction Shells#

The coord_type can be specified as a list of strings, each representing the coord_type of a contraction shell, which allows mixed contraction shell types. Obviously, the length of this list must be equal to the number of contraction shells in the molecule.

The following example shows how to build mixed contraction shells for \(\mathrm{H}_{2}\) molecule. The first 3 contraction shells (corresponding to the first atom) are built in the Cartesian coordinate system, while the last 3 contraction shells (corresponding to the second atom) are built in the spherical coordinate system.

# list of coordinate types, one for each shell
coord_types = ["cartesian", "cartesian", "cartesian", "spherical", "spherical", "spherical"]

# make contractions for the hydrogen def2-SVP basis set
gbs_basis = make_contractions(gbs_basis_dict, atoms, atcoords, coord_types=coord_types)

print("Number of contracted basis functions:", len(gbs_basis))  # 3 for each H atom
print(f"Types of contractions: {[i.coord_type for i in gbs_basis]}", end="\n\n")

print(f"Number of Contracted Basis Functions: {len(gbs_basis)}\n")

print("Showing the first three contraction shells:\n")
for i, shell in enumerate(gbs_basis[:3]):
    print(f"Contraction Shell #{i}")
    print(f"   Center: {shell.coord}")
    print(f"   Angular momentum: {shell.angmom}")
    print(f"   Primitive coefficients {shell.coeffs.T}")
    print(f"   Primitive exponents {shell.exps}")
    print(f"   Primitive normalization constant {shell.norm_cont}\n")
    print(f"   Coordinate type: {shell.coord_type}")
Number of contracted basis functions: 6
Types of contractions: ['cartesian', 'cartesian', 'cartesian', 'spherical', 'spherical', 'spherical']

Number of Contracted Basis Functions: 6

Showing the first three contraction shells:

Contraction Shell #0
   Center: [0. 0. 0.]
   Angular momentum: 0
   Primitive coefficients [[0.01968216 0.13796524 0.47831935]]
   Primitive exponents [13.010701    1.9622572   0.44453796]
   Primitive normalization constant [[1.70131166]]

   Coordinate type: cartesian
Contraction Shell #1
   Center: [0. 0. 0.]
   Angular momentum: 0
   Primitive coefficients [[1.]]
   Primitive exponents [0.12194962]
   Primitive normalization constant [[1.]]

   Coordinate type: cartesian
Contraction Shell #2
   Center: [0. 0. 0.]
   Angular momentum: 1
   Primitive coefficients [[1.]]
   Primitive exponents [0.8]
   Primitive normalization constant [[1. 1. 1.]]

   Coordinate type: cartesian

2. Building Basis Sets from Quantum Chemistry Calculations#

gbasis supports obtaining basis function information from quantum chemistry calculations by interfacing with iodata and pySCF.

2.1. Interfacing with IOData Library: from_iodata#

IOData supports parsing various quantum chemistry file formats, like Gaussian formatted checkpoint files (.fchk), molden (.molden), and wave-function files (.wfn and .wfx), and provides a unified interface to access the data in these files through IOData object. This object is passed to from_iodata function to obtain the basis set information.

The following example loads basis functions from a FCHK file, but other formats supported by iodata can also be used.

from iodata import load_one
from gbasis.wrappers import from_iodata

# load basis functions from a fchk file of water at uwB97XD/def2-TZVPD level
iodata_mol = load_one("water.fchk")
iodata_basis = from_iodata(iodata_mol)

# print the basis set information
print(f"Number of Contracted Basis Functions: {len(iodata_basis)}")
print(f"Types of contractions: {[b.coord_type for b in iodata_basis]}", end="\n\n")
print("Showing the first three contraction shells:", end="\n\n")

for i, shell in enumerate(iodata_basis[:3]):
    print(f"Contraction Shell #{i}")
    print(f"   Center: {shell.coord}")
    print(f"   Angular momentum: {shell.angmom}")
    print(f"   Primitive coefficients: {shell.coeffs.T}")
    print(f"   Primitive exponents: {shell.exps}")
    print(f"   Primitive normalization constant: {shell.norm_cont}\n")
Number of Contracted Basis Functions: 24
Types of contractions: ['cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'spherical', 'spherical', 'spherical', 'spherical', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian']

Showing the first three contraction shells:

Contraction Shell #0
   Center: [ 0.01418428  0.01049743 -0.00741906]
   Angular momentum: 0
   Primitive coefficients: [[5.72273352e-04 4.43532335e-03 2.30201077e-02 9.28224907e-02
  2.93785000e-01 6.74016045e-01]]
   Primitive exponents: [27032.3826     4052.38714     922.327227    261.24071      85.3546414
    31.0350352]
   Primitive normalization constant: [[1.]]

Contraction Shell #1
   Center: [ 0.01418428  0.01049743 -0.00741906]
   Angular momentum: 0
   Primitive coefficients: [[0.63839937 0.39534587]]
   Primitive exponents: [12.2608607  4.9987076]
   Primitive normalization constant: [[1.]]

Contraction Shell #2
   Center: [ 0.01418428  0.01049743 -0.00741906]
   Angular momentum: 0
   Primitive coefficients: [[1.]]
   Primitive exponents: [1.17031082]
   Primitive normalization constant: [[1.]]

2.2. Interfacing with pySCF Library: from_pyscf#

The from_pyscf function supports building basis functions directly from pyscf.gto.mole.Mole object. Setting cart=False when creating an instance of Mole, spherical coordinates are used.

from pyscf import gto
from gbasis.wrappers import from_pyscf

# build an STO-3G basis for water using PySCF
molecule = """
O 0 0 0;
H 0 1 0;
H 0 0 1
"""
pyscf_mol = gto.Mole(cart=True)
pyscf_mol.build(atom=molecule, basis="sto-3g")
pyscf_basis = from_pyscf(pyscf_mol)

print(f"Number of contracted basis functions: {len(pyscf_basis)}")
print(f"Types of contractions: {[shell.coord_type for shell in pyscf_basis]}", end="\n\n")
print("Showing the first three contraction shells:", end="\n\n")

for i, shell in enumerate(pyscf_basis[:3]):
    print(f"Contraction Shell #{i}")
    print(f"   Center: {shell.coord}")
    print(f"   Angular momentum: {shell.angmom}")
    print(f"   Primitive coefficients {shell.coeffs.T}")
    print(f"   Primitive exponents {shell.exps}")
    print(f"   Primitive normalization constant {shell.norm_cont}\n")
Number of contracted basis functions: 5
Types of contractions: ['cartesian', 'cartesian', 'cartesian', 'cartesian', 'cartesian']

Showing the first three contraction shells:

Contraction Shell #0
   Center: [0. 0. 0.]
   Angular momentum: 0
   Primitive coefficients [[0.15432897 0.53532814 0.44463454]]
   Primitive exponents [130.70932    23.808861    6.4436083]
   Primitive normalization constant [[0.99999999]]

Contraction Shell #1
   Center: [0. 0. 0.]
   Angular momentum: 0
   Primitive coefficients [[-0.09996723  0.39951283  0.70011547]]
   Primitive exponents [5.0331513 1.1695961 0.380389 ]
   Primitive normalization constant [[0.99999999]]

Contraction Shell #2
   Center: [0. 0. 0.]
   Angular momentum: 1
   Primitive coefficients [[0.15591627 0.60768372 0.39195739]]
   Primitive exponents [5.0331513 1.1695961 0.380389 ]
   Primitive normalization constant [[0.99999999 0.99999999 0.99999999]]