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

# PyHMMER

> [PyHMMER](https://github.com/althonos/pyhmmer) is a Python library that binds [HMMER3](http://hmmer.org/) for [profile hidden Markov model](https://en.wikipedia.org/wiki/Hidden_Markov_model) sequence search and domain annotation. It exposes the five canonical HMMER programs (`hmmsearch`, `hmmscan`, `phmmer`, `nhmmer`, `jackhmmer`) as Python functions, returns structured per-hit and per-domain results, and reaches the sensitivity of HMMER while staying entirely in-process.

<div class="page-hero">
  <img class="page-hero-banner" src="https://proto-bio.github.io/proto-assets/images/tool/pyhmmer/hero.png" alt="PyHMMER" />
</div>

<Note>
  **License:** PyHMMER is open source and free for academic and commercial use under an MIT license. Please refer to [the license](https://github.com/althonos/pyhmmer/blob/master/COPYING) for full terms.
</Note>

<p class="entity-disclaimer">This toolkit 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-pyhmmer" id="none-pyhmmer" class="tab-radio-input" />

<input type="radio" name="tab-pyhmmer" id="paper-pyhmmer" class="tab-radio-input" defaultChecked />

<input type="radio" name="tab-pyhmmer" id="cite-pyhmmer" class="tab-radio-input" />

<input type="radio" name="tab-pyhmmer" id="source-pyhmmer" class="tab-radio-input" />

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

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

<div class="tool-tab-bar">
  <span class="tool-tab-wrap"><label for="paper-pyhmmer" class="tool-tab tab-open badge-paper"><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="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Publication</label><label for="none-pyhmmer" class="tool-tab tab-close badge-paper"><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="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Publication</label></span> <span class="tool-tab-wrap"><label for="cite-pyhmmer" class="tool-tab tab-open badge-cite"><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="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Cite</label><label for="none-pyhmmer" class="tool-tab tab-close badge-cite"><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="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Cite</label></span> <span class="tool-tab-wrap"><label for="source-pyhmmer" 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-pyhmmer" 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-pyhmmer" 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-pyhmmer" 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-pyhmmer" 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-pyhmmer" 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://doi.org/10.1093/bioinformatics/btad214" target="_blank" class="tab-panel paper-panel" data-tab="paper-pyhmmer">
  <div class="paper-info">
    <div class="paper-title">pyHMMER: a Python library binding to HMMER for efficient sequence analysis</div>
    <div class="paper-meta">Martin Larralde and Georg Zeller</div>
    <div class="paper-meta paper-venue">Bioinformatics (2023)</div>
  </div>

  <span class="panel-goto-btn pub-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="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Read paper</span></span>
</a>

<div class="tab-panel cite-panel" data-tab="cite-pyhmmer">
  <div class="cite-code-wrap">
    ```bibtex theme={null}
    @article{larralde2023pyhmmer,
      title={pyHMMER: a Python library binding to HMMER for efficient sequence analysis},
      author={Larralde, Martin and Zeller, Georg},
      journal={Bioinformatics},
      volume={39},
      number={5},
      pages={btad214},
      year={2023},
      publisher={Oxford University Press},
      doi={10.1093/bioinformatics/btad214}
    }
    ```
  </div>

  <span class="panel-goto-btn cite-copy-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="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Copy citation</span></span>
</div>

<a href="https://github.com/evo-design/proto-tools/tree/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/gene_annotation/pyhmmer" target="_blank" class="tab-panel source-panel" data-tab="source-pyhmmer">
  <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/gene\_annotation/pyhmmer</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/gene_annotation/pyhmmer/examples/example.ipynb" target="_blank" class="tab-panel notebook-panel" data-tab="notebook-pyhmmer">
  <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-pyhmmer">
  <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/pyhmmer-hmmscan" target="_blank" class="proto-action-btn"><span>PyHMMER Scan</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>
    <a href="https://proto.evodesign.org/tools/pyhmmer-hmmsearch" target="_blank" class="proto-action-btn"><span>PyHMMER Profile Search</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>
    <a href="https://proto.evodesign.org/tools/pyhmmer-jackhmmer" target="_blank" class="proto-action-btn"><span>PyHMMER JackHMMER Search</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>
    <a href="https://proto.evodesign.org/tools/pyhmmer-nhmmer" target="_blank" class="proto-action-btn"><span>PyHMMER NHMMER Search</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>
    <a href="https://proto.evodesign.org/tools/pyhmmer-phmmer" target="_blank" class="proto-action-btn"><span>PyHMMER PHMMER Search</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: 19 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: 14 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_pyhmmer_hmmscan()`   | Search sequences against HMM database using PyHMMER                         | <a href="#api-run-pyhmmer-hmmscan" 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/gene_annotation/pyhmmer/hmmscan.py#L117" 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>     |
| `run_pyhmmer_hmmsearch()` | Search HMM profile(s) against sequences using PyHMMER                       | <a href="#api-run-pyhmmer-hmmsearch" 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/gene_annotation/pyhmmer/hmmsearch.py#L118" 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> |
| `run_pyhmmer_jackhmmer()` | Iteratively search protein sequences against protein database using PyHMMER | <a href="#api-run-pyhmmer-jackhmmer" 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/gene_annotation/pyhmmer/jackhmmer.py#L121" 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> |
| `run_pyhmmer_nhmmer()`    | Search nucleotide sequences against nucleotide database using PyHMMER       | <a href="#api-run-pyhmmer-nhmmer" 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/gene_annotation/pyhmmer/nhmmer.py#L121" 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>       |
| `run_pyhmmer_phmmer()`    | Search protein sequences against protein database using PyHMMER             | <a href="#api-run-pyhmmer-phmmer" 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/gene_annotation/pyhmmer/phmmer.py#L84" 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

[PyHMMER](https://github.com/althonos/pyhmmer) ([Larralde & Zeller, 2023](https://doi.org/10.1093/bioinformatics/btad214)) is a Cython binding to the HMMER C API that ships the HMMER source itself, so a single `pip install` provides both the Python interface and the compiled search engine. The underlying [HMMER3](http://hmmer.org/) algorithm ([Eddy, 2011](https://doi.org/10.1371/journal.pcbi.1002195)) builds a profile hidden Markov model from a [multiple sequence alignment](https://en.wikipedia.org/wiki/Multiple_sequence_alignment), where each match state stores position-specific emission probabilities and the transitions between states model insertions and deletions. Search proceeds through a cascade of accelerated filters: a [SIMD](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data)-vectorised multiple-segment Viterbi (MSV) filter, a vectorised Viterbi filter, and a Forward/Backward filter, each tightening the candidate set before the final scored alignment. Each hit carries a database-size-independent bit score together with an [E-value](https://en.wikipedia.org/wiki/E-value) derived from extreme-value-distribution theory. The E-value calibrates the expected number of false-positive hits at that bit score for the database being searched.

Profile HMMs detect homology that pairwise methods such as [BLAST](https://en.wikipedia.org/wiki/BLAST_\(biotechnology\)) miss because they encode an entire family's position-specific conservation pattern rather than the similarity of two sequences alone. HMMER3 brought profile-HMM search within roughly the runtime envelope of BLAST while keeping that sensitivity advantage. PyHMMER preserves the algorithm exactly and adds Python-native multithreading, in-memory HMM and sequence handles, and structured result objects. Coordinates returned for HMM matches, target alignments, and envelopes are reported as 1-indexed, inclusive intervals to match biological residue selection conventions.

### Learning Resources

* [pyhmmer documentation](https://pyhmmer.readthedocs.io/) (Martin Larralde) - the canonical API reference, with worked examples for every binding and a guide to feeding HMM and sequence files in and out of memory.
* [HMMER User's Guide](http://hmmer.org/) (The Eddy/Rivas Laboratory, Harvard) - reference for the HMMER 3 command-line surface, the MSV/Viterbi/Forward filter cascade, E-value statistics, and the gathering/noise/trusted cutoff system used by Pfam HMMs.
* [Pfam (via InterPro)](https://www.ebi.ac.uk/interpro/) (EMBL-EBI) - the standard curated HMM library that ships gathering, noise, and trusted cutoffs, and the typical target database for `hmmscan` domain annotation.

## Tools

<a name="api-run-pyhmmer-hmmsearch" />

<div class="tool-section-card tool-section-card--search">
  ### PyHMMER Profile Search (`pyhmmer-hmmsearch`)

  Searches one or more HMM profiles against a set of protein sequences and returns the sequences (and the per-domain alignments within them) that match each profile.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/gene_annotation/pyhmmer/hmmsearch.py#L25" 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: PyHmmsearchInput">
      <ParamField path="hmm" type="string | string" required>
        Path to an HMM file containing one or more profile HMMs. The file should be in HMMER3 format (typically `.hmm` extension). Can contain multiple HMM profiles; all will be searched against the target sequences.
      </ParamField>

      <ParamField path="sequences" type="List[string]" required>
        Target protein sequences to search. Inherited from `PyHmmerInput`. Can be a single sequence string or a list of sequence strings.
      </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/gene_annotation/pyhmmer/hmmsearch.py#L50" 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: PyHmmsearchConfig">
      <ParamField path="bit_cutoffs" type="string">
        Use the HMM's stored bit-score cutoff in place of E-value reporting. `gathering` is the Pfam-curated default for inclusion; `noise` is the most permissive; `trusted` is the strictest. None = use E-value/score thresholds. Default: None. Pyhmmer raises `MissingCutoffs` if the HMM file lacks the requested cutoff line — set None for HMMs without curated thresholds.
      </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>

      <ParamField path="num_threads" type="integer" default="0">
        CPU threads (0 = auto). Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="evalue_threshold" type="number" default="10.0">
        Sequence-level E-value cap to report. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="score_threshold" type="number">
        Sequence-level bit-score floor. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_evalue_threshold" type="number" default="10.0">
        Per-domain E-value cap to report. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_score_threshold" type="number">
        Per-domain bit-score floor. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="inclusion_evalue_threshold" type="number" default="0.01">
        Sequence-level E-value cap for inclusion. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="inclusion_domain_evalue_threshold" type="number" default="0.01">
        Per-domain E-value cap for inclusion. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="z_value" type="number">
        Effective database size. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_z_value" type="number">
        Significant hit count. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="skip_filters" type="boolean" default="False">
        Disable MSV/Vit/Fwd filters. Inherited from `PyHmmerConfig`.
      </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/gene_annotation/pyhmmer/shared_data_models.py#L197" 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: PyHmmerOutput">
      <ResponseField name="sequence_hits" type="List[SequenceHit]">
        List of sequence-level hits from the search. Each SequenceHit contains:

        <Expandable title="SequenceHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="evalue" type="number" required>
            E-value of the hit.
          </ResponseField>

          <ResponseField name="score" type="number" required>
            Bit score of the full sequence.
          </ResponseField>

          <ResponseField name="bias" type="number" required>
            Bias correction for the sequence score.
          </ResponseField>

          <ResponseField name="sum_score" type="number" required>
            Sum of domain scores.
          </ResponseField>

          <ResponseField name="reported" type="boolean" required>
            Whether the hit passes reporting thresholds.
          </ResponseField>

          <ResponseField name="included" type="boolean" required>
            Whether the hit passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="pvalue" type="number" required>
            P-value of the hit.
          </ResponseField>

          <ResponseField name="num_domains" type="integer" required>
            Number of domains found in the hit.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="domain_hits" type="List[DomainHit]">
        List of domain-level hits from the search. Each DomainHit contains:

        <Expandable title="DomainHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="hmm_length" type="integer" required>
            Length of the HMM profile.
          </ResponseField>

          <ResponseField name="hmm_from" type="integer" required>
            Start position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="hmm_to" type="integer" required>
            End position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="target_from" type="integer" required>
            Start position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_to" type="integer" required>
            End position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_length" type="integer" required>
            Length of the target sequence.
          </ResponseField>

          <ResponseField name="c_evalue" type="number" required>
            Conditional E-value of the domain.
          </ResponseField>

          <ResponseField name="i_evalue" type="number" required>
            Independent E-value of the domain.
          </ResponseField>

          <ResponseField name="domain_score" type="number" required>
            Bit score of the domain.
          </ResponseField>

          <ResponseField name="domain_bias" type="number" required>
            Bias correction of the domain score.
          </ResponseField>

          <ResponseField name="domain_idx" type="integer" required>
            Index of the domain within the hit (0-indexed).
          </ResponseField>

          <ResponseField name="env_from" type="integer" required>
            Envelope start position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="env_to" type="integer" required>
            Envelope end position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="envelope_score" type="number" required>
            Bit score of the domain envelope.
          </ResponseField>

          <ResponseField name="domain_included" type="boolean" required>
            Whether the domain passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="domain_reported" type="boolean" required>
            Whether the domain passes reporting thresholds.
          </ResponseField>

          <ResponseField name="domain_pvalue" type="number" required>
            P-value of the domain.
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  Use this when the question is "which proteins belong to family X." Build or download an HMM for a family of interest, then sweep a proteome, a [metagenome](https://en.wikipedia.org/wiki/Metagenomics), or a designed library to enumerate members and pull out their domain coordinates for downstream filtering or alignment.

  #### Usage Tips

  * **`bit_cutoffs="gathering"` activates the Pfam-curated thresholds and replaces the E-value filter.** Each Pfam HMM ships a hand-curated gathering (`--cut_ga`) cutoff that defines family membership, together with the auto-derived noise (`--cut_nc`) and trusted (`--cut_tc`) cutoffs that bracket the curated set. Use `"gathering"` for routine Pfam annotation; ad-hoc HMMs without stored cutoffs raise `MissingCutoffs`.
  * **The default `evalue_threshold=10.0` is intentionally permissive.** Tighten to `0.001` for confident annotation or `1e-10` for stringent homology detection; loose thresholds are useful only when you plan to post-filter on `included` or `domain_included`.

  <a name="api-run-pyhmmer-hmmscan" />
</div>

<div class="tool-section-card">
  ### PyHMMER HMM Scan (`pyhmmer-hmmscan`)

  Searches one or more query protein sequences against an HMM database and returns the profiles that match each query.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/gene_annotation/pyhmmer/hmmscan.py#L24" 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: PyHmmscanInput">
      <ParamField path="hmm_db" type="string | string" required>
        Path to an HMM database file containing multiple profile HMMs. The file should be in HMMER3 format and typically represents a comprehensive database like Pfam. All HMMs in the database will be searched against the query sequences.
      </ParamField>

      <ParamField path="sequences" type="List[string]" required>
        Query protein sequences to search. Inherited from `PyHmmerInput`. Can be a single sequence string or a list of sequence strings.
      </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/gene_annotation/pyhmmer/hmmscan.py#L49" 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: PyHmmscanConfig">
      <ParamField path="bit_cutoffs" type="string">
        Use the HMM's stored bit-score cutoff in place of E-value reporting. `gathering` is the Pfam-curated default for inclusion; `noise` is the most permissive; `trusted` is the strictest. None = use E-value/score thresholds. Default: None. Pyhmmer raises `MissingCutoffs` if the HMM file lacks the requested cutoff line — set None for HMMs without curated thresholds.
      </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>

      <ParamField path="num_threads" type="integer" default="0">
        CPU threads (0 = auto). Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="evalue_threshold" type="number" default="10.0">
        Sequence-level E-value cap to report. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="score_threshold" type="number">
        Sequence-level bit-score floor. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_evalue_threshold" type="number" default="10.0">
        Per-domain E-value cap to report. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_score_threshold" type="number">
        Per-domain bit-score floor. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="inclusion_evalue_threshold" type="number" default="0.01">
        Sequence-level E-value cap for inclusion. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="inclusion_domain_evalue_threshold" type="number" default="0.01">
        Per-domain E-value cap for inclusion. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="z_value" type="number">
        Effective database size. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_z_value" type="number">
        Significant hit count. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="skip_filters" type="boolean" default="False">
        Disable MSV/Vit/Fwd filters. Inherited from `PyHmmerConfig`.
      </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/gene_annotation/pyhmmer/shared_data_models.py#L197" 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: PyHmmerOutput">
      <ResponseField name="sequence_hits" type="List[SequenceHit]">
        List of sequence-level hits from the search. Each SequenceHit contains:

        <Expandable title="SequenceHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="evalue" type="number" required>
            E-value of the hit.
          </ResponseField>

          <ResponseField name="score" type="number" required>
            Bit score of the full sequence.
          </ResponseField>

          <ResponseField name="bias" type="number" required>
            Bias correction for the sequence score.
          </ResponseField>

          <ResponseField name="sum_score" type="number" required>
            Sum of domain scores.
          </ResponseField>

          <ResponseField name="reported" type="boolean" required>
            Whether the hit passes reporting thresholds.
          </ResponseField>

          <ResponseField name="included" type="boolean" required>
            Whether the hit passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="pvalue" type="number" required>
            P-value of the hit.
          </ResponseField>

          <ResponseField name="num_domains" type="integer" required>
            Number of domains found in the hit.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="domain_hits" type="List[DomainHit]">
        List of domain-level hits from the search. Each DomainHit contains:

        <Expandable title="DomainHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="hmm_length" type="integer" required>
            Length of the HMM profile.
          </ResponseField>

          <ResponseField name="hmm_from" type="integer" required>
            Start position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="hmm_to" type="integer" required>
            End position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="target_from" type="integer" required>
            Start position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_to" type="integer" required>
            End position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_length" type="integer" required>
            Length of the target sequence.
          </ResponseField>

          <ResponseField name="c_evalue" type="number" required>
            Conditional E-value of the domain.
          </ResponseField>

          <ResponseField name="i_evalue" type="number" required>
            Independent E-value of the domain.
          </ResponseField>

          <ResponseField name="domain_score" type="number" required>
            Bit score of the domain.
          </ResponseField>

          <ResponseField name="domain_bias" type="number" required>
            Bias correction of the domain score.
          </ResponseField>

          <ResponseField name="domain_idx" type="integer" required>
            Index of the domain within the hit (0-indexed).
          </ResponseField>

          <ResponseField name="env_from" type="integer" required>
            Envelope start position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="env_to" type="integer" required>
            Envelope end position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="envelope_score" type="number" required>
            Bit score of the domain envelope.
          </ResponseField>

          <ResponseField name="domain_included" type="boolean" required>
            Whether the domain passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="domain_reported" type="boolean" required>
            Whether the domain passes reporting thresholds.
          </ResponseField>

          <ResponseField name="domain_pvalue" type="number" required>
            P-value of the domain.
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  Use this when the question is "what does this protein contain." Run a query proteome against [Pfam](https://www.ebi.ac.uk/interpro/) to annotate each protein with its domain architecture, then filter on `domain_included` to keep curated hits.

  #### Usage Tips

  * **Pick `hmmscan` versus `hmmsearch` by what you are querying with.** `hmmscan` takes sequences as queries and a database of HMMs as the target; `hmmsearch` is the reverse. For one or a few queries against Pfam, `hmmscan` is the natural choice; for one HMM against a large sequence database, `hmmsearch` is much faster.
  * **`bit_cutoffs="gathering"` applies here too and is the recommended Pfam annotation default.** As with `hmmsearch`, the cutoff is read from the HMM file and ad-hoc HMMs without stored cutoffs will fail with `MissingCutoffs`.

  <a name="api-run-pyhmmer-phmmer" />
</div>

<div class="tool-section-card">
  ### PyHMMER Single-Sequence Protein Search (`pyhmmer-phmmer`)

  Searches one or more protein query sequences against a target protein database by building a temporary HMM around each query.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/gene_annotation/pyhmmer/phmmer.py#L24" 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: PyPhmmerInput">
      <ParamField path="target_sequences" type="List[string]" required>
        Target protein sequences to search against. Can be a single sequence string or a list of sequence strings. The query sequences will be compared against these targets.
      </ParamField>

      <ParamField path="sequences" type="List[string]" required>
        Query protein sequences. Inherited from `PyHmmerInput`. Can be a single sequence string or a list of sequence strings. These sequences will be used to build temporary HMM profiles on-the-fly.
      </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/gene_annotation/pyhmmer/shared_data_models.py#L330" 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: PyHmmerConfig">
      <ParamField path="num_threads" type="integer" default="0">
        CPU threads; 0 = auto-detect. Default 0.
      </ParamField>

      <ParamField path="evalue_threshold" type="number" default="10.0">
        Sequence-level E-value cap to report. Default 10.0.
      </ParamField>

      <ParamField path="score_threshold" type="number">
        Sequence-level bit-score floor. Overrides E-value when set. Default None.
      </ParamField>

      <ParamField path="domain_evalue_threshold" type="number" default="10.0">
        Per-domain E-value cap to report. Default 10.0.
      </ParamField>

      <ParamField path="domain_score_threshold" type="number">
        Per-domain bit-score floor. Overrides domain E-value when set. Default None.
      </ParamField>

      <ParamField path="inclusion_evalue_threshold" type="number" default="0.01">
        Sequence-level inclusion E-value. Default 0.01.
      </ParamField>

      <ParamField path="inclusion_domain_evalue_threshold" type="number" default="0.01">
        Per-domain inclusion E-value. Default 0.01.
      </ParamField>

      <ParamField path="z_value" type="number">
        Effective database size for E-value calc. None = use the actual target count.
      </ParamField>

      <ParamField path="domain_z_value" type="number">
        Significant hit count for domain E-value calc. None = use actual.
      </ParamField>

      <ParamField path="skip_filters" type="boolean" default="False">
        Disable MSV/Vit/Fwd heuristic filters. Slower but maximally sensitive. Default False.
      </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/gene_annotation/pyhmmer/shared_data_models.py#L197" 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: PyHmmerOutput">
      <ResponseField name="sequence_hits" type="List[SequenceHit]">
        List of sequence-level hits from the search. Each SequenceHit contains:

        <Expandable title="SequenceHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="evalue" type="number" required>
            E-value of the hit.
          </ResponseField>

          <ResponseField name="score" type="number" required>
            Bit score of the full sequence.
          </ResponseField>

          <ResponseField name="bias" type="number" required>
            Bias correction for the sequence score.
          </ResponseField>

          <ResponseField name="sum_score" type="number" required>
            Sum of domain scores.
          </ResponseField>

          <ResponseField name="reported" type="boolean" required>
            Whether the hit passes reporting thresholds.
          </ResponseField>

          <ResponseField name="included" type="boolean" required>
            Whether the hit passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="pvalue" type="number" required>
            P-value of the hit.
          </ResponseField>

          <ResponseField name="num_domains" type="integer" required>
            Number of domains found in the hit.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="domain_hits" type="List[DomainHit]">
        List of domain-level hits from the search. Each DomainHit contains:

        <Expandable title="DomainHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="hmm_length" type="integer" required>
            Length of the HMM profile.
          </ResponseField>

          <ResponseField name="hmm_from" type="integer" required>
            Start position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="hmm_to" type="integer" required>
            End position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="target_from" type="integer" required>
            Start position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_to" type="integer" required>
            End position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_length" type="integer" required>
            Length of the target sequence.
          </ResponseField>

          <ResponseField name="c_evalue" type="number" required>
            Conditional E-value of the domain.
          </ResponseField>

          <ResponseField name="i_evalue" type="number" required>
            Independent E-value of the domain.
          </ResponseField>

          <ResponseField name="domain_score" type="number" required>
            Bit score of the domain.
          </ResponseField>

          <ResponseField name="domain_bias" type="number" required>
            Bias correction of the domain score.
          </ResponseField>

          <ResponseField name="domain_idx" type="integer" required>
            Index of the domain within the hit (0-indexed).
          </ResponseField>

          <ResponseField name="env_from" type="integer" required>
            Envelope start position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="env_to" type="integer" required>
            Envelope end position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="envelope_score" type="number" required>
            Bit score of the domain envelope.
          </ResponseField>

          <ResponseField name="domain_included" type="boolean" required>
            Whether the domain passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="domain_reported" type="boolean" required>
            Whether the domain passes reporting thresholds.
          </ResponseField>

          <ResponseField name="domain_pvalue" type="number" required>
            P-value of the domain.
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  Use this for HMM-grade sensitivity when no pre-built profile is available. Typical workflows include finding remote homologs of a newly characterised protein in a reference proteome and running a sequence-based homology pass when the family of interest is too narrow or too new to have a curated HMM.

  #### Usage Tips

  * **A single-query, single-target search will not converge.** `phmmer` builds the HMM from the query against the target database's residue statistics; a database of one sequence has no background to estimate against. Use `phmmer` with a real target proteome, not a synthetic pair.

  <a name="api-run-pyhmmer-nhmmer" />
</div>

<div class="tool-section-card">
  ### PyHMMER Nucleotide Search (`pyhmmer-nhmmer`)

  Searches nucleotide query sequences against a nucleotide target database with the same profile-HMM machinery used for proteins.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/gene_annotation/pyhmmer/nhmmer.py#L24" 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: PyNhmmerInput">
      <ParamField path="target_sequences" type="List[string]" required>
        Target nucleotide sequences to search against. Can be a single sequence string or a list of sequence strings.
      </ParamField>

      <ParamField path="sequences" type="List[string]" required>
        Query nucleotide sequences. Inherited from `PyHmmerInput`. Can be a single sequence string or a list of sequence strings.
      </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/gene_annotation/pyhmmer/nhmmer.py#L60" 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: PyNhmmerConfig">
      <ParamField path="strand" type="enum" default="both">
        Strand to search. `both` (default) runs the forward strand and its reverse complement; `watson` runs only the forward strand; `crick` runs only the reverse complement.

        Available options: `both`, `watson`, `crick`
      </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>

      <ParamField path="num_threads" type="integer" default="0">
        CPU threads (0 = auto). Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="evalue_threshold" type="number" default="10.0">
        Sequence-level E-value cap to report. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="score_threshold" type="number">
        Sequence-level bit-score floor. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_evalue_threshold" type="number" default="10.0">
        Per-domain E-value cap to report. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_score_threshold" type="number">
        Per-domain bit-score floor. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="inclusion_evalue_threshold" type="number" default="0.01">
        Sequence-level E-value cap for inclusion. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="inclusion_domain_evalue_threshold" type="number" default="0.01">
        Per-domain E-value cap for inclusion. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="z_value" type="number">
        Effective database size. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_z_value" type="number">
        Significant hit count. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="skip_filters" type="boolean" default="False">
        Disable MSV/Vit/Fwd filters. Inherited from `PyHmmerConfig`.
      </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/gene_annotation/pyhmmer/shared_data_models.py#L197" 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: PyHmmerOutput">
      <ResponseField name="sequence_hits" type="List[SequenceHit]">
        List of sequence-level hits from the search. Each SequenceHit contains:

        <Expandable title="SequenceHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="evalue" type="number" required>
            E-value of the hit.
          </ResponseField>

          <ResponseField name="score" type="number" required>
            Bit score of the full sequence.
          </ResponseField>

          <ResponseField name="bias" type="number" required>
            Bias correction for the sequence score.
          </ResponseField>

          <ResponseField name="sum_score" type="number" required>
            Sum of domain scores.
          </ResponseField>

          <ResponseField name="reported" type="boolean" required>
            Whether the hit passes reporting thresholds.
          </ResponseField>

          <ResponseField name="included" type="boolean" required>
            Whether the hit passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="pvalue" type="number" required>
            P-value of the hit.
          </ResponseField>

          <ResponseField name="num_domains" type="integer" required>
            Number of domains found in the hit.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="domain_hits" type="List[DomainHit]">
        List of domain-level hits from the search. Each DomainHit contains:

        <Expandable title="DomainHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="hmm_length" type="integer" required>
            Length of the HMM profile.
          </ResponseField>

          <ResponseField name="hmm_from" type="integer" required>
            Start position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="hmm_to" type="integer" required>
            End position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="target_from" type="integer" required>
            Start position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_to" type="integer" required>
            End position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_length" type="integer" required>
            Length of the target sequence.
          </ResponseField>

          <ResponseField name="c_evalue" type="number" required>
            Conditional E-value of the domain.
          </ResponseField>

          <ResponseField name="i_evalue" type="number" required>
            Independent E-value of the domain.
          </ResponseField>

          <ResponseField name="domain_score" type="number" required>
            Bit score of the domain.
          </ResponseField>

          <ResponseField name="domain_bias" type="number" required>
            Bias correction of the domain score.
          </ResponseField>

          <ResponseField name="domain_idx" type="integer" required>
            Index of the domain within the hit (0-indexed).
          </ResponseField>

          <ResponseField name="env_from" type="integer" required>
            Envelope start position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="env_to" type="integer" required>
            Envelope end position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="envelope_score" type="number" required>
            Bit score of the domain envelope.
          </ResponseField>

          <ResponseField name="domain_included" type="boolean" required>
            Whether the domain passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="domain_reported" type="boolean" required>
            Whether the domain passes reporting thresholds.
          </ResponseField>

          <ResponseField name="domain_pvalue" type="number" required>
            P-value of the domain.
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  Use this to find homologs of transposable elements, non-coding RNAs, regulatory elements, and other nucleotide features that diverge fast enough to slip past direct sequence alignment. Pair it with [Dfam](https://www.dfam.org/) - the curated profile-HMM library of transposable-element families that was co-designed with nhmmer - or with custom-built nucleotide HMMs when annotating genomes and metagenomic contigs.

  #### Usage Tips

  * **`strand` defaults to `"both"` and searches the forward and reverse-complement strands.** Set `"watson"` to restrict to forward or `"crick"` to restrict to reverse-complement when the orientation of a hit is meaningful (e.g., on annotated coding strands).

  <a name="api-run-pyhmmer-jackhmmer" />
</div>

<div class="tool-section-card">
  ### PyHMMER Iterative Protein Search (`pyhmmer-jackhmmer`)

  Performs iterative protein-sequence search against a target protein database, rebuilding the HMM from each round's included hits to extend the search outward across remote homologs.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/gene_annotation/pyhmmer/jackhmmer.py#L24" 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: PyJackhmmerInput">
      <ParamField path="target_sequences" type="List[string]" required>
        Target protein sequences to search against. Can be a single sequence string or a list of sequence strings.
      </ParamField>

      <ParamField path="sequences" type="List[string]" required>
        Query protein sequences. Inherited from `PyHmmerInput`. Can be a single sequence string or a list of sequence strings.
      </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/gene_annotation/pyhmmer/jackhmmer.py#L55" 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: PyJackhmmerConfig">
      <ParamField path="max_iterations" type="integer" default="5">
        Maximum jackhmmer iterations; stops early on convergence. Default 5.
      </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>

      <ParamField path="num_threads" type="integer" default="0">
        CPU threads (0 = auto). Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="evalue_threshold" type="number" default="10.0">
        Sequence-level E-value cap to report. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="score_threshold" type="number">
        Sequence-level bit-score floor. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_evalue_threshold" type="number" default="10.0">
        Per-domain E-value cap to report. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_score_threshold" type="number">
        Per-domain bit-score floor. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="inclusion_evalue_threshold" type="number" default="0.01">
        Sequence-level inclusion E-value. Inherited from `PyHmmerConfig`. Critical for jackhmmer — the included set seeds the next iteration's HMM.
      </ParamField>

      <ParamField path="inclusion_domain_evalue_threshold" type="number" default="0.01">
        Per-domain inclusion E-value. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="z_value" type="number">
        Effective database size for E-value calc. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="domain_z_value" type="number">
        Significant hit count for domain E-value. Inherited from `PyHmmerConfig`.
      </ParamField>

      <ParamField path="skip_filters" type="boolean" default="False">
        Disable MSV/Vit/Fwd filters. Inherited from `PyHmmerConfig`.
      </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/gene_annotation/pyhmmer/shared_data_models.py#L197" 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: PyHmmerOutput">
      <ResponseField name="sequence_hits" type="List[SequenceHit]">
        List of sequence-level hits from the search. Each SequenceHit contains:

        <Expandable title="SequenceHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="evalue" type="number" required>
            E-value of the hit.
          </ResponseField>

          <ResponseField name="score" type="number" required>
            Bit score of the full sequence.
          </ResponseField>

          <ResponseField name="bias" type="number" required>
            Bias correction for the sequence score.
          </ResponseField>

          <ResponseField name="sum_score" type="number" required>
            Sum of domain scores.
          </ResponseField>

          <ResponseField name="reported" type="boolean" required>
            Whether the hit passes reporting thresholds.
          </ResponseField>

          <ResponseField name="included" type="boolean" required>
            Whether the hit passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="pvalue" type="number" required>
            P-value of the hit.
          </ResponseField>

          <ResponseField name="num_domains" type="integer" required>
            Number of domains found in the hit.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="domain_hits" type="List[DomainHit]">
        List of domain-level hits from the search. Each DomainHit contains:

        <Expandable title="DomainHit">
          <ResponseField name="query_name" type="string" required>
            Name of the query HMM.
          </ResponseField>

          <ResponseField name="query_accession" type="string" required>
            Accession of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_description" type="string" required>
            Description of the query HMM. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="query_idx" type="integer" required>
            Index of the query (0-indexed).
          </ResponseField>

          <ResponseField name="target_name" type="string" required>
            Name of the target sequence.
          </ResponseField>

          <ResponseField name="target_accession" type="string" required>
            Accession of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="target_description" type="string" required>
            Description of the target sequence. `"-"` if unavailable.
          </ResponseField>

          <ResponseField name="hmm_length" type="integer" required>
            Length of the HMM profile.
          </ResponseField>

          <ResponseField name="hmm_from" type="integer" required>
            Start position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="hmm_to" type="integer" required>
            End position of the domain match in the HMM (1-indexed).
          </ResponseField>

          <ResponseField name="target_from" type="integer" required>
            Start position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_to" type="integer" required>
            End position of the domain match in the target (1-indexed).
          </ResponseField>

          <ResponseField name="target_length" type="integer" required>
            Length of the target sequence.
          </ResponseField>

          <ResponseField name="c_evalue" type="number" required>
            Conditional E-value of the domain.
          </ResponseField>

          <ResponseField name="i_evalue" type="number" required>
            Independent E-value of the domain.
          </ResponseField>

          <ResponseField name="domain_score" type="number" required>
            Bit score of the domain.
          </ResponseField>

          <ResponseField name="domain_bias" type="number" required>
            Bias correction of the domain score.
          </ResponseField>

          <ResponseField name="domain_idx" type="integer" required>
            Index of the domain within the hit (0-indexed).
          </ResponseField>

          <ResponseField name="env_from" type="integer" required>
            Envelope start position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="env_to" type="integer" required>
            Envelope end position in the target (1-indexed).
          </ResponseField>

          <ResponseField name="envelope_score" type="number" required>
            Bit score of the domain envelope.
          </ResponseField>

          <ResponseField name="domain_included" type="boolean" required>
            Whether the domain passes inclusion thresholds.
          </ResponseField>

          <ResponseField name="domain_reported" type="boolean" required>
            Whether the domain passes reporting thresholds.
          </ResponseField>

          <ResponseField name="domain_pvalue" type="number" required>
            P-value of the domain.
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  Use this when you need to reach divergent family members that a single-pass `phmmer` would miss, for example when seeding a new family from one characterised representative or expanding a manually curated set to its full evolutionary breadth.

  #### Usage Tips

  * **`inclusion_evalue_threshold` is the lever that controls iterative drift.** Each iteration rebuilds the HMM from hits that pass the inclusion thresholds (`--incE` / `--incdomE`, defaults `0.01`). A looser inclusion threshold pulls in more sequences per round and increases the risk of pulling in unrelated families; tighten it when iterations start drifting.
  * **`max_iterations` defaults to 5 and the search exits early on convergence.** Raising it rarely helps if the search has already converged on a stable set, and a higher cap multiplies runtime on long-running jobs.
</div>

## Toolkit Notes

These apply to every PyHMMER tool in this toolkit (`pyhmmer-hmmsearch`, `pyhmmer-hmmscan`, `pyhmmer-phmmer`, `pyhmmer-nhmmer`, `pyhmmer-jackhmmer`).

* **Runs on CPU with SIMD acceleration.** The HMMER3 filter cascade is SIMD-vectorised on x86 platforms. pyhmmer compiles HMMER from source at install time and inherits whatever instruction sets the build host exposes, with no GPU acceleration to enable.
* **Self-contained after install.** The HMMER C library is compiled into the PyHMMER wheel, so no separate HMMER install or PATH lookup is needed; HMM databases such as Pfam-A still have to be downloaded separately.
* **`num_threads` parallelises within a single search.** Default `0` auto-detects the available cores. Memory scales with HMM database size; Pfam-A (around 20,000 HMMs) needs roughly 2 GB of RAM held resident.
* **Reporting versus inclusion thresholds are independent filters.** `evalue_threshold` / `score_threshold` (and their `domain_*` siblings) control what appears in the output, while `inclusion_evalue_threshold` marks the stricter "trusted" subset via the `included` and `domain_included` flags. `jackhmmer` seeds the next iteration's HMM from the included set, so the inclusion threshold drives iterative behaviour while reporting only affects what is returned.

<Tip>
  **Example notebook:** See the [full working example](https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/gene_annotation/pyhmmer/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>
