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

# Random Nucleotide Sampling

> Random Nucleotide Sampling fills the masked positions of a DNA or RNA sequence with random bases drawn from an IUPAC ambiguity-code pool. Positions can be marked directly with `_` or selected automatically by a masking strategy, and the substitution alphabet is set by a single IUPAC code: `N` for any base, `R` for purines, `S` for strong pairs, and so on. It runs on CPU with no model and no external dependencies, and serves as an unbiased random baseline for sequence-design and library-generation workflows.

<div class="page-hero"><img class="page-hero-banner" src="https://proto-bio.github.io/proto-assets/images/tool/random_nucleotide/hero.png" alt="Random Nucleotide Sampling" /><div class="tool-org-badges page-hero-badges"><a href="/docs/tools/organizations/proto" class="tool-org-badge" style={{background: "#7C3AED"}} title="Proto"><img src="https://mintcdn.com/bio-pro/UeudeF7pW-Dj-pIN/assets/images/cached/5586d2ede12e.png?fit=max&auto=format&n=UeudeF7pW-Dj-pIN&q=85&s=5d259f1a4ac3d5597c20cba7aa7521b2" alt="" class="tool-org-badge-logo" width="200" height="200" data-path="assets/images/cached/5586d2ede12e.png" /> Proto</a></div></div>

<Note>
  **License:** Random Nucleotide Sampling is open source and free for academic and commercial use under an MIT license. Please refer to [the license](https://github.com/evo-design/proto-tools) for full terms.
</Note>

<p class="entity-disclaimer">Proto is not affiliated with Proto. This toolkit is open source and builds on the implementation produced by this organization. Product names, logos, and trademarks are the property of their respective owners.</p>

<hr class="entity-rule" />

<input type="radio" name="tab-random-nucleotide" id="none-random-nucleotide" class="tab-radio-input" />

<input type="radio" name="tab-random-nucleotide" id="source-random-nucleotide" class="tab-radio-input" defaultChecked />

<input type="radio" name="tab-random-nucleotide" id="notebook-random-nucleotide" class="tab-radio-input" />

<input type="radio" name="tab-random-nucleotide" id="proto-random-nucleotide" class="tab-radio-input" />

<div class="tool-tab-bar">
  <span class="tool-tab-wrap"><label for="source-random-nucleotide" 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> Tool Source</label><label for="none-random-nucleotide" 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> Tool Source</label></span> <span class="tool-tab-wrap"><label for="notebook-random-nucleotide" class="tool-tab tab-open badge-notebook"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open as Notebook</label><label for="none-random-nucleotide" class="tool-tab tab-close badge-notebook"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open as Notebook</label></span> <span class="tool-tab-wrap"><label for="proto-random-nucleotide" class="tool-tab tab-open badge-proto"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" /></svg> Open on Proto</label><label for="none-random-nucleotide" class="tool-tab tab-close badge-proto"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" /></svg> Open on Proto</label></span>
</div>

<a href="https://github.com/evo-design/proto-tools/tree/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/mutagenesis/random_nucleotide" target="_blank" class="tab-panel source-panel" data-tab="source-random-nucleotide">
  <div class="source-info">
    <img src="https://github.com/evo-design.png?size=40" class="source-avatar" width="36" height="36" />

    <span class="source-path">evo-design/proto-tools<span class="source-subpath">/proto\_tools/tools/mutagenesis/random\_nucleotide</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>

<a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/mutagenesis/random_nucleotide/examples/example.ipynb" target="_blank" class="tab-panel notebook-panel" data-tab="notebook-random-nucleotide">
  <div class="notebook-info">
    <span class="notebook-icon">
      <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
        <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />

        <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
      </svg>
    </span>

    <span class="notebook-label">Open Notebook</span>
  </div>

  <span class="panel-goto-btn notebook-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open notebook</span></span>
</a>

<div class="tab-panel proto-panel" data-tab="proto-random-nucleotide">
  <div class="proto-info">
    <div class="proto-cloud">
      <svg class="proto-cloud-bg" viewBox="0 0 640 512" xmlns="http://www.w3.org/2000/svg">
        <path d="M0 336c0 79.5 64.5 144 144 144H512c70.7 0 128-57.3 128-128c0-61.9-44-113.6-102.4-125.4c4.1-10.7 6.4-22.4 6.4-34.6c0-53-43-96-96-96c-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32C167.6 32 96 103.6 96 192c0 2.7 .1 5.4 .2 8.1C40.2 219.8 0 273.2 0 336z" />
      </svg>

      <img noZoom src="https://mintcdn.com/bio-pro/KVh0EKV-IKblvXR8/assets/logo/evo-logo-light.svg?fit=max&auto=format&n=KVh0EKV-IKblvXR8&q=85&s=0cb66034ba45618505501aee6ea5f5c1" class="proto-panel-logo block dark:hidden" alt="Proto" width="198" height="151" data-path="assets/logo/evo-logo-light.svg" />

      <img noZoom src="https://mintcdn.com/bio-pro/KVh0EKV-IKblvXR8/assets/logo/evo-logo-dark.svg?fit=max&auto=format&n=KVh0EKV-IKblvXR8&q=85&s=2c9e23a14635e60384a434e220788f54" class="proto-panel-logo hidden dark:block" alt="Proto" width="198" height="151" data-path="assets/logo/evo-logo-dark.svg" />
    </div>
  </div>

  <div class="proto-actions">
    <a href="https://proto.evodesign.org/tools/random-nucleotide-sample" target="_blank" class="proto-action-btn"><span>Random Nucleotide Sampling</span><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="7" y1="17" x2="17" y2="7" /><polyline points="7 7 17 7 17 17" /></svg></a>
  </div>
</div>

<div class="entity-contributors"><span class="entity-contributors-label">Toolkit contributors</span><span class="entity-contributors-people"><a class="entity-contributor" href="https://github.com/bviggiano" target="_blank" rel="noopener" title="bviggiano: 21 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><a class="entity-contributor" href="https://github.com/dguo8412" target="_blank" rel="noopener" title="dguo8412: 10 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/leba01" target="_blank" rel="noopener" title="leba01: 3 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/124846286?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">leba01</span></a></span></div>

| Function                         | Description                                                                                          |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| -------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `run_random_nucleotide_sample()` | Sample nucleotide sequences by filling masked positions with random bases from an IUPAC substitut... | <a href="#api-run-random-nucleotide-sample" class="func-table-btn func-api-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20" /></svg> Docs</a> <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/mutagenesis/random_nucleotide/random_nucleotide_sample.py#L216" target="_blank" class="func-table-btn func-source-btn"><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> |

## Background

Random Nucleotide Sampling performs random mutagenesis at the nucleotide level: it takes a DNA or RNA sequence, determines which positions are designable, and replaces each with a base drawn uniformly from a chosen IUPAC degenerate-base pool. It generates nucleotide diversity without any learned model, the simplest possible baseline against which model-guided generators can be compared.

Internally, designable positions are either the `_` characters already present in the input or, when none are present, positions chosen by the configured masking strategy. Each masked position is filled independently by drawing one base uniformly at random from the pool that the IUPAC code expands to: `N` expands to A/C/G/T, `R` to A/G, `S` to G/C, and so on. Sampling is uniform within the pool, with no frequency weighting. When the input is RNA, sampled `T` bases are converted to `U`. With a fixed seed the output is deterministic.

This tool is original proto-tools code maintained by [Proto](https://github.com/evo-design/proto-tools).

## Tools

<a name="api-run-random-nucleotide-sample" />

<div class="tool-section-card tool-section-card--sample">
  ### Random Nucleotide Sampling (`random-nucleotide-sample`)

  Fills every masked position in each input sequence with a random base from the configured IUPAC substitution pool, returning one filled sequence per input.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/mutagenesis/random_nucleotide/random_nucleotide_sample.py#L51" 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>

    <Accordion title="Input: RandomNucleotideSampleInput">
      <ParamField path="sequences" type="List[string]" required>
        DNA or RNA sequences, possibly containing `_` at positions to mutate. Accepts a single string or a list.
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-config-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/mutagenesis/random_nucleotide/random_nucleotide_sample.py#L132" 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>

    <Accordion title="Config: RandomNucleotideSampleConfig">
      <ParamField path="masking_strategy" type="RandomMaskingStrategy">
        Controls which positions to mask for sampling.

        <Expandable title="RandomMaskingStrategy">
          <ParamField path="method" type="string" default="random">
            Position-selection method. Always `"random"` for this tier (uniform selection, no model).
          </ParamField>

          <ParamField path="num_mutations" type="integer">
            Exact number of positions to mask per sequence.
          </ParamField>

          <ParamField path="mask_fraction" type="number">
            Fraction of designable positions to mask (e.g. 0.15 for \~15%).
          </ParamField>

          <ParamField path="fixed_positions" type="array">
            1-indexed positions that must NOT be masked. Applied uniformly to all sequences.
          </ParamField>
        </Expandable>
      </ParamField>

      <ParamField path="substitution_scheme" type="enum" default="N">
        IUPAC ambiguity code defining the nucleotide pool for substitutions. `"N"` = any base (ACGT); `"R"` = purines (AG); `"Y"` = pyrimidines (CT); etc.

        Available options: `N`, `R`, `Y`, `S`, `W`, `K`, `M`, `B`, `D`, `H`, `V`
      </ParamField>

      <ParamField path="sequence_type" type="enum" default="auto">
        How to interpret input sequences. `"auto"` detects DNA vs RNA by presence of U; `"dna"` or `"rna"` forces the type.

        Available options: `auto`, `dna`, `rna`
      </ParamField>

      <ParamField path="verbose" type="integer" default="0">
        Verbosity level (0=quiet, 1=info, 2=debug, 3=raw subprocess stderr). `True` is coerced to `1` and `False` to `0`.
      </ParamField>

      <ParamField path="device" type="string" default="cpu">
        Device to run the tool on.
      </ParamField>

      <ParamField path="timeout" type="integer" default="3600">
        Maximum execution time in seconds. `None` waits indefinitely.
      </ParamField>

      <ParamField path="seed" type="integer">
        Random seed. When set, tools run reproducibly up to small GPU float noise (see `BaseToolOutput.approx_equal`), and the seed participates in cache keys. When None, cacheable seed-sensitive tools skip cache until seeded.
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-output-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/mutagenesis/random_nucleotide/random_nucleotide_sample.py#L89" 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>

    <Accordion title="Output: RandomNucleotideSampleOutput">
      <ResponseField name="results" type="List[RandomNucleotideSample]" required>
        One sampled sequence per input, in input order.

        <Expandable title="RandomNucleotideSample">
          <ResponseField name="sequence" type="string" required>
            Nucleotide sequence with masked positions filled by random bases.
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  Use this to build randomized nucleotide libraries: degenerate positions in promoters, ribosome binding sites, UTRs, or coding regions for directed-evolution and combinatorial-screening campaigns. It also serves as an unbiased random baseline for judging whether a model-guided generator produces better-than-chance sequences.

  #### Usage Tips

  * **`substitution_scheme` (default `N`) sets the substitution alphabet.** `N` allows any base for maximum diversity; restrict it to bias the library, for example `R` for purines (A/G), `S` for strong pairs (G/C), or `W` for weak pairs (A/T).
  * **`_` masks override the masking strategy.** If an input already contains `_`, exactly those positions are filled and `masking_strategy` is ignored; remove the `_` characters to let the strategy choose positions instead.
  * **`sequence_type` (default `auto`) controls RNA handling.** `auto` treats the sequence as RNA only when it contains `U`; force it with `dna` or `rna`. In RNA mode sampled `T` bases are written as `U`, so set `rna` explicitly when the input is fully masked.
  * **`masking_strategy.fixed_positions` are 1-indexed.** Positions listed there are never mutated; they are specified using 1-based indexing to match biological residue selection conventions.
  * **Set `seed` for reproducibility.** Sampling is otherwise nondeterministic; a fixed seed makes the filled sequences reproducible across runs.
</div>

## Toolkit Notes

These apply to every Random Nucleotide Sampling tool in this toolkit (`random-nucleotide-sample`).

* **Runs on CPU.** The sampler is pure Python with no model and no external dependencies; execution is near-instant.
* **Deterministic only with a seed.** Without a `seed` the filled positions differ every run; set one when you need reproducible libraries.

<Tip>
  **Example notebook:** See the [full working example](https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/mutagenesis/random_nucleotide/examples/example.ipynb) for a copy-paste-ready walkthrough.
</Tip>

## Infrastructure Guides

The following guides cover how to run tools efficiently and at scale.

<CardGroup cols={2}>
  <Card title="Tool Persistence" icon="repeat" href="/docs/tools/guides/tool-persistence">Keep a tool's model warm across calls instead of reloading it every invocation.</Card>
  <Card title="Device Management" icon="cpu" href="/docs/tools/guides/device-management">How GPUs are allocated to tools and how to target specific devices.</Card>
  <Card title="Parallel Execution" icon="layers" href="/docs/tools/guides/parallel-execution">Fan a batch of inputs out across multiple GPUs.</Card>
</CardGroup>
