Skip to content
Open
Changes from all commits
Commits
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
253 changes: 253 additions & 0 deletions other/materials_designer/text_on_nanoribbon.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d8a8021cf80ad95c",
"metadata": {},
"source": [
"# Create a nanoribbon material with the digits (or letters) on a nanoribbon."
]
},
{
"cell_type": "code",
"id": "b1158553",
"metadata": {},
"source": [
"from mat3ra.made.material import Material\n",
"from mat3ra.made.tools.build.nanoribbon import create_nanoribbon, NanoribbonConfiguration\n",
"from mat3ra.standata.materials import Materials\n",
"from mat3ra.made.tools.modify import rotate\n",
"from IPython.display import display\n",
"import numpy as np\n",
"\n",
"\n",
"DIGITS_STRING = \"2026\"\n",
"grid_size = 10\n",
"\n",
"SHOW_DIGITS = False\n",
"\n",
"combined_length = 32\n",
"material = Material(Material.default_config)\n",
"graphene = Material(Materials.get_by_name_first_match(\"Graphene\"))\n",
"config = NanoribbonConfiguration(material=graphene, width=4 * 10, length=combined_length, edge_type=\"zigzag\")\n",
"nanoribbon = create_nanoribbon(config)\n"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "code",
"id": "f6ba0797",
"metadata": {},
"source": [
"def generate_digit_grid(digit, grid_size=10):\n",
" \"\"\"\n",
" Generate a binary grid for a digit and return ON pixel coordinates.\n",
" \"\"\"\n",
" from PIL import Image, ImageDraw, ImageFont\n",
" \n",
" image = Image.new(\"1\", (grid_size, grid_size), color=1)\n",
" draw = ImageDraw.Draw(image)\n",
" \n",
" try:\n",
" font = ImageFont.load_default()\n",
" except IOError:\n",
" raise RuntimeError(\"Failed to load bitmap font.\")\n",
" \n",
" draw.text((0, 0), digit, fill=0, font=font)\n",
" grid = np.array(image)\n",
" \n",
" on_pixels = [(x, y) for y in range(grid.shape[0]) for x in range(grid.shape[1]) if not grid[y, x]]\n",
" return on_pixels\n",
"\n",
"def visualize_digit_coords(coords, grid_size=10):\n",
" \"\"\"\n",
" Visualize digit coordinates as a grid and image.\n",
" \"\"\"\n",
" from PIL import Image\n",
" \n",
" grid = np.ones((grid_size, grid_size), dtype=int)\n",
" for x, y in coords:\n",
" if 0 <= y < grid_size and 0 <= x < grid_size:\n",
" grid[y, x] = 0\n",
" \n",
" print(\" \", end=\"\")\n",
" for x in range(grid_size):\n",
" print(f\"{x:2}\", end=\" \")\n",
" print()\n",
" \n",
" for y in range(grid_size):\n",
" print(f\"{y:2} \", end=\"\")\n",
" for x in range(grid_size):\n",
" print(f\"{grid[y, x]:2}\", end=\" \")\n",
" print()\n",
" \n",
" image = Image.fromarray((grid * 255).astype(np.uint8), mode='L')\n",
" scale_factor = 10\n",
" scaled_image = image.resize((grid_size * scale_factor, grid_size * scale_factor), resample=Image.NEAREST)\n",
" display(scaled_image)\n",
" \n",
" print(f\"\\nON pixels: {coords}\")\n",
"\n",
"def toggle_pixels(coords, toggles):\n",
" \"\"\"\n",
" Toggle pixels in the coordinate list.\n",
" If a coordinate is in the list, remove it. If not, add it.\n",
" \"\"\"\n",
" coords_set = set(coords)\n",
" for toggle in toggles:\n",
" if toggle in coords_set:\n",
" coords_set.remove(toggle)\n",
" else:\n",
" coords_set.add(toggle)\n",
" return list(coords_set)\n"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "code",
"id": "c625e22c",
"metadata": {},
"source": [
"\n",
"digits_coords = []\n",
"for i, digit in enumerate(DIGITS_STRING):\n",
" coords = generate_digit_grid(digit, grid_size)\n",
" digits_coords.append(coords)\n",
" if SHOW_DIGITS:\n",
" print(f\"Digit {i} ('{digit}'):\")\n",
" visualize_digit_coords(coords, grid_size)\n",
" print()\n"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "code",
"id": "187f99ff",
"metadata": {},
"source": [
"adjustments = {\n",
" # 3: [(5, 4)],\n",
"}\n",
"\n",
"\n",
"for digit_index, toggles in adjustments.items():\n",
" digits_coords[digit_index] = toggle_pixels(digits_coords[digit_index], toggles)\n",
" print(f\"Adjusted Digit {digit_index} ('{DIGITS_STRING[digit_index]}'):\")\n",
" visualize_digit_coords(digits_coords[digit_index], grid_size)\n",
" print()\n"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "code",
"id": "03ef6570",
"metadata": {},
"source": [
"def create_material_from_digit_coords(digit_coords_list, nanoribbon, grid_size, lattice_param=2.46, spacing=0, x_shift=-5):\n",
" \"\"\"\n",
" Create material with atoms positioned based on digit coordinates.\n",
" \"\"\"\n",
" material = nanoribbon.clone()\n",
" x_offset = 0\n",
" \n",
" for digit_coords in digit_coords_list:\n",
" x_offset += grid_size * lattice_param + spacing * lattice_param + x_shift\n",
" \n",
" for x, y in digit_coords:\n",
" coord = np.array([\n",
" x * lattice_param + x_offset - lattice_param * 7,\n",
" y * lattice_param + lattice_param * 2 + 90,\n",
" 2 * lattice_param\n",
" ])\n",
" material.add_atom(\"Au\", coord, use_cartesian_coordinates=True)\n",
" \n",
" mirror_coord = np.array([\n",
" -coord[0],\n",
" coord[1],\n",
" 5 * lattice_param\n",
" ])\n",
" material.add_atom(\"Cs\", mirror_coord, use_cartesian_coordinates=True)\n",
" \n",
" return material\n"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "code",
"id": "0e554c39",
"metadata": {},
"source": [
"lattice_param = 2.46\n",
"spacing = 0\n",
"x_shift = -5\n",
"\n",
"material = create_material_from_digit_coords(digits_coords, nanoribbon, grid_size, lattice_param, spacing, x_shift)\n"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "code",
"id": "bca66033",
"metadata": {},
"source": [
"from utils.jupyterlite import set_materials\n",
"from utils.visualize import visualize_materials\n",
"from mat3ra.made.tools.modify import add_vacuum, translate_to_z_level\n",
"\n",
"material_copy = material.clone()\n",
"material_copy = add_vacuum(material_copy, 20, to_bottom=True)\n",
"material_copy = translate_to_z_level(material_copy, \"center\")\n",
"material_copy = rotate(material_copy, [1, 0, 0], -90, rotate_cell=False)\n",
"\n",
"visualize_materials([material_copy], rotation=\"-180x\")\n",
"visualize_materials([material_copy], rotation=\"-90x\")\n",
"\n",
"material_copy.name = DIGITS_STRING\n",
"set_materials([material_copy])\n"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"id": "71c7e7b7",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"id": "cfb846e053e5b355",
"metadata": {},
"source": [],
"outputs": [],
"execution_count": null
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading