Skip to content

Commit 68c2427

Browse files
authored
Merge pull request PolusAI#248 from jfennick/move_mm_viewer
move molecular modeling viewer
2 parents 7270b34 + 1bd9476 commit 68c2427

File tree

8 files changed

+385
-2
lines changed

8 files changed

+385
-2
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,17 @@ This repository contains workflows for various molecular modeling tasks. The wor
44

55
## Quick Start
66
Follow the [installation instructions](https://github.com/PolusAI/workflow-inference-compiler#quick-start) here.
7+
8+
## Jupyter notebook visualization
9+
10+
You can view 3D molecular structures in the Jupyter notebook `src/vis/viewer.ipynb`. The visualization currently needs to be in its own conda environment.
11+
12+
```
13+
install/install_conda.sh
14+
conda create --name vis
15+
conda activate vis
16+
install/install_nglview.sh
17+
pip install -e ".[all]"
18+
```
19+
20+
![Plots](docs/tree_viewer.png)

docs/dev/api.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,12 @@ mm_workflows.schemas.biobb
66

77
mm_workflows.schemas.gromacs_mdp
88
------------------------------------
9-
.. automodule:: mm_workflows.schemas.gromacs_mdp
9+
.. automodule:: mm_workflows.schemas.gromacs_mdp
10+
11+
vis.filewatcher
12+
------------------------------------
13+
.. automodule:: vis.filewatcher
14+
15+
vis.viewer
16+
------------------------------------
17+
.. automodule:: vis.viewer

install/install_nglview.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash -e
2+
# NOTE: mamba is a drop-in replacement for conda, just much faster.
3+
# (i.e. You can replace mamba with conda below.)
4+
# See https://github.com/conda-forge/miniforge#mambaforge-pypy3
5+
CONDA=conda
6+
if [ "$(which mamba)" ]; then
7+
CONDA=mamba
8+
fi
9+
10+
# mdtraj needs binary build dependencies (specifically cython) so do not install via pip
11+
$CONDA install -y -c conda-forge mdtraj
12+
13+
# mdtraj and pypy CANNOT currently be installed into the same environment:
14+
# $CONDA install -y -c conda-forge mdtraj pypy
15+
16+
$CONDA install -y pip
17+
18+
pip install jupyterlab ipytree
19+
20+
# See release notes about jupyterlab
21+
# https://github.com/nglviewer/nglview/releases/tag/v3.0.4
22+
pip install nglview
23+
24+
jupyter-nbextension enable nglview --py --sys-prefix

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ ignore_errors = false
147147
# versioneer to the exclude=regex above, but this works.
148148

149149
[[tool.mypy.overrides]]
150-
module = ["BioSimSpace.*", "MDAnalysis.*", "pymol.*", "rdkit.*", "nmrformd.*", "setuptools.*", "parmed.*", "pdbfixer.*", "openmm.*", "mdtraj.*"]
150+
module = ["BioSimSpace.*", "MDAnalysis.*", "pymol.*", "rdkit.*", "nmrformd.*", "setuptools.*", "parmed.*", "pdbfixer.*", "openmm.*", "mdtraj.*", "nglview.*"]
151151
ignore_missing_imports = true
152152

153153

src/vis/__init__.py

Whitespace-only changes.

src/vis/filewatcher.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import glob
2+
import os
3+
from pathlib import Path
4+
from typing import Dict, List
5+
6+
7+
# NOTE: You should be very careful when using file watchers! Most libraries
8+
# (watchdog, watchfiles, etc) will use operating system / platform-specific
9+
# APIs to check for changes (for performance reasons). However, this can cause
10+
# problems in some cases, specifically for network drives.
11+
# See https://stackoverflow.com/questions/45441623/using-watchdog-of-python-to-monitoring-afp-shared-folder-from-linux
12+
# I'm 99% sure the same problem happens with Docker containers. Either way, the
13+
# solution is to use polling. However, for unknown reasons, simply replacing
14+
# Observer with PollingObserver doesn't seem to work! So we are forced to write
15+
# our own basic file watcher using glob.
16+
17+
18+
def file_watcher_glob(cachedir_path: Path, patterns: List[str], prev_files: Dict[str, float]) -> Dict[str, float]:
19+
"""Determines whether files (specified by the given glob patterns) have been either recently created or modified.\n
20+
Note that this is a workaround due to an issue with using standard file-watching libraries.
21+
22+
Args:
23+
cachedir_path (Path): The --cachedir directory of the main workflow.
24+
patterns (List[str]): The glob patterns which specifies the files to be watched.
25+
prev_files (Dict[str, float]): This should be the return value from the previous function call.
26+
27+
Returns:
28+
Dict[str, float]: A dictionary containing the filepaths and last modification times.
29+
"""
30+
changed_files = {}
31+
file_patterns = [str(cachedir_path / f'**/{pattern}') for pattern in patterns]
32+
file_paths_all = [glob.glob(fp, recursive=True) for fp in file_patterns]
33+
file_paths_flat = [path for fps in file_paths_all for path in fps]
34+
for file in file_paths_flat:
35+
mtime = os.path.getmtime(file)
36+
if file not in prev_files:
37+
# created
38+
changed_files[file] = mtime
39+
elif mtime > prev_files[file]:
40+
# modified
41+
changed_files[file] = mtime
42+
return changed_files

src/vis/viewer.ipynb

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"from vis import viewer\n",
10+
"# Once the workflow has finished executing, you can view the output files.\n",
11+
"viewer.tree_viewer()"
12+
]
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": null,
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"from vis import viewer\n",
21+
"# Alternatively, you can view the files in realtime while the workflow is executing.\n",
22+
"# This runs for about 10 mins before printing 'done'.\n",
23+
"# You can always re-run the cell and/or increase num_iterations.\n",
24+
"num_iterations = 60 * 10\n",
25+
"viewer.realtime_viewer(num_iterations)"
26+
]
27+
}
28+
],
29+
"metadata": {
30+
"kernelspec": {
31+
"display_name": "Python 3.10.6",
32+
"language": "python",
33+
"name": "python3"
34+
},
35+
"language_info": {
36+
"codemirror_mode": {
37+
"name": "ipython",
38+
"version": 3
39+
},
40+
"file_extension": ".py",
41+
"mimetype": "text/x-python",
42+
"name": "python",
43+
"nbconvert_exporter": "python",
44+
"pygments_lexer": "ipython3",
45+
"version": "3.10.6"
46+
},
47+
"vscode": {
48+
"interpreter": {
49+
"hash": "612ab4556636a7986aff5653e5d5ed5cb1e0c640daa830f0dae50b030d37dcd4"
50+
}
51+
}
52+
},
53+
"nbformat": 4,
54+
"nbformat_minor": 2
55+
}

0 commit comments

Comments
 (0)