> ## Documentation Index
> Fetch the complete documentation index at: https://proto.evodesign.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Protein Symmetry Ring Structure

> Constrain protein to form symmetric ring-like multimeric structure

<div class="page-hero">
  <img class="page-hero-banner" src="https://proto-bio.github.io/proto-assets/images/constraint/protein-symmetry-ring/hero.png" alt="Protein Symmetry Ring Structure" />
</div>

<Note>
  **License:** This constraint can use multiple tools, each under its own license. See the **Tools Used** tab and each tool's page for license details.
</Note>

<p class="entity-disclaimer">This constraint is open source. Any third-party models, product names, or trademarks referenced are the property of their respective owners, and Proto is not affiliated with them.</p>

<hr class="entity-rule" />

<input type="radio" name="tab-constraint-protein-symmetry-ring" id="none-constraint-protein-symmetry-ring" class="tab-radio-input" />

<input type="radio" name="tab-constraint-protein-symmetry-ring" id="tools-constraint-protein-symmetry-ring" class="tab-radio-input" defaultChecked />

<input type="radio" name="tab-constraint-protein-symmetry-ring" id="source-constraint-protein-symmetry-ring" class="tab-radio-input" />

<div class="tool-tab-bar"><span class="tool-tab-wrap"><label for="tools-constraint-protein-symmetry-ring" class="tool-tab tab-open badge-tools"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="7" height="7" x="3" y="3" rx="1" /><rect width="7" height="7" x="14" y="3" rx="1" /><rect width="7" height="7" x="14" y="14" rx="1" /><rect width="7" height="7" x="3" y="14" rx="1" /></svg> Tools Used</label><label for="none-constraint-protein-symmetry-ring" class="tool-tab tab-close badge-tools"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="7" height="7" x="3" y="3" rx="1" /><rect width="7" height="7" x="14" y="3" rx="1" /><rect width="7" height="7" x="14" y="14" rx="1" /><rect width="7" height="7" x="3" y="14" rx="1" /></svg> Tools Used</label></span> <span class="tool-tab-wrap"><label for="source-constraint-protein-symmetry-ring" class="tool-tab tab-open badge-source"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</label><label for="none-constraint-protein-symmetry-ring" class="tool-tab tab-close badge-source"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</label></span></div>

<div class="tab-panel tools-panel" data-tab="tools-constraint-protein-symmetry-ring">
  <div class="tools-used-grid">
    <a href="/docs/tools/structure-prediction/esmfold" class="tools-used-tile">
      <img noZoom src="https://proto-bio.github.io/proto-assets/images/tool/esmfold/social.png" alt="" loading="lazy" />
    </a>

    <a href="/docs/tools/orf-prediction/orfipy" class="tools-used-tile">
      <img noZoom src="https://proto-bio.github.io/proto-assets/images/tool/orfipy/social.png" alt="" loading="lazy" />
    </a>
  </div>
</div>

<a href="https://github.com/evo-design/proto-language/blob/d3b7822f74ea64747cc751a3b2ab1aa6b799ac47/proto_language/constraint/protein_structure/protein_symmetry_ring_constraint.py#L94" target="_blank" class="tab-panel source-panel" data-tab="source-constraint-protein-symmetry-ring">
  <div class="source-info">
    <img noZoom src="https://github.com/evo-design.png?size=40" class="source-avatar" width="36" height="36" />

    <span class="source-path">evo-design/proto-language<span class="source-subpath">/proto\_language/constraint/protein\_structure/protein\_symmetry\_ring\_constraint.py</span></span>
  </div>

  <span class="panel-goto-btn source-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> View source</span></span>
</a>

<div class="entity-contributors"><span class="entity-contributors-label">Constraint contributors</span><span class="entity-contributors-people"><a class="entity-contributor" href="https://github.com/dguo8412" target="_blank" rel="noopener" title="dguo8412: 3 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/46211285?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">dguo8412</span></a><a class="entity-contributor" href="https://github.com/bviggiano" target="_blank" rel="noopener" title="bviggiano: 2 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/21143637?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">bviggiano</span></a></span></div>
Constrain proteins to form symmetric ring-like multimeric structures using ESMFold.

This constraint function uses ESMFold to predict multimeric protein
structures and evaluates whether they form symmetric ring-like arrangements.
Ring symmetry is quantified by calculating the centroid (center of mass) of
each protomer's backbone and measuring how uniformly the protomers are
distributed around the ring. Perfect symmetric rings have all inter-protomer
distances equal, resulting in zero standard deviation.

Many functional protein complexes naturally form symmetric rings, including
chaperonins, proteasomes (heptameric rings), hexameric helicases, and various
ring-shaped enzymes. This constraint is useful for designing or selecting
proteins that form such symmetric assemblies.

Each input tuple is folded as one complex with an arbitrary number of protein
chains. DNA chains are first resolved with ORFipy by scanning both strands
for canonical ATG-to-stop ORFs and selecting the longest ORF as that chain's
translated CDS.

Structure prediction is GPU-intensive and may take several minutes per protein
depending on length and hardware.

## API Reference

<div class="api-model-section api-model-static api-config-section">
  <div class="api-model-header"><span class="api-model-badge api-config-badge">Config</span><span class="api-model-name">ProteinSymmetryRingConfig</span><a href="https://github.com/evo-design/proto-language/blob/d3b7822f74ea64747cc751a3b2ab1aa6b799ac47/proto_language/constraint/protein_structure/protein_symmetry_ring_constraint.py#L26" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a></div>

  Configuration for protein symmetry ring constraint.

  This class defines configuration parameters for evaluating whether proteins
  form symmetric ring-like multimeric structures using ESMFold structure
  prediction. Ring symmetry is measured by analyzing the spatial arrangement
  of protomer centroids in predicted oligomeric structures. Symmetric rings
  have protomers evenly distributed in a circular arrangement with consistent
  inter-protomer distances, characteristic of many functional protein complexes
  like chaperonins, proteasomes, and ring-shaped enzymes. Symmetry is calculated by
  taking the centroids of each protomer (using backbone atom coordinates) and
  measuring the standard deviation of distances between protomers. Lower standard
  deviation indicates more symmetric arrangements where all protomers are equally spaced.
  The score is normalized by dividing by `max_symmetry_std` and capped at 1.0.

  <ParamField path="max_symmetry_std" type="number" default="10.0">
    Max std of inter-protomer centroid distances (Å) for normalization; above this gets worst score 1.0.
  </ParamField>

  <ParamField path="all_to_all_protomer_symmetry" type="boolean" default="False">
    True uses pairwise distances between all protomers. Else, use distances between adjacent protomers
  </ParamField>

  <ParamField path="esmfold_config" type="ESMFoldConfig">
    ESMFold configuration for structure prediction.
  </ParamField>
</div>

<div class="api-model-section api-model-static api-output-section">
  <div class="api-model-header"><span class="api-model-badge api-output-badge">Returns</span><span class="api-model-name">ConstraintOutput</span></div>

  Per-proposal score in `[0.0, 1.0]` where 0.0 is
  perfect ring symmetry. Protein results attach the predicted `Structure`
  to slot 0. `metadata` carries:

  * `avg_plddt`: Float average pLDDT score for structure confidence (0.0-1.0)
  * `ptm`: Float predicted TM-score for structure accuracy (0.0-1.0)
  * `pdb_output`: String PDB format structure file content
  * `esmfolded_sequence`: String colon-separated protein-chain representation
  * `symmetry_std_raw`: Float raw standard deviation of inter-protomer
    distances in Ångströms (lower = more symmetric)
  * `symmetry_score_normalized`: Float normalized symmetry score (0.0-1.0)
  * `dna_chain_orfs`: Per-DNA-chain ORFipy metadata when DNA chains are present
</div>

## Usage

Designing a symmetric hexameric ring:

```python python icon="python" theme={null}
>>> from proto_language.core import Sequence, SequenceType
>>> seq = Sequence("MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSF", "protein")
>>> config = ProteinSymmetryRingConfig(
...     max_symmetry_std=10.0,
... )
>>> results = protein_symmetry_ring_constraint([(seq, seq, seq, seq, seq, seq)], config)
>>> print(results[0].score)  # e.g., 0.35 (3.5 Å std / 10.0 Å max)
>>> print(results[0].metadata["symmetry_std_raw"])  # e.g., 3.5 Å
>>> print(results[0].metadata["symmetry_score_normalized"])  # 0.35
```

## Metadata

| Property        | Value                              |
| --------------- | ---------------------------------- |
| Key             | `protein-symmetry-ring`            |
| Function        | `protein_symmetry_ring_constraint` |
| Category        | `protein_structure`                |
| Mode            | `discrete`                         |
| Uses GPU        | `True`                             |
| Supported Types | `dna`, `protein`                   |
