Skip to content
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

OCPCalculator to FAIRChemCalculator #722

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,19 @@ pip install -e packages/fairchem-{fairchem-package-name}
- [Installation Guide](https://fair-chem.github.io/core/install.html)

### Quick Start
Pretrained models can be used directly with ASE through our `OCPCalculator` interface:
Pretrained models can be used directly with ASE through our `FAIRChemCalculator` interface:

```python
from ase.build import fcc100, add_adsorbate, molecule
from ase.optimize import LBFGS
from fairchem.core import OCPCalculator
from fairchem.core import FAIRChemCalculator

# Set up your system as an ASE atoms object
slab = fcc100('Cu', (3, 3, 3), vacuum=8)
adsorbate = molecule("CO")
add_adsorbate(slab, adsorbate, 2.0, 'bridge')

calc = OCPCalculator(
calc = FAIRChemCalculator(
model_name="EquiformerV2-31M-S2EF-OC20-All+MD",
local_cache="pretrained_models",
cpu=False,
Expand Down
6 changes: 3 additions & 3 deletions docs/core/fine-tuning/fine-tuning-oxides.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ atoms, c['data']['total_energy'], c['data']['forces']
Next, we will create an OCP calculator that we can use to get predictions from.

```{code-cell} ipython3
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
calc = OCPCalculator(checkpoint_path=checkpoint_path, trainer='forces', cpu=False)
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, trainer='forces', cpu=False)
```

Now, we loop through each structure and accumulate the OCP predictions. Then, we plot the parity results.
Expand Down Expand Up @@ -282,7 +282,7 @@ The `best_checkpoint.pt` is the one that performs best on the validation dataset

```{code-cell} ipython3
newckpt = cpdir + '/checkpoint.pt'
newcalc = OCPCalculator(checkpoint_path=newckpt, cpu=False)
newcalc = FAIRChemCalculator(checkpoint_path=newckpt, cpu=False)
```

```{code-cell} ipython3
Expand Down
32 changes: 16 additions & 16 deletions docs/core/gotchas.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ RuntimeError: cannot reshape tensor of 0 elements into shape [0, -1] because the
The problem here is that no neighbors are found for the single atom which causes an error. This may be model dependent. There is currently no way to get atomic energies for some models.

```{code-cell} ipython3
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
HabibOmar marked this conversation as resolved.
Show resolved Hide resolved
from fairchem.core.models.model_registry import model_name_to_local_file
checkpoint_path = model_name_to_local_file('GemNet-OC-S2EFS-OC20+OC22', local_cache='/tmp/ocp_checkpoints/')
calc = OCPCalculator(checkpoint_path=checkpoint_path)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path)
```

```{code-cell} ipython3
Expand Down Expand Up @@ -82,7 +82,7 @@ from fairchem.core.models.model_registry import model_name_to_local_file
checkpoint_path = model_name_to_local_file('GemNet-OC-S2EF-OC20-All', local_cache='/tmp/ocp_checkpoints/')

with contextlib.redirect_stdout(StringIO()) as _:
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=False)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=False)



Expand All @@ -95,7 +95,7 @@ slab.get_potential_energy()
checkpoint_path = model_name_to_local_file('GemNet-OC-S2EFS-OC20+OC22', local_cache='/tmp/ocp_checkpoints/')

with contextlib.redirect_stdout(StringIO()) as _:
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=False)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=False)



Expand All @@ -108,7 +108,7 @@ slab.get_potential_energy()
checkpoint_path = model_name_to_local_file('eSCN-L4-M2-Lay12-S2EF-OC20-2M', local_cache='/tmp/ocp_checkpoints/')

with contextlib.redirect_stdout(StringIO()) as _:
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=False)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=False)

slab.set_calculator(calc)
slab.get_potential_energy()
Expand All @@ -133,7 +133,7 @@ You can ignore this warning, it is not important for predictions.
The trainer is not specified in some checkpoints, and defaults to `forces` which means energy and forces are calculated. This is the default for the ASE OCP calculator, and this warning just alerts you it is setting that.

```
WARNING:root:Unable to identify ocp trainer, defaulting to `forces`. Specify the `trainer` argument into OCPCalculator if otherwise.
WARNING:root:Unable to identify ocp trainer, defaulting to `forces`. Specify the `trainer` argument into FAIRChemCalculator if otherwise.
```

+++
Expand All @@ -154,13 +154,13 @@ Gemnet in particular seems to require at least 4 atoms. This has to do with inte

```{code-cell} ipython3
%%capture
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
from fairchem.core.models.model_registry import model_name_to_local_file
import os

