Skip to content

feature/SOF 7901#318

Merged
VsevolodX merged 15 commits into
mainfrom
feature/SOF-7901
May 20, 2026
Merged

feature/SOF 7901#318
VsevolodX merged 15 commits into
mainfrom
feature/SOF-7901

Conversation

@VsevolodX
Copy link
Copy Markdown
Member

@VsevolodX VsevolodX commented May 18, 2026

  • chore: update README
  • update: move mace model getter
  • update: use mace mp switch

Summary by CodeRabbit

  • New Features

    • Selectable MACE foundation model for local MLFF pre-relaxation with a Pyodide-compatible loader
    • Real-time relaxation progress and energy visualization callback
  • Documentation

    • Added “Pre-relaxation with MLFF” subsection to relaxation workflow docs
  • Chores

    • Broadened notebook pre-commit processing and normalized notebook metadata; cleaned up dependency ordering in project config
  • UX

    • Improved device authentication UI with a fallback verification link

Review Change Stack

@review-notebook-app
Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 328814b6-c50d-4e7a-a77b-9ff212890049

📥 Commits

Reviewing files that changed from the base of the PR and between 3c8544a and 20c8f97.

📒 Files selected for processing (7)
  • other/experiments/create_interface_with_min_energy_by_miller_indices.ipynb
  • other/experiments/create_interface_with_relaxation_matgl_m3gnet.ipynb
  • other/experiments/jarvis/import_material_from_jarvis_db_entry.ipynb
  • other/experiments/jarvis/run_job_using_material_from_jarvis_db.ipynb
  • other/experiments/mtrsm/calculate_energy_for_vacancy_mattersim.ipynb
  • other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb
  • pyproject.toml
✅ Files skipped from review due to trivial changes (6)
  • pyproject.toml
  • other/experiments/create_interface_with_relaxation_matgl_m3gnet.ipynb
  • other/experiments/jarvis/run_job_using_material_from_jarvis_db.ipynb
  • other/experiments/create_interface_with_min_energy_by_miller_indices.ipynb
  • other/experiments/jarvis/import_material_from_jarvis_db_entry.ipynb
  • other/experiments/mtrsm/calculate_energy_for_vacancy_mattersim.ipynb
🚧 Files skipped from review as they are similar to previous changes (1)
  • other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb

📝 Walkthrough

Walkthrough

This PR adds a Pyodide-compatible MACE model loader, parameterizes MACE model selection in JupyterLite notebooks, expands pre-commit notebook coverage, adds Plotly progress and device-flow UI tweaks, and delivers a full local MACE-MP relaxation workflow notebook integrating auth, relaxation, analysis, and optional persistence.

Changes

MACE Pyodide Integration and JupyterLite Updates

Layer / File(s) Summary
Pyodide MACE model loading utility
src/py/mat3ra/notebooks_utils/pyodide/packages/mace.py
MODEL_PATHS_MAP maps model names (small, medium, large) to /drive/packages/models/ paths. get_mace_model_pyodide() validates model names and returns an MACECalculator configured with resolved path, dispersion, default_dtype, device, and **kwargs.
JupyterLite notebook parameterization and relaxation
other/experiments/jupyterlite/relax_structure_with_mace.ipynb
Replaces notebook-local MODEL_PATHS_MAP with MACE_MODEL parameter; relaxation cell now selects mace_mp by MACE_MODEL with dispersion=True, swapping to get_mace_model_pyodide in Pyodide. Notebook cell ids/installation ordering updated.
Pre-commit hook pattern update
.pre-commit-config.yaml
Expands nbstripout hook file glob to include other/experiments/**/*.ipynb in addition to other/materials_designer/**/*.ipynb.

Supporting Library Enhancements

Layer / File(s) Summary
Plotly progress callback for ASE dynamics
src/py/mat3ra/notebooks_utils/ipython/plot/_plotly.py
Docstring for create_update_callback now specifies ASE Dynamics object; new progress_callback() builds a real-time Plotly steps/values figure and returns an update callable for live energy tracking.
OIDC device flow UI enhancement
src/py/mat3ra/notebooks_utils/ipython/ui.py
show_device_flow_popup now renders the "Enter this code" line inside the styled HTML and adds a fallback anchor to verification_uri_complete.
Workflows introduction table of contents
other/materials_designer/workflows/Introduction.ipynb
Adds "3.2. Pre-relaxation with MLFF (MACE)" entry linking to local/relaxation_mlff_mace.ipynb.

