Skip to content

Commit

Permalink
Merge pull request #6 from jennyfothergill/fix/interact
Browse files Browse the repository at this point in the history
Fix/interact
  • Loading branch information
jennyfothergill authored Mar 26, 2021
2 parents 9d41af3 + 8d5d5fd commit de900a6
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 413 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/build-ex.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: build-ex

on:
push:
branches: [ master ]
# Run when container or environment is changed
paths:
- 'containers/dockerfile-ex'
- 'examples/environment-ex.yml'
# Allows workflow to be manually triggered
workflow_dispatch:

jobs:
build-ex:
runs-on: ubuntu-latest

steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./containers/dockerfile
pus: true
tags: cmelab/gixstapose-ex:latest
-
name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
workflow_dispatch:

jobs:
build_gpu:
build:
runs-on: ubuntu-latest

steps:
Expand Down
13 changes: 13 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
comment:
layout: "reach, diff, flags, files"
behavior: default
require_changes: false # if true: only post the comment if coverage changes
require_base: no # [yes :: must have a base report to post]
require_head: yes # [yes :: must have a head report to post]
branches: # branch names that can post comment
- "master"
ignore:
- "gixstapose/tests"
- "gixstapose/__version__.py"
- "setup.py"

8 changes: 8 additions & 0 deletions containers/dockerfile-ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM cmelab/gpuconda:latest

# Create the environment
COPY examples/environment-ex.yml ./

# Install in base environment
RUN conda env update -n base -f environment-ex.yml && \
conda clean --all --yes -f
52 changes: 26 additions & 26 deletions Figure_Example.ipynb → examples/Figure_Example.ipynb

Large diffs are not rendered by default.

Empty file added examples/README.md
Empty file.
21 changes: 21 additions & 0 deletions examples/environment-ex.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: gixstapose-ex
channels:
- conda-forge
dependencies:
- fresnel=0.13.1
- gsd=2.4.1
- jupyterlab=3.0.10
- ipython=7.10.0
- matplotlib=3.3.4
- mbuild=0.10.13
- nodejs>=10
- numpy=1.20.1
- openbabel=3.1.1
- pillow=8.1
- pip=21.0.1
- py3Dmol=0.8.0
- pyside2=5.13.2
- python=3.7
- rowan=1.3.0
- pip:
- git+https://bitbucket.org/cmelab/cme_utils
3 changes: 3 additions & 0 deletions gixstapose/__version__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
VERSION = (0, 0, 1)

__version__ = ".".join(map(str, VERSION))
97 changes: 57 additions & 40 deletions gixstapose/draw_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import gsd.hoomd

import fresnel
import freud
import mbuild as mb
import PIL

Expand Down Expand Up @@ -67,8 +66,11 @@ def compound_load(inputfile, frame=-1):
Parameters
----------
inputfile: str, path to input file
frame: int, if inputfile is a trajectory, which frame to load. Supports negative indexing (default -1)
inputfile: str,
path to input file
frame: int,
if inputfile is a trajectory, which frame to load. Supports
negative indexing (default -1)
Returns
-------
Expand Down Expand Up @@ -144,9 +146,9 @@ def distance(pos1, pos2):
return np.linalg.norm(pos1 - pos2)


def mb_to_freud_box(box):
def mb_box_convert(box):
"""
Convert an mbuild box object to a freud box object
Convert an mbuild box object to hoomd/gsd style: [Lx, Ly, Lz, xy, xz, yz]
These sites are helpful as reference:
http://gisaxs.com/index.php/Unit_cell
https://hoomd-blue.readthedocs.io/en/stable/box.html
Expand All @@ -157,26 +159,19 @@ def mb_to_freud_box(box):
Returns
-------
freud.box.Box()
numpy array
"""
Lx = box.lengths[0]
Ly = box.lengths[1]
Lz = box.lengths[2]
alpha = box.angles[0]
beta = box.angles[1]
gamma = box.angles[2]

frac = (
np.cos(np.radians(alpha)) - np.cos(np.radians(beta)) * np.cos(np.radians(gamma))
) / np.sin(np.radians(gamma))
c = np.sqrt(1 - np.cos(np.radians(beta)) ** 2 - frac ** 2)

xy = np.cos(np.radians(gamma)) / np.sin(np.radians(gamma))
Lx, Ly, Lz = box.lengths
alpha, beta, gamma = np.deg2rad(box.angles)

frac = np.cos(alpha) - np.cos(beta) * np.cos(gamma) / np.sin(gamma)
c = np.sqrt(1 - np.cos(beta) ** 2 - frac ** 2)

xy = np.cos(gamma) / np.sin(gamma)
xz = frac / c
yz = np.cos(np.radians(beta)) / c
yz = np.cos(beta) / c

box_list = list(box.maxs) + [xy, yz, xz]
return freud.box.Box(*box_list)
return np.array([Lx, Ly, Lz, xy, xz, yz])