checkpoint_path = model_name_to_local_file('GemNet-OC-S2EFS-OC20+OC22', local_cache='/tmp/ocp_checkpoints/')

calc = OCPCalculator(checkpoint_path=checkpoint_path)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path)
```

```{code-cell} ipython3
Expand All @@ -180,12 +180,12 @@ Some models use tags to determine which atoms to calculate energies for. For exa

```{code-cell} ipython3
%%capture
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
from fairchem.core.models.model_registry import model_name_to_local_file
import os

checkpoint_path = model_name_to_local_file('GemNet-OC-S2EFS-OC20+OC22', local_cache='/tmp/ocp_checkpoints/')
calc = OCPCalculator(checkpoint_path=checkpoint_path)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path)
```

```{code-cell} ipython3
Expand All @@ -205,13 +205,13 @@ atoms.get_potential_energy()
Not all models require tags though. This EquiformerV2 model does not use them. This is another detail that is important to keep in mind.

```{code-cell} ipython3
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
from fairchem.core.models.model_registry import model_name_to_local_file
import os

checkpoint_path = model_name_to_local_file('EquiformerV2-31M-S2EF-OC20-All+MD', local_cache='/tmp/ocp_checkpoints/')

calc = OCPCalculator(checkpoint_path=checkpoint_path)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path)
```

```{code-cell} ipython3
Expand All @@ -229,10 +229,10 @@ This happens because a random selection of is made to sample edges, and a differ

```{code-cell} ipython3
from fairchem.core.models.model_registry import model_name_to_local_file
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator

checkpoint_path = model_name_to_local_file('EquiformerV2-31M-S2EF-OC20-All+MD', local_cache='/tmp/ocp_checkpoints/')
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=True)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=True)

from ase.build import fcc111, add_adsorbate
from ase.optimize import BFGS
Expand Down Expand Up @@ -260,8 +260,8 @@ In DFT, the forces on all the atoms should sum to zero; otherwise, there is a ne
from fairchem.core.models.model_registry import model_name_to_local_file
checkpoint_path = model_name_to_local_file('EquiformerV2-31M-S2EF-OC20-All+MD', local_cache='/tmp/ocp_checkpoints/')

from fairchem.core.common.relaxation.ase_utils import OCPCalculator
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=True)
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=True)

from ase.build import fcc111, add_adsorbate
from ase.optimize import BFGS
Expand Down
4 changes: 2 additions & 2 deletions docs/core/inference.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ We include this here just to show that:
2. That this is much slower.

```{code-cell} ipython3
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=False)
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=False)
```

```{code-cell} ipython3
Expand Down
4 changes: 2 additions & 2 deletions docs/core/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ checkpoint_path
4. Finally, use this checkpoint in an ASE calculator for a simple relaxation!

```{code-cell} ipython3
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
from ase.build import fcc111, add_adsorbate
from ase.optimize import BFGS
import matplotlib.pyplot as plt
Expand All @@ -44,7 +44,7 @@ slab = fcc111('Pt', size=(2, 2, 5), vacuum=10.0)
add_adsorbate(slab, 'O', height=1.2, position='fcc')

# Load the pre-trained checkpoint!
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=False)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=False)
slab.set_calculator(calc)

# Run the optimization!
Expand Down
4 changes: 2 additions & 2 deletions docs/legacy_tutorials/OCP_Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -2036,7 +2036,7 @@ colab:
id: o_MHpzbhPKN_
outputId: fa4336cf-ba85-43b6-e608-551ffcf3763a
---
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
import ase.io
from ase.optimize import BFGS
from ase.build import fcc100, add_adsorbate, molecule
Expand All @@ -2057,7 +2057,7 @@ adslab.center(vacuum=13.0, axis=2)
adslab.set_pbc(True)

# Define the calculator
calc = OCPCalculator(checkpoint_path=checkpoint_path)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path)

# Set up the calculator
adslab.calc = calc
Expand Down
6 changes: 3 additions & 3 deletions docs/tutorials/NRR/NRR_example.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ In the previous example, we constructed slab models of adsorbates on desired sit


```{code-cell} ipython3
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
import ase.io
from ase.optimize import BFGS
import sys
Expand Down Expand Up @@ -126,8 +126,8 @@ Running the model with BFGS prints at each relaxation step which is a lot to pri
os.makedirs(f"data/{bulk_src_id}_{adsorbate_smiles_h}", exist_ok=True)