New Relax Structure (MACE-MP) Notebook

Layer / File(s) Summary
Notebook introduction and environment setup
other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb (lines 1–76)
Defines usage, upload folder, material lookup, relaxed naming, FMAX, and MACE preset settings (model, dispersion, dtype, device).
Platform authentication and account selection
other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb (lines 77–178)
Adds OIDC authenticate(), APIClient init, account listing, and optional organization override to select ACCOUNT_ID.
Material loading and input persistence
other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb (lines 179–227)
Resolves material via platform search or local uploads, visualizes input, and persists canonical original via get_or_create_material.
MACE-MP calculator construction
other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb (lines 228–287)
Constructs ASE calculator using MACE-MP; uses Pyodide conditional to call get_mace_model_pyodide when needed, passing dispersion/dtype/device.
ASE relaxation with real-time progress tracking
other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb (lines 288–313)
Converts to ASE atoms, sets calculator, instantiates BFGS optimizer, registers progress_callback on total energy, and runs optimization with configured FMAX.
Energy calculation and extraction
other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb (lines 314–344)
Computes and prints pre- and post-relax energies by converting and setting calculators as needed.
Structure visualization and interlayer distance analysis
other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb (lines 345–383)
Converts ASE outputs to Material objects, names original vs relaxed, visualizes both, and computes interlayer distances.
Relaxed structure persistence
other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb (lines 384–431)
Attaches relaxation metadata, clears basis labels, persists relaxed geometry via get_or_create_material (deduplication), and finalizes references and notebook metadata.

Sequence Diagram(s)

sequenceDiagram
  participant Notebook as relax_structure_with_mace.ipynb
  participant Helper as get_mace_model_pyodide
  participant ModelMap as MODEL_PATHS_MAP
  participant mace_mp as mace_mp (import)
  participant Calculator as MACECalculator
  Notebook->>mace_mp: import using MACE_MODEL (non-Pyodide)
  Note right of mace_mp: returns mace_mp factory
  Notebook->>Helper: request(model=MACE_MODEL, dispersion=True) (Pyodide path)
  Helper->>ModelMap: validate model name
  ModelMap-->>Helper: model_path
  Helper->>Calculator: construct MACECalculator(model_path, dispersion, dtype, device)
  Calculator-->>Helper: configured_calculator
  Helper-->>Notebook: calculator instance
Loading

Estimated code review effort:
🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • timurbazhirov

Poem

🐰 A rabbit hops through Pyodide paths,
Mapping MACE models, doing the maths—
BFGS nudges atoms, Plotly hums in time,
Auth and saves keep the flow sublime,
Relaxed structures gleam — a tidy rhyme!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'feature/SOF 7901' is vague and does not clearly describe the main changes in the pull request, which involve adding MACE model selection, updating relaxation workflows, and integrating Pyodide support. Provide a descriptive title that summarizes the main feature or change, such as 'Add MACE model selection and Pyodide support for structure relaxation' or similar.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/SOF-7901

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Ruff (0.15.13)
other/experiments/jarvis/import_material_from_jarvis_db_entry.ipynb

Unexpected end of JSON input

other/experiments/mtrsm/calculate_energy_for_vacancy_mattersim.ipynb

Unexpected end of JSON input

other/experiments/jarvis/run_job_using_material_from_jarvis_db.ipynb

