-
Notifications
You must be signed in to change notification settings - Fork 42
Adding cleavage benchmarks #404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
vue1999
wants to merge
30
commits into
ddmms:main
Choose a base branch
from
vue1999:cleavage_benchmark
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+457
−0
Open
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
7011b8d
Adding cleavage benchmarks
vue1999 aa13732
Update ml_peg/calcs/surfaces/cleavage_energy/calc_cleavage_energy.py
vue1999 2de40cd
Update ml_peg/calcs/surfaces/cleavage_energy/calc_cleavage_energy.py
vue1999 b7bf3f5
Update ml_peg/calcs/surfaces/cleavage_energy/calc_cleavage_energy.py
vue1999 22a2d68
Update ml_peg/calcs/surfaces/cleavage_energy/calc_cleavage_energy.py
vue1999 c0b5256
Update ml_peg/analysis/surfaces/cleavage_energy/metrics.yml
vue1999 acc02ef
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 9727b82
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 c988422
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 44a633f
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 51e3400
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 152e174
Update ml_peg/app/surfaces/cleavage_energy/app_cleavage_energy.py
vue1999 fcaa3f8
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 d955056
Update ml_peg/app/surfaces/cleavage_energy/app_cleavage_energy.py
vue1999 f2bb3ca
Update ml_peg/app/surfaces/cleavage_energy/app_cleavage_energy.py
vue1999 179592e
Update ml_peg/app/surfaces/cleavage_energy/app_cleavage_energy.py
vue1999 7025768
Update ml_peg/app/surfaces/cleavage_energy/app_cleavage_energy.py
vue1999 7e8ddaa
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 a3c85b0
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 0eee54f
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 a8abb46
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 5dc9eb0
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 8f9cc86
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 20f76be
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 b106bd0
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 43ff312
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 708a4cc
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 3c2230f
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 28da106
Update ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_ener…
vue1999 96daa54
Update docs/source/user_guide/benchmarks/surfaces.rst
vue1999 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
238 changes: 238 additions & 0 deletions
238
ml_peg/analysis/surfaces/cleavage_energy/analyse_cleavage_energy.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,238 @@ | ||
| """Analyse cleavage energy benchmark.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import json | ||
| from pathlib import Path | ||
|
|
||
| import numpy as np | ||
| import pytest | ||
|
|
||
| from ml_peg.analysis.utils.decorators import build_table, plot_parity | ||
| from ml_peg.analysis.utils.utils import load_metrics_config, mae | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| from ml_peg.app import APP_ROOT | ||
| from ml_peg.calcs import CALCS_ROOT | ||
| from ml_peg.models.get_models import get_model_names | ||
| from ml_peg.models.models import current_models | ||
|
|
||
| MODELS = get_model_names(current_models) | ||
| CALC_PATH = CALCS_ROOT / "surfaces" / "cleavage_energy" / "outputs" | ||
| OUT_PATH = APP_ROOT / "data" / "surfaces" / "cleavage_energy" | ||
|
|
||
| METRICS_CONFIG_PATH = Path(__file__).with_name("metrics.yml") | ||
| DEFAULT_THRESHOLDS, DEFAULT_TOOLTIPS, DEFAULT_WEIGHTS = load_metrics_config( | ||
| METRICS_CONFIG_PATH | ||
| ) | ||
|
|
||
| EV_TO_MEV = 1000.0 | ||
|
|
||
|
|
||
| def _load_model_results(model_name: str) -> dict | None: | ||
| """ | ||
| Load the JSON energy results for a model, or None if absent. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| model_name | ||
| Name of the model whose results file to load. | ||
|
|
||
| Returns | ||
| ------- | ||
| dict | None | ||
| Parsed JSON results dictionary, or None if the file does not exist. | ||
| """ | ||
| result_file = CALC_PATH / f"{model_name}.json" | ||
| if not result_file.exists(): | ||
| return None | ||
| with open(result_file, encoding="utf-8") as f: | ||
| return json.load(f) | ||
|
|
||
|
|
||
| def system_names() -> list[str]: | ||
| """ | ||
| Get list of system identifiers from calc outputs. | ||
|
|
||
| Returns | ||
| ------- | ||
| list[str] | ||
| Sorted list of unique_id values from the first model with results. | ||
| """ | ||
| for model_name in MODELS: | ||
| data = _load_model_results(model_name) | ||
| if data is not None: | ||
| return sorted(data.keys()) | ||
| return [] | ||
|
|
||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
|
|
||
| def compute_cleavage_energy( | ||
| slab_energy: float, | ||
| bulk_energy: float, | ||
| thickness_ratio: float, | ||
| area_slab: float, | ||
| ) -> float: | ||
| """ | ||
| Compute cleavage energy from slab and bulk energies. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| slab_energy | ||
| Total energy of the slab. | ||
| bulk_energy | ||
| Total energy of the lattice-matched bulk unit cell. | ||
| thickness_ratio | ||
| Number of bulk unit cells in the slab thickness. | ||
| area_slab | ||
| Surface area of the slab in Angstrom^2. | ||
|
|
||
| Returns | ||
| ------- | ||
| float | ||
| Cleavage energy in eV/Angstrom^2. | ||
| """ | ||
| return (slab_energy - thickness_ratio * bulk_energy) / (2 * area_slab) | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| @plot_parity( | ||
| filename=OUT_PATH / "figure_cleavage_energies.json", | ||
| title="Cleavage Energies", | ||
| x_label="Predicted cleavage energy / meV/\u00c5\u00b2", | ||
| y_label="Reference cleavage energy / meV/\u00c5\u00b2", | ||
| hoverdata={ | ||
| "System": system_names(), | ||
| }, | ||
| ) | ||
| def cleavage_energies() -> dict[str, list]: | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| """ | ||
| Get cleavage energies for all systems in meV/A^2. | ||
|
|
||
| Also saves per-system errors for the distribution plot. | ||
|
|
||
| Returns | ||
| ------- | ||
| dict[str, list] | ||
| Dictionary of reference and predicted cleavage energies in meV/A^2. | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| """ | ||
| results = {"ref": []} | {mlip: [] for mlip in MODELS} | ||
| canonical_ids = None | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
|
|
||
| for model_name in MODELS: | ||
| data = _load_model_results(model_name) | ||
| if data is None: | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| continue | ||
|
|
||
| if canonical_ids is None: | ||
| canonical_ids = sorted(data.keys()) | ||
| for uid in canonical_ids: | ||
| entry = data[uid] | ||
| results["ref"].append(entry["ref_cleavage_energy"] * EV_TO_MEV) | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
|
|
||
| for uid in canonical_ids: | ||
| entry = data[uid] | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| pred_ce = ( | ||
| compute_cleavage_energy( | ||
| entry["slab_energy"], | ||
| entry["bulk_energy"], | ||
| entry["thickness_ratio"], | ||
| entry["area_slab"], | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| ) | ||
| * EV_TO_MEV | ||
| ) | ||
| results[model_name].append(pred_ce) | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
|
|
||
| return results | ||
|
|
||
|
|
||
|
vue1999 marked this conversation as resolved.
|
||
| @pytest.fixture | ||
| def cleavage_mae(cleavage_energies: dict[str, list]) -> dict[str, float]: | ||
| """ | ||
| Get mean absolute error for cleavage energies. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| cleavage_energies | ||
| Dictionary of reference and predicted cleavage energies. | ||
|
|
||
| Returns | ||
| ------- | ||
| dict[str, float] | ||
| MAE for each model. | ||
| """ | ||
| results = {} | ||
| for model_name in MODELS: | ||
| if cleavage_energies[model_name]: | ||
| results[model_name] = mae( | ||
| cleavage_energies["ref"], cleavage_energies[model_name] | ||
| ) | ||
| else: | ||
| results[model_name] = None | ||
| return results | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def cleavage_rmse(cleavage_energies: dict[str, list]) -> dict[str, float]: | ||
| """ | ||
| Get root mean squared error for cleavage energies. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| cleavage_energies | ||
| Dictionary of reference and predicted cleavage energies. | ||
|
|
||
| Returns | ||
| ------- | ||
| dict[str, float] | ||
| RMSE for each model. | ||
| """ | ||
| results = {} | ||
| for model_name in MODELS: | ||
| if cleavage_energies[model_name]: | ||
| ref = np.array(cleavage_energies["ref"]) | ||
| pred = np.array(cleavage_energies[model_name]) | ||
| results[model_name] = float(np.sqrt(np.mean((pred - ref) ** 2))) | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| else: | ||
| results[model_name] = None | ||
| return results | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| @build_table( | ||
| filename=OUT_PATH / "cleavage_energy_metrics_table.json", | ||
| metric_tooltips=DEFAULT_TOOLTIPS, | ||
| thresholds=DEFAULT_THRESHOLDS, | ||
|
vue1999 marked this conversation as resolved.
|
||
| ) | ||
| def metrics( | ||
| cleavage_mae: dict[str, float], | ||
| cleavage_rmse: dict[str, float], | ||
| ) -> dict[str, dict]: | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| """ | ||
| Get all cleavage energy metrics. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| cleavage_mae | ||
| Mean absolute errors for all models. | ||
| cleavage_rmse | ||
| Root mean squared errors for all models. | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
|
|
||
| Returns | ||
| ------- | ||
| dict[str, dict] | ||
| Metric names and values for all models. | ||
| """ | ||
| return { | ||
| "MAE": cleavage_mae, | ||
| "RMSE": cleavage_rmse, | ||
| } | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
|
|
||
|
|
||
| def test_cleavage_energy(metrics: dict[str, dict]) -> None: | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| """ | ||
| Run cleavage energy analysis. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| metrics | ||
| All cleavage energy metrics. | ||
| """ | ||
|
vue1999 marked this conversation as resolved.
|
||
| return | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| metrics: | ||
| MAE: | ||
| good: 0.0 | ||
| bad: 10.0 | ||
| unit: meV/A^2 | ||
| tooltip: Mean Absolute Error of cleavage energies | ||
| level_of_theory: PBE | ||
| RMSE: | ||
| good: 0.0 | ||
| bad: 10.0 | ||
| unit: meV/A^2 | ||
| tooltip: Root Mean Squared Error of cleavage energies | ||
| level_of_theory: PBE | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
68 changes: 68 additions & 0 deletions
68
ml_peg/app/surfaces/cleavage_energy/app_cleavage_energy.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| """Run cleavage energy app.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from dash import Dash | ||
| from dash.html import Div | ||
|
|
||
| from ml_peg.app import APP_ROOT | ||
| from ml_peg.app.base_app import BaseApp | ||
| from ml_peg.app.utils.load import read_plot | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| from ml_peg.models.get_models import get_model_names | ||
| from ml_peg.models.models import current_models | ||
|
|
||
| MODELS = get_model_names(current_models) | ||
| BENCHMARK_NAME = "Cleavage Energy" | ||
| DOCS_URL = ( | ||
| "https://ddmms.github.io/ml-peg/user_guide/benchmarks/surfaces.html#cleavage-energy" | ||
| ) | ||
| DATA_PATH = APP_ROOT / "data" / "surfaces" / "cleavage_energy" | ||
|
|
||
|
|
||
| class CleavageEnergyApp(BaseApp): | ||
| """Cleavage energy benchmark app layout and callbacks.""" | ||
|
|
||
| def register_callbacks(self) -> None: | ||
| """No interactive callbacks needed.""" | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
|
|
||
|
|
||
| def get_app() -> CleavageEnergyApp: | ||
| """ | ||
| Get cleavage energy benchmark app layout and callback registration. | ||
|
|
||
| Returns | ||
| ------- | ||
| CleavageEnergyApp | ||
| Benchmark layout and callback registration. | ||
| """ | ||
| scatter = read_plot( | ||
| DATA_PATH / "figure_cleavage_energies.json", | ||
| id=f"{BENCHMARK_NAME}-figure", | ||
| ) | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
|
|
||
| return CleavageEnergyApp( | ||
| name=BENCHMARK_NAME, | ||
| description=( | ||
| "Performance in predicting cleavage energies for " | ||
| "36,718 surface configurations." | ||
| ), | ||
| docs_url=DOCS_URL, | ||
| table_path=DATA_PATH / "cleavage_energy_metrics_table.json", | ||
| extra_components=[ | ||
| Div(scatter, style={"marginTop": "20px"}), | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| ], | ||
| ) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| full_app = Dash( | ||
| __name__, | ||
| assets_folder=DATA_PATH.parent.parent, | ||
| suppress_callback_exceptions=True, | ||
|
vue1999 marked this conversation as resolved.
Outdated
|
||
| ) | ||
|
|
||
| cleavage_energy_app = get_app() | ||
| full_app.layout = cleavage_energy_app.layout | ||
| cleavage_energy_app.register_callbacks() | ||
|
|
||
| full_app.run(port=8056, debug=True) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.