AlphaFold3 / flax_model /alphafold3 /model /mmcif_metadata.py
wuxing0105's picture
Add files using upload-large-folder tool
62d3300 verified
Raw
History Blame Contribute Delete
8.49 kB
"""Adds mmCIF metadata (to be ModelCIF-conformant) and author and legal info."""
from typing import Final
from flax_model.alphafold3.structure import mmcif
import numpy as np
_LICENSE_URL: Final[str] = (
'https://github.com/google-deepmind/alphafold3/blob/main/OUTPUT_TERMS_OF_USE.md'
)
_LICENSE: Final[str] = f"""
Non-commercial use only, by using this file you agree to the terms of use found
at {_LICENSE_URL}.
To request access to the AlphaFold 3 model parameters, follow the process set
out at https://github.com/google-deepmind/alphafold3. You may only use these if
received directly from Google. Use is subject to terms of use available at
https://github.com/google-deepmind/alphafold3/blob/main/WEIGHTS_TERMS_OF_USE.md.
""".strip()
_DISCLAIMER: Final[str] = """\
AlphaFold 3 and its output are not intended for, have not been validated for,
and are not approved for clinical use. They are provided "as-is" without any
warranty of any kind, whether expressed or implied. No warranty is given that
use shall not infringe the rights of any third party.
""".strip()
_MMCIF_PAPER_AUTHORS: Final[tuple[str, ...]] = (
'Google DeepMind',
'Isomorphic Labs',
)
# Authors of the mmCIF - we set them to be equal to the authors of the paper.
_MMCIF_AUTHORS: Final[tuple[str, ...]] = _MMCIF_PAPER_AUTHORS
def add_metadata_to_mmcif(
old_cif: mmcif.Mmcif, version: str, model_id: bytes
) -> mmcif.Mmcif:
"""Adds metadata to a mmCIF to make it ModelCIF-conformant."""
cif = {}
# ModelCIF conformation dictionary.
cif['_audit_conform.dict_name'] = ['mmcif_ma.dic']
cif['_audit_conform.dict_version'] = ['1.4.5']
cif['_audit_conform.dict_location'] = [
'https://raw.githubusercontent.com/ihmwg/ModelCIF/master/dist/mmcif_ma.dic'
]
cif['_pdbx_data_usage.id'] = ['1', '2']
cif['_pdbx_data_usage.type'] = ['license', 'disclaimer']
cif['_pdbx_data_usage.details'] = [_LICENSE, _DISCLAIMER]
cif['_pdbx_data_usage.url'] = [_LICENSE_URL, '?']
# Structure author details.
cif['_audit_author.name'] = []
cif['_audit_author.pdbx_ordinal'] = []
for author_index, author_name in enumerate(_MMCIF_AUTHORS, start=1):
cif['_audit_author.name'].append(author_name)
cif['_audit_author.pdbx_ordinal'].append(str(author_index))
# Paper author details.
cif['_citation_author.citation_id'] = []
cif['_citation_author.name'] = []
cif['_citation_author.ordinal'] = []
for author_index, author_name in enumerate(_MMCIF_PAPER_AUTHORS, start=1):
cif['_citation_author.citation_id'].append('primary')
cif['_citation_author.name'].append(author_name)
cif['_citation_author.ordinal'].append(str(author_index))
# Paper citation details.
cif['_citation.id'] = ['primary']
cif['_citation.title'] = [
'Accurate structure prediction of biomolecular interactions with'
' AlphaFold 3'
]
cif['_citation.journal_full'] = ['Nature']
cif['_citation.journal_volume'] = ['630']
cif['_citation.page_first'] = ['493']
cif['_citation.page_last'] = ['500']
cif['_citation.year'] = ['2024']
cif['_citation.journal_id_ASTM'] = ['NATUAS']
cif['_citation.country'] = ['UK']
cif['_citation.journal_id_ISSN'] = ['0028-0836']
cif['_citation.journal_id_CSD'] = ['0006']
cif['_citation.book_publisher'] = ['?']
cif['_citation.pdbx_database_id_PubMed'] = ['38718835']
cif['_citation.pdbx_database_id_DOI'] = ['10.1038/s41586-024-07487-w']
# Type of data in the dataset including data used in the model generation.
cif['_ma_data.id'] = ['1']
cif['_ma_data.name'] = ['Model']
cif['_ma_data.content_type'] = ['model coordinates']
# Description of number of instances for each entity.
cif['_ma_target_entity_instance.asym_id'] = old_cif['_struct_asym.id']
cif['_ma_target_entity_instance.entity_id'] = old_cif[
'_struct_asym.entity_id'
]
cif['_ma_target_entity_instance.details'] = ['.'] * len(
cif['_ma_target_entity_instance.entity_id']
)
# Details about the target entities.
cif['_ma_target_entity.entity_id'] = cif[
'_ma_target_entity_instance.entity_id'
]
cif['_ma_target_entity.data_id'] = ['1'] * len(
cif['_ma_target_entity.entity_id']
)
cif['_ma_target_entity.origin'] = ['.'] * len(
cif['_ma_target_entity.entity_id']
)
# Details of the models being deposited.
cif['_ma_model_list.ordinal_id'] = ['1']
cif['_ma_model_list.model_id'] = ['1']
cif['_ma_model_list.model_group_id'] = ['1']
cif['_ma_model_list.model_name'] = ['Top ranked model']
cif['_ma_model_list.model_group_name'] = [
f'AlphaFold-beta-20231127 ({version})'
]
cif['_ma_model_list.data_id'] = ['1']
cif['_ma_model_list.model_type'] = ['Ab initio model']
# Software used.
cif['_software.pdbx_ordinal'] = ['1']
cif['_software.name'] = ['AlphaFold']
cif['_software.version'] = [
f'AlphaFold-beta-20231127 ({model_id.decode("ascii")})'
]
cif['_software.type'] = ['package']
cif['_software.description'] = ['Structure prediction']
cif['_software.classification'] = ['other']
cif['_software.date'] = ['?']
# Collection of software into groups.
cif['_ma_software_group.ordinal_id'] = ['1']
cif['_ma_software_group.group_id'] = ['1']
cif['_ma_software_group.software_id'] = ['1']
# Method description to conform with ModelCIF.
cif['_ma_protocol_step.ordinal_id'] = ['1', '2', '3']
cif['_ma_protocol_step.protocol_id'] = ['1', '1', '1']
cif['_ma_protocol_step.step_id'] = ['1', '2', '3']
cif['_ma_protocol_step.method_type'] = [
'coevolution MSA',
'template search',
'modeling',
]
# Details of the metrics use to assess model confidence.
cif['_ma_qa_metric.id'] = ['1', '2']
cif['_ma_qa_metric.name'] = ['pLDDT', 'pLDDT']
# Accepted values are distance, energy, normalised score, other, zscore.
cif['_ma_qa_metric.type'] = ['pLDDT', 'pLDDT']
cif['_ma_qa_metric.mode'] = ['global', 'local']
cif['_ma_qa_metric.software_group_id'] = ['1', '1']
# Global model confidence pLDDT value.
cif['_ma_qa_metric_global.ordinal_id'] = ['1']
cif['_ma_qa_metric_global.model_id'] = ['1']
cif['_ma_qa_metric_global.metric_id'] = ['1']
# Mean over all atoms, since AlphaFold 3 outputs pLDDT per-atom.
global_plddt = np.mean(
[float(v) for v in old_cif['_atom_site.B_iso_or_equiv']]
)
cif['_ma_qa_metric_global.metric_value'] = [f'{global_plddt:.2f}']
# Local (per residue) model confidence pLDDT value.
cif['_ma_qa_metric_local.ordinal_id'] = []
cif['_ma_qa_metric_local.model_id'] = []
cif['_ma_qa_metric_local.label_asym_id'] = []
cif['_ma_qa_metric_local.label_seq_id'] = []
cif['_ma_qa_metric_local.label_comp_id'] = []
cif['_ma_qa_metric_local.metric_id'] = []
cif['_ma_qa_metric_local.metric_value'] = []
plddt_grouped_by_res = {}
for *res, atom_plddt in zip(
old_cif['_atom_site.label_asym_id'],
old_cif['_atom_site.label_seq_id'],
old_cif['_atom_site.label_comp_id'],
old_cif['_atom_site.B_iso_or_equiv'],
):
plddt_grouped_by_res.setdefault(tuple(res), []).append(float(atom_plddt))
for ordinal_id, ((chain_id, res_id, res_name), res_plddts) in enumerate(
plddt_grouped_by_res.items(), start=1
):
res_plddt = np.mean(res_plddts)
cif['_ma_qa_metric_local.ordinal_id'].append(str(ordinal_id))
cif['_ma_qa_metric_local.model_id'].append('1')
cif['_ma_qa_metric_local.label_asym_id'].append(chain_id)
cif['_ma_qa_metric_local.label_seq_id'].append(res_id)
cif['_ma_qa_metric_local.label_comp_id'].append(res_name)
cif['_ma_qa_metric_local.metric_id'].append('2') # See _ma_qa_metric.id.
cif['_ma_qa_metric_local.metric_value'].append(f'{res_plddt:.2f}')
cif['_atom_type.symbol'] = sorted(set(old_cif['_atom_site.type_symbol']))
return old_cif.copy_and_update(cif)
def add_legal_comment(cif: str) -> str:
"""Adds legal comment at the top of the mmCIF."""
# fmt: off
# pylint: disable=line-too-long
comment = (
'# By using this file you agree to the legally binding terms of use found at\n'
f'# {_LICENSE_URL}.\n'
'# To request access to the AlphaFold 3 model parameters, follow the process set\n'
'# out at https://github.com/google-deepmind/alphafold3. You may only use these if\n'
'# received directly from Google. Use is subject to terms of use available at\n'
'# https://github.com/google-deepmind/alphafold3/blob/main/WEIGHTS_TERMS_OF_USE.md.'
)
# pylint: enable=line-too-long
# fmt: on
return f'{comment}\n{cif}'