| import numpy as np
|
| from colabdesign.af.alphafold.common import residue_constants
|
|
|
| def make_atom14_positions(batch):
|
| """Constructs denser atom positions (14 dimensions instead of 37)."""
|
| restype_atom14_to_atom37 = []
|
| restype_atom37_to_atom14 = []
|
| restype_atom14_mask = []
|
|
|
| for rt in residue_constants.restypes:
|
| atom_names = residue_constants.restype_name_to_atom14_names[
|
| residue_constants.restype_1to3[rt]]
|
|
|
| restype_atom14_to_atom37.append([
|
| (residue_constants.atom_order[name] if name else 0)
|
| for name in atom_names
|
| ])
|
|
|
| atom_name_to_idx14 = {name: i for i, name in enumerate(atom_names)}
|
| restype_atom37_to_atom14.append([
|
| (atom_name_to_idx14[name] if name in atom_name_to_idx14 else 0)
|
| for name in residue_constants.atom_types
|
| ])
|
|
|
| restype_atom14_mask.append([(1. if name else 0.) for name in atom_names])
|
|
|
|
|
| restype_atom14_to_atom37.append([0] * 14)
|
| restype_atom37_to_atom14.append([0] * 37)
|
| restype_atom14_mask.append([0.] * 14)
|
|
|
| restype_atom14_to_atom37 = np.array(restype_atom14_to_atom37, dtype=np.int32)
|
| restype_atom37_to_atom14 = np.array(restype_atom37_to_atom14, dtype=np.int32)
|
| restype_atom14_mask = np.array(restype_atom14_mask, dtype=np.float32)
|
|
|
|
|
|
|
| residx_atom14_to_atom37 = restype_atom14_to_atom37[batch["aatype"]]
|
| residx_atom14_mask = restype_atom14_mask[batch["aatype"]]
|
|
|
|
|
| residx_atom14_gt_mask = residx_atom14_mask * np.take_along_axis(
|
| batch["all_atom_mask"], residx_atom14_to_atom37, axis=1).astype(np.float32)
|
|
|
|
|
| residx_atom14_gt_positions = residx_atom14_gt_mask[:, :, None] * (
|
| np.take_along_axis(batch["all_atom_positions"],
|
| residx_atom14_to_atom37[..., None],
|
| axis=1))
|
|
|
| prot = {}
|
| prot["atom14_atom_exists"] = residx_atom14_mask
|
| prot["atom14_gt_exists"] = residx_atom14_gt_mask
|
| prot["atom14_gt_positions"] = residx_atom14_gt_positions
|
|
|
| prot["residx_atom14_to_atom37"] = residx_atom14_to_atom37
|
|
|
|
|
| residx_atom37_to_atom14 = restype_atom37_to_atom14[batch["aatype"]]
|
| prot["residx_atom37_to_atom14"] = residx_atom37_to_atom14
|
|
|
|
|
| restype_atom37_mask = np.zeros([21, 37], dtype=np.float32)
|
| for restype, restype_letter in enumerate(residue_constants.restypes):
|
| restype_name = residue_constants.restype_1to3[restype_letter]
|
| atom_names = residue_constants.residue_atoms[restype_name]
|
| for atom_name in atom_names:
|
| atom_type = residue_constants.atom_order[atom_name]
|
| restype_atom37_mask[restype, atom_type] = 1
|
|
|
| residx_atom37_mask = restype_atom37_mask[batch["aatype"]]
|
| prot["atom37_atom_exists"] = residx_atom37_mask
|
|
|
|
|
|
|
| restype_3 = [
|
| residue_constants.restype_1to3[res] for res in residue_constants.restypes
|
| ]
|
| restype_3 += ["UNK"]
|
|
|
|
|
| all_matrices = {res: np.eye(14, dtype=np.float32) for res in restype_3}
|
| for resname, swap in residue_constants.residue_atom_renaming_swaps.items():
|
| correspondences = np.arange(14)
|
| for source_atom_swap, target_atom_swap in swap.items():
|
| source_index = residue_constants.restype_name_to_atom14_names[
|
| resname].index(source_atom_swap)
|
| target_index = residue_constants.restype_name_to_atom14_names[
|
| resname].index(target_atom_swap)
|
| correspondences[source_index] = target_index
|
| correspondences[target_index] = source_index
|
| renaming_matrix = np.zeros((14, 14), dtype=np.float32)
|
| for index, correspondence in enumerate(correspondences):
|
| renaming_matrix[index, correspondence] = 1.
|
| all_matrices[resname] = renaming_matrix.astype(np.float32)
|
| renaming_matrices = np.stack([all_matrices[restype] for restype in restype_3])
|
|
|
|
|
|
|
| renaming_transform = renaming_matrices[batch["aatype"]]
|
|
|
|
|
| alternative_gt_positions = np.einsum("rac,rab->rbc",
|
| residx_atom14_gt_positions,
|
| renaming_transform)
|
| prot["atom14_alt_gt_positions"] = alternative_gt_positions
|
|
|
|
|
|
|
|
|
| alternative_gt_mask = np.einsum("ra,rab->rb",
|
| residx_atom14_gt_mask,
|
| renaming_transform)
|
|
|
| prot["atom14_alt_gt_exists"] = alternative_gt_mask
|
|
|
|
|
| restype_atom14_is_ambiguous = np.zeros((21, 14), dtype=np.float32)
|
| for resname, swap in residue_constants.residue_atom_renaming_swaps.items():
|
| for atom_name1, atom_name2 in swap.items():
|
| restype = residue_constants.restype_order[
|
| residue_constants.restype_3to1[resname]]
|
| atom_idx1 = residue_constants.restype_name_to_atom14_names[resname].index(
|
| atom_name1)
|
| atom_idx2 = residue_constants.restype_name_to_atom14_names[resname].index(
|
| atom_name2)
|
| restype_atom14_is_ambiguous[restype, atom_idx1] = 1
|
| restype_atom14_is_ambiguous[restype, atom_idx2] = 1
|
|
|
|
|
| prot["atom14_atom_is_ambiguous"] = (restype_atom14_is_ambiguous[batch["aatype"]])
|
| return prot |