Unexpected end of JSON input

  • 3 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/py/mat3ra/notebooks_utils/pyodide/packages/mace.py`:
- Around line 10-14: The function get_mace_model_pyodide currently defines its
first parameter as model_name which mismatches callers expecting model and will
raise a TypeError; rename the parameter model_name to model (and update any
internal references like MODEL_PATHS_MAP lookup and the variable used to build
model_path) so the signature is def get_mace_model_pyodide(model: str,
dispersion=False, default_dtype="float32", device="cpu") and it still returns
MACECalculator(model_path=model_path, ...); ensure any local variable names and
docstring/comments reflect the new parameter name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ecdfea09-ffe8-4c9d-a7ef-09307f6cffe6

📥 Commits

Reviewing files that changed from the base of the PR and between f828635 and 51b2038.

📒 Files selected for processing (2)
  • other/experiments/jupyterlite/relax_structure_with_mace.ipynb
  • src/py/mat3ra/notebooks_utils/pyodide/packages/mace.py

Comment thread src/py/mat3ra/notebooks_utils/pyodide/packages/mace.py Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
other/experiments/jupyterlite/relax_structure_with_mace.ipynb (1)

150-151: ⚡ Quick win

API parameters are compatible; consider clarifying variable naming to avoid shadowing.

The conditional swap works correctly—get_mace_model_pyodide accepts all the parameters being passed (model, dispersion, default_dtype, device). The parameter names align exactly with the function signature.

For improved readability, consider using a distinct variable name instead of shadowing the mace_mp import:

♻️ Suggested refactor
-mace_mp = mace_mp if not is_pyodide_environment() else get_mace_model_pyodide
-calculator = mace_mp(model=MACE_MODEL, dispersion=True, default_dtype="float32", device="cpu")
+model_factory = get_mace_model_pyodide if is_pyodide_environment() else mace_mp
+calculator = model_factory(model=MACE_MODEL, dispersion=True, default_dtype="float32", device="cpu")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/experiments/jupyterlite/relax_structure_with_mace.ipynb` around lines
150 - 151, The current code conditionally reassigns the imported symbol mace_mp
to get_mace_model_pyodide which shadows the original import; change the
conditional to produce a new factory name (e.g., mace_factory or
mace_constructor) instead of overwriting mace_mp, then instantiate the
calculator via that factory (pass MACE_MODEL, dispersion=True,
default_dtype="float32", device="cpu") to preserve clarity and avoid shadowing
the mace_mp import and keep usage consistent where calculator is created.
other/materials_designer/workflows/relax_structure_mlp.ipynb (1)

284-284: ⚡ Quick win

Replace deprecated set_calculator() with direct .calc property assignment.

ASE deprecated set_calculator() in version 3.20.0 in favor of direct property assignment. Update all three occurrences in this notebook:

♻️ Proposed fixes
-atoms_relaxed.set_calculator(calculator)
+atoms_relaxed.calc = calculator
-ase_original_structure.set_calculator(calculator)
+ase_original_structure.calc = calculator
-atoms.set_calculator(calc)
+atoms.calc = calc
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/relax_structure_mlp.ipynb` at line 284,
Replace the deprecated set_calculator call with direct calculator property
assignment: locate each occurrence of atoms_relaxed.set_calculator(calculator)
(three places in this notebook) and change them to assign the calculator to the
.calc property (atoms_relaxed.calc = calculator) so ASE 3.20+ uses the supported
API.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@other/materials_designer/workflows/relax_structure_mlp.ipynb`:
- Around line 413-419: The computation of effective_delta_relaxed can raise
ZeroDivisionError if any of get_global_number_of_atoms() returns 0 (n_interface,
n_substrate, or n_layer); add a guard before performing the divisions in the
block that computes effective_delta_relaxed: check n_interface, n_substrate and
n_layer for zero and handle explicitly (for example, raise a clear ValueError
mentioning which tag/part has zero atoms or return/assign NaN) so the code using
substrate_relaxed, layer_relaxed and the effective_delta_relaxed calculation
fails with an informative message instead of a ZeroDivisionError.
- Line 271: Three calls to the deprecated ASE method set_calculator() must be
replaced with direct assignment to the .calc attribute: find each occurrence of
set_calculator(calc) (e.g., atoms.set_calculator(calc) or
structure.set_calculator(mace_calc)) in this notebook (likely in
relax_structure_mlp or related cell functions) and change them to assign the
calculator object to the .calc attribute (atoms.calc = calc or structure.calc =
mace_calc); leave the calculator object creation (e.g., get_mace_model_pyodide
or any MACE/ASE calculator constructors) untouched and only change the setter
calls to the .calc assignment so the code is compatible with ASE 3.20+.

---

Nitpick comments:
In `@other/experiments/jupyterlite/relax_structure_with_mace.ipynb`:
- Around line 150-151: The current code conditionally reassigns the imported
symbol mace_mp to get_mace_model_pyodide which shadows the original import;
change the conditional to produce a new factory name (e.g., mace_factory or
mace_constructor) instead of overwriting mace_mp, then instantiate the
calculator via that factory (pass MACE_MODEL, dispersion=True,
default_dtype="float32", device="cpu") to preserve clarity and avoid shadowing
the mace_mp import and keep usage consistent where calculator is created.

