Singlepoint calculations#

Singlepoints represent the core of quantum chemistry calculations. They are the simplest type of calculation and are used to evaluate the energy and properties of a molecule at a particular fixed geometry.

Singlepoint Records#

Singlepoint records contain all the fields of a base record, but also contain:

  • molecule - The molecule that was used in the calculation

  • return_result - The overall requested result of the calculation (energy, gradient, etc.)

  • wavefunction - The final wavefunction (orbitals, density, etc)

Singlepoint Specification (QCSpecification)#

The specification for a singlepoint record is a QCSpecification. The main fields this contains are:

  • program - The program the record is to be run with (or was run with)

  • driver - The main target of this calculation (see SinglepointDriver)

  • method - The quantum chemistry (or similar) method

  • basis - Basis set to use. May be None or an empty string if the method does not use them (for example, classical or machine learning methods)

  • keywords - Program-specific keywords

  • protocols - Additional keywords controlling the return of information (see SinglepointProtocols)

Protocols control additional flags for the computation. For singlepoint calculations, this includes whether to save the raw outputs, wavefunction, or native files.

See the the SinglepointProtocols API documentation for more information.

QCSpecification objects can be created manually (for example, when adding to datasets).

Basic QCSpecification
from qcportal.singlepoint import QCSpecification

spec = QCSpecification(
    program="psi4",
    driver="energy",
    method="b3lyp",
    basis="def2-svp",
)
Request a gradient calculation
from qcportal.singlepoint import QCSpecification

spec = QCSpecification(
    program="psi4",
    driver="gradient",
    method="b3lyp",
    basis="def2-svp",
)
A method without a basis set
from qcportal.singlepoint import QCSpecification

spec = QCSpecification(
    program="rdkit",
    driver="energy",
    method="uff",
    basis=None,
)
Pass in program-specific keywords
from qcportal.singlepoint import QCSpecification

spec = QCSpecification(
    program="psi4",
    driver="energy",
    method="b3lyp",
    basis="def2-svp",
    keywords={
        "guess": "sad",
        "maxiter": 1000,
        "mp2_type": "df",
        "scf_type": "df",
        "freeze_core": True,
        "d_convergence": 8,
        "e_convergence": 8
    }
)
Request outputs (stdout) not be saved
from qcportal.singlepoint import QCSpecification

spec = QCSpecification(
    program="psi4",
    driver="energy",
    method="b3lyp",
    basis="def2-svp",
    protocols={
        "stdout": False
    }
)
Save full wavefunction objects
from qcportal.singlepoint import QCSpecification

spec = QCSpecification(
    program="psi4",
    driver="energy",
    method="b3lyp",
    basis="def2-svp",
    protocols={
        "wavefunction": "all"
    }
)
Save only orbitals and eigenvalues of the wavefunction, and various other files
from qcportal.singlepoint import QCSpecification

spec = QCSpecification(
    program="psi4",
    driver="energy",
    method="b3lyp",
    basis="def2-svp",
    protocols={
        "wavefunction": "orbitals_and_eigenvalues",
        "native_files": "all"
    }
)

Submitting Records#

Singlepoint records can be submitted using a client via the add_singlepoints() method. This method takes the following information:

  • molecules - A single molecule or list of molecules to compute

  • program, driver, method, basis, keywords, protocols - The computational details of the calculation (see above)

See Submitting computations for more information about other fields.

Singlepoint Datasets#

Singlepoint datasets are collections of singlepoint records. Entries contain a single molecule. The dataset specifications contain a singlepoint specification (see above)

Adding entries from other types of datasets#

Singlepoint datasets contain a add_entries_from() method which can be used to add entries from another singlepoint dataset or from an optimization dataset.

When copying from an optimization dataset, a specification must be given. The new entries will have the same name and metadata as in the source dataset, however will contain the optimized molecules from the records for the given specification. If a particular record is not complete, the given entry will not be added.

If an entry with the same name already exists, it will be ignored.

>>> ds = client.add_dataset("singlepoint", "Dataset from optimization")
>>> ds.add_entries_from(377, 'default') # from an optimization dataset
InsertCountsMetadata(n_inserted=20, n_existing=0, error_description=None, errors=[])

>>> print(ds.entry_names)
['000280960', '000524682', '010464300', ...

Client Examples#

Obtain a single record by ID
r = client.get_singlepoints(123)
Obtain multiple records by ID
r_lst = client.get_singlepoints([123, 456])
Obtain multiple records by ID, ignoring missing records
r_lst = client.get_singlepoints([123, 456, 789], missing_ok=True)
Include all data for a record during initial fetch
r_lst = client.get_singlepoints([123, 456], include=['**'])
Query singlepoints by program, method, basis
r_iter = client.query_singlepoints(program='psi4', method='b3lyp', basis='def2-svp')
for r in r_iter:
    print(r.id)
Query singlepoints by program and when the record was created, include all data
r_iter = client.query_singlepoints(program='psi4',
                                   created_after='2024-03-21 12:34:56',
                                   include=['**'])
                                   limit=50)
for r in r_iter:
    print(r.id)
Add a singlepoint record
meta, ids = client.add_singlepoints([mol1, mol2],
                                    program='psi4',
                                    driver='energy',
                                    method='b3lyp',
                                    basis='def2-svp')
Add a singlepoint record, specify program-specific keywords
meta, ids = client.add_singlepoints([mol1, mol2],
                                    program='psi4',
                                    driver='energy',
                                    method='b3lyp',
                                    basis='def2-svp',
                                    keywords={'scf_type': 'df'}
Add a singlepoint record, don’t store raw output
meta, ids = client.add_singlepoints([mol1, mol2],
                                    program='psi4',
                                    driver='energy',
                                    method='b3lyp',
                                    basis='def2-svp',
                                    protocols={'stdout': False})
Add a singlepoint record, store wavefunction and native files
meta, ids = client.add_singlepoints([mol1, mol2],
                                    program='psi4',
                                    driver='energy',
                                    method='b3lyp',
                                    basis='def2-svp',
                                    protocols={'wavefunction': 'all', 'native_files': 'all'})

Dataset Examples#

See Datasets for more information and advanced usage. See the specification section for all the options in creating specifications.

Create a singlepoint dataset with default options
ds = client.add_dataset(
         "singlepoint",
         "Dataset Name",
         "An example of a singlepoint dataset"
)
Add a single entry to a singlepoint dataset
h2_mol = Molecule(symbols=['h', 'h'], geometry=[0, 0, 0, 0, 0, 1.5])
ds.add_entry("hydrogen", h2_mol)
Add many entries to a singlepoint dataset
from qcportal.singlepoint import SinglepointDatasetEntry

# Construct a list of entries to add somehow
new_entries = []
for element in ['h', 'n', 'o']:
    mol = Molecule(symbols=[element], geometry=[0, 0, 0])
    ent = SinglepointDatasetEntry(name=f"{element}_atom", molecule=mol)
    new_entries.append(ent)

# Efficiently add all entries in a single call
ds.add_entries(new_entries)
Add many entries to a singlepoint dataset
# Construct a list of entries to add somehow
new_entries = []
for element in ['h', 'n', 'o']:
    mol = Molecule(symbols=[element], geometry=[0, 0, 0])
    ent = SinglepointDatasetEntry(name=f"{element}_atom", molecule=mol)
    new_entries.append(ent)

# Efficiently add all entries in a single call
ds.add_entries(new_entries)
Add a specification to a singlepoint dataset
from qcportal.singlepoint import QCSpecification

spec = QCSpecification(
    program="psi4",
    driver="energy",
    method="b3lyp",
    basis="def2-svp",
)

ds.add_specification("psi4/b3lyp/def2-svp", spec)

Singlepoint QCPortal API#