# Define the calculator
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=False) # if you have a GPU
# calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=True) # If you have CPU only
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=False) # if you have a GPU
# calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=True) # If you have CPU only
```

Now we setup and run the relaxation.
Expand Down
6 changes: 3 additions & 3 deletions docs/tutorials/OCP-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ checkpoint_path = model_name_to_local_file('EquiformerV2-31M-S2EF-OC20-All+MD',
Next we load the checkpoint. The output is somewhat verbose, but it can be informative for debugging purposes.

```{code-cell}
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=False)
# calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=True)
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=False)
# calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, cpu=True)
```

Next we can build a slab with an adsorbate on it. Here we use the ASE module to build a Pt slab. We use the experimental lattice constant that is the default. This can introduce some small errors with DFT since the lattice constant can differ by a few percent, and it is common to use DFT lattice constants. In this example, we do not constrain any layers.
Expand Down
8 changes: 4 additions & 4 deletions docs/tutorials/adsorbml_walkthrough.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ kernelspec:
# AdsorbML tutorial

```{code-cell} ipython3
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
import ase.io
from ase.optimize import BFGS

Expand Down Expand Up @@ -63,15 +63,15 @@ random_adslabs = AdsorbateSlabConfig(slabs[0], adsorbate, mode="random_site_heur
## Run ML relaxations:

There are 2 options for how to do this.
1. Using `OCPCalculator` as the calculator within the ASE framework
1. Using `FAIRChemCalculator` as the calculator within the ASE framework
2. By writing objects to lmdb and relaxing them using `main.py` in the ocp repo

(1) is really only adequate for small stuff and it is what I will show here, but if you plan to run many relaxations, you should definitely use (2). More details about writing lmdbs has been provided [here](../core/lmdb_dataset_creation.md) - follow the IS2RS/IS2RE instructions. And more information about running relaxations once the lmdb has been written is [here](../core/model_training.md).

You need to provide the calculator with a path to a model checkpoint file. That can be downloaded [here](../core/model_checkpoints)

```{code-cell} ipython3
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
from fairchem.core.models.model_registry import model_name_to_local_file
import os

Expand All @@ -80,7 +80,7 @@ checkpoint_path = model_name_to_local_file('EquiformerV2-31M-S2EF-OC20-All+MD',
os.makedirs(f"data/{bulk}_{adsorbate}", exist_ok=True)

# Define the calculator
calc = OCPCalculator(checkpoint_path=checkpoint_path) # if you have a gpu, add `cpu=False` to speed up calculations
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path) # if you have a gpu, add `cpu=False` to speed up calculations

adslabs = [*heuristic_adslabs.atoms_list, *random_adslabs.atoms_list]
# Set up the calculator
Expand Down
4 changes: 2 additions & 2 deletions docs/tutorials/advanced/embedding_monkeypatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import torch

from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
from fairchem.core.common.utils import conditional_grad, scatter_det
from fairchem.core.datasets import data_list_collater
from fairchem.core.models.gemnet_oc.gemnet_oc import GemNetOC
Expand Down Expand Up @@ -200,4 +200,4 @@ def embed(self, atoms):
return out


OCPCalculator.embed = embed
FAIRChemCalculator.embed = embed
6 changes: 3 additions & 3 deletions docs/tutorials/advanced/embeddings.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ We used them to search for similar atomic structures.

We can use them for diagnostic purposes, or clustering.

In this example, we patch the GemNetOC model to save the embeddings so you can easily access them. This requires two changes. The first is in the GemNetOC model where the embeddings are saved, and the second is in the OCPCalculator to retrieve them.
In this example, we patch the GemNetOC model to save the embeddings so you can easily access them. This requires two changes. The first is in the GemNetOC model where the embeddings are saved, and the second is in the FAIRChemCalculator to retrieve them.

We provide 5 different kinds of embeddings:

Expand Down Expand Up @@ -54,13 +54,13 @@ import numpy as np

```{code-cell} ipython3
%%capture
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
from fairchem.core.models.model_registry import model_name_to_local_file

import os
checkpoint_path = model_name_to_local_file('GemNet-OC-S2EFS-OC20+OC22', local_cache='/tmp/ocp_checkpoints/')

calc = OCPCalculator(checkpoint_path=checkpoint_path)
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path)
```

## Bulk Cu equation of state example
Expand Down
4 changes: 2 additions & 2 deletions docs/tutorials/advanced/fine-tuning-in-python.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ root.addHandler(handler_err)
from fairchem.core.models.model_registry import model_name_to_local_file

checkpoint_path = model_name_to_local_file('GemNet-OC-S2EFS-OC20+OC22', local_cache='/tmp/ocp_checkpoints/')
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
calc = OCPCalculator(checkpoint_path=checkpoint_path, trainer='forces', cpu=False)
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
calc = FAIRChemCalculator(checkpoint_path=checkpoint_path, trainer='forces', cpu=False)
```

