MSA and pair representations
MSA cluster profiles and deletion features
AlphaFold2OpenFold
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Your task
Assign extra MSA rows to supplied cluster centers and build masked cluster profiles and deletion features. Return assignments, profiles, and the requested center/extra-row feature tensors.
Function signature
msa_profile_features(
msa: torch.Tensor,
extra_msa: torch.Tensor,
msa_mask: torch.Tensor,
extra_mask: torch.Tensor,
deletions: torch.Tensor,
extra_deletions: torch.Tensor,
agreement_weights: torch.Tensor,
) -> dict[str, torch.Tensor]Worked example
Count observations within each cluster
Extra row 0 exactly matches representative 0, with weighted agreement 1+1+1+0.2=3.2; extra row 1 matches representative 1. Extra row 2 matches representative 0 at its third position, giving agreement 1. Thus assignments are [0, 1, 0]. In cluster 0 at position 0, the representative and first extra row contain category 0, while the third extra row contains category 3: frequencies are 2/3 and 1/3.
import torch
msa = torch.tensor([[[0, 1, 2, 3], [1, 2, 0, 3]]], dtype=torch.int64)
extra_msa = torch.tensor([[[0, 1, 2, 3], [1, 2, 0, 3], [3, 3, 2, 1]]], dtype=torch.int64)
msa_mask = torch.full((1, 2, 4), True, dtype=torch.bool)
extra_mask = torch.full((1, 3, 4), True, dtype=torch.bool)
deletions = torch.tensor([[[0.33440397994552407, 0.7618063009752785, 0.3232192763322387, 0.6017582635498979], [0.6090226915412557, 0.21896612648967853, 0.42954764715125526, 0.41624465502273716]]], dtype=torch.float64, requires_grad=True)
extra_deletions = torch.tensor([[[0.311435034228908, 0.5125377709315249, 0.3756854033911365, 0.6103182835033594], [0.3925585032328245, 0.8529914727477061, 0.32150636483641926, 0.423268971317183], [0.21148476464956434, 0.4895142803803796, 0.4337284046223584, 0.5169061875189971]]], dtype=torch.float64, requires_grad=True)
agreement_weights = torch.tensor([1.0, 1.0, 1.0, 0.2, 0.0], dtype=torch.float64)
result = msa_profile_features(msa=msa, extra_msa=extra_msa, msa_mask=msa_mask, extra_mask=extra_mask, deletions=deletions, extra_deletions=extra_deletions, agreement_weights=agreement_weights)Expected return
{
'assignment': torch.tensor([[0, 1, 0]], dtype=torch.int64),
'profile': torch.tensor([[[[0.6666666666666666, 0.0, 0.0, 0.3333333333333333, 0.0], [0.0, 0.6666666666666666, 0.0, 0.3333333333333333, 0.0], [0.0, 0.0, 1.0, 0.0, 0.0], [0.0, 0.3333333333333333, 0.0, 0.6666666666666666, 0.0]], [[0.0, 1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0, 0.0]]]], dtype=torch.float64),
'mean_deletion': torch.tensor([[[0.2857745929413322, 0.5879527840957276, 0.3775443614485779, 0.5763275781907514], [0.5007905973870401, 0.5359787996186923, 0.37552700599383726, 0.41975681316996005]]], dtype=torch.float64),
'features': torch.tensor([[[[1.0, 0.0, 0.0, 0.0, 0.0, 0.33440397994552407, 0.07067099371170948, 0.6666666666666666, 0.0, 0.0, 0.3333333333333333, 0.0, 0.06046081621029981], [0.0, 1.0, 0.0, 0.0, 0.0, 0.7618063009752785, 0.15831406843724105, 0.0, 0.6666666666666666, 0.0, 0.3333333333333333, 0.0, 0.12320585706872142], [0.0, 0.0, 1.0, 0.0, 0.0, 0.3232192763322387, 0.06832570248268699, 0.0, 0.0, 1.0, 0.0, 0.0, 0.07969841635957112], [0.0, 0.0, 0.0, 1.0, 0.0, 0.6017582635498979, 0.126024640440868, 0.0, 0.3333333333333333, 0.0, 0.6666666666666666, 0.0, 0.12082843409856038]], [[0.0, 1.0, 0.0, 0.0, 0.0, 0.6090226915412557, 0.12750588033819898, 0.0, 1.0, 0.0, 0.0, 0.0, 0.10530014209586326], [0.0, 0.0, 1.0, 0.0, 0.0, 0.21896612648967853, 0.046383804277378204, 0.0, 0.0, 1.0, 0.0, 0.0, 0.11255074789230625], [1.0, 0.0, 0.0, 0.0, 0.0, 0.42954764715125526, 0.09053747816281954, 1.0, 0.0, 0.0, 0.0, 0.0, 0.07927695955931023], [0.0, 0.0, 0.0, 1.0, 0.0, 0.41624465502273716, 0.08776950283838884, 0.0, 0.0, 0.0, 1.0, 0.0, 0.08850061222300255]]]], dtype=torch.float64),
'extra_features': torch.tensor([[[[1.0, 0.0, 0.0, 0.0, 0.0, 0.311435034228908, 0.0658526810863654], [0.0, 1.0, 0.0, 0.0, 0.0, 0.5125377709315249, 0.10772383555365878], [0.0, 0.0, 1.0, 0.0, 0.0, 0.3756854033911365, 0.07931005376090094], [0.0, 0.0, 0.0, 1.0, 0.0, 0.6103182835033594, 0.12776990915364153]], [[0.0, 1.0, 0.0, 0.0, 0.0, 0.3925585032328245, 0.08283287352129885], [0.0, 0.0, 1.0, 0.0, 0.0, 0.8529914727477061, 0.17635630393825594], [1.0, 0.0, 0.0, 0.0, 0.0, 0.32150636483641926, 0.06796636049696612], [0.0, 0.0, 0.0, 1.0, 0.0, 0.423268971317183, 0.08923148672474324]], [[0.0, 0.0, 0.0, 1.0, 0.0, 0.21148476464956434, 0.04480434011383874], [0.0, 0.0, 0.0, 1.0, 0.0, 0.4895142803803796, 0.10297069404882583], [0.0, 0.0, 1.0, 0.0, 0.0, 0.4337284046223584, 0.09140666897406385], [0.0, 1.0, 0.0, 0.0, 0.0, 0.5169061875189971, 0.10862433366899243]]]], dtype=torch.float64),
}Parameters
| Parameter | Shape and meaning |
|---|---|
msatorch.Tensor | [B, S, N]Supplied MSA cluster-center token sequences. |
extra_msatorch.Tensor | [B, E, N]Extra MSA sequences to assign to those centers. |
msa_masktorch.Tensor | [B, S, N]True marks an observed sequence/residue entry in the MSA. |
extra_masktorch.Tensor | [B, E, N]True marks an observed residue in an extra MSA sequence. |
deletionstorch.Tensor | [B, S, N]Deletion counts/continuous relaxation |
extra_deletionstorch.Tensor | [B, E, N]Deletion counts/continuous relaxation |
agreement_weightstorch.Tensor | [A]Fixed category weights used only when scoring token agreement. |
Return
dict[str, torch.Tensor]
Return exactly the named fields applicable to this operation.
Required behavior
- Build nearest-center MSA cluster profiles and deletion features.
B,S,N,Apositive;E\ge 0extra rows is allowed.msa[B,S,N]andextra_msa[B,E,N]areint64category IDs in[0,A).agreement_weights[A]is a fixed nonnegative vector: for example, - ordinary amino acids
1, gaps downweighted, masked-token agreement0.msa_mask/extra_maskare BooleanTruemeans an observed position. Finitedeletions[B,S,N]andextra_deletions[B,E,N]are nonnegative at observed positions, and can be treated as continuous noninteger values for differentiation. - Missing payloads are ignored. Score each extra row
eagainst centerswith\mathrm{score}_{b,e,s}=\sum_n\mathbf{1}[\text{both masks and equal tokens}]\,\mathrm{agreement\_weights}[\mathrm{token}]. assignment[b,e]is the maximum-score center; exact ties choose the lowest center index, even an entirely unobserved extra row. E=0returns an empty assignment.- For each center
sand residuen, include the center observation if masked valid and all valid extra observations assigned tos. profile[b,s,n,a]is\operatorname{count}(\mathrm{category}\,a)/\mathrm{observed\_count}, andmean_deletionis the same observed-position mean of deletion values. - Empty clusters/positions return exact zeros; do not divide by the number of sequences irrespective of per-position masks. Let
onehot_centerandonehot_extrabe zero at missing positions. \mathrm{has\_deletion}=\operatorname{clamp}(d,0,1),\mathrm{bounded\_deletion}=(2/\pi)\cdot \arctan(d/3), and\mathrm{bounded\_mean}=(2/\pi)\cdot \arctan(\mathrm{mean\_deletion}/3).- Concatenate
features[B,S,N,2A+3]in order[\underbrace{\mathrm{center\_onehot}}_{A},\underbrace{\mathrm{has\_deletion}}_{1},\underbrace{\mathrm{bounded\_deletion}}_{1},\underbrace{\mathrm{profile}}_{A},\underbrace{\mathrm{bounded\_mean}}_{1}], then zero all channels where the CENTER position is masked out. - Returned profile/
mean_deletionthemselves can still reflect valid extra rows at that position.extra_features[B,E,N,A+2]=[\underbrace{\mathrm{extra\_onehot}}_{A},\underbrace{\mathrm{extra\_has\_deletion}}_{1},\underbrace{\mathrm{extra\_bounded\_deletion}}_{1}], zero on missing extra positions. - Return assignment, profile,
mean_deletion, features andextra_features. Database search, sequence alignment, stochastic MSA subsampling and masked-token corruption occur outside this deterministic tensor operation. - The strict missing-center/count-zero behavior differs from preprocessing paths that assume unpadded valid cluster centers.
Why this matters
Each extra sequence joins the center with the strongest weighted agreement. Within a cluster, each residue position gets its own observed count: a missing character must not dilute a profile or deletion average.
Starter code
You write the body of this function in the BioTorch workspace. Your code runs in an isolated PyTorch sandbox; Run checks the public examples and Submit grades the full test suite, including gradients.
import torch
def msa_profile_features(
msa: torch.Tensor, # (B, S, N)
extra_msa: torch.Tensor, # (B, E, N)
msa_mask: torch.Tensor, # (B, S, N)
extra_mask: torch.Tensor, # (B, E, N)
deletions: torch.Tensor, # (B, S, N)
extra_deletions: torch.Tensor, # (B, E, N)
agreement_weights: torch.Tensor, # (A,)
) -> dict[str, torch.Tensor]:
"""Return dict[str, torch.Tensor]:
assignment: (B, E).
profile: (B, S, N, A).
mean_deletion: (B, S, N).
features: (B, S, N, 2A+3).
extra_features: (B, E, N, A+2)."""
# Implement the operation. Inputs and test setup are supplied by BioTorch.
raise NotImplementedError("Implement msa_profile_features")
Ready to implement it?
3 progressive hints, a solution walkthrough, and grading that checks values, shapes and gradients are waiting in the workspace.
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Sources and further reading
A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.