> ## 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.

# Semigreedy Mutation Generator

> Logit-guided single-point mutations for semigreedy discrete refinement

<div class="page-hero">
  <img class="page-hero-banner" src="https://proto-bio.github.io/proto-assets/images/generator/semigreedy-mutation/hero.png" alt="Semigreedy Mutation Generator" />
</div>

<p class="entity-disclaimer">This generator 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" />

<div class="tool-tab-bar entity-source-bar"><span class="tool-tab-wrap"><span class="tool-tab badge-source entity-source-tab"><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</span></span></div>

<a href="https://github.com/evo-design/proto-language/blob/d3b7822f74ea64747cc751a3b2ab1aa6b799ac47/proto_language/generator/semigreedy_mutation_generator.py#L119" target="_blank" class="tab-panel source-panel entity-source-panel">
  <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/generator/semigreedy\_mutation\_generator.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">Generator contributors</span><span class="entity-contributors-people"><a class="entity-contributor" href="https://github.com/dguo8412" target="_blank" rel="noopener" title="dguo8412: 4 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></span></div>
Introduce single-point mutations guided by a PSSM derived from `seq.logits`.

Each call to `sample()` selects one position per proposal sequence and
replaces the amino acid there by sampling from the softmax distribution over
logits (with the current residue optionally excluded). Position selection is
controlled by `position_weighting`:

* `"uniform"`: every position is equally likely.
* `"entropy"`: positions with higher Shannon entropy in the PSSM are more
  likely, targeting the most uncertain residues.
* `"plddt"`: positions are weighted by `(1 - pLDDT)` read from the
  canonical `proposal.structure.per_residue_plddt` property when a
  `Structure` with pLDDT B-factors is present, so structurally uncertain
  residues are mutated more frequently; otherwise it falls back to uniform.

`frozen_positions` hard-excludes listed indices from selection (deterministic
counterpart to `sequence_bias`); whatever residue is there stays. Implements
Germinal's `design_semigreedy` phase (`MCMCOptimizer` at near-zero
temperature, `proposals_per_result > 1`).

<Note>
  `clear_logits=False` (default) requires upstream `GradientOptimizer` logits at
  runtime; `clear_logits=True` runs as pure sequence-only mutation.
</Note>

## 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">SemigreedyMutationGeneratorConfig</span><a href="https://github.com/evo-design/proto-language/blob/d3b7822f74ea64747cc751a3b2ab1aa6b799ac47/proto_language/generator/semigreedy_mutation_generator.py#L22" 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 semigreedy single-point mutation sampling.

  Converts `seq.logits` (from a preceding gradient-based optimizer) to a PSSM
  via softmax and samples single-point mutations from it. Stage 2 of the Germinal
  pipeline: paired with `MCMCOptimizer` at near-zero temperature for
  greedy/semigreedy discrete refinement.

  <ParamField path="position_weighting" type="enum" default="uniform">
    'uniform' picks at random; 'entropy' picks high-entropy positions; 'plddt' picks low-pLDDT.

    Options: `uniform`, `entropy`, `plddt`
  </ParamField>

  <ParamField path="temperature" type="number" default="1.0">
    Softmax temperature on logits when building the PSSM. Below 1 sharpens; above 1 flattens (> 0).
  </ParamField>

  <ParamField path="exclude_current" type="boolean" default="True">
    Zero out the current amino acid before sampling to guarantee a mutation.
  </ParamField>

  <ParamField path="sequence_bias" type="SequenceLogitBiasConfig">
    Optional declarative sequence-symbol bias applied before AA sampling.
  </ParamField>

  <ParamField path="clear_logits" type="boolean" default="False">
    When True, ignore proposal logits and sample replacement from sequence\_bias (or uniform if unset).
  </ParamField>

  <ParamField path="frozen_positions" type="array">
    Position indices to keep untouched during mutation (Python-style zero-based).
  </ParamField>
</div>

## Usage

```python python icon="python" theme={null}
>>> from proto_language.core import Segment
>>> segment = Segment(sequence="ACDEF", sequence_type="protein")
>>> gen = SemigreedyMutationGenerator(SemigreedyMutationGeneratorConfig(position_weighting="entropy"))
>>> gen.assign(segment)
>>> # Normally logits come from a GradientOptimizer; here we set them manually:
>>> import numpy as np
>>> segment.proposal_sequences[0].logits = np.random.randn(5, 20)
>>> gen.sample()
>>> # Exactly one position differs from "ACDEF"
```

## Metadata

| Property                 | Value                         |
| ------------------------ | ----------------------------- |
| Key                      | `semigreedy-mutation`         |
| Class                    | `SemigreedyMutationGenerator` |
| Category                 | `mutation`                    |
| Input Type               | `starting_sequence`           |
| Uses GPU                 | `False`                       |
| Supported Sequence Types | `protein`                     |
| Allows Empty Start       | `False`                       |
