Skip to content

TeraChem

qcop.adapters.terachem.TeraChemAdapter

Adapter for TeraChem.

supported_calctypes class-attribute instance-attribute

supported_calctypes = [
    energy,
    gradient,
    hessian,
    optimization,
]

Supported calculation types.

program_version

program_version(stdout: Optional[str] = None) -> str

Get the program version.

Parameters:

Name Type Description Default
stdout Optional[str]

The stdout from the program.

None

Returns:

Type Description
str

The program version.

Source code in qcop/adapters/terachem.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def program_version(self, stdout: Optional[str] = None) -> str:
    """Get the program version.

    Args:
        stdout: The stdout from the program.

    Returns:
        The program version.
    """
    if stdout:
        return parse_version_string(stdout)
    else:
        # Cut out "TeraChem version " (17 chars) from the output
        return execute_subprocess(self.program, ["--version"])[17:]

compute_results

compute_results(
    inp_obj: ProgramInput,
    update_func: Optional[Callable] = None,
    update_interval: Optional[float] = None,
    **kwargs
) -> tuple[SinglePointResults, str]

Execute TeraChem on the given input.

Parameters:

Name Type Description Default
inp_obj ProgramInput

The qcio ProgramInput object for a computation.

required
update_func Optional[Callable]

A callback function to call as the program executes.

None
update_interval Optional[float]

The minimum time in seconds between calls to the update_func.

None

Returns:

Type Description
tuple[SinglePointResults, str]

A tuple of SinglePointResults and the stdout str.

Source code in qcop/adapters/terachem.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
def compute_results(
    self,
    inp_obj: ProgramInput,
    update_func: Optional[Callable] = None,
    update_interval: Optional[float] = None,
    **kwargs,
) -> tuple[SinglePointResults, str]:
    """Execute TeraChem on the given input.

    Args:
        inp_obj: The qcio ProgramInput object for a computation.
        update_func: A callback function to call as the program executes.
        update_interval: The minimum time in seconds between calls to the
            update_func.

    Returns:
        A tuple of SinglePointResults and the stdout str.
    """
    # Construct and write input file and xyz file to disk
    input_filename = "tc.in"
    try:
        native_input = qcparse.encode(inp_obj, self.program)
    except qcparse.exceptions.EncoderError:
        raise AdapterInputError(self.program, "Invalid input for TeraChem")
    Path(input_filename).write_text(native_input.input_file)
    Path(native_input.geometry_filename).write_text(native_input.geometry_file)

    # Execute TeraChem
    stdout = execute_subprocess(
        self.program, [input_filename], update_func, update_interval
    )

    # Parse output
    if inp_obj.calctype == CalcType.optimization:
        parsed_output = parse_optimization_dir(
            f"scr.{XYZ_FILENAME.split('.')[0]}", stdout, inp_obj=inp_obj
        )
    else:
        parsed_output = qcparse.parse(stdout, self.program, "stdout")

    return parsed_output, stdout

collect_wfn

collect_wfn() -> dict[str, Union[str, bytes]]

Append wavefunction data to the output.

Source code in qcop/adapters/terachem.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
def collect_wfn(self) -> dict[str, Union[str, bytes]]:
    """Append wavefunction data to the output."""

    # Naming conventions from TeraChem uses xyz filename as scratch dir postfix
    scr_postfix = XYZ_FILENAME.split(".")[0]

    # Wavefunction filenames
    wfn_filenames = ("c0", "ca0", "cb0")
    wfn_paths = [Path(f"scr.{scr_postfix}/{fn}") for fn in wfn_filenames]
    if not any(wfn_path.exists() for wfn_path in wfn_paths):
        raise AdapterError(f"No wavefunction files found in {Path.cwd()}")

    wfns: dict[str, Union[str, bytes]] = {}
    for wfn_path in wfn_paths:
        if wfn_path.exists():
            wfns[str(wfn_path)] = wfn_path.read_bytes()
    return wfns

propagate_wfn

propagate_wfn(
    output: ProgramOutput, prog_inp: ProgramInput
) -> None

Propagate the wavefunction from the previous calculation.

Parameters:

Name Type Description Default
output ProgramOutput

The output from a previous calculation containing wavefunction data.

required
prog_inp ProgramInput

The ProgramInput object on which to place the wavefunction data.

required

Returns:

Type Description
None

None. Modifies the prog_inp object in place.

