Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MigrationGraph Renderable #267

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fceeb21
initiation
hmlli Jul 21, 2022
9f04e08
Merge remote-tracking branch 'origin/main' into MGComponent
hmlli Sep 1, 2022
2275002
Auto stash before merge of "MGComponent" and "origin/main"
hmlli Sep 1, 2022
824b76e
Merge branch 'MGComponent' into origin/main
hmlli Sep 1, 2022
a9ab1ff
Merge remote-tracking branch 'origin/main' into MGComponent
hmlli Sep 1, 2022
c8d2046
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 1, 2022
4798d7b
Auto stash before merge of "MGComponent" and "hmlli/MGComponent"
hmlli Sep 1, 2022
3b1de94
Merge branch 'MGComponent' into hmlli/MGComponent
hmlli Sep 1, 2022
7e251c4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 1, 2022
f4d43ba
add get_scene func for mg
hmlli Sep 1, 2022
31957e5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 1, 2022
a0bf356
adjust radius
hmlli Sep 1, 2022
92f1e83
boundary double graphing
hmlli Sep 1, 2022
e8fe350
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 1, 2022
a5f3328
revert to whole structure + cleanup
hmlli Sep 1, 2022
4430cc7
Merge remote-tracking branch 'hmlli/MGComponent' into MGComponent
hmlli Sep 1, 2022
d7c97c5
Merge remote-tracking branch 'origin/main' into MGComponent
hmlli Sep 6, 2022
816b6e0
adjust radius, visual
hmlli Sep 6, 2022
519143c
init file change + example app setup
hmlli Sep 10, 2022
8b074b1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 10, 2022
e4cb6cf
add color coding & radius adjustment
hmlli Sep 14, 2022
07d2292
cwd for example app
hmlli Sep 14, 2022
05dea70
build dist egginfo gitignore
hmlli Sep 14, 2022
5b9da58
delete build dist egginfo
hmlli Sep 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ __pycache__/

# auto-generated documentation
docs_rst/_build
build
dist
*.egg-info
1 change: 1 addition & 0 deletions crystal_toolkit/apps/examples/LiMnP2O7_mg.json

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions crystal_toolkit/apps/examples/migrationgraph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import os

import dash
from dash import html
from dash_mp_components import CrystalToolkitScene
from monty.serialization import loadfn

import crystal_toolkit.components as ctc
from crystal_toolkit.settings import SETTINGS

app = dash.Dash(assets_folder=SETTINGS.ASSETS_PATH)

# create the MigrationGraph object
module_dir = os.path.dirname(os.path.abspath(__file__))
mg = loadfn(f"{module_dir}/LiMnP2O7_mg.json")

# create the Crystal Toolkit component
# no MigrationGraph component yet
component = ctc.StructureMoleculeComponent(mg.structure, id="my_structure")
test_scene = mg.get_scene()

# example layout
my_layout = html.Div(
[html.Div([CrystalToolkitScene(data=test_scene.to_json())])],
style=dict(
margin="2em auto", display="grid", placeContent="center", placeItems="center"
),
)

# tell crystal toolkit about your app and layout
ctc.register_crystal_toolkit(app, layout=my_layout)

# run this app with "python path/to/this/file.py"
# in production, deploy behind gunicorn or similar
# see Dash documentation for more information
if __name__ == "__main__":
app.run_server(debug=True, port=8050)
1 change: 1 addition & 0 deletions crystal_toolkit/renderables/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from crystal_toolkit.renderables.lattice import Lattice as Lattice
from crystal_toolkit.renderables.migrationgraph import MigrationGraph as MigrationGraph
from crystal_toolkit.renderables.molecule import Molecule as Molecule
from crystal_toolkit.renderables.moleculegraph import MoleculeGraph as MoleculeGraph
from crystal_toolkit.renderables.phasediagram import PhaseDiagram as PhaseDiagram
Expand Down
96 changes: 96 additions & 0 deletions crystal_toolkit/renderables/migrationgraph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import numpy as np
from pymatgen.analysis.diffusion.neb.full_path_mapper import MigrationGraph

from crystal_toolkit.core.scene import Cylinders, Scene

color_scheme = [
(32, 178, 170),
(0, 255, 127),
(47, 79, 79),
(30, 144, 255),
(138, 43, 226),
(186, 85, 211),
(199, 21, 133),
(255, 20, 147),
(250, 235, 215),
(160, 82, 45),
(244, 164, 96),
(176, 196, 222),
]


def _get_extras_cross_boundary(self, one_hop, only_wi_structure, color_code):
extras = []
working_struct = only_wi_structure.copy()
wi = working_struct[0].specie.name
ori_epos = working_struct[one_hop["eindex"]]

# extra atoms
working_struct.insert(0, wi, one_hop["epos"])
shifted_ipos = one_hop["ipos"] - np.array(one_hop["to_jimage"])
working_struct.insert(0, wi, shifted_ipos)
sites_contents = [working_struct[0].get_scene(), working_struct[1].get_scene()]
extras.extend(sites_contents)

# extra cylinders
extra_ipos = list(working_struct[0].coords)
extra_epos = list(ori_epos.coords)
extras.append(
Cylinders(
positionPairs=[[extra_ipos, extra_epos]],
radius=0.3,
clickable=True,
color=color_code,
)
)

return extras


def get_migrationgraph_scene(
self,
) -> Scene:
"""
Creates CTK object to display hops from a MigrationGraph object
Args:
mg: MigrationGraph object with hops to be visualized

Returns:
CTK scene object to be rendered
"""

result_scene = self.structure.get_scene()
hop_contents = []

for k, one_hop in self.unique_hops.items():
one_hop_contents = []
rgb_code = color_scheme[k % len(color_scheme)]
color_code = f"#{rgb_code[0]:02x}{rgb_code[1]:02x}{rgb_code[2]:02x}"

hop_cyl = Cylinders(
positionPairs=[[list(one_hop["ipos_cart"]), list(one_hop["epos_cart"])]],
radius=0.3,
clickable=True,
color=color_code,
)
one_hop_contents.append(hop_cyl)

if one_hop["to_jimage"] != (0, 0, 0):
extras_cross_boundary = self._get_extras_cross_boundary(
one_hop, self.only_sites, color_code
)
one_hop_contents.extend(extras_cross_boundary)

one_hop_scene = Scene(name=f"hop_{k}", contents=one_hop_contents)
hop_contents.append(one_hop_scene)

result_scene.contents.append(
Scene(
name="hops", origin=result_scene.contents[0].origin, contents=hop_contents
)
)
return result_scene


MigrationGraph._get_extras_cross_boundary = _get_extras_cross_boundary
MigrationGraph.get_scene = get_migrationgraph_scene