diff --git a/other/materials_designer/workflows/band_gap.ipynb b/other/materials_designer/workflows/band_gap.ipynb
index 055199b9..b2c099b0 100644
--- a/other/materials_designer/workflows/band_gap.ipynb
+++ b/other/materials_designer/workflows/band_gap.ipynb
@@ -5,19 +5,27 @@
"id": "0",
"metadata": {},
"source": [
- "# Bandgap Workflow Example\n",
+ "# Band Gap\n",
"\n",
- "This notebook demonstrates how to build and run a bandgap calculation workflow for materials using the Mat3ra API. The example uses Silicon as the target material and shows how to configure DFT calculations with custom model parameters and k-grids.\n",
+ "Calculate the electronic band gap of a material using a DFT workflow on the Mat3ra platform.\n",
"\n",
- "## Process Overview\n",
- "1. Set up environment and parameters\n",
- "2. Authenticate and initialize API client\n",
- "3. Create and save material to the platform\n",
- "4. Create workflow configuration with relaxation and band structure calculations\n",
- "5. Configure compute resources\n",
- "6. Create and submit job\n",
- "7. Monitor job execution\n",
- "8. Retrieve and display bandgap results"
+ "
Usage
\n",
+ "\n",
+ "1. Set material and calculation parameters in cells 1.2 and 1.3 below (or use the default values).\n",
+ "1. Click \"Run\" > \"Run All\" to run all cells.\n",
+ "1. Wait for the job to complete.\n",
+ "1. Scroll down to view the result.\n",
+ "\n",
+ "## Summary\n",
+ "\n",
+ "1. Set up the environment and parameters: install packages (JupyterLite only) and configure parameters for material, workflow, compute resources, and job.\n",
+ "1. Authenticate and initialize API client: authenticate via browser, initialize the client, then select account and project.\n",
+ "1. Create material: materials are read from the `../uploads` folder — place files there manually or run a material creation notebook first. If the material is not found by name, Standata is used as a fallback. The material is then saved to the platform.\n",
+ "1. Configure workflow: select application, load band gap workflow from Standata, optionally add relaxation, set model and computational parameters, and save the workflow.\n",
+ "1. Configure compute: get list of clusters and create compute configuration with selected cluster, queue, and number of processors.\n",
+ "1. Create the job with material and workflow configuration: assemble the job from material, workflow, project, and compute configuration.\n",
+ "1. Submit the job and monitor the status: submit the job and wait for completion.\n",
+ "1. Retrieve results: get and display the band gap."
]
},
{
@@ -25,7 +33,8 @@
"id": "1",
"metadata": {},
"source": [
- "## 1. Set up the environment and parameters"
+ "## 1. Set up the environment and parameters\n",
+ "### 1.1. Install packages (JupyterLite)"
]
},
{
@@ -34,113 +43,151 @@
"id": "2",
"metadata": {},
"outputs": [],
+ "source": [
+ "import sys\n",
+ "\n",
+ "if sys.platform == \"emscripten\":\n",
+ " import micropip\n",
+ "\n",
+ " await micropip.install(\"mat3ra-api-examples\", deps=False)\n",
+ " await micropip.install(\"mat3ra-utils\")\n",
+ " from mat3ra.utils.jupyterlite.packages import install_packages\n",
+ "\n",
+ " await install_packages(\"api_examples\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3",
+ "metadata": {},
+ "source": [
+ "### 1.2. Set parameters"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4",
+ "metadata": {},
+ "outputs": [],
"source": [
"from datetime import datetime\n",
+ "from mat3ra.ide.compute import QueueName\n",
"\n",
- "# Material parameters\n",
+ "# 2. Auth and organization parameters\n",
+ "ORGANIZATION_NAME = None\n",
+ "\n",
+ "# 3. Material parameters\n",
"FOLDER = \"../uploads\"\n",
"MATERIAL_NAME = \"Silicon\"\n",
"\n",
- "# Workflow parameters\n",
- "WORKFLOW_SEARCH_TERM = \"band_gap.json\"\n",
- "MY_WORKFLOW_NAME = \"Band Gap Calculation Workflow\"\n",
- "ADD_RELAXATION = True # Whether to add relaxation subworkflow before band structure calculation\n",
+ "# 4. Workflow parameters\n",
+ "# Options: \"band_gap\" / \"band_gap_dos_hse\"\n",
+ "CALCULATION_TYPE = \"band_gap\"\n",
"\n",
- "# Model parameters\n",
- "MODEL_TYPE = \"dft\"\n",
- "MODEL_SUBTYPE = \"lda\" # or \"gga\"\n",
- "MODEL_FUNCTIONAL = \"pz\" # for lda: pz, for gga: pbe\n",
+ "APPLICATION_NAME = \"espresso\"\n",
+ "ADD_RELAXATION = False\n",
"\n",
- "# K-grid parameters\n",
- "RELAXATION_KGRID = [1, 2, 3] # k-grid for relaxation\n",
- "SCF_KGRID = [1, 1, 1] # k-grid for SCF calculation\n",
- "NSCF_KGRID = [1, 1, 1] # k-grid for NSCF calculation\n",
+ "WORKFLOW_SEARCH_TERM = f\"{CALCULATION_TYPE}.json\"\n",
+ "MY_WORKFLOW_NAME = CALCULATION_TYPE.replace(\"_\", \" \").title() + (\" (relax)\" if ADD_RELAXATION else \"\")\n",
"\n",
- "# Job parameters\n",
- "timestamp = datetime.now().strftime(\"%Y-%m-%d %H:%M\")\n",
- "JOB_NAME = f\"Band Gap {timestamp}\"\n",
+ "# Model parameters\n",
+ "MODEL_SUBTYPE = \"gga\" # or \"lda\"\n",
"\n",
- "POLL_INTERVAL = 30 # seconds\n",
+ "# 5. Compute parameters\n",
+ "CLUSTER_NAME = None # specify full or partial name i.e. \"cluster-001\" to select\n",
+ "QUEUE_NAME = QueueName.D\n",
+ "PPN = 1\n",
"\n",
- "# Set organization name to use it as the owner for materials and job created here, otherwise your personal account is used\n",
- "ORGANIZATION_NAME = None\n"
+ "# 6. Job parameters\n",
+ "timestamp = datetime.now().strftime(\"%Y-%m-%d %H:%M\")\n",
+ "POLL_INTERVAL = 30 # seconds"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5",
+ "metadata": {},
+ "source": [
+ "### 1.3. Set specific band gap parameters"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "3",
+ "id": "6",
"metadata": {},
"outputs": [],
"source": [
- "import sys\n",
+ "# Method parameters\n",
+ "PSEUDOPOTENTIAL_TYPE = \"us\" # \"us\" (ultrasoft), \"nc\" (norm-conserving), \"paw\"\n",
+ "FUNCTIONAL = \"pbe\" # for lda: \"pz\"; for gga: \"pbe\", \"pbesol\"\n",
"\n",
- "if sys.platform == \"emscripten\":\n",
- " import micropip\n",
- "\n",
- " await micropip.install(\"mat3ra-api-examples\", deps=False)\n",
- " await micropip.install(\"mat3ra-utils\")\n",
- " from mat3ra.utils.jupyterlite.packages import install_packages\n",
+ "# K-grids\n",
+ "RELAXATION_KGRID = None # e.g. [4, 4, 4]\n",
+ "SCF_KGRID = None # e.g. [4, 4, 4]\n",
+ "NSCF_KGRID = None # e.g. [8, 8, 8] — used for band_gap_dos_hse\n",
"\n",
- " await install_packages(\"api_examples\")"
+ "# Energy cutoffs\n",
+ "ECUTWFC = 40\n",
+ "ECUTRHO = 200"
]
},
{
"cell_type": "markdown",
- "id": "4",
+ "id": "7",
"metadata": {},
"source": [
"## 2. Authenticate and initialize API client\n",
- "### 2.1. Upon running of this cell, the browser with Mat3ra CLI login page will open."
+ "### 2.1. Authenticate\n",
+ "Authenticate in the browser and have credentials stored in environment variable \"OIDC_ACCESS_TOKEN\"."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "5",
+ "id": "8",
"metadata": {},
"outputs": [],
"source": [
"from utils.auth import authenticate\n",
"\n",
- "# Authenticate and have credentials stored in environment variables\n",
"await authenticate()"
]
},
{
"cell_type": "markdown",
- "id": "6",
+ "id": "9",
"metadata": {},
"source": [
- "### 2.2. Initialize API client\n",
- "Authorization is done via environment variables, where token is stored after authentication."
+ "### 2.2. Initialize API client"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "7",
+ "id": "10",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.api_client import APIClient\n",
"\n",
- "client = APIClient.authenticate()"
+ "client = APIClient.authenticate()\n",
+ "client"
]
},
{
"cell_type": "markdown",
- "id": "8",
+ "id": "11",
"metadata": {},
"source": [
- "### 2.3. Select account to work under\n",
- "You can choose to use your personal one or any of the organizations you belong to."
+ "### 2.3. Select account"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "9",
+ "id": "12",
"metadata": {},
"outputs": [],
"source": [
@@ -150,7 +197,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "10",
+ "id": "13",
"metadata": {},
"outputs": [],
"source": [
@@ -160,125 +207,114 @@
" selected_account = client.get_account(name=ORGANIZATION_NAME)\n",
"\n",
"ACCOUNT_ID = selected_account.id\n",
- "print(f\"✅ Selected account ID: {ACCOUNT_ID}, name: {selected_account.name}\")"
+ "print(f\"\\u2705 Selected account ID: {ACCOUNT_ID}, name: {selected_account.name}\")"
]
},
{
"cell_type": "markdown",
- "id": "11",
+ "id": "14",
"metadata": {},
"source": [
- "## 3. Create material\n",
- "### 3.1. Load material from local file (or Standata)"
+ "### 2.4. Select project"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "12",
+ "id": "15",
"metadata": {},
"outputs": [],
"source": [
- "from mat3ra.made.material import Material\n",
- "from mat3ra.standata.materials import Materials\n",
- "from utils.visualize import visualize_materials as visualize\n",
- "from utils.jupyterlite import load_material_from_folder\n",
- "\n",
- "material = load_material_from_folder(FOLDER, MATERIAL_NAME) or Material.create(\n",
- " Materials.get_by_name_first_match(MATERIAL_NAME))\n",
- "\n",
- "visualize(material)"
+ "projects = client.projects.list({\"isDefault\": True, \"owner._id\": ACCOUNT_ID})\n",
+ "project_id = projects[0][\"_id\"]\n",
+ "print(f\"\\u2705 Using project: {projects[0]['name']} ({project_id})\")"
]
},
{
"cell_type": "markdown",
- "id": "13",
+ "id": "16",
"metadata": {},
"source": [
- "### 3.2. Save material to the platform"
+ "## 3. Create material\n",
+ "### 3.1. Load material from local file (or Standata)"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "14",
+ "id": "17",
"metadata": {},
"outputs": [],
"source": [
- "from utils.generic import dict_to_namespace\n",
+ "from mat3ra.made.material import Material\n",
+ "from mat3ra.standata.materials import Materials\n",
+ "from utils.visualize import visualize_materials as visualize\n",
+ "from utils.jupyterlite import load_material_from_folder\n",
"\n",
- "material.basis.set_labels_from_list([])\n",
- "saved_material_response = client.materials.create(material.to_dict(), owner_id=ACCOUNT_ID)\n",
- "saved_material = dict_to_namespace(saved_material_response)\n",
- "print(f\"✅ Material created: {saved_material._id}\")"
+ "material = load_material_from_folder(FOLDER, MATERIAL_NAME) or Material.create(\n",
+ " Materials.get_by_name_first_match(MATERIAL_NAME))\n",
+ "\n",
+ "visualize(material)"
]
},
{
"cell_type": "markdown",
- "id": "15",
- "metadata": {
- "tags": []
- },
+ "id": "18",
+ "metadata": {},
"source": [
- "### 3.3. Get material id"
+ "### 3.2. Save material to the platform"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "16",
+ "id": "19",
"metadata": {},
"outputs": [],
"source": [
- "print(\"Material ID:\", saved_material._id)"
+ "from utils.api import get_or_create_material\n",
+ "\n",
+ "material.basis.set_labels_from_list([])\n",
+ "saved_material_response = get_or_create_material(client, material, ACCOUNT_ID)\n",
+ "saved_material = Material.create(saved_material_response)"
]
},
{
"cell_type": "markdown",
- "id": "17",
+ "id": "20",
"metadata": {},
"source": [
- "## 5. Create workflow and set its parameters\n",
- "### 5.1. Get list of applications and select one"
+ "## 4. Configure workflow\n",
+ "### 4.1. Select application"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "18",
+ "id": "21",
"metadata": {},
"outputs": [],
"source": [
"from mat3ra.standata.applications import ApplicationStandata\n",
"from mat3ra.ade.application import Application\n",
"\n",
- "apps_list = ApplicationStandata.list_all()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "19",
- "metadata": {},
- "outputs": [],
- "source": [
- "app_config = ApplicationStandata.get_by_name_first_match(\"espresso\")\n",
+ "app_config = ApplicationStandata.get_by_name_first_match(APPLICATION_NAME)\n",
"app = Application(**app_config)\n",
- "app.name"
+ "print(f\"Using application: {app.name}\")"
]
},
{
"cell_type": "markdown",
- "id": "20",
+ "id": "22",
"metadata": {},
"source": [
- "### 5.2. Create workflow from standard workflows and preview it"
+ "### 4.2. Load workflow from Standata and preview it"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "21",
+ "id": "23",
"metadata": {},
"outputs": [],
"source": [
@@ -288,62 +324,37 @@
"\n",
"workflow_config = WorkflowStandata.filter_by_application(app.name).get_by_name_first_match(WORKFLOW_SEARCH_TERM)\n",
"workflow = Workflow.create(workflow_config)\n",
+ "workflow.name = MY_WORKFLOW_NAME\n",
"\n",
"visualize_workflow(workflow)"
]
},
{
"cell_type": "markdown",
- "id": "22",
+ "id": "24",
"metadata": {},
"source": [
- "### 5.3. Add relaxation subworkflow"
+ "### 4.3. Add relaxation (optional)"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "23",
+ "id": "25",
"metadata": {},
"outputs": [],
"source": [
- "from utils.visualize import visualize_workflow\n",
- "\n",
"if ADD_RELAXATION:\n",
" workflow.add_relaxation()\n",
- " # Relaxation subworkflow is added as the first subworkflow\n",
" visualize_workflow(workflow)"
]
},
- {
- "cell_type": "markdown",
- "id": "24",
- "metadata": {},
- "source": [
- "### 5.4. Change subworkflow details (Model subtype)\n",
- "#### 5.4.1. Get available model subtypes and functionals"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "25",
- "metadata": {},
- "outputs": [],
- "source": [
- "from mat3ra.standata.model_tree import ModelTreeStandata\n",
- "\n",
- "# Change model subtype for relaxation subworkflow\n",
- "subtypes = ModelTreeStandata.get_subtypes_by_model_type(MODEL_TYPE)\n",
- "functionals = ModelTreeStandata.get_functionals_by_subtype(MODEL_TYPE, MODEL_SUBTYPE)"
- ]
- },
{
"cell_type": "markdown",
"id": "26",
"metadata": {},
"source": [
- "#### 5.4.2. Modify model in subworkflow units"
+ "### 4.4. Set Model and its parameters (physics)"
]
},
{
@@ -353,28 +364,19 @@
"metadata": {},
"outputs": [],
"source": [
- "from mat3ra.mode import Model\n",
- "\n",
- "RELAXATION_SWF_INDEX = 0 if ADD_RELAXATION else None\n",
- "BAND_GAP_SWF_INDEX = 1 if ADD_RELAXATION else 0\n",
- "\n",
- "swf_0 = workflow.subworkflows[RELAXATION_SWF_INDEX] if ADD_RELAXATION else None\n",
- "swf_1 = workflow.subworkflows[BAND_GAP_SWF_INDEX]\n",
+ "from mat3ra.standata.model_tree import ModelTreeStandata\n",
+ "from mat3ra.mode.model import Model\n",
"\n",
"model_config = ModelTreeStandata.get_model_by_parameters(\n",
- " type=MODEL_TYPE,\n",
- " subtype=MODEL_SUBTYPE,\n",
- " functional={\"slug\": MODEL_FUNCTIONAL},\n",
+ " type=\"dft\", subtype=MODEL_SUBTYPE, functional=FUNCTIONAL\n",
")\n",
+ "model_config[\"method\"] = {\"type\": \"pseudopotential\", \"subtype\": PSEUDOPOTENTIAL_TYPE}\n",
+ "model = Model.create(model_config)\n",
"\n",
- "method_config = {\"type\": \"pseudopotential\", \"subtype\": \"us\"}\n",
- "model_config[\"method\"] = method_config\n",
+ "for subworkflow in workflow.subworkflows:\n",
+ " subworkflow.model = model\n",
"\n",
- "model = Model.create(model_config)\n",
- "if ADD_RELAXATION:\n",
- " swf_0.model = model\n",
- "swf_1.model = model\n",
- "print(model)\n"
+ "visualize_workflow(workflow)"
]
},
{
@@ -382,8 +384,7 @@
"id": "28",
"metadata": {},
"source": [
- "### 5.5. Modify k-grid in subworkflow units\n",
- "#### 5.5.1. Get k-grid context"
+ "### 4.5. Modify Method (computational parameters): k-grid and cutoffs"
]
},
{
@@ -393,11 +394,36 @@
"metadata": {},
"outputs": [],
"source": [
- "from mat3ra.wode.context.providers import PointsGridDataProvider\n",
+ "from mat3ra.wode.context.providers import PlanewaveCutoffsContextProvider, PointsGridDataProvider\n",
+ "\n",
+ "bg_subworkflow = workflow.subworkflows[1 if ADD_RELAXATION else 0]\n",
+ "\n",
+ "if RELAXATION_KGRID is not None and ADD_RELAXATION:\n",
+ " unit = workflow.subworkflows[0].get_unit_by_name(name_regex=\"relax\")\n",
+ " unit.add_context(PointsGridDataProvider(dimensions=RELAXATION_KGRID, isEdited=True).yield_data())\n",
+ " workflow.subworkflows[0].set_unit(unit)\n",
"\n",
- "new_context_relax = PointsGridDataProvider(dimensions=RELAXATION_KGRID, isEdited=True).yield_data() if ADD_RELAXATION else None\n",
- "new_context_scf = PointsGridDataProvider(dimensions=SCF_KGRID, isEdited=True).yield_data()\n",
- "new_context_nscf = PointsGridDataProvider(dimensions=NSCF_KGRID, isEdited=True).yield_data()"
+ "if SCF_KGRID is not None:\n",
+ " for unit_name in [\"pw_scf\", \"pw_scf_hse\"]:\n",
+ " unit = bg_subworkflow.get_unit_by_name(name=unit_name)\n",
+ " if unit:\n",
+ " unit.add_context(PointsGridDataProvider(dimensions=SCF_KGRID, isEdited=True).yield_data())\n",
+ " bg_subworkflow.set_unit(unit)\n",
+ "\n",
+ "if NSCF_KGRID is not None:\n",
+ " unit = bg_subworkflow.get_unit_by_name(name=\"pw_nscf\")\n",
+ " if unit:\n",
+ " unit.add_context(PointsGridDataProvider(dimensions=NSCF_KGRID, isEdited=True).yield_data())\n",
+ " bg_subworkflow.set_unit(unit)\n",
+ "\n",
+ "if ECUTWFC is not None:\n",
+ " cutoffs_context = PlanewaveCutoffsContextProvider(wavefunction=ECUTWFC, density=ECUTRHO, isEdited=True).yield_data()\n",
+ " for unit_name in [\"pw_relax\", \"pw_vc-relax\", \"pw_scf\", \"pw_scf_hse\", \"pw_nscf\"]:\n",
+ " for swf in workflow.subworkflows:\n",
+ " unit = swf.get_unit_by_name(name=unit_name)\n",
+ " if unit:\n",
+ " unit.add_context(cutoffs_context)\n",
+ " swf.set_unit(unit)"
]
},
{
@@ -405,7 +431,7 @@
"id": "30",
"metadata": {},
"source": [
- "#### 5.5.3. Modify workflow units with new context"
+ "### 4.6. Preview final workflow"
]
},
{
@@ -415,26 +441,8 @@
"metadata": {},
"outputs": [],
"source": [
- "# Get workflow's specific unit that needs to be modified\n",
- "if ADD_RELAXATION:\n",
- " relaxation_subworkflow = workflow.subworkflows[RELAXATION_SWF_INDEX]\n",
- " unit_to_modify_relax = relaxation_subworkflow.get_unit_by_name(name_regex=\"relax\")\n",
- " unit_to_modify_relax.add_context(new_context_relax)\n",
- " # Set the modified unit back to the workflow\n",
- " # Option 1: direct set by unit object, replacing the existing one\n",
- " relaxation_subworkflow.set_unit(unit_to_modify_relax)\n",
- "\n",
- "band_gap_subworkflow = workflow.subworkflows[BAND_GAP_SWF_INDEX]\n",
- "unit_to_modify_scf = band_gap_subworkflow.get_unit_by_name(name=\"pw_scf\")\n",
- "unit_to_modify_scf.add_context(new_context_scf)\n",
- "unit_to_modify_nscf = band_gap_subworkflow.get_unit_by_name(name=\"pw_nscf\")\n",
- "unit_to_modify_nscf.add_context(new_context_nscf)\n",
- "\n",
- "# Option 2: set by unit flowchart id and new unit object\n",
- "band_gap_subworkflow.set_unit(unit_flowchart_id=unit_to_modify_scf.flowchart_id, new_unit=unit_to_modify_scf)\n",
- "band_gap_subworkflow.set_unit(unit_flowchart_id=unit_to_modify_nscf.flowchart_id, new_unit=unit_to_modify_nscf)\n",
- "workflow.name = workflow.name + \" (custom k-grids)\"\n",
- "visualize_workflow(workflow)"
+ "visualize_workflow(workflow)\n",
+ "workflow.to_dict()"
]
},
{
@@ -442,7 +450,7 @@
"id": "32",
"metadata": {},
"source": [
- "### 5.6. Save workflow to collection"
+ "### 4.7. Save workflow to collection"
]
},
{
@@ -452,12 +460,12 @@
"metadata": {},
"outputs": [],
"source": [
- "workflow_dict = workflow.to_dict()\n",
- "\n",
- "saved_workflow_response = client.workflows.create(workflow_dict, owner_id=ACCOUNT_ID)\n",
+ "from utils.generic import dict_to_namespace\n",
+ "from utils.api import get_or_create_workflow\n",
"\n",
- "saved_workflow = dict_to_namespace(saved_workflow_response)\n",
- "print(f\"✅ Workflow created: {saved_workflow._id}\")"
+ "saved_workflow_response = get_or_create_workflow(client, workflow, ACCOUNT_ID)\n",
+ "saved_workflow = Workflow.create(saved_workflow_response)\n",
+ "print(f\"Workflow ID: {saved_workflow.id}\")"
]
},
{
@@ -465,8 +473,8 @@
"id": "34",
"metadata": {},
"source": [
- "## 6. Create the compute configuration\n",
- "### 6.1. Get list of clusters"
+ "## 5. Create the compute configuration\n",
+ "### 5.1. Get list of clusters"
]
},
{
@@ -477,7 +485,7 @@
"outputs": [],
"source": [
"clusters = client.clusters.list()\n",
- "clusters"
+ "print(f\"Available clusters: {[c['hostname'] for c in clusters]}\")"
]
},
{
@@ -485,7 +493,7 @@
"id": "36",
"metadata": {},
"source": [
- "### 6.2. Create compute configuration for the job"
+ "### 5.2. Create compute configuration"
]
},
{
@@ -495,14 +503,19 @@
"metadata": {},
"outputs": [],
"source": [
- "from mat3ra.ide.compute import Compute, QueueName\n",
+ "from mat3ra.ide.compute import Compute\n",
+ "\n",
+ "if CLUSTER_NAME:\n",
+ " cluster = next((c for c in clusters if CLUSTER_NAME in c[\"hostname\"]), None)\n",
+ "else:\n",
+ " cluster = clusters[0]\n",
"\n",
- "cluster = clusters[0]\n",
"compute = Compute(\n",
" cluster=cluster,\n",
- " queue=QueueName.D,\n",
- " ppn=1\n",
- ")"
+ " queue=QUEUE_NAME,\n",
+ " ppn=PPN\n",
+ ")\n",
+ "print(f\"Using cluster: {compute.cluster.hostname}, queue: {QUEUE_NAME}, ppn: {PPN}\")"
]
},
{
@@ -510,8 +523,8 @@
"id": "38",
"metadata": {},
"source": [
- "## 7. Create the job with material and workflow configuration\n",
- "### 7.1. Get default project id"
+ "## 6. Create the job\n",
+ "### 6.1. Create job"
]
},
{
@@ -521,71 +534,54 @@
"metadata": {},
"outputs": [],
"source": [
- "projects = client.projects.list({\"isDefault\": True, \"owner._id\": ACCOUNT_ID})\n",
- "project_id = projects[0][\"_id\"]\n"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "40",
- "metadata": {},
- "source": [
- "### 7.2. Create job"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "41",
- "metadata": {},
- "outputs": [],
- "source": [
+ "from utils.api import create_job\n",
"from utils.visualize import display_JSON\n",
"\n",
- "material_from_collection = client.materials.get(saved_material._id)\n",
- "\n",
- "print(f\"📦 Material: {material_from_collection['_id']}\")\n",
- "print(f\"📦 Workflow: {saved_workflow._id}\")\n",
- "print(f\"📦 Project: {project_id}\")\n",
+ "print(f\"Material: {saved_material.id}\")\n",
+ "print(f\"Workflow: {saved_workflow.id}\")\n",
+ "print(f\"Project: {project_id}\")\n",
"\n",
- "job_response = client.jobs.create_by_ids(\n",
- " materials=[vars(saved_material)],\n",
- " workflow_id=saved_workflow._id,\n",
+ "job_name = MY_WORKFLOW_NAME + \" \" + saved_material.formula + \" \" + timestamp\n",
+ "job_response = create_job(\n",
+ " api_client=client,\n",
+ " materials=[saved_material],\n",
+ " workflow=workflow,\n",
" project_id=project_id,\n",
- " prefix=JOB_NAME,\n",
" owner_id=ACCOUNT_ID,\n",
+ " prefix=job_name,\n",
" compute=compute.to_dict(),\n",
")\n",
"\n",
- "job_dict = job_response[0]\n",
- "job = dict_to_namespace(job_dict)\n",
+ "job = dict_to_namespace(job_response)\n",
"job_id = job._id\n",
- "print(\"✅ Job created successfully!\")\n",
+ "print(\"\\u2705 Job created successfully!\")\n",
+ "print(f\"Job ID: {job_id}\")\n",
"display_JSON(job_response)"
]
},
{
"cell_type": "markdown",
- "id": "42",
+ "id": "40",
"metadata": {},
"source": [
- "## 8. Submit the job and monitor the status"
+ "## 7. Submit the job and monitor the status"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "43",
+ "id": "41",
"metadata": {},
"outputs": [],
"source": [
- "client.jobs.submit(job_id)"
+ "client.jobs.submit(job_id)\n",
+ "print(f\"\\u2705 Job {job_id} submitted successfully!\")"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "44",
+ "id": "42",
"metadata": {},
"outputs": [],
"source": [
@@ -596,51 +592,36 @@
},
{
"cell_type": "markdown",
- "id": "45",
+ "id": "43",
"metadata": {},
"source": [
- "## 9. Retrieve results"
+ "## 8. Retrieve and visualize results\n",
+ "### 8.1. Band Gap"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "46",
+ "id": "44",
"metadata": {},
"outputs": [],
"source": [
- "from utils.visualize import visualize_properties\n",
"from mat3ra.prode import PropertyName\n",
+ "from utils.visualize import visualize_properties\n",
"\n",
- "band_gaps_property = client.properties.get_for_job(job_id, property_name=PropertyName.non_scalar.band_gaps)\n",
- "visualize_properties(band_gaps_property, title=\"Band Gaps\")"
+ "band_gaps_data = client.properties.get_for_job(job_id, property_name=PropertyName.non_scalar.band_gaps.value)\n",
+ "visualize_properties(band_gaps_data, title=\"Band Gap\")"
]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "47",
- "metadata": {},
- "outputs": [],
- "source": []
}
],
"metadata": {
"kernelspec": {
- "display_name": ".venv-3.11.2 (3.11.2)",
+ "display_name": "Python 3",
"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.11.2"
}
},