Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
![Coverage](https://raw.githubusercontent.com/rigdenlab/ABCFold/refs/heads/main/.blob/coverage.svg)


Scripts to run AlphaFold3, Boltz, Chai-1, OpenFold3 and Protenix with MMseqs2 Multiple sequence alignments (MSAs) and custom templates.
Scripts to run AlphaFold3, Boltz, Chai-1, OpenFold3, Protenix and RosettaFold3 with MMseqs2 Multiple sequence alignments (MSAs) and custom templates.

## Table of Contents
- [Installation](#installation)
Expand All @@ -26,7 +26,7 @@ micromamba activate abcfold
> **Environment note**
>
> - Your main Python environment can be Conda, micromamba, or virtualenv.
> - `abcfold` will automatically create **internal micromamba environments** to run Boltz, Chai-1, OpenFold3 and Protenix safely, therefore a micromamba installation is required.
> - `abcfold` will automatically create **internal micromamba environments** to run Boltz, Chai-1, OpenFold3, Protenix and RosettaFold3 safely, therefore a micromamba installation is required.
> - This prevents package conflicts with your main environment and ensures reproducible results.


Expand Down Expand Up @@ -57,7 +57,7 @@ python -m pre_commit install

### Running ABCfold

ABCFold will run Alphafold3, Boltz, Chai-1, OpenFold3 and Protenix consecutively. The program takes an input of a JSON in the Alphafold3 format (For full instruction on how to format this, click [here](https://github.com/google-deepmind/alphafold3/blob/main/docs/input.md)). An example JSON is shown below:
ABCFold will run Alphafold3, Boltz, Chai-1, OpenFold3, Protenix and RosettaFold3 consecutively. The program takes an input of a JSON in the Alphafold3 format (For full instruction on how to format this, click [here](https://github.com/google-deepmind/alphafold3/blob/main/docs/input.md)). An example JSON is shown below:

```json
{
Expand All @@ -76,7 +76,7 @@ ABCFold will run Alphafold3, Boltz, Chai-1, OpenFold3 and Protenix consecutively
}
```

Please make sure you have AlphaFold3 installed on your system (Instructions [here](https://github.com/google-deepmind/alphafold3/blob/main/docs/installation.md)) and have procured the model parameters. Boltz, Chai-1, OpenFold3 and Protenix are installed upon runtime.
Please make sure you have AlphaFold3 installed on your system (Instructions [here](https://github.com/google-deepmind/alphafold3/blob/main/docs/installation.md)) and have procured the model parameters. Boltz, Chai-1, OpenFold3, Protenix and RosettaFold3 are installed upon runtime.

For the majority of jobs, ABCFold can be run as follows:
```bash
Expand All @@ -100,7 +100,7 @@ However, there you may wish to use the following flags to add run time options s
#### Main arguments
- `<input_json>`: Path to the input AlphaFold3 JSON file.
- `<output_dir>`: Path to the output directory.
- `-a`, `-b`, `-c`, `-o`, `-p` (`--alphafold3`, `--boltz`,`--chai1`, `--openfold3`, `--protenix`): Flags to run Alphafold3, Boltz, Chai-1, OpenFold3 and Protenix respectively. If none of these flags are provided, Alphafold3 will be run by default.
- `-a`, `-b`, `-c`, `-o`, `-p`, `-r` (`--alphafold3`, `--boltz`,`--chai1`, `--openfold3`, `--protenix`, `--rosettafold3`): Flags to run Alphafold3, Boltz, Chai-1, OpenFold3, Protenix and RosettaFold3 respectively. If none of these flags are provided, Alphafold3 will be run by default.
- `--mmseqs2`: [optional] Flag to use MMseqs2 MSAs and templates (if specified).
- `--mmseqs_database`: [optional] The path to the database used by a local copy of MMSeqs2, provided mmseqs is installed, the inclusion of this flag allows MMseqs2 to be run locally.
- `--override`: [optional] Flag to override the existing output directory.
Expand All @@ -118,7 +118,6 @@ However, there you may wish to use the following flags to add run time options s
- `--inference_ckpt_path` [optional] Path for model checkpoint to be used for inference. If not specified, will attempt to find or download parameters in ~/.openfold3/

#### Template arguments

- `--templates`: Flag to enable a template search
- `--num_templates`: [optional] The number of templates to use (default: 20)

Expand All @@ -135,19 +134,19 @@ However, there you may wish to use the following flags to add run time options s
If you wanted to provide a custom template, `custom_a.pdb` for your protein sequence with the ID `A` and you have your template has two chains: chain `A` and chain `B` and chain `B` is what you want the template to be, you could run:

```bash
abcfold <input_json> <output_dir> -abcop --mmseqs2 --custom_template custom_a.pdb --custom_template_chain B --target_id A
abcfold <input_json> <output_dir> -abcopr --mmseqs2 --custom_template custom_a.pdb --custom_template_chain B --target_id A

```

If you had multiple IDs in your input sequence, multiple template files and you wanted to provide 3 custom templates, chain `A` from `custom_a.pdb`, chain `B` from `custom_b.pdb`, and chain B from `custom_c.pdb`, where `custom_a.pdb` and `custom_b.pdb` correspond to the ID `A` and `custom_c.pdb` corresponds to the ID `B`, you could run:

```bash
abcfold <input_json> <output_dir> -abcop --mmseqs2 --custom_template custom_a.pdb custom_b.pdb custom_c.pdb --custom_template_chain A B B --target_id A A B
abcfold <input_json> <output_dir> -abcopr --mmseqs2 --custom_template custom_a.pdb custom_b.pdb custom_c.pdb --custom_template_chain A B B --target_id A A B

```
### Output

ABCFold will output the AlphaFold, Boltz, Chai, OpenFold3 and Protenix models in the `<output_dir>`, it will also produce an output page containing a results table and informative [PAE viewer](https://gitlab.gwdg.de/general-microbiology/pae-viewer). This is opened automatically in your default browser unless the `--no_server` or `--no_visuals` flags are used.
ABCFold will output the AlphaFold, Boltz, Chai, OpenFold3, Protenix and RosettaFold3 models in the `<output_dir>`, it will also produce an output page containing a results table and informative [PAE viewer](https://gitlab.gwdg.de/general-microbiology/pae-viewer). This is opened automatically in your default browser unless the `--no_server` or `--no_visuals` flags are used.

Unless the `--no_visuals` flag is used, you can then open the output pages by running:

Expand All @@ -171,7 +170,7 @@ you will find `open_output.py` in your `<output_dir>`. This needs to be run from
Below are scripts for adding MMseqs2 MSAs and custom templates to AlphaFold3 input JSON files.

> [!WARNING]
> These scripts will only modify the input JSON files, I.E. they will NOT run AlphaFold3, Boltz, Chai-1, OpenFold3 and Protenix.
> These scripts will only modify the input JSON files, I.E. they will NOT run AlphaFold3, Boltz, Chai-1, OpenFold3, Protenix and RosettaFold3.

### Adding MMseqs2 MSAs and templates

Expand Down
74 changes: 66 additions & 8 deletions abcfold/abcfold.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import tempfile
import webbrowser
from pathlib import Path
from textwrap import dedent
from typing import Any, Dict, List, Union

from abcfold.alphafold3.run_alphafold3 import run_alphafold3
Expand All @@ -19,6 +20,7 @@
prediction_argparse_util,
protenix_argparse_util,
raise_argument_errors,
rosettafold_argparse_util,
visuals_argparse_util)
from abcfold.html.html_utils import (PORT, NoCacheHTTPRequestHandler,
get_all_cif_files, get_model_data,
Expand All @@ -31,6 +33,7 @@
from abcfold.output.file_handlers import superpose_models
from abcfold.output.openfold3 import OpenfoldOutput
from abcfold.output.protenix import ProtenixOutput
from abcfold.output.rosettafold3 import RosettafoldOutput
from abcfold.output.utils import (get_gap_indicies, insert_none_by_minus_one,
make_dummy_m8_file, verify_config_file)
from abcfold.scripts.abc_script_utils import (check_input_json, make_dir,
Expand All @@ -45,7 +48,8 @@
PLOTS_DIR = ".plots"

ModelOutput = Union[
AlphafoldOutput, BoltzOutput, ChaiOutput, ProtenixOutput, OpenfoldOutput
AlphafoldOutput, BoltzOutput, ChaiOutput,
ProtenixOutput, OpenfoldOutput, RosettafoldOutput
]


Expand Down Expand Up @@ -272,6 +276,28 @@ def run(args, config, defaults, config_file):
outputs.append(oo)
successful_runs.append(openfold_success)

if args.rosettafold3:
from abcfold.rosettafold3.run_rosettafold3 import run_rosettafold

rosettafold_success = run_rosettafold(
input_json=run_json,
output_dir=args.output_dir,
save_input=args.save_input,
number_of_models=args.number_of_models,
config=rt_config
)

if rosettafold_success:
rosettafold_output_dirs = list(
args.output_dir.glob("rosettafold_results*")
)
ro = RosettafoldOutput(
rosettafold_output_dirs, input_params, name, args.save_input
)
outputs.append(ro)

successful_runs.append(rosettafold_success)

if args.no_visuals:
logger.info("Visuals disabled")
return
Expand Down Expand Up @@ -431,12 +457,41 @@ def run(args, config, defaults, config_file):
)
protenix_models["models"].append(model_data)

rosettafold_models: Dict[str, List[Dict[str, Any]]] = {"models": []}
if args.rosettafold3:
if rosettafold_success:
programs_run.append("RosettaFold3")
for seed in ro.output.keys():
for idx in ro.output[seed].keys():
if idx >= 0:
model = ro.output[seed][idx]["cif"]
model.check_clashes()
score_file = ro.output[seed][idx]["scores"]
plddt = model.residue_plddts
pae = ro.output[seed][idx]["af3_pae"]
if len(indicies) > 0:
plddt = insert_none_by_minus_one(
indicies[index_counter], plddt
)
index_counter += 1
model_data = get_model_data(
model,
plot_dict,
"RosettaFold3",
plddt,
pae,
score_file,
args.output_dir,
)
rosettafold_models["models"].append(model_data)

combined_models = (
alphafold_models["models"] +
boltz_models["models"] +
chai_models["models"] +
openfold_models["models"] +
protenix_models["models"]
protenix_models["models"] +
rosettafold_models["models"]
)

# Make the output directory for the models
Expand All @@ -454,6 +509,8 @@ def run(args, config, defaults, config_file):
output_name = "openfold_model_" + model["model_id"][-1] + ".cif"
elif model["model_source"] == "Protenix":
output_name = "protenix_model_" + model["model_id"][-1] + ".cif"
elif model["model_source"] == "RosettaFold3":
output_name = "rosettafold_model_" + model["model_id"][-1] + ".cif"
shutil.copy(
cif_file,
args.output_dir.joinpath("output_models").joinpath(output_name),
Expand Down Expand Up @@ -544,7 +601,7 @@ def run(args, config, defaults, config_file):

def main():
"""
Run AlphaFold3 / Boltz / Chai-1 / OpenFold3 / Protenix
Run AlphaFold3 / Boltz / Chai-1 / OpenFold3 / Protenix / RosettaFold3
"""
import argparse

Expand All @@ -553,10 +610,9 @@ def main():
'--config-file',
type=str,
default=str(Path.home() / ".abcfold_config.ini"),
help='Path to the config file. '
'If not provided, a config file will be created '
'at ~/.abcfold_config.ini with default values. '
'If a config file already exists at that location, it will be used.'
help=dedent('Path to the config file. If not provided, a config file will \
be created at ~/.abcfold_config.ini with default values. \
If a config file already exists at that location, it will be used.')
)
config_args, remaining = config_parser.parse_known_args()

Expand All @@ -574,7 +630,8 @@ def main():
defaults.update(dict(config.items(section)))

parser = argparse.ArgumentParser(
description="Run AlphaFold3 / Boltz / Chai-1 / OpenFold3 / Protenix",
description=dedent("Run AlphaFold3 / Boltz / Chai-1 / \
OpenFold3 / Protenix / RosettaFold3"),
parents=[config_parser],
)

Expand All @@ -584,6 +641,7 @@ def main():
parser = chai_argparse_util(parser)
parser = openfold_argparse_util(parser)
parser = protenix_argparse_util(parser)
parser = rosettafold_argparse_util(parser)
parser = mmseqs2_argparse_util(parser)
parser = custom_template_argpase_util(parser)
parser = prediction_argparse_util(parser)
Expand Down
15 changes: 13 additions & 2 deletions abcfold/argparse_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,16 @@ def openfold_argparse_util(parser):
return parser


def rosettafold_argparse_util(parser):
parser.add_argument(
"-r",
"--rosettafold3",
action="store_true",
help="Run RosettaFold 3",
)
return parser


def alphafold_argparse_util(parser):
parser.add_argument(
"--database",
Expand Down Expand Up @@ -235,10 +245,11 @@ def raise_argument_errors(args):
and not args.chai1
and not args.protenix
and not args.openfold3
and not args.rosettafold3
):
logger.info(
dedent("None of AlphaFold3, Boltz, Chai-1, Protenix or OpenFold3 selected. \
Running AlphaFold3 by default")
dedent("None of AlphaFold3, Boltz, Chai-1, Protenix, OpenFold3 or \
RosettaFold3 selected. Running AlphaFold3 by default")
)
args.alphafold3 = True

Expand Down
3 changes: 3 additions & 0 deletions abcfold/data/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ af3_sif_path = None
model_params = None
boltz_weights = None
openfold_weights = None
rosettafold_weights = None

[Environments]
af3_docker_env = alphafold3
boltz_env = abcfold-boltz-py311
chai_env = abcfold-chai-py311
openfold_env = abcfold-openfold-py311
protenix_env = abcfold-protenix-py311
rosettafold_env = abcfold-rosetta-py312

[Versions]
af3_version = 3.0.0
boltz_version = 2.2.1
chai_version = 0.6.1
openfold_version = 0.4.1
protenix_version = 2.0.0
rosetta_version = 0.1.12

[Models]
protenix_model = protenix-v2
2 changes: 2 additions & 0 deletions abcfold/html/abcfold_vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ Vue.component('abc-table', {
return 'btn-source4';
case 'OpenFold3':
return 'btn-source5';
case 'RosettaFold3':
return 'btn-source6';
default:
return 'btn-default';
}
Expand Down
6 changes: 6 additions & 0 deletions abcfold/html/html_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from abcfold.output.file_handlers import ConfidenceJsonFile, NpzFile
from abcfold.output.openfold3 import OpenfoldOutput
from abcfold.output.protenix import ProtenixOutput
from abcfold.output.rosettafold3 import RosettafoldOutput
from abcfold.plots.pae_plot import create_pae_plots
from abcfold.plots.plddt_plot import plot_plddt
from abcfold.scripts.ipsae import Ipsae
Expand Down Expand Up @@ -293,6 +294,11 @@ def get_all_cif_files(outputs) -> Dict[str, list]:
if "Protenix" not in method_cif_objs:
method_cif_objs["Protenix"] = []
method_cif_objs["Protenix"].extend(output.cif_files[seed])
elif isinstance(output, RosettafoldOutput):
for seed in output.seeds:
if "RosettaFold3" not in method_cif_objs:
method_cif_objs["RosettaFold3"] = []
method_cif_objs["RosettaFold3"].extend(output.cif_files[seed])

return method_cif_objs

Expand Down
8 changes: 4 additions & 4 deletions abcfold/html/static/ABCfold-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions abcfold/html/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,16 @@ rect{
transition: background-color 0.3s ease;
}

.btn-source6 {
background-color: #49aaa1eb;
color: #F8F9FA;
border: none;
border-radius: 12px;
padding: 7px 15px;
cursor: pointer;
transition: background-color 0.3s ease;
}

.btn-default {
background-color: rgb(199, 195, 195);
color: white;
Expand Down
2 changes: 1 addition & 1 deletion abcfold/openfold3/run_openfold3.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def run_openfold(
save_input: bool = False,
test: bool = False,
number_of_models: int = 5,
template_hits_path: Path | None = None,
template_hits_path: Optional[Path] = None,
input_ckpt: Optional[Union[str, Path]] = None,
) -> bool:
"""
Expand Down
Loading
Loading