def create_scene(comp, color="cpk", scale=1.0, box=None):
Expand All @@ -186,12 +181,16 @@ def create_scene(comp, color="cpk", scale=1.0, box=None):
Parameters
----------
comp : (mbuild.Compound), compound to visualize
color : ("cpk", "bsu", the name of a matplotlib colormap, or a custom dictionary),
comp : (mbuild.Compound),
compound to visualize
color : ("cpk", "bsu", the name of a matplotlib colormap,
or a custom dictionary),
color scheme to use (default "cpk")
scale : (float), scaling factor for the particle, bond, and box radii (default 1.0)
box : (mb.Box), box object for the structure. If no box is provided,
comp.boundingbox is used
scale : (float),
scaling factor for the particle, bond, and box radii (default 1.0)
box : (mb.Box),
box object for the structure. If no box is provided,
comp.boundingbox is used (default None)
Returns
-------
Expand All @@ -205,16 +204,20 @@ def create_scene(comp, color="cpk", scale=1.0, box=None):
N_bonds = comp.n_bonds
if N_bonds > 0:
# all_bonds.shape is (nbond, 2 ends, xyz)
all_bonds = np.stack([np.stack((i[0].pos, i[1].pos)) for i in comp.bonds()])
all_bonds = np.stack([
np.stack((i[0].pos, i[1].pos)) for i in comp.bonds()
])

color_array = np.empty((N, 3), dtype="float64")
if type(color) is dict:
# Populate the color_array with colors based on particle name
# -- if name is not defined in the dictionary, try using the cpk dictionary
# if name is not defined in the dictionary, try using the cpk dictionary
for i, n in enumerate(particle_names):
try:
ncolor = color[n]
color_array[i, :] = fresnel.color.linear(mplcolors.to_rgba(ncolor))
color_array[i, :] = fresnel.color.linear(
mplcolors.to_rgba(ncolor)
)
except KeyError:
try:
color_array[i, :] = cpk_colors[n]
Expand All @@ -230,31 +233,38 @@ def create_scene(comp, color="cpk", scale=1.0, box=None):
color_array[i, :] = cpk_colors["default"]
elif color == "bsu":
# Populate the color array with the brand standard bsu colors
# https://www.boisestate.edu/communicationsandmarketing/brand-standards/colors/
# if there are more unique particle names than colors, colors will be reused
# https://www.boisestate.edu/communicationsandmarketing/
# brand-standards/colors/
# if there are more unique particle names than colors,
# colors will be reused
unique_names = list(set(particle_names))
for i, n in enumerate(particle_names):
color_array[i, :] = bsu_colors[uniq_atoms.index(n) % len(bsu_colors)]
color_array[i, :] = bsu_colors[
uniq_atoms.index(n) % len(bsu_colors)
]
else:
# Populate the color_array with colors based on particle name
# choose colors evenly distributed through a matplotlib colormap
try:
cmap = matplotlib.cm.get_cmap(name=color)
except ValueError:
print(
"The 'color' argument takes either 'cpk', 'bsu', or the name of a matplotlib colormap."
"The 'color' argument takes either 'cpk', 'bsu', or the name",
" of a matplotlib colormap."
)
raise
mapper = matplotlib.cm.ScalarMappable(
norm=matplotlib.colors.Normalize(vmin=0, vmax=1, clip=True), cmap=cmap
norm=mplcolors.Normalize(vmin=0, vmax=1, clip=True), cmap=cmap
)
particle_types = list(set(particle_names))
N_types = len(particle_types)
v = np.linspace(0, 1, N_types)
# Color by typeid
type_ids = np.array([particle_types.index(i) for i in particle_names])
for i in range(N_types):
color_array[type_ids == i] = fresnel.color.linear(mapper.to_rgba(v)[i])
color_array[type_ids == i] = fresnel.color.linear(
mapper.to_rgba(v)[i]
)

# Make an array of the radii based on particle name
# -- if name is not defined in the dictionary, use default
Expand Down Expand Up @@ -294,16 +304,23 @@ def create_scene(comp, color="cpk", scale=1.0, box=None):
bonds.points[:] = all_bonds

bonds.color[:] = np.stack(
[fresnel.color.linear(bond_colors), fresnel.color.linear(bond_colors)], axis=1
[fresnel.color.linear(bond_colors),
fresnel.color.linear(bond_colors)
], axis=1
)
bonds.radius[:] = [0.03 * scale] * N_bonds

if box:
# Use comp.box, unless it does not exist, then use comp.boundingbox
try:
freud_box = mb_to_freud_box(box)
new_box = mb_box_convert(box)
except AttributeError:
freud_box = mb_to_freud_box(comp.boundingbox)
new_box = mb_box_convert(comp.boundingbox)
# Create box in fresnel
fresnel.geometry.Box(scene, freud_box, box_radius=0.008 * scale)
fresnel.geometry.Box(scene, new_box, box_radius=0.008 * scale)

# Set the initial camera position
max_dist = np.max(comp.xyz) - np.min(comp.xyz)
scene.camera.height = 1.5 * max_dist
scene.camera.position = [max_dist, max_dist, max_dist]
return scene
Loading

0 comments on commit de900a6

Please sign in to comment.