Prerequisites
WebMO can be accessed from an external program using REST (Representational State Transfer) queries. Although REST queries can be issued directly from Python, a webmo library of wrapper functions has been written to greatly simplify this process.
Accessing WebMO from a Python program requires the following:
- The webserver must be configured to support REST queries, as described on the REST-JSON Interface for WebMO.
- Python must be available to the local user. Windows and Mac OS users can do this most easily by installing Anaconda. Linux systems typically have Python installed by default. Python can also be obtained from the official Python website. For WebMO usage, Python can be provided without having to install any software on the user's computer via a hosted instance of JupyterLab.
- The Python requests library must be installed to support REST queries. If not already present, this can be done with:
% python -m pip install requests
- The Python webmo library must be installed, which can be done with:
% python -m pip install webmo
(from the command line)
OR
%pip install webmo
(from inside a JuypterLab notebook; note that one must type the "%" in "%pip" because it is a magic command)
To check your version of the webmo library against available versions and then potentially update it, from the command line type:
% python -m pip show webmo
% python -m pip index versions webmo
% python -m pip install --upgrade webmo
Accessing WebMO Using the webmo Python Library
The webmo Python library greatly simplifies the use of REST queries.
The following Python program is similar to the command line calls that directly use REST, but it is much easier to follow. It obtains an authorization token, uses of the token to obtain information about the user and results of a job, and deletes the token.
#minimal.py
from webmo import WebMOREST
#obtain a REST session
rest = WebMOREST("https://server.university.edu/~webmo/cgi-bin/webmo/rest.cgi", "smith")
#request information about user
results = rest.get_user_info("smith")
print(results)
#request information about job
results = rest.get_job_results(2)
print(results)
#end the REST sessions
rest = None
Running this Python program on the local computer results in the following output:
$ python minimal.py
Enter WebMO password for user smith: ......
{"admin":false,"user":"smith","properties":{"archiveFormat":"tar","fullName":"John Smith","allowNewUsers":"1","enabledQueues":"all","jobTimeLimit":"-1","timeLimit":"-1","email":"smith@university.edu","viewJobInNewWindow":"0","enabledInterfaces":"all","emailNotification":"0","enabledServers":"all"}}
{"success":true,"molecular_multiplicity":1,"connectivity":[[1,2,1],[1,3,1]],"provenance":{"creator":"Gaussian"},"molecular_charge":0,"schema_name":"QC_JSON","properties":{"rhf_energy":{"value":-76.0107465155,"units":"Hartree"},"rotational_constants":[858.6603475,440.9401844,291.3340235],"route":" #N HF/6-31G(d) OPT Geom=Connectivity","scf_dipole_moment":[0,0,2.1989],"symmetry":"C2V","dipole_moment":[0,0,2.1989],"cpu_time":{"value":6.1,"units":"sec"},"stoichiometry":"H<sub>2</sub>O","basis":"6-31G(d)"},"comment":"H2O; Geometry Optimization","symbols":["O","H","H"],"geometry":[0,0,0.114681,0,0.754069,-0.458726,0,-0.754069,-0.458726],"schema_version":0}
Sample Python Programs
One could extend the previous program to access any job and extract specific information as follows:
#minimal2.py
from webmo import WebMOREST
baseURL = "https://server.university.edu/~webmo/cgi-bin/webmo/rest.cgi"
#obtain a REST session
username=input('Enter WebMO username:')
rest = WebMOREST(baseURL, username)
#request information about user
results = rest.get_user_info(username)
print(results["properties"]["email"])
#request information about job
jobNumber=int(input('Enter WebMO job number:'))
results = rest.get_job_results(jobNumber)
print(results["properties"]["rhf_energy"])
#end the REST session
rest = None
which when run produces:
$ python minimal2.py
Enter WebMO username: smith
Enter WebMO password for user smith: ......
smith@university.edu
Enter WebMO job number: 2
{'value': -76.0107465155, 'units': 'Hartree'}
Another example is submitting a job to be run on the WebMO server and then printing the results:
#submit.py
from webmo import WebMOREST
from webmo.util import xyz_from_name
import json
baseURL = "https://server.university.edu/~webmo/cgi-bin/webmo/rest.cgi"
#obtain a REST session
username=input('Enter WebMO username:')
rest = WebMOREST(baseURL, username)
#generate our input file
templates = rest.get_templates('gaussian')
template = templates['Geometry Optimization']
jobName = "H2O Optimization (from Python)"
input_file_contents = rest.generate_input(template, variables={
'jobName' : jobName,
'geometry' : xyz_from_name('water'),
'theory' : 'HF',
'basisSet' : '6-31G(d)'})
jobNumber = rest.submit_job(jobName, input_file_contents, "gaussian")
print("Submitted job", jobNumber)
#wait for the job to complete
rest.wait_for_job(jobNumber)
#fetch the job results (as JSON)
rest.get_job_results(jobNumber)
results = rest.get_job_results(jobNumber)
print(json.dumps(results, indent=4))
#end the REST session
rest = None
which when run produces:
$ python submit.py
Enter WebMO username: smith
Enter WebMO password for user smith: ......
Submitted job 723
...
"rhf_energy": {
"value": -76.0107465155,
"units": "Hartree"
},
...
and results in a new job file within WebMO:
Additional examples of Python programs are provided in the <cgiBase>/REST/templates directory:
- _print_results.py: display job results in formatted JSON
- _visualize_results.py: display job geometry image (requires JupyterLab notebook)
- coordinate_scan: graph coordinate scan energies as a function of geometry change
- geometry_convergence.py: graph convergence of energy and rms geometry change from an optimization job
- orbital_diagram.py: graph orbital energy levels from a molecular orbital job
- spectra.py: display job infrared spectrum image (requires JupyterLab notebook)
- thermochemistry.py: use computed energy and frequencies to calculate and graph internal energy and Cvib as a function of temperature
webmo Python Library Functions
The "help" function in Python will produce detailed documentation for the WebMOREST interface, including available functions, their arguments, and return codes. As an example, run the following Python program:
#webmohelp.py
from webmo import WebMOREST
#output detailed documentation for the REST interface
help(WebMOREST)
#or for a specific function
help(WebMOREST.get_job_info)
which produces the following documentation:
$ webmohelp.py
class WebMOREST(builtins.object)
| WebMOREST(base_url, username, password='')
|
| The WebMOREST class provides an object-oriented Python API for the WebMO REST interface.
|
| The WebMOREST class provides a simple Python API to access the WebMO REST interface. As of now
| there are no public methods. Session tokens are handled automatically handled during object
| creation/destruction.
|
| Methods defined here:
...
| get_job_geometry(self, job_number)
| Returns the final optimized geometry from the specified job.
|
| This call returns an XYZ formatted file of the final optimized geometry from the specified job.
|
| Arguments:
| job_number(int): The job about whom to return information
|
| Returns:
| A string containing XYZ formatted optmized geometry |
...
A summary of many of the available functions follows:
Function | Description |
---|---|
WebMOREST(base_url, username, password='') | Generates a WebMOREST object and also generates and stores a newly session token |
delete_job(job_number) | Permanently deletes a WebMO job |
generate_input(template,variables,auto_defaults=True) | Generates an input file by populating the specified job template with the provided variables |
get_engines(target_user='') | Fetches a list of computational engines available to the current user or specified target user |
get_folders(target_user='') | Fetches a list of folders owned by the current user or the specified target user |
get_group_info(groupname) | Returns information about the specified group |
get_groups(self) | Fetches a list of available WebMO groups |
get_job_archive(job_number) | Returns a WebMO archive from the specified job |
get_job_geometry(job_number) | Returns the final optimized geometry from the specified job |
get_job_info(job_number) | Returns information about the specified job |
get_job_output(job_number) | Returns the raw text output from the specified job |
get_job_results(job_number) | Returns detailed results of the calculation (e.g. energy, properties) from the specified job |
get_jobs(engine='', status='', folder_id='', job_name='', target_user='') | Fetches a list of jobs satisfying the specified filter criteria |
get_status_info(self) | Returns information about the specified WebMO instance |
get_templates(engine) | Fetches a list of job templates associated with the specified computational engine |
get_user_info(username) | Returns information about the specified user |
get_users(self) | Fetches a list of available WebMO users |
import_job(job_name, filename, engine) | Imports an existing output file into WebMO |
submit_job(job_name, input_file_contents, engine, queue=None) | Submits and executes a new WebMO job |
wait_for_job(job_number, poll_frequency=5) | Waits for completion of the specified WebMO job |
wait_for_jobs(job_numbers, poll_frequency=5) | Waits for completion of the specified list of WebMO jobs |
In addition the following IPython function is available within Jupyter Notebooks:
Function | Description |
---|---|
async display_job_property(self, job_number, property_name, property_index=1, peak_width=0.0, tms_shift=0.0, proton_coupling=0.0, nmr_field=400.0, x_range=None, y_range=None, width=400, height=400, background_color=(255, 255, 255), transparent_background=False, rotate=(0.0, 0.0, 0.0)) | Uses Javascript and IPython to display an image of the specified molecule and property, calculated from a previous WebMO job |
The source code for the webmo Python library is available on github.
Use the "help" function as illustrated above for argument data types and returned data type. The help function will also include any recent changes made to the library.