## Split the data into train, test, val sets
Expand Down
6 changes: 3 additions & 3 deletions docs/tutorials/cattsunami_walkthrough.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ tags: ["skip-execution"]
---
from fairchem.applications.cattsunami.core import Reaction
from fairchem.data.oc.core import Slab, Adsorbate, Bulk, AdsorbateSlabConfig
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
from ase.optimize import BFGS
from x3dase.visualize import view_x3d_n
from ase.io import read
Expand Down Expand Up @@ -86,13 +86,13 @@ tags: ["skip-execution"]
# NOTE: Change the checkpoint path to locally downloaded files as needed
checkpoint_path = model_name_to_local_file('EquiformerV2-31M-S2EF-OC20-All+MD', local_cache='/tmp/ocp_checkpoints/')
cpu = True
calc = OCPCalculator(checkpoint_path = checkpoint_path, cpu = cpu)
calc = FAIRChemCalculator(checkpoint_path = checkpoint_path, cpu = cpu)
```

### Run ML local relaxations:

There are 2 options for how to do this.
1. Using `OCPCalculator` as the calculator within the ASE framework
1. Using `FAIRChemCalculator` as the calculator within the ASE framework
2. By writing objects to lmdb and relaxing them using `main.py` in the ocp repo

(1) is really only adequate for small stuff and it is what I will show here, but if you plan to run many relaxations, you should definitely use (2). More details about writing lmdbs has been provided [here](https://github.com/Open-Catalyst-Project/ocp/blob/main/tutorials/lmdb_dataset_creation.ipynb) - follow the IS2RS/IS2RE instructions. And more information about running relaxations once the lmdb has been written is [here](https://github.com/Open-Catalyst-Project/ocp/blob/main/TRAIN.md#initial-structure-to-relaxed-structure-is2rs).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"metadata": {},
"outputs": [],
"source": [
"from ocpmodels.common.relaxation.ase_utils import OCPCalculator\n",
"from ocpmodels.common.relaxation.ase_utils import FAIRChemCalculator \n",
"import ase.io\n",
"from ase.optimize import BFGS\n",
"\n",
Expand Down Expand Up @@ -88,7 +88,7 @@
"# Run ML relaxations:\n",
"\n",
"There are 2 options for how to do this.\n",
" 1. Using `OCPCalculator` as the calculator within the ASE framework\n",
" 1. Using `FAIRChemCalculator ` as the calculator within the ASE framework\n",
" 2. By writing objects to lmdb and relaxing them using `main.py` in the ocp repo\n",
" \n",
"(1) is really only adequate for small stuff and it is what I will show here, but if you plan to run many relaxations, you should definitely use (2). More details about writing lmdbs has been provided [here](https://github.com/Open-Catalyst-Project/ocp/blob/main/tutorials/lmdb_dataset_creation.ipynb) - follow the IS2RS/IS2RE instructions. And more information about running relaxations once the lmdb has been written is [here](https://github.com/Open-Catalyst-Project/ocp/blob/main/TRAIN.md#initial-structure-to-relaxed-structure-is2rs).\n",
Expand Down Expand Up @@ -446,7 +446,7 @@
"os.makedirs(f\"data/{bulk}_{adsorbate}\", exist_ok=True)\n",
"\n",
"# Define the calculator\n",
"calc = OCPCalculator(checkpoint=checkpoint_path) # if you have a gpu, add `cpu=False` to speed up calculations\n",
"calc = FAIRChemCalculator (checkpoint=checkpoint_path) # if you have a gpu, add `cpu=False` to speed up calculations\n",
"\n",
"adslabs = [*heuristic_adslabs.atoms_list, *random_adslabs.atoms_list]\n",
"# Set up the calculator\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from ase.optimize import BFGS
import torch
import argparse
from fairchem.core.common.relaxation.ase_utils import OCPCalculator
from fairchem.core.common.relaxation.ase_utils import FAIRChemCalculator
from fairchem.applications.cattsunami.core.ocpneb import OCPNEB
import os
import pandas as pd
Expand Down Expand Up @@ -300,7 +300,7 @@ def get_single_point(
delta_fmax_climb = float(args.delta_fmax_climb)
k = float(args.k)
fmax = float(args.fmax)
calc = OCPCalculator(checkpoint_path=checkpoint_path, cpu=args.cpu)
calc = FAIRChemCalculator (checkpoint_path=checkpoint_path, cpu=args.cpu)
model_id = checkpoint_path.split("/")[-1].split(".")[0]
vasp_command = args.vasp_command
os.makedirs(f"{args.output_file_path}/{model_id}", exist_ok=True)
Expand Down
Loading