In `@other/materials_designer/workflows/relax_structure_mlp.ipynb`:
- Line 284: Replace the deprecated set_calculator call with direct calculator
property assignment: locate each occurrence of
atoms_relaxed.set_calculator(calculator) (three places in this notebook) and
change them to assign the calculator to the .calc property (atoms_relaxed.calc =
calculator) so ASE 3.20+ uses the supported API.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d5e630e1-60d5-42e6-999f-0d31e40b0b1a

📥 Commits

Reviewing files that changed from the base of the PR and between 51b2038 and 7101d86.

📒 Files selected for processing (4)
  • .pre-commit-config.yaml
  • other/experiments/jupyterlite/relax_structure_with_mace.ipynb
  • other/materials_designer/workflows/relax_structure_mlp.ipynb
  • src/py/mat3ra/notebooks_utils/pyodide/packages/mace.py
✅ Files skipped from review due to trivial changes (1)
  • .pre-commit-config.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/py/mat3ra/notebooks_utils/pyodide/packages/mace.py

"source": [
"from mat3ra.notebooks_utils.ipython.plot._plotly import create_realtime_plot, create_update_callback\n",
"from mat3ra.notebooks_utils.primitive.environment import is_pyodide_environment\n",
"from mat3ra.notebooks_utils.pyodide.packages.mace import get_mace_model_pyodide\n",
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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if get_mace_model_pyodide has Pyodide-specific dependencies
fd -t f 'mace.py' --exec cat {} \; | head -50

Repository: Exabyte-io/api-examples

Length of output: 795


🏁 Script executed:

#!/bin/bash
# Extract the notebook JSON and look at the code around lines 271
# First, check the file structure
file other/materials_designer/workflows/relax_structure_mlp.ipynb

# Get the file size to determine how to read it
wc -l other/materials_designer/workflows/relax_structure_mlp.ipynb

Repository: Exabyte-io/api-examples

Length of output: 193


🏁 Script executed:

#!/bin/bash
# Read the notebook file (it's JSON) and extract relevant cells
# Look for the import statement and its context
cat other/materials_designer/workflows/relax_structure_mlp.ipynb | python <<'EOF'
import json
import sys

data = json.load(sys.stdin)
cells = data.get('cells', [])

# Look for cells containing the get_mace_model_pyodide import
for i, cell in enumerate(cells):
    if cell.get('cell_type') == 'code':
        source = ''.join(cell.get('source', []))
        if 'get_mace_model_pyodide' in source or 'mace_mp' in source:
            print(f"=== CELL {i} ===")
            print(source)
            print()
EOF

Repository: Exabyte-io/api-examples

Length of output: 788


🌐 Web query:

ASE calculator assignment deprecated set_calculator method

💡 Result:

In the Atomic Simulation Environment (ASE), the set_calculator method has been deprecated since version 3.20.0 [1]. Users are advised to use the.calc attribute directly to attach or update a calculator on an Atoms object [1][2]. To attach a calculator, you should assign it to the calc property: atoms.calc = calculator Similarly, to retrieve the currently attached calculator, you should access the.calc property: calculator = atoms.calc This change was implemented to simplify the interface by treating the calculator as a property of the Atoms object rather than requiring explicit method calls [3][1]. Using the.calc attribute is the standard, recommended approach in modern versions of ASE [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
# Try a different approach - use jq to parse the notebook
# Extract cells that contain 'get_mace_model_pyodide' or 'mace_mp'
jq -r '.cells[] | select(.cell_type == "code") | select((.source | join("")) | contains("get_mace_model_pyodide") or contains("mace_mp")) | .source | join("")' other/materials_designer/workflows/relax_structure_mlp.ipynb

Repository: Exabyte-io/api-examples

Length of output: 1516


🏁 Script executed:

#!/bin/bash
# Check if the pyodide packages module exists and what's in it
fd -t d 'pyodide' other/materials_designer/ --exec find {} -type f -name '*.py' \;

# Also search for how this module is imported elsewhere
rg 'from mat3ra.notebooks_utils.pyodide' --type py
rg 'from mat3ra.notebooks_utils.pyodide' --type ipynb

Repository: Exabyte-io/api-examples

Length of output: 213


🏁 Script executed:

#!/bin/bash
# Check the structure of mat3ra packages
fd -type f -path '*/mat3ra/notebooks_utils/*' | head -20

Repository: Exabyte-io/api-examples

Length of output: 238


🏁 Script executed:

#!/bin/bash
# Search for other instances of set_calculator in the repository
rg 'set_calculator' --type ipynb -A 2 -B 2

Repository: Exabyte-io/api-examples

Length of output: 97


🏁 Script executed:

#!/bin/bash
# Search for set_calculator in all files (not just by type)
rg 'set_calculator' -A 2 -B 2

Repository: Exabyte-io/api-examples

Length of output: 9284


🏁 Script executed:

#!/bin/bash
# Look for pyodide imports in Python files and notebooks
rg 'from mat3ra.notebooks_utils.pyodide' -A 2 -B 2

Repository: Exabyte-io/api-examples

Length of output: 3700


🏁 Script executed:

#!/bin/bash
# Check how the pyodide module is structured in mat3ra
fd 'pyodide' -type d

Repository: Exabyte-io/api-examples

Length of output: 238


🏁 Script executed:

#!/bin/bash
# Search for how is_pyodide_environment is used with imports
rg 'is_pyodide_environment' -A 5 -B 2

Repository: Exabyte-io/api-examples

Length of output: 8276


🏁 Script executed:

#!/bin/bash
# Search for the definition of pyodide packages modules
fd 'pyodide' --type d | head -10

# Look for mace.py in pyodide structure
find . -path '*/pyodide/packages/mace.py' -o -path '*/pyodide/packages/mace/*'

Repository: Exabyte-io/api-examples

Length of output: 163


🏁 Script executed:

#!/bin/bash
# Check if mat3ra.notebooks_utils.pyodide is a real importable module
rg 'def get_mace_model_pyodide' -B 5 -A 10

Repository: Exabyte-io/api-examples

Length of output: 1305


🏁 Script executed:

#!/bin/bash
# Look at the structure - where are pyodide packages defined?
rg 'packages.*mace' | grep -E '(def|import|__init__)' | head -20

Repository: Exabyte-io/api-examples

Length of output: 368


🏁 Script executed:

#!/bin/bash
# Verify that set_calculator appears exactly 3 times in the notebook
rg 'set_calculator' other/materials_designer/workflows/relax_structure_mlp.ipynb | wc -l

Repository: Exabyte-io/api-examples

Length of output: 69


🏁 Script executed:

#!/bin/bash
# Get context around each set_calculator call in the notebook
rg 'set_calculator' other/materials_designer/workflows/relax_structure_mlp.ipynb -B 1 -A 1

Repository: Exabyte-io/api-examples

Length of output: 486


Replace set_calculator() with direct .calc assignment (ASE 3.20+ deprecation).

ASE has deprecated set_calculator() in favor of direct attribute assignment. Update the three occurrences:

Fix: Use `.calc` instead of `set_calculator()`
- atoms_relaxed.set_calculator(calculator)
+ atoms_relaxed.calc = calculator
- ase_original_structure.set_calculator(calculator)
+ ase_original_structure.calc = calculator
  def calculate_energy(atoms, calc):
-     atoms.set_calculator(calc)
+     atoms.calc = calc
      return atoms.get_total_energy()

The import of get_mace_model_pyodide is safe—the module exists in the codebase and is importable in all environments.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/relax_structure_mlp.ipynb` at line 271,
Three calls to the deprecated ASE method set_calculator() must be replaced with
direct assignment to the .calc attribute: find each occurrence of
set_calculator(calc) (e.g., atoms.set_calculator(calc) or
structure.set_calculator(mace_calc)) in this notebook (likely in
relax_structure_mlp or related cell functions) and change them to assign the
calculator object to the .calc attribute (atoms.calc = calc or structure.calc =
mace_calc); leave the calculator object creation (e.g., get_mace_model_pyodide
or any MACE/ASE calculator constructors) untouched and only change the setter
calls to the .calc assignment so the code is compatible with ASE 3.20+.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb`:
- Around line 198-200: The code assumes platform_matches has at least one
element when using platform_matches[0] during Material creation; if
load_material_from_folder(FOLDER, MATERIAL_NAME) returns falsy and
client.materials.list(...) yields an empty list this raises IndexError. Fix by
checking platform_matches for truthiness before indexing: if platform_matches is
non-empty use Material.create(platform_matches[0]), otherwise handle the empty
case (e.g., raise a clear ValueError/RuntimeError mentioning MATERIAL_NAME and
ACCOUNT_ID or create a new standalone Material) so the code never directly
indexes platform_matches when it may be empty.

In `@src/py/mat3ra/notebooks_utils/ipython/ui.py`:
- Around line 178-179: The anchor tag built using verification_uri_complete in
src/py/mat3ra/notebooks_utils/ipython/ui.py opens a new tab with target='_blank'
but lacks rel='noopener noreferrer'; update the HTML string that constructs the
link (the f-string containing verification_uri_complete and "Click here if the
browser tab did not open automatically") to add rel="noopener noreferrer" to the
<a> tag to mitigate window.opener/security risks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 89d1fed3-8966-4b48-a810-70cfbaee992e

📥 Commits

Reviewing files that changed from the base of the PR and between 7101d86 and cb79c41.

📒 Files selected for processing (4)
  • other/materials_designer/workflows/Introduction.ipynb
  • other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb
  • src/py/mat3ra/notebooks_utils/ipython/plot/_plotly.py
  • src/py/mat3ra/notebooks_utils/ipython/ui.py
✅ Files skipped from review due to trivial changes (1)
  • other/materials_designer/workflows/Introduction.ipynb

Comment on lines +198 to +200
"platform_matches = client.materials.list({\"name\": MATERIAL_NAME, \"owner._id\": ACCOUNT_ID})\n",
"material = load_material_from_folder(FOLDER, MATERIAL_NAME) or Material.create(platform_matches[0])\n",
"\n",
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 | 🟠 Major | ⚡ Quick win

Handle empty platform search results before indexing.

Line 199 can crash with IndexError when local load fails and platform_matches is empty.

Suggested fix
 platform_matches = client.materials.list({"name": MATERIAL_NAME, "owner._id": ACCOUNT_ID})
-material = load_material_from_folder(FOLDER, MATERIAL_NAME) or Material.create(platform_matches[0])
+material = load_material_from_folder(FOLDER, MATERIAL_NAME)
+if material is None:
+    if not platform_matches:
+        raise ValueError(
+            f'No material named "{MATERIAL_NAME}" found in "{FOLDER}" or in account "{ACCOUNT_ID}".'
+        )
+    material = Material.create(platform_matches[0])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@other/materials_designer/workflows/local/relaxation_mlff_mace.ipynb` around
lines 198 - 200, The code assumes platform_matches has at least one element when
using platform_matches[0] during Material creation; if
load_material_from_folder(FOLDER, MATERIAL_NAME) returns falsy and
client.materials.list(...) yields an empty list this raises IndexError. Fix by
checking platform_matches for truthiness before indexing: if platform_matches is
non-empty use Material.create(platform_matches[0]), otherwise handle the empty
case (e.g., raise a clear ValueError/RuntimeError mentioning MATERIAL_NAME and
ACCOUNT_ID or create a new standalone Material) so the code never directly
indexes platform_matches when it may be empty.

Comment on lines +178 to +179
f"<a href='{verification_uri_complete}' target='_blank' style='color: #1976d2;'>"
f"Click here if the browser tab did not open automatically</a>"
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 | 🟡 Minor | ⚡ Quick win

Add rel="noopener noreferrer" to the anchor tag.

When using target='_blank', it's a security best practice to include rel="noopener noreferrer" to prevent the opened page from accessing the window.opener property. While the risk is minimal in this OIDC context (the verification URI comes from a trusted identity provider), this attribute provides defense-in-depth protection.

🔒 Proposed fix
-f"<a href='{verification_uri_complete}' target='_blank' style='color: `#1976d2`;'>"
+f"<a href='{verification_uri_complete}' target='_blank' rel='noopener noreferrer' style='color: `#1976d2`;'>"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/py/mat3ra/notebooks_utils/ipython/ui.py` around lines 178 - 179, The
anchor tag built using verification_uri_complete in
src/py/mat3ra/notebooks_utils/ipython/ui.py opens a new tab with target='_blank'
but lacks rel='noopener noreferrer'; update the HTML string that constructs the
link (the f-string containing verification_uri_complete and "Click here if the
browser tab did not open automatically") to add rel="noopener noreferrer" to the
<a> tag to mitigate window.opener/security risks.

@Exabyte-io Exabyte-io deleted a comment from coderabbitai Bot May 19, 2026
@VsevolodX VsevolodX merged commit 19f57a8 into main May 20, 2026
15 checks passed
@VsevolodX VsevolodX deleted the feature/SOF-7901 branch May 20, 2026 00:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants