Skip to content

Commit

Permalink
Add volume slice plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
superstar54 committed Nov 15, 2024
1 parent b110cd1 commit b59b627
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 4 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,23 @@ viewer.avr.lp.build_plane()

<img src="docs/source/_static/images/lattice_plane.png" width="300px"/>

### Slice 2D
```python
from ase.build import molecule
from weas_widget import WeasWidget
from ase.io.cube import read_cube_data
volume, atoms = read_cube_data("h2o-homo.cube")
viewer = WeasWidget()
viewer.from_ase(atoms)
viewer.avr.model_style = 1
viewer.avr.volume_slice.volumetric_data = {"values": volume}
viewer.avr.volume_slice.settings = {"Slice 1": {"h": 0, "k": 1, "l": 0, "distance": 5.5, "samplingDistance": 0.1 },
"Slice 2": {"h": 1, "k": 1, "l": 0, "distance": 5.5, "samplingDistance": 0.1 },
}
viewer.camera.setting = {"direction": [0.5, 1, 2], "zoom": 1.5}
viewer
```
<img src="docs/source/_static/images/example-volume-slice.png" width="300px"/>


## Test
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions docs/source/volume_slice.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Volume Slice
=================

The volume slice is a 2D cross-sectional visualization of 3D volumetric data. It is an effective method for analyzing volumetric properties, such as molecular orbitals or charge densities, by slicing through the data at specified orientations and distances.

Usage Example
-------------
Here is an example of drawing volume slices for the HOMO of the H2O molecule.

.. code-block:: python
from ase.build import molecule
from weas_widget import WeasWidget
from ase.io.cube import read_cube_data
volume, atoms = read_cube_data("h2o-homo.cube")
viewer = WeasWidget()
viewer.from_ase(atoms)
viewer.avr.model_style = 1
viewer.avr.volume_slice.volumetric_data = {"values": volume}
viewer.avr.volume_slice.settings = {
"Slice 1": {"h": 0, "k": 1, "l": 0, "distance": 5.5, "samplingDistance": 0.1},
"Slice 2": {"h": 1, "k": 1, "l": 0, "distance": 5.5, "samplingDistance": 0.1},
}
viewer.camera.setting = {"direction": [0.5, 1, 2], "zoom": 1.5}
viewer
.. figure:: _static/images/example-volume-slice.png
:width: 40%
:align: center


For the ``settings``:

- **h, k, l**: Miller indices defining the orientation of the slice.
- **distance**: The distance of the slice from the origin, in Ångstroms.
- **samplingDistance**: The sampling distance for rendering the slice, affecting resolution.

.. tip::

Support for multiple slices with individual settings, allowing analysis from different orientations and depths.
8 changes: 5 additions & 3 deletions js/widget.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// if we want test weas package, clone the weas repo and import the weas module, then use the following import
// import * as weas from "../../weas/src/index.js";
import * as weas from "../../weas/src/index.js";
// if not, then use the following import
import * as weas from "weas";
// import * as weas from "weas";
import "./widget.css";


Expand Down Expand Up @@ -75,8 +75,10 @@ function render({ model, el }) {
editor.avr.highlightManager.fromSettings(model.get("highlightSettings"));
// volumetric data
editor.avr.isosurfaceManager.volumetricData = createVolumeData(model.get("volumetricData"), atoms.cell);
console.log("isosettings: ", model.get("isoSettings"));
editor.avr.isosurfaceManager.fromSettings(model.get("isoSettings"));
// volume slice
editor.avr.volumeSliceManager.volumetricData = createVolumeData(model.get("volumetricData"), atoms.cell);
editor.avr.volumeSliceManager.fromSettings(model.get("sliceSettings"));
// vector field
editor.avr.VFManager.fromSettings(model.get("vectorField"));
editor.avr.showVectorField = model.get("showVectorField");
Expand Down
3 changes: 3 additions & 0 deletions src/weas_widget/atoms_viewer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .base_class import WidgetWrapper
from .plugins.vector_field import VectorField
from .plugins.isosurface import Isosurface
from .plugins.volume_slice import VolumeSlice
from .plugins.lattice_plane import LatticePlane
from .plugins.bond import BondManager
from .plugins.species import SpeciesManager
Expand Down Expand Up @@ -36,6 +37,7 @@ class AtomsViewer(WidgetWrapper):
"species",
"vf",
"iso",
"volume_slice",
"lp",
"atoms",
"bond",
Expand All @@ -53,6 +55,7 @@ def __init__(self, _widget):
setattr(self, "bond", BondManager(_widget))
setattr(self, "species", SpeciesManager(_widget))
setattr(self, "highlight", HighlightManager(_widget))
setattr(self, "volume_slice", VolumeSlice(_widget))

@property
def atoms(self):
Expand Down
5 changes: 4 additions & 1 deletion src/weas_widget/base_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class BaseWidget(anywidget.AnyWidget):
modelSticks = tl.List([]).tag(sync=True)
modelPolyhedras = tl.List([]).tag(sync=True)
volumetricData = tl.Dict({"values": [[[]]]}).tag(sync=True)
isoSettings = tl.Dict([]).tag(sync=True)
imageData = tl.Unicode("").tag(sync=True)
vectorField = tl.Dict().tag(sync=True)
showVectorField = tl.Bool(True).tag(sync=True)
Expand All @@ -65,6 +64,10 @@ class BaseWidget(anywidget.AnyWidget):
speciesSettings = tl.Dict({}).tag(sync=True)
# bond
bondSettings = tl.Dict({}).tag(sync=True)
# isosurface
isoSettings = tl.Dict({}).tag(sync=True)
# volume slice
sliceSettings = tl.Dict({}).tag(sync=True)
# phonon
phonon = tl.Dict({}).tag(sync=True)
# highlight
Expand Down
16 changes: 16 additions & 0 deletions src/weas_widget/plugins/volume_slice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from ..base_class import WidgetWrapper


class VolumeSlice(WidgetWrapper):

catalog = "VolumeSlice"

_attribute_map = {
"volumetric_data": "volumetricData",
"settings": "sliceSettings",
}

_extra_allowed_attrs = []

def __init__(self, _widget):
super().__init__(_widget)
34 changes: 34 additions & 0 deletions tests/notebooks/tests/notebooks/plugins.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,40 @@
"viewer.avr.highlight.settings[\"fixed\"][\"indices\"] = [0, 1, 2]\n",
"viewer"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from weas_widget import WeasWidget\n",
"import requests\n",
"from io import StringIO\n",
"from ase.io.cube import read_cube_data\n",
"url = \"https://raw.githubusercontent.com/superstar54/weas/main/demo/datas/h2o-homo.cube\"\n",
"response = requests.get(url)\n",
"file_content = response.text\n",
"# Use StringIO to simulate a file-like object for ASE to read from\n",
"file_like_object = StringIO(file_content)\n",
"volume, atoms = read_cube_data(file_like_object)\n",
"viewer = WeasWidget()\n",
"viewer.from_ase(atoms)\n",
"viewer.avr.model_style = 1\n",
"viewer.avr.volume_slice.volumetric_data = {\"values\": volume}\n",
"viewer.avr.volume_slice.settings = {\"Slice 1\": {\"h\": 0, \"k\": 1, \"l\": 0, \"distance\": 5.5, \"samplingDistance\": 0.1 },\n",
" \"Slice 2\": {\"h\": 1, \"k\": 1, \"l\": 0, \"distance\": 5.5, \"samplingDistance\": 0.1 },\n",
" }\n",
"viewer.camera.setting = {\"direction\": [0.5, 1, 2], \"zoom\": 1.5}\n",
"viewer"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down

0 comments on commit b59b627

Please sign in to comment.