How do I retrieve computation results by ID?#

This tutorial introduces the basics of connecting to a QCArchive server and retrieving computation results.

When you retrieve results from QCArchive, they can be in the form of single records or a larger dataset.

A record represents a single quantum chemistry computation and contains the input details and the results. While some records represent simple computations (like a single point computation), others can encapsulate more complex workflows and multiple associated computations.

A dataset is a collection of similar records.

In this QuickStart, you’ll learn how to connect to the QCArchive Demo Server and retrieve records by their IDs. If you’d like to learn more about records, see the “How do I work with records?” tutorial.

import qcportal as ptl

Create a client object and connect to the demo server#

The PortalClient is how you interact with the server, including querying records and submitting computations.

The demo server allows for unauthenticated guest access, so no username/password is necessary to read from the server. However, you will need to log in to submit or modify computations.

# Guest access
client = ptl.PortalClient("https://qcademo.molssi.org")
WARNING: This client version is newer than the server version. This may work if the versions are close, but expect exceptions and errors if attempting things the server does not support. client version: 0.57.post14+g011be51d, server version: 0.57

Connecting with username/password

If you have a username/password, you would include those in the client connection.

client = ptl.PortalClient("https://qcademo.molssi.org", username="YOUR_USERNAME", password="YOUR_PASSWORD")

⚠️Caution⚠️: Always handle credentials with care. Never commit sensitive information like usernames or passwords to public repositories.

Retrieving a Single Record by ID#

To retrieve a record, you can use the get_records method. You pass in the IDs of the records you would like to retrieve.

If a list of IDs is specified, then a list of records is returned. Otherwise, only a single record is returned.

record = client.get_records(1)
print(record)
<SinglepointRecord id=1 status=RecordStatusEnum.complete>

From printing the record, we see that the record with ID 1 is a single point calculation (SinglePointRecord) and that this computation is “complete” (RecordStatusEnum.complete).

Viewing Record Information#

Records have lots of features, and what they have depends on the type of record - we will only cover a few here.

For the single point calculation we retrieved, we can see information about the molecule (molecule attribute), the method, basis, etc (specification), and more.

To see information about the molecule used in the calculation, use record.molecule.

# The molecule that we computed
print(record.molecule)
Molecule(name='H2', formula='H2', hash='df0385c')

The information above tells us that the single point calculation was performed on a helium atom.

Molecule “hash”

The molecule hash is a unique identifier that takes atom identity, connectivity, coordinates, and fragmentation into account.

The record specification shows the program used for the calculation, as well as information about the method as basis.

# The specification (method, basis, etc)
print(record.specification)
program='psi4' driver=<SinglepointDriver.energy: 'energy'> method='hf' basis='sto-3g' keywords={} protocols=AtomicResultProtocols(wavefunction=<WavefunctionProtocolEnum.all: 'all'>, stdout=True, error_correction=ErrorCorrectionProtocol(default_policy=True, policies=None), native_files=<NativeFilesProtocolEnum.none: 'none'>)

The specification printed above tells us that this calculation was performed with the Psi4 software using the hf method and sto-3g basis set.

Retrieving Multiple Records#

The previous example showed retrieving just one record from QCArchive using the get_records method. However, more than one record at a time can be retrieved by passing a list of computation IDs to the method.

records = client.get_records([1, 2, 3])

print(f"Retrieved {len(records)} records.")
Retrieved 3 records.

Using, the information presented earlier, we can see data about each computation.

for record in records:
    print(record, record.molecule)
<SinglepointRecord id=1 status=RecordStatusEnum.complete> Molecule(name='H2', formula='H2', hash='df0385c')
<SinglepointRecord id=2 status=RecordStatusEnum.complete> Molecule(name='HO', formula='HO', hash='33ccbd7')
<SinglepointRecord id=3 status=RecordStatusEnum.complete> Molecule(name='H2O', formula='H2O', hash='635ff91')

Retrieving Records by Computation Type#

The QCArchive API also allows you to retrieve records based on the computation type. QCArchive supports different types of computations including single points, optimizations, torsion drives and more. In addition to using get_records, you can also use methods specific to the type of computation of interest. For example, to retrieve single point computations only, you can use the method get_singlepoints.

records = client.get_singlepoints([1,2])
print(records)
[SinglepointRecord(id=1, record_type='singlepoint', is_service=False, properties={'pe energy': 0.0, 'scf dipole': [0.0, 0.0, 2.220446049250313e-15], 'calcinfo_nmo': 2, 'return_energy': -1.1117197122934774, 'return_result': -1.1117197122934774, 'calcinfo_natom': 2, 'calcinfo_nbeta': 1, 'current dipole': [0.0, 0.0, 2.220446049250313e-15], 'current energy': -1.1117197122934774, 'return_hessian': None, 'scf_iterations': 2, 'calcinfo_nalpha': 1, 'calcinfo_nbasis': 2, 'hf total energy': -1.1117197122934774, 'hf virial ratio': 1.934796988812115, 'return_gradient': None, 'scf_total_energy': -1.1117197122934774, 'hf kinetic energy': 1.1892632577969529, 'scf_dipole_moment': [0.0, 0.0, 2.220446049250313e-15], 'scf_total_hessian': None, 'scf total energies': [-0.7024534616091184, -1.1117197122934768, -1.1117197122934774], 'scf_total_gradient': None, 'dd solvation energy': 0.0, 'hf potential energy': -2.3009829700904305, 'one-electron energy': -2.4428764829334075, 'two-electron energy': 0.6644901039732637, 'scf iteration energy': -1.1117197122934774, 'pcm polarization energy': 0.0, 'scf_one_electron_energy': -2.4428764829334075, 'scf_two_electron_energy': 0.6644901039732637, 'current reference energy': -1.1117197122934774, 'nuclear_repulsion_energy': 0.6666666666666666}, extras={}, status=<RecordStatusEnum.complete: 'complete'>, manager_name='snowflake_compute-pyra-d5f57dbc-7ad5-462e-ac55-9d99fbbe6ba4', created_on=datetime.datetime(2024, 8, 20, 16, 35, 30, 163671, tzinfo=datetime.timezone.utc), modified_on=datetime.datetime(2024, 8, 20, 16, 35, 35, 300115, tzinfo=datetime.timezone.utc), owner_user='ben', owner_group=None, compute_history_=None, task_=None, service_=None, comments_=None, native_files_=None, specification=QCSpecification(program='psi4', driver=<SinglepointDriver.energy: 'energy'>, method='hf', basis='sto-3g', keywords={}, protocols=AtomicResultProtocols(wavefunction=<WavefunctionProtocolEnum.all: 'all'>, stdout=True, error_correction=ErrorCorrectionProtocol(default_policy=True, policies=None), native_files=<NativeFilesProtocolEnum.none: 'none'>)), molecule_id=1, molecule_=None, wavefunction_=None), SinglepointRecord(id=2, record_type='singlepoint', is_service=False, properties={'pe energy': 0.0, 'scf dipole': [0.48430923022446315, -0.09806269387557531, 0.0], 'calcinfo_nmo': 6, 'return_energy': -74.36430040801095, 'return_result': -74.36430040801095, 'calcinfo_natom': 2, 'calcinfo_nbeta': 4, 'current dipole': [0.48430923022446315, -0.09806269387557531, 0.0], 'current energy': -74.36430040801095, 'return_hessian': None, 'scf_iterations': 8, 'calcinfo_nalpha': 5, 'calcinfo_nbasis': 6, 'hf total energy': -74.36430040801095, 'hf virial ratio': 2.005116124286366, 'return_gradient': None, 'scf_total_energy': -74.36430040801095, 'hf kinetic energy': 73.98577996230009, 'scf_dipole_moment': [0.48430923022446315, -0.09806269387557531, 0.0], 'scf_total_hessian': None, 'scf total energies': [-73.47215468948193, -74.34115348234721, -74.36333189277605, -74.36416739613848, -74.36425552848871, -74.3642977839295, -74.36430037703754, -74.3643004079822, -74.36430040801095], 'scf_total_gradient': None, 'dd solvation energy': 0.0, 'hf potential energy': -148.35008037031105, 'one-electron energy': -111.95688184241482, 'two-electron energy': 33.313740163299, 'scf iteration energy': -74.36430040801095, 'pcm polarization energy': 0.0, 'scf_one_electron_energy': -111.95688184241482, 'scf_two_electron_energy': 33.313740163299, 'current reference energy': -74.36430040801095, 'nuclear_repulsion_energy': 4.278841271104872}, extras={}, status=<RecordStatusEnum.complete: 'complete'>, manager_name='snowflake_compute-pyra-d5f57dbc-7ad5-462e-ac55-9d99fbbe6ba4', created_on=datetime.datetime(2024, 8, 20, 16, 35, 30, 163676, tzinfo=datetime.timezone.utc), modified_on=datetime.datetime(2024, 8, 20, 16, 35, 35, 309332, tzinfo=datetime.timezone.utc), owner_user='ben', owner_group=None, compute_history_=None, task_=None, service_=None, comments_=None, native_files_=None, specification=QCSpecification(program='psi4', driver=<SinglepointDriver.energy: 'energy'>, method='hf', basis='sto-3g', keywords={}, protocols=AtomicResultProtocols(wavefunction=<WavefunctionProtocolEnum.all: 'all'>, stdout=True, error_correction=ErrorCorrectionProtocol(default_policy=True, policies=None), native_files=<NativeFilesProtocolEnum.none: 'none'>)), molecule_id=2, molecule_=None, wavefunction_=None)]