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

# Protein Domain Match

> Evaluate whether sequences contains protein domains matching specified keywords

<div class="page-hero">
  <img class="page-hero-banner" src="https://proto-bio.github.io/proto-assets/images/constraint/protein-domain/hero.png" alt="Protein Domain Match" />
</div>

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

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

<hr class="entity-rule" />

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

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

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

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

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

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

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

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

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

<div class="entity-contributors"><span class="entity-contributors-label">Constraint contributors</span><span class="entity-contributors-people"><a class="entity-contributor" href="https://github.com/dguo8412" target="_blank" rel="noopener" title="dguo8412: 5 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/46211285?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">dguo8412</span></a><a class="entity-contributor" href="https://github.com/bviggiano" target="_blank" rel="noopener" title="bviggiano: 1 commit"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/21143637?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">bviggiano</span></a></span></div>
Evaluate whether sequences contain protein domains matching specified keywords.

This constraint function searches for functional protein domains using HMMER's
hmmscan tool against HMM profile databases. It identifies domains in protein
sequences and matches them against user-specified keywords, enabling selection
of proteins with desired functional domains.

For DNA sequences, the function first runs Prodigal to predict protein-coding
regions (ORFs), then searches each predicted protein for matching domains. For
protein sequences, the domain search is performed directly. The constraint is
satisfied when the specified keyword criteria are met (any or all keywords,
depending on configuration).

## API Reference

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

  Configuration for protein domain constraint.

  This class defines configuration parameters for evaluating whether protein
  sequences contain specific functional domains identified by keyword searches
  against HMM (Hidden Markov Model) profile databases. The constraint uses
  HMMER's hmmscan tool to identify protein domains and matches them against
  user-specified keywords, enabling targeted selection for proteins with
  desired functional characteristics.

  <Note>
    For DNA sequences, Prodigal is used to predict ORFs first, then each
    predicted protein is searched for domains. For protein sequences, the
    search is performed directly.
  </Note>

  <ParamField path="hmm_db" type="string" required>
    Path to HMM database file for hmmscan (e.g., Pfam-A.hmm). Must be pressed with hmmpress.
  </ParamField>

  <ParamField path="keywords" type="List[string]" required>
    Keywords to search for in domain descriptions (case-insensitive).
  </ParamField>

  <ParamField path="evalue_threshold" type="number" default="0.005">
    Maximum E-value for significant HMM hits; lower is more stringent (typical range 0.0001 to 0.01).
  </ParamField>

  <ParamField path="query_coverage" type="number">
    Min query coverage percentage for significant hits (0-100).
  </ParamField>

  <ParamField path="match_all_keywords" type="boolean" default="False">
    If True, require ALL keywords to be found. If False, require ANY keyword (default).
  </ParamField>

  <ParamField path="hmmscan_config" type="PyHmmerConfig">
    Configuration for PyHMMER hmmscan.
  </ParamField>
</div>

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

  One result per sequence. A score of 0.0 indicates
  domain criteria are satisfied (matching domains found) and 1.0 indicates
  no matching domains found or failure to meet keyword requirements.
  `metadata` carries:

  **For DNA sequences:**

  * `prodigal_proteins`: List of dicts of predicted proteins from
    Prodigal (or `None` if no ORFs were predicted)
  * `prodigal_protein_count`: Integer count of predicted ORFs
  * `domain_search_results`: List of domain search results for each
    predicted protein
  * `domain_keywords_found`: List of unique keywords found across all
    predicted proteins
  * `domain_matching_proteins`: List of protein IDs that matched keywords

  **For protein sequences:**

  * `domain_search_results`: List containing domain search results
  * `domain_keywords_found`: List of keywords found in domain descriptions
  * `domain_matching_hits`: DataFrame of domain hits matching keywords
  * `hmmscan_all_hits`: DataFrame of all significant hmmscan hits
</div>

## Usage

Evaluating domain presence in protein with single keyword:

```python python icon="python" theme={null}
>>> from proto_language.core import Sequence, SequenceType
>>> seq = Sequence("MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSF", "protein")
>>> cfg = ProteinDomainConfig(hmm_db="Pfam-A.hmm", keywords=["kinase"], evalue_threshold=0.001)
>>> results = protein_domain_constraint([(seq,)], config=cfg)
>>> print(results[0].score)  # 0.0 if kinase domain found, 1.0 if not
>>> print(results[0].metadata["domain_keywords_found"])  # ['kinase'] if found
```

Evaluating DNA sequence (with automatic ORF prediction):

```python python icon="python" theme={null}
>>> dna_seq = Sequence("ATGGTACTGAGCCCAGCG...", "dna")
>>> cfg = ProteinDomainConfig(hmm_db="Pfam-A.hmm", keywords=["helicase"])
>>> results = protein_domain_constraint([(dna_seq,)], config=cfg)
>>> print(results[0].metadata["prodigal_protein_count"])  # Number of predicted ORFs
>>> print(results[0].metadata["domain_matching_proteins"])  # IDs of proteins with helicase domain
```

## Metadata

| Property        | Value                       |
| --------------- | --------------------------- |
| Key             | `protein-domain`            |
| Function        | `protein_domain_constraint` |
| Category        | `protein_quality`           |
| Mode            | `discrete`                  |
| Uses GPU        | `False`                     |
| Supported Types | `dna`, `protein`            |
