Skip to content
Open
Changes from 7 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
327 changes: 327 additions & 0 deletions other/materials_designer/specific_examples/run_bandgap_workflow.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "0",
"metadata": {},
"source": [
"# Bandgap Workflow Example\n",
" This notebook demonstrates how to build and run a bandgap workflow for a material.\n",
"\n",
"## Process Overview\n",
"### 1. Set up the environment and parameters.\n",
"### 2. Log in to get the API token\n",
"### 3. Load the target material.\n",
"### 4. Import workflow builder and related analyzers.\n",
"### 5. Analyze material to get parameters for the workflow configuration.\n",
"### 6. Create the workflow configuration.\n",
"### 7. Create a job with material and workflow configuration.\n",
"### 8. Submit the job to the server.\n",
"### 9. Monitor the job status and retrieve results.\n",
"### 10. Display the results."
]
},
{
"cell_type": "markdown",
"id": "1",
"metadata": {},
"source": [
"## 1. Set up the environment and parameters"
]
},
{
"cell_type": "markdown",
"id": "2",
"metadata": {},
"source": [
"## 2. Log in to get the API token"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.api import ApiClient\n",
"\n",
"from examples.reproducing_publications.band_gaps_for_interface_bilayer_twisted_molybdenum_disulfide import \\\n",
" unit_flowchart_id\n",
"\n",
"# Log in to get the API token\n",
"auth_config = await ApiClient().login()"
Comment on lines 48 to 51
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove unused import or clarify its purpose.

The imported unit_flowchart_id from line 49-50 is not used in this cell or anywhere else in the notebook. If it's intended for future use, consider adding a comment explaining its purpose, otherwise remove it.

Apply this diff to remove the unused import:

 from mat3ra.api import ApiClient
 
-from examples.reproducing_publications.band_gaps_for_interface_bilayer_twisted_molybdenum_disulfide import \
-    unit_flowchart_id
-
 # Log in to get the API token
 auth_config = await ApiClient().login()
📝 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
"from mat3ra.api import ApiClient\n",
"\n",
"from examples.reproducing_publications.band_gaps_for_interface_bilayer_twisted_molybdenum_disulfide import \\\n",
" unit_flowchart_id\n",
"\n",
"# Log in to get the API token\n",
"auth_config = await ApiClient().login()"
"from mat3ra.api import ApiClient\n",
"\n",
"# Log in to get the API token\n",
"auth_config = await ApiClient().login()"
🧰 Tools
🪛 Ruff (0.14.6)

50-50: Undefined name kgrid_context_provider

(F821)

🤖 Prompt for AI Agents
other/materials_designer/specific_examples/run_bandgap_workflow.ipynb around
lines 47-53: the import of unit_flowchart_id from
examples.reproducing_publications.band_gaps_for_interface_bilayer_twisted_molybdenum_disulfide
is unused; remove unit_flowchart_id from the import statement (or delete the
entire import line) to eliminate the unused import, or if it’s intended for
future use, keep it but add a concise comment in the same cell explaining its
purpose so reviewers know it’s intentional.

]
},
{
"cell_type": "markdown",
"id": "4",
"metadata": {},
"source": [
"## 3. Load the target material"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5",
"metadata": {},
"outputs": [],
"source": [
"from utils.visualize import visualize_materials as visualize\n",
"from utils.jupyterlite import load_material_from_folder\n",
"\n",
"material = load_material_from_folder(\"/uploads\", \"MoS2_twisted_interface_60_degrees.json\")\n",
"visualize(material)"
]
},
{
"cell_type": "markdown",
"id": "6",
"metadata": {},
"source": [
"## 4. Import workflow builder and related analyzers"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.wode.context_providers import (\n",
" PointsGridFormDataProvider, # exists - for k-points\n",
" PlanewaveCutoffsContextProvider, # exists - for cutoffs\n",
" SmearingContextProvider, # no JS implementation yet\n",
" BandsContextProvider # no JS implementation yet\n",
")\n",
"\n",
"\n",
"kgrid_provider = PointsGridFormDataProvider(material=material)\n",
"cutoffs_provider = PlanewaveCutoffsContextProvider(material=material)\n",
"smearing_provider = SmearingContextProvider(material=material)\n",
"bands_provider = BandsContextProvider(material=material)\n",
"\n",
"kpoints = kgrid_provider.get_dimensions() # or calculate_dimensions()\n",
"cutoff = cutoffs_provider.get_cutoff() # defaultECUTWFC, defaultECUTRHO\n",
"smearing = smearing_provider.get_smearing()\n",
"number_of_bands = bands_provider.get_number_of_bands()"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cd /tmp/repo && find . -type f -name "*.py" | head -20

Repository: Exabyte-io/api-examples

Length of output: 126


🏁 Script executed:

cd /tmp/repo && rg "class SmearingContextProvider|class BandsContextProvider|class PointsGridFormDataProvider" -A 5 --max-count=10

Repository: Exabyte-io/api-examples

Length of output: 126


🏁 Script executed:

cd /tmp/repo && rg "def get_dimensions|def calculate_dimensions" -B 2 -A 3

Repository: Exabyte-io/api-examples

Length of output: 126


🏁 Script executed:

git ls-files | grep -E "(context|provider)" | head -20

Repository: Exabyte-io/api-examples

Length of output: 49


🏁 Script executed:

rg "class SmearingContextProvider|class BandsContextProvider|class PointsGridFormDataProvider" -A 5

Repository: Exabyte-io/api-examples

Length of output: 49


🏁 Script executed:

rg "def get_dimensions|def calculate_dimensions" -B 2 -A 3

Repository: Exabyte-io/api-examples

Length of output: 49


🏁 Script executed:

find . -name "run_bandgap_workflow.ipynb" -type f

Repository: Exabyte-io/api-examples

Length of output: 138


🏁 Script executed:

python3 << 'EOF'
import json
import sys

try:
    with open('./other/materials_designer/specific_examples/run_bandgap_workflow.ipynb', 'r') as f:
        notebook = json.load(f)
    
    # Find cells with imports and provider usage
    for i, cell in enumerate(notebook.get('cells', [])):
        if cell.get('cell_type') == 'code':
            source = ''.join(cell.get('source', []))
            if 'PointsGridFormDataProvider' in source or 'SmearingContextProvider' in source or 'get_dimensions' in source:
                print(f"\n=== Cell {i} ===")
                print(source)
except Exception as e:
    print(f"Error: {e}", file=sys.stderr)
    sys.exit(1)
EOF

Repository: Exabyte-io/api-examples

Length of output: 853


🏁 Script executed:

rg "SmearingContextProvider|BandsContextProvider" --type py

Repository: Exabyte-io/api-examples

Length of output: 49


🏁 Script executed:

rg "def get_dimensions|def calculate_dimensions" --type py

Repository: Exabyte-io/api-examples

Length of output: 49


🏁 Script executed:

rg "mat3ra|wode" --type py -A 2 -B 2 | head -50

Repository: Exabyte-io/api-examples

Length of output: 2696


🏁 Script executed:

find . -name "*.md" -o -name "*.rst" | xargs grep -l "SmearingContextProvider\|BandsContextProvider\|get_dimensions" 2>/dev/null | head -10

Repository: Exabyte-io/api-examples

Length of output: 49


🏁 Script executed:

web_search
mat3ra wode PointsGridFormDataProvider SmearingContextProvider API documentation

Repository: Exabyte-io/api-examples

Length of output: 162


🌐 Web query:

mat3ra.wode PointsGridFormDataProvider get_dimensions API

💡 Result:

I can't find a public reference to "PointsGridFormDataProvider.get_dimensions" in the mat3ra.wode docs or source from my quick search. Do you want me to:

  • search deeper (PyPI package source / GitHub / docs) for the exact API and return code/docs, or
  • show how to call a similar "get_dimensions" function (example usage) if you can paste the package code or the class file?

🌐 Web query:

SmearingContextProvider BandsContextProvider mat3ra wode

💡 Result:

I’m not sure what you mean. Do you mean React context providers named SmearingContextProvider and BandsContextProvider (where did you see them)? What does “mat3ra wode” mean here — is that a transliteration of Arabic asking “what is this”? Please share the code or a link and I’ll look them up.


🏁 Script executed:

find . -name "requirements.txt" -o -name "pyproject.toml" -o -name "setup.py" | xargs cat 2>/dev/null | grep -i mat3ra

Repository: Exabyte-io/api-examples

Length of output: 280


🏁 Script executed:

rg "SmearingContextProvider|BandsContextProvider|PointsGridFormDataProvider" -l

Repository: Exabyte-io/api-examples

Length of output: 136


🏁 Script executed:

find . -name "*.ipynb" -type f | xargs grep -l "context_providers\|ContextProvider" 2>/dev/null

Repository: Exabyte-io/api-examples

Length of output: 138


Remove or clarify internal development notes from production notebook.

Lines 96-97 contain comments stating "no JS implementation yet", which are internal development notes about a JavaScript port. These are inappropriate in user-facing documentation and create confusion about the Python API status.

Additionally, line 106's comment "or calculate_dimensions()" suggests API uncertainty. If this reflects actual uncertainty about the correct method, verify with mat3ra-made package documentation and update the code accordingly; otherwise, remove the comment.

]
},
{
"cell_type": "markdown",
"id": "8",
"metadata": {},
"source": [
"## 5. Create workflow and set its parameters"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.standata.workflows import Workflows\n",
"from mat3ra.wode.workflows import Workflow\n",
"from mat3ra.wode.pseudopotentials import PseudopotentialEnum\n",
"\n",
"# Get Applications list (with versions, build)\n",
"# Search WF by name and and n\n",
"workflow_config = Workflows.get_by_name_first_match(\"band_structure\")\n",
"workflow = Workflow.create(workflow_config)\n",
"\n",
"# View workflow to understand its structure\n",
"visualize(workflow)\n",
"# Get workflow's specific unit that needs to be modified\n",
"unit_to_modify = workflow.get_unit_by_name(name=\"scf\", subworkflow_name=\"xxx\", order_in_subworkflow=1)\n",
"new_context = kgrid_context_provider.get_data(dimentions=[6,6,6])\n",
"unit_to_modify.context.add_context(new_context)\n",
"workflow.set_unit(unit_flowchart_id=unit_to_modify.flowchart_id, new_unit=unit_to_modify)\n",
"\n",
"workflow.set_context_providers(kpoints)\n",
"workflow.set_pseudopotential(PseudopotentialEnum.Funtional_GGA) # elements will be set automatically based on the material"
]
},
{
"cell_type": "markdown",
"id": "10",
"metadata": {},
"source": [
"## 6. Create the compute configuration"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "11",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.ide.compute import ComputeConfiguration, QueueEnum\n",
"compute_config = ComputeConfiguration(\n",
" queue = QueueEnum.OR8,\n",
" nodes = 1,\n",
" cores = 8,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "12",
"metadata": {},
"source": [
"## 7. Create the job with material and workflow configuration"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "13",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.jode.job import create_job\n",
"job = create_job(workflow=workflow, material=material, compute = compute_config, auth_config=auth_config)\n"
]
},
{
"cell_type": "markdown",
"id": "14",
"metadata": {},
"source": [
"## 8. Submit the job and monitor the status"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "15",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.prode import PropertyEnum\n",
"job.run()\n",
"job.wait_for_complete()\n",
"# job.check_status()\n",
"# job.get_current_output()"
]
},
{
"cell_type": "markdown",
"id": "16",
"metadata": {},
"source": [
"## 9. Retrieve results"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "17",
"metadata": {},
"outputs": [],
"source": [
"# AFTER Finished\n",
"# A class from Prode to handle results\n",
"results = job.get_results(PropertyEnum.BAND_GAP, PropertyEnum.BAND_STRUCTURE)"
]
},
{
"cell_type": "markdown",
"id": "18",
"metadata": {},
"source": [
"## 10. Display results"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "19",
"metadata": {},
"outputs": [],
"source": [
"# Visual library that can visualize any property defined in Prode\n",
"from mat3ra.prove import visualize_property\n",
"visualize_property(results.band_structure)\n",
"print(results.band_gap)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "20",
"metadata": {},
"outputs": [],
"source": [
"import pydot\n",
"import json\n",
"\n",
"# Example JSON data (you would load this from a file)\n",
"json_data = {\n",
" \"nodes\": [\n",
" {\"name\": \"A\", \"shape\": \"box\", \"label\": \"Start\"},\n",
" {\"name\": \"B\", \"shape\": \"box\", \"label\": \"Process 1\"},\n",
" {\"name\": \"C\", \"shape\": \"diamond\", \"label\": \"Decision\"},\n",
" {\"name\": \"D\", \"shape\": \"box\", \"label\": \"End\"}\n",
" ],\n",
" \"edges\": [\n",
" {\"source\": \"A\", \"target\": \"B\", \"label\": \"\"},\n",
" {\"source\": \"B\", \"target\": \"C\", \"label\": \"\"},\n",
" {\"source\": \"C\", \"target\": \"D\", \"label\": \"Yes\"},\n",
" {\"source\": \"C\", \"target\": \"B\", \"label\": \"No\"}\n",
" ]\n",
"}\n",
"\n",
"# Create a new directed graph\n",
"dot_graph = pydot.Dot(\"my_flowchart\", graph_type=\"digraph\")\n",
"\n",
"# Add nodes\n",
"for node_data in json_data[\"nodes\"]:\n",
" node = pydot.Node(node_data[\"name\"], shape=node_data[\"shape\"], label=node_data[\"label\"])\n",
" dot_graph.add_node(node)\n",
"\n",
"# Add edges\n",
"for edge_data in json_data[\"edges\"]:\n",
" edge = pydot.Edge(edge_data[\"source\"], edge_data[\"target\"], label=edge_data[\"label\"])\n",
" dot_graph.add_edge(edge)\n",
"\n",
"# Save the flowchart as a PNG\n",
"dot_graph.write_png(\"flowchart.png\")\n",
"print(\"Flowchart rendered to flowchart.png\")\n"
]
Comment on lines 289 to 381
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove unrelated pydot flowchart code.

This code cell appears to be test or example code for creating flowcharts with pydot, which is completely unrelated to the bandgap calculation workflow demonstrated in this notebook. It should be removed to maintain focus and clarity.

If flowchart visualization of the workflow is intended, it should be integrated with the actual workflow object created in earlier cells, not use hardcoded JSON data.

🤖 Prompt for AI Agents
In other/materials_designer/specific_examples/run_bandgap_workflow.ipynb around
lines 253 to 295, remove the unrelated pydot flowchart example cell that uses
hardcoded JSON (nodes/edges) because it is not part of the bandgap workflow;
either delete the entire cell or replace it with code that integrates a
visualization using the actual workflow object from earlier cells (e.g., build
the graph from the real workflow data structure and render that), ensuring no
stray test/example pydot JSON remains in the notebook.

},
{
"cell_type": "code",
"execution_count": null,
"id": "21",
"metadata": {},
"outputs": [],
"source": []
}
],
"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
}