Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
179 changes: 179 additions & 0 deletions docs/hands_on/tutorial2_2d_mat.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "078cef78",
"metadata": {},
"source": [
"# Tutorial 2: Quantum Transport in 2D materials"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c514189b",
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"dptb esk bn_spds.json -o hbn_spd_model\n",
"dptb config -m hbn_spd_model/sktb.json -tr -sk ./\n",
"\n",
"\"onsite\": {\n",
" \"method\": \"strain\"\n",
"}\n",
"\n",
"dptb train input.json -i ../extra_baseline/hbn_spd_model/sktb.json -o train_out\n",
"dptb run band.json -i train/train_out/checkpoint/nnsk.best.pth -o band_plot"
Comment on lines +22 to +30
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Clean up shell commands in code cell

The code cell contains shell commands mixed with Python configuration snippet. These should either be in a markdown cell as documentation or properly formatted as shell commands using ! prefix or %%bash magic.

Convert this to a markdown cell with proper code formatting:

## Setup Commands

Run these commands to set up the hBN model:

```bash
dptb esk bn_spds.json -o hbn_spd_model
dptb config -m hbn_spd_model/sktb.json -tr -sk ./

For the configuration, modify the onsite method:

"onsite": {
    "method": "strain"
}

Then train and run:

dptb train input.json -i ../extra_baseline/hbn_spd_model/sktb.json -o train_out
dptb run band.json -i train/train_out/checkpoint/nnsk.best.pth -o band_plot

<details>
<summary>🤖 Prompt for AI Agents</summary>

In docs/hands_on/tutorial2_2d_mat.ipynb around lines 22–30, the notebook cell
mixes shell commands with a JSON snippet; replace that cell with a single
Markdown cell titled "Setup Commands" that contains three fenced code blocks: a
bash block listing the two dptb setup/config commands, a json block showing the
onsite configuration with "method": "strain", and a final bash block with the
dptb train and dptb run commands; ensure proper fences (bash and json) and
brief explanatory text before each block.


</details>

<!-- fingerprinting:phantom:medusa:armadillo -->

<!-- This is an auto-generated comment by CodeRabbit -->

]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "026e2584",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"band.json\tgraphene.vasp\tlatest_dptb_b3.300_c2.600_w0.200.pth\n"
]
}
],
"source": [
"import os\n",
"from pathlib import Path\n",
"workdir='../../examples/graphene'\n",
"wd = Path(workdir)\n",
"if not wd.is_dir():\n",
" raise FileNotFoundError(f\"Workdir '{wd}' not found. Please adjust 'workdir'.\")\n",
"os.chdir(wd)\n",
"print(\"\\t\".join(sorted(os.listdir(\".\"))))"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "664ee3cc",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"DPNEGF INFO ================================================================================\n",
"DPNEGF INFO Version Info \n",
"DPNEGF INFO --------------------------------------------------------------------------------\n",
"DPNEGF INFO DPNEGF : 0.1.1.dev97+bccd946\n",
"DPNEGF INFO DeePTB : 2.1.2.dev53+5b97981\n",
"DPNEGF INFO ================================================================================\n",
"\n"
]
}
],
"source": [
"from dpnegf.utils.loggers import set_log_handles\n",
"import logging\n",
"from pathlib import Path\n",
"\n",
"\n",
"results_path = '../band_plot'\n",
"log_path = os.path.join(results_path, 'log')\n",
Comment on lines +90 to +91
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Ensure results directory exists before logging

The code sets up logging to a directory that may not exist yet.

Create the results directory before setting up logging:

 results_path = '../band_plot'
+os.makedirs(results_path, exist_ok=True)
 log_path = os.path.join(results_path, 'log')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"results_path = '../band_plot'\n",
"log_path = os.path.join(results_path, 'log')\n",
results_path = '../band_plot'
os.makedirs(results_path, exist_ok=True)
log_path = os.path.join(results_path, 'log')
🤖 Prompt for AI Agents
In docs/hands_on/tutorial2_2d_mat.ipynb around lines 84-85, the code sets
results_path and log_path but doesn't ensure the results/log directories exist
before configuring logging; create the results directory (and the nested log
directory) before any logging calls by calling os.makedirs(results_path,
exist_ok=True) and os.makedirs(log_path, exist_ok=True) (or a single
os.makedirs(log_path, exist_ok=True)) so the logging target path exists.

"log_level = logging.INFO\n",
"set_log_handles(log_level, Path(log_path) if log_path else None)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5c4797d7",
"metadata": {},
"outputs": [
{
"ename": "KeyError",
"evalue": "'config'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[3], line 5\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mdptb\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mnn\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mbuild\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m build_model\n\u001b[1;32m 3\u001b[0m model \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlatest_dptb_b3.300_c2.600_w0.200.pth\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;66;03m# the model for demonstration\u001b[39;00m\n\u001b[0;32m----> 5\u001b[0m model \u001b[38;5;241m=\u001b[39m \u001b[43mbuild_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/opt/mamba/envs/dpnegf-dev/lib/python3.10/site-packages/dptb/nn/build.py:50\u001b[0m, in \u001b[0;36mbuild_model\u001b[0;34m(checkpoint, model_options, common_options, no_check)\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 49\u001b[0m f \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mload(checkpoint, map_location\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcpu\u001b[39m\u001b[38;5;124m\"\u001b[39m, weights_only\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[0;32m---> 50\u001b[0m ckptconfig \u001b[38;5;241m=\u001b[39m \u001b[43mf\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mconfig\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m\n\u001b[1;32m 51\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m f\n\u001b[1;32m 53\u001b[0m \u001b[38;5;66;03m# init model from checkpoint\u001b[39;00m\n",
"\u001b[0;31mKeyError\u001b[0m: 'config'"
]
}
],
"source": [
"from dptb.nn.build import build_model\n",
"\n",
"model = \"latest_dptb_b3.300_c2.600_w0.200.pth\" # the model for demonstration\n",
"\n",
"model = build_model(model,\n",
" model_options= model_json['model_options'],\n",
" common_options=model_json['common_options'])"
]
Comment on lines +93 to +141
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix undefined variables in model building code

The code references undefined variables model_json which will cause a NameError. The model loading also appears to fail with a KeyError for 'config', suggesting the checkpoint format might be incompatible.

Fix the undefined variables and handle the missing config gracefully:

 from dptb.nn.build import build_model
+import json
 
 model =  "latest_dptb_b3.300_c2.600_w0.200.pth" # the model for demonstration
 
+# Load model configuration from a JSON file
+with open('band.json', 'r') as f:
+    model_json = json.load(f)
+
+# Build model with proper error handling
+try:
+    model = build_model(model,
+                       model_options=model_json.get('model_options', {}),
+                       common_options=model_json.get('common_options', {}))
+except KeyError as e:
+    print(f"Model checkpoint may be missing configuration. Error: {e}")
+    # Alternative: load model directly if it's a pre-configured checkpoint
+    import torch
+    model = torch.load(model, map_location="cpu", weights_only=False)
-model = build_model(model,
-                    model_options= model_json['model_options'],
-                    common_options=model_json['common_options'])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"id": "5c4797d7",
"metadata": {},
"outputs": [
{
"ename": "KeyError",
"evalue": "'config'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[3], line 5\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mdptb\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mnn\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mbuild\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m build_model\n\u001b[1;32m 3\u001b[0m model \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlatest_dptb_b3.300_c2.600_w0.200.pth\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;66;03m# the model for demonstration\u001b[39;00m\n\u001b[0;32m----> 5\u001b[0m model \u001b[38;5;241m=\u001b[39m \u001b[43mbuild_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/opt/mamba/envs/dpnegf-dev/lib/python3.10/site-packages/dptb/nn/build.py:50\u001b[0m, in \u001b[0;36mbuild_model\u001b[0;34m(checkpoint, model_options, common_options, no_check)\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 49\u001b[0m f \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mload(checkpoint, map_location\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcpu\u001b[39m\u001b[38;5;124m\"\u001b[39m, weights_only\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[0;32m---> 50\u001b[0m ckptconfig \u001b[38;5;241m=\u001b[39m \u001b[43mf\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mconfig\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m\n\u001b[1;32m 51\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m f\n\u001b[1;32m 53\u001b[0m \u001b[38;5;66;03m# init model from checkpoint\u001b[39;00m\n",
"\u001b[0;31mKeyError\u001b[0m: 'config'"
]
}
],
"source": [
"from dptb.nn.build import build_model\n",
"\n",
"model = \"latest_dptb_b3.300_c2.600_w0.200.pth\" # the model for demonstration\n",
"\n",
"model = build_model(model,\n",
" model_options= model_json['model_options'],\n",
" common_options=model_json['common_options'])"
]
from dptb.nn.build import build_model
import json
model = "latest_dptb_b3.300_c2.600_w0.200.pth" # the model for demonstration
# Load model configuration from a JSON file
with open('band.json', 'r') as f:
model_json = json.load(f)
# Build model with proper error handling
try:
model = build_model(model,
model_options=model_json.get('model_options', {}),
common_options=model_json.get('common_options', {}))
except KeyError as e:
print(f"Model checkpoint may be missing configuration. Error: {e}")
# Alternative: load model directly if it's a pre-configured checkpoint
import torch
model = torch.load(model, map_location="cpu", weights_only=False)
🤖 Prompt for AI Agents
In docs/hands_on/tutorial2_2d_mat.ipynb around lines 93 to 117, the snippet uses
an undefined model_json and the checkpoint load fails with KeyError 'config';
define or load model_json before calling build_model (e.g., read a JSON/dict
with 'model_options' and 'common_options' or construct defaults) and change the
build step to handle checkpoints without a 'config' key by catching KeyError
when accessing ckpt['config'] and falling back to sensible defaults or passing
explicit model_options/common_options; ensure the checkpoint path is correct and
use torch.load(map_location='cpu') to inspect its keys before calling
build_model so you can adapt the call to the actual checkpoint format.

},
{
"cell_type": "code",
"execution_count": null,
"id": "1041ae1c",
"metadata": {},
"outputs": [],
"source": [
"from dptb.postprocess.bandstructure.band import Band\n",
"import shutil\n",
"\n",
"task_options = {\n",
" \"task\": \"band\",\n",
" \"kline_type\":\"abacus\",\n",
" \"kpath\":[\n",
" [0, 0, 0, 50],\n",
" [0.5, 0, 0, 50],\n",
" [0.3333333, 0.3333333, 0, 50],\n",
" [0, 0, 0, 1]\n",
" ],\n",
" \"klabels\":[\"G\", \"M\", \"K\", \"G\"],\n",
" \"emin\":-20,\n",
" \"emax\": 20,\n",
" \"nel_atom\":{\"C\": 4} \n",
"\n",
" }\n",
"\n",
"if os.path.isdir(results_path):\n",
" shutil.rmtree(results_path, ignore_errors=True) \n",
"\n",
"band = Band(model, results_path)\n",
"AtomicData_options = {\"r_max\": 3.0, \"pbc\": True}\n",
"band.get_bands(data = uni_cell_atoms, \n",
" kpath_kwargs = task_options,\n",
" AtomicData_options = AtomicData_options)\n",
"band.band_plot(emin = task_options['emin'],\n",
" emax = task_options['emax'])"
]
Comment on lines +125 to +206
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix undefined variable uni_cell_atoms

The code references an undefined variable uni_cell_atoms which needs to be defined before use.

Add the missing structure definition before using it:

 from dptb.postprocess.bandstructure.band import Band
 import shutil
+from ase.io import read
+
+# Load the structure from POSCAR or graphene.vasp
+uni_cell_atoms = read("graphene.vasp")  # or appropriate structure file
 
 task_options = {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"source": [
"from dptb.postprocess.bandstructure.band import Band\n",
"import shutil\n",
"\n",
"task_options = {\n",
" \"task\": \"band\",\n",
" \"kline_type\":\"abacus\",\n",
" \"kpath\":[\n",
" [0, 0, 0, 50],\n",
" [0.5, 0, 0, 50],\n",
" [0.3333333, 0.3333333, 0, 50],\n",
" [0, 0, 0, 1]\n",
" ],\n",
" \"klabels\":[\"G\", \"M\", \"K\", \"G\"],\n",
" \"emin\":-20,\n",
" \"emax\": 20,\n",
" \"nel_atom\":{\"C\": 4} \n",
"\n",
" }\n",
"\n",
"if os.path.isdir(results_path):\n",
" shutil.rmtree(results_path, ignore_errors=True) \n",
"\n",
"band = Band(model, results_path)\n",
"AtomicData_options = {\"r_max\": 3.0, \"pbc\": True}\n",
"band.get_bands(data = uni_cell_atoms, \n",
" kpath_kwargs = task_options,\n",
" AtomicData_options = AtomicData_options)\n",
"band.band_plot(emin = task_options['emin'],\n",
" emax = task_options['emax'])"
]
from dptb.postprocess.bandstructure.band import Band
import shutil
from ase.io import read
# Load the structure from POSCAR or graphene.vasp
uni_cell_atoms = read("graphene.vasp") # or appropriate structure file
task_options = {
"task": "band",
"kline_type":"abacus",
"kpath":[
[0, 0, 0, 50],
[0.5, 0, 0, 50],
[0.3333333, 0.3333333, 0, 50],
[0, 0, 0, 1]
],
"klabels":["G", "M", "K", "G"],
"emin":-20,
"emax": 20,
"nel_atom":{"C": 4}
}
if os.path.isdir(results_path):
shutil.rmtree(results_path, ignore_errors=True)
band = Band(model, results_path)
AtomicData_options = {"r_max": 3.0, "pbc": True}
band.get_bands(data = uni_cell_atoms,
kpath_kwargs = task_options,
AtomicData_options = AtomicData_options)
band.band_plot(emin = task_options['emin'],
emax = task_options['emax'])

}
],
"metadata": {
"kernelspec": {
"display_name": "dpnegf-dev",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.16"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
18 changes: 18 additions & 0 deletions examples/graphene/band.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"structure":"train/data/POSCAR",
"task_options": {
"task": "band",
"kline_type":"abacus",
"kpath":[
[0, 0, 0, 50],
[0.5, 0, 0, 50],
[0.3333333, 0.3333333, 0, 50],
[0, 0, 0, 1]
],
"nkpoints":151,
"klabels":["G", "M", "K", "G"],
"emin":-20,
"emax":20,
"nel_atom":{"C":4}
}
}
11 changes: 11 additions & 0 deletions examples/graphene/extr_baseline/c_spds.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"common_options": {
"basis": {
"C": [
"2s",
"2p",
"d*"
]
}
}
}
Comment on lines +1 to +11
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Fix directory name: extr_baseline vs extra_baseline

Graphene uses "extr_baseline" while hBN uses "extra_baseline". This inconsistency will break scripts relying on a common pattern. Rename the directory or align all references.

Run to spot all occurrences:


🏁 Script executed:

#!/bin/bash
rg -n 'extra_baseline|extr_baseline' -C2

Length of output: 396


Fix directory name: extr_baseline vs extra_baseline

PR adds examples/graphene/extr_baseline (e.g., examples/graphene/extr_baseline/c_spds.json) while docs reference ../extra_baseline/hbn_spd_model/sktb.json (docs/hands_on/tutorial2_2d_mat.ipynb:29). Align the directory name or update all references to avoid breaking scripts.

🤖 Prompt for AI Agents
In examples/graphene/extr_baseline/c_spds.json (lines 1-11) the new directory is
named "extr_baseline" but docs reference "extra_baseline" (e.g.,
docs/hands_on/tutorial2_2d_mat.ipynb line ~29); fix by making the paths
consistent across the repo: either rename the examples/graphene/extr_baseline
directory to examples/graphene/extra_baseline, or update all documentation and
scripts to use "extr_baseline". Search the repo for both "extra_baseline" and
"extr_baseline" and apply the chosen name consistently, updating notebook
references (docs/hands_on/tutorial2_2d_mat.ipynb) and any CI/scripts that
consume these example paths.

Loading