Home

Awesome

JSME notebook

JSME molecular editor in a Jupyter or Colab notebook. These two work in a very different manner and this is very inelegant, but works.

This is not expected to be stable, but works as an interim solution.

The following discussion talks about Jupyter vs. Colab differences: for more see my blog post about it

This should be a widget (see below), but it is not for a series of reasons.

As a result I am not going to pip release it:

pip install jsme_notebook

jsme in googlecolab demo

I think it may be possible to make comms to work with it, thus removing the weirdness. Were it done, it would no longer be that hacky.

Example

from jsme_notebook import JSMENotebook

jsme = JSMENotebook('CCCC')  # outputs to display...
None

Changes to the molecule will be available in jsme.smiles in subsequent cells.

For it to work in both Colab and in a Jupyter notebook, the instance in Jupyter relies on pointers —so reassignment of the object name or deletion of the object will cause a segfault when the view is altered.

As an extra, there's an alternative way to use it, i.e. via Rdkit:

from jsme_notebook.rdkit import JSMERDKit

mol: Chem.Mol = ...
jsme = JSMERDKit(mol)

Examples in the wild

This is not intended to be exhaustive.

JSME in a notebook

JSME Molecule Editor is a great tool for creating and editing molecules.

There are a few Python implementations that are available for this. The other main option is Marvin for example. The latter however requires a server to be running and return a valid SMILES string. JSME is 100% client side.

As a result JSME is perfectly suitable for a Jupyter notebook. Despite being an obvious candiate, there are three options for using JSME in a notebook, but only one worked for me, but is not a package.

The latter shows it is possible, but is not a module. The first raises a JS error and has only 6 watchers, despite having documentation. As a result I decided to make it into a package, but it turned out to be a rabbit hole of madness.

Proper widget?

JSME_ipywidget is very interesting as it does not make a widget via the bizantine widget cookiecutter, but circumvents it by getting DOMWidgetView from '@jupyter-widgets/base' by RequireJS and using the fact that Jupyter serves all files within the workspace as they are listed. Colab does not use RequireJS nor does it work for me when I load it nor does Colab serve the files like Jupyter nor can I get @jupyter-widgets/base to import.

I tried making it JSME into a proper widget, but the fact that JSME loads weirdly it did not work. Namely:

There are two packages in NPM, JSME and JSME-editor. The latter is available from https://cdn.skypack.dev/jsme-editor but does not work.

This explains why there is not a plethora of JSME widgets out there.

CDN

I uploaded the JSME folder from JSME_ipywidget to my public html folder of my university with a .htaccess file in it with Header add Access-Control-Allow-Origin "*": https://users.ox.ac.uk/~bioc1451/jsme/jsme.nocache.js

This solves the CDN issue.

Colab

The DOMWidgetView widget from '@jupyter-widgets/base' approach does not work for Colab as mentioned.

As a result Colab's system is required.

In Python

from google.colab import output

def python_fun(*args):
    pass

output.register_callback('handle_for_python_fun', python_fun)

In Javascript

google.colab.kernel.invokeFunction('handle_for_python_fun', [arg1, arg2])

Whereas in Jupyter the command for JS --> Python is in JS:

Jupyter.notebook.kernel.execute(`python_fun(${arg1}, ${arg2})`);

There is the comms option, but I am not expecting much dialog, back from Python as the JSME editor will be bound by previous cell.

The Colab handle thing means that I can use a bound method, which is fun. With Jupyer I need to be naughty and use a pointer: i.e. deleting the faux-widget instance, will cause a segfault.