Source code in qcop/adapters/terachem.py
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
def propagate_wfn(self, output: ProgramOutput, prog_inp: ProgramInput) -> None:
    """Propagate the wavefunction from the previous calculation.

    Args:
        output: The output from a previous calculation containing wavefunction data.
        prog_inp: The ProgramInput object on which to place the wavefunction data.

    Returns:
        None. Modifies the prog_inp object in place.
    """

    # Naming conventions from TeraChem uses xyz filename as scratch dir postfix
    scr_postfix = XYZ_FILENAME.split(".")[0]

    # Wavefunction filenames
    c0, ca0, cb0 = "c0", "ca0", "cb0"

    c0_bytes = output.results.files.get(f"scr.{scr_postfix}/{c0}")
    ca0_bytes = output.results.files.get(f"scr.{scr_postfix}/{ca0}")
    cb0_bytes = output.results.files.get(f"scr.{scr_postfix}/{cb0}")

    if not c0_bytes and not (ca0_bytes and cb0_bytes):
        raise AdapterInputError(
            program=self.program,
            message="Could not find c0 or ca/b0 files in output.",
        )

    # Load wavefunction data onto ProgramInput object

    if c0_bytes:
        prog_inp.files[c0] = c0_bytes
        prog_inp.keywords["guess"] = c0

    else:  # ca0_bytes and cb0_bytes
        assert ca0_bytes and cb0_bytes  # for mypy
        prog_inp.files[ca0] = ca0_bytes
        prog_inp.files[cb0] = cb0_bytes
        prog_inp.keywords["guess"] = f"{ca0} {cb0}"

qcop.adapters.terachem_fe.TeraChemFEAdapter

TeraChemFEAdapter()

Adapter for TeraChem's Protocol Buffer Server and Frontend file server.

Source code in qcop/adapters/terachem_fe.py
18
19
20
21
22
def __init__(self):
    super().__init__()
    # Check that xtb-python is installed.
    self.tcpb = self._ensure_tcpb()
    self.client = self.tcpb.TCFrontEndClient

supported_calctypes class-attribute instance-attribute

supported_calctypes = [energy, gradient]

Supported calculation types.

program_version

program_version(stdout: Optional[str] = None) -> str

Program version is not available via the PB server.

Source code in qcop/adapters/terachem_fe.py
38
39
40
def program_version(self, stdout: Optional[str] = None) -> str:
    """Program version is not available via the PB server."""
    return ""

compute_results

compute_results(
    inp_obj: ProgramInput,
    update_func: Optional[Callable] = None,
    update_interval: Optional[float] = None,
    **kwargs
) -> tuple[SinglePointResults, str]

Execute TeraChem on the given input.

Parameters:

Name Type Description Default
inp_obj ProgramInput

The qcio ProgramInput object for a computation.

required
update_func Optional[Callable]

A callback function to call as the program executes.

None
update_interval Optional[float]

The minimum time in seconds between calls to the update_func.

None

Returns:

Type Description
tuple[SinglePointResults, str]

A tuple of SinglePointResults and the stdout str.

Source code in qcop/adapters/terachem_fe.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def compute_results(
    self,
    inp_obj: ProgramInput,
    update_func: Optional[Callable] = None,
    update_interval: Optional[float] = None,
    **kwargs,
) -> tuple[SinglePointResults, str]:
    """Execute TeraChem on the given input.

    Args:
        inp_obj: The qcio ProgramInput object for a computation.
        update_func: A callback function to call as the program executes.
        update_interval: The minimum time in seconds between calls to the
            update_func.

    Returns:
        A tuple of SinglePointResults and the stdout str.
    """
    try:
        with self.client() as client:
            prog_output = client.compute(inp_obj)
    except self.tcpb.exceptions.TCPBError as e:
        exc = AdapterError("An error occurred with TeraChem PBS")
        # Pass stdout to .compute() via the exception
        # Will only exist for TeraChemFrontendAdapter
        exc.stdout = e.program_output.stdout
        raise exc

    else:
        # Write files to disk to be collected by BaseAdapter.compute()
        # Used only for TeraChemFrontendAdapter
        prog_output.results.save_files()

    return prog_output.results, prog_output.stdout

qcop.adapters.terachem_pbs.TeraChemPBSAdapter

TeraChemPBSAdapter()

Adapter for TeraChem's Protocol Buffer Server.

Source code in qcop/adapters/terachem_pbs.py
 9
10
11
12
13
def __init__(self):
    super().__init__()
    # Check that xtb-python is installed.
    self.tcpb = self._ensure_tcpb()
    self.client = self.tcpb.TCProtobufClient