Skip to content

Commit aebbcf1

Browse files
update docs (#749)
* update docs * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * use rst file * christmas tree docs * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent b8fddfb commit aebbcf1

File tree

6 files changed

+523
-2
lines changed

6 files changed

+523
-2
lines changed

docs/source/2025/01.rst

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
01 - Christmas Tree Builder
2+
============================
3+
4+
You can use a ZnDraw extension to provide a graphical user interface for building a Christmas tree out of molecules.
5+
6+
.. code:: python
7+
8+
from ase import Atoms
9+
from zndraw import ZnDraw, Extension
10+
from pydantic import Field
11+
from rdkit2ase import smiles2atoms, smiles2conformers
12+
13+
vis = ZnDraw(url="http://localhost:5003/", token="tree")
14+
15+
class BuildChristmasTree(Extension):
16+
smiles: str = Field(
17+
"CO", description="SMILES string of the molecule to use for the tree"
18+
)
19+
n: int = Field(5, description="Number of layers for the tree", ge=1, le=10)
20+
x_spacing: float = Field(
21+
4,
22+
description="Horizontal spacing between molecules in each layer (in Ångstroms)",
23+
ge=0,
24+
le=10,
25+
)
26+
y_spacing: float = Field(
27+
3, description="Vertical spacing between layers (in Ångstroms)", ge=0, le=10
28+
)
29+
trunk_height: int = Field(
30+
2, description="Number of molecules in the trunk", ge=0, le=10
31+
)
32+
conformers: bool = True
33+
34+
def run(self, vis, **kwargs):
35+
# compute number of needed conformers
36+
n_molecules = (self.n * (self.n + 1)) + self.trunk_height
37+
if self.conformers:
38+
molecules = smiles2conformers(self.smiles, numConfs=n_molecules)
39+
else:
40+
molecule = smiles2atoms(self.smiles)
41+
molecules = [molecule.copy() for _ in range(n_molecules)]
42+
tree = build_christmas_tree(
43+
molecules, self.n, self.trunk_height, self.x_spacing, self.y_spacing
44+
)
45+
vis.append(tree)
46+
47+
@classmethod
48+
def model_json_schema(cls):
49+
schema = super().model_json_schema()
50+
schema["properties"]["conformers"]["format"] = "checkbox"
51+
# make format range
52+
schema["properties"]["n"]["format"] = "range"
53+
schema["properties"]["x_spacing"]["format"] = "range"
54+
schema["properties"]["x_spacing"]["step"] = 0.1
55+
schema["properties"]["y_spacing"]["format"] = "range"
56+
schema["properties"]["y_spacing"]["step"] = 0.1
57+
schema["properties"]["trunk_height"]["format"] = "range"
58+
return schema
59+
60+
61+
def build_christmas_tree(
62+
molecules: list[Atoms],
63+
n: int = 5,
64+
trunk_height: int = 2,
65+
x_spacing: float = 3.0,
66+
y_spacing: float = 3.0,
67+
) -> Atoms:
68+
"""Build an atomic Christmas tree.
69+
70+
Arguments
71+
---------
72+
molecules : list[Atoms]
73+
A list of molecular structures to use for each part of the tree.
74+
n : int
75+
The number of layers for the tree.
76+
trunk_height : int
77+
The number of molecules in the trunk.
78+
x_spacing : float
79+
Horizontal spacing between molecules in each layer (in Ångstroms).
80+
y_spacing : float
81+
Vertical spacing between layers (in Ångstroms).
82+
83+
Returns
84+
-------
85+
tree : Atoms
86+
An assembled "tree" with the trunk and branches built from the provided molecules.
87+
"""
88+
# Ensure there are enough molecules to build the tree
89+
if len(molecules) < n * (n + 1) // 2 + trunk_height:
90+
raise ValueError(
91+
"Not enough molecules to build the tree and trunk with the given parameters."
92+
)
93+
94+
# Center molecules individually
95+
for mol in molecules:
96+
mol.center()
97+
98+
# Create an empty structure for the tree
99+
tree = Atoms()
100+
101+
# Build the trunk
102+
for _ in range(trunk_height):
103+
mol_copy = molecules.pop()
104+
tree += mol_copy
105+
[mol.translate([0, y_spacing, 0]) for mol in molecules]
106+
107+
# Build the layers from bottom to top
108+
for layer_num in reversed(range(n)):
109+
layer = Atoms()
110+
num_molecules = layer_num + 1
111+
x_offset = (
112+
x_spacing * (num_molecules - 1) / 2
113+
) # Offset to center the layer horizontally
114+
115+
for j in range(num_molecules):
116+
mol_copy = molecules.pop()
117+
mol_copy.translate([j * x_spacing - x_offset, 0, 0])
118+
layer += mol_copy
119+
120+
tree += layer
121+
[mol.translate([0, y_spacing, 0]) for mol in molecules]
122+
123+
return tree
124+
125+
vis.register(BuildChristmasTree, public=True)
126+
vis.socket.wait()
127+
128+
The Extension will appear on the modifier sidebar and gives you full control over the parameters of the tree builder.
129+
130+
.. image:: https://github.com/user-attachments/assets/161e6b40-f539-45b9-9bab-cfa613e37b8f
131+
:width: 100%
132+
:alt: ZnDraw
133+
:class: only-light
134+
135+
.. image:: https://github.com/user-attachments/assets/f1495096-c443-4a53-98c4-07368354b21d
136+
:width: 100%
137+
:alt: ZnDraw
138+
:class: only-dark
139+
140+
141+
.. tip::
142+
143+
Use the PathTracer integrated with ZnDraw to make the christmas tree reflective like christmas decorations.
144+
145+
.. image:: https://github.com/user-attachments/assets/ca382068-1f17-4bcb-a6f2-ef48c671ac48
146+
:width: 100%
147+
:alt: ZnDraw
148+
:class: only-light
149+
150+
.. image:: https://github.com/user-attachments/assets/5df7e7ab-a930-4361-ac5e-e4f0fcd10cc1
151+
:width: 100%
152+
:alt: ZnDraw
153+
:class: only-dark

docs/source/adventofcode.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Advent of Code
2+
==============
3+
4+
Each day of the Advent we will showcase one of ZnDraws features for you!
5+
6+
Each example - unless otherwise noted - assumes a running ZnDraw instance on ``http://localhost:5003``.
7+
8+
.. toctree::
9+
:maxdepth: 2
10+
:glob:
11+
12+
2025/*

docs/source/conf.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
# -- General configuration ---------------------------------------------------
1717
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
1818

19-
extensions = []
19+
extensions = [
20+
"nbsphinx",
21+
]
2022

2123
templates_path = ["_templates"]
2224
exclude_patterns = []

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ You can use port forwarding to access the visualisation from a remote machine.
2828
:hidden:
2929

3030
python-api
31+
adventofcode

0 commit comments

Comments
 (0)