# kprot


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

The sections below introduce the package and show quick-start examples
from each exported module.

## Installation

``` bash
pip install kprot
```

## Quick start

The examples below follow the notebooks under `nbs/` in order. Each
function example lives in its own cell and starts with a short comment
derived from the function docstring.

### 01 utils

``` python
from kprot.uniprot import get_uniprot_seq, get_uniprot_features, get_uniprot_kd, get_uniprot_type, apply_mut_single, apply_mut_complex, compare_seq
```

``` python
import re
from functools import lru_cache
import requests
from Bio.Align import PairwiseAligner
```

``` python
# Queries the UniProt database to retrieve the protein sequence for a given UniProt ID.
get_uniprot_seq("P04626")[:60]
```

    'MELAALCRWGLLLALLPPGAASTQVCTGTDMKLRLPASPETHLDMLRHLYQGCQVVQGNL'

``` python
# Given a UniProt ID, fetch the protein metadata and annotated features.
get_uniprot_features("P04626").keys()
```

    dict_keys(['uniprot_id', 'protein_name', 'gene_name', 'features'])

``` python
# Query Domain: Protein kinase entries based on a UniProt ID.
get_uniprot_kd("P04626")
```

    [{'uniprot_id': 'P04626',
      'protein_name': 'Receptor tyrosine-protein kinase erbB-2',
      'gene_name': 'ERBB2',
      'start': 720,
      'end': 987,
      'description': 'Protein kinase',
      'sequence': 'LRKVKVLGSGAFGTVYKGIWIPDGENVKIPVAIKVLRENTSPKANKEILDEAYVMAGVGSPYVSRLLGICLTSTVQLVTQLMPYGCLLDHVRENRGRLGSQDLLNWCMQIAKGMSYLEDVRLVHRDLAARNVLVKSPNHVKITDFGLARLLDIDETEYHADGGKVPIKWMALESILRRRFTHQSDVWSYGVTVWELMTFGAKPYDGIPAREIPDLLEKGERLPQPPICTIDVYMIMVKCWMIDSECRPRFRELVSEFSRMARDPQRFV'}]

``` python
# Get region sequences for a UniProt feature type.
get_uniprot_type("P04626", "Signal")[:1]
```

    [{'uniprot_id': 'P04626',
      'type': 'Signal',
      'protein_name': 'Receptor tyrosine-protein kinase erbB-2',
      'gene_name': 'ERBB2',
      'start': 1,
      'end': 22,
      'description': '',
      'sequence': 'MELAALCRWGLLLALLPPGAAS'}]

``` python
# Apply point mutations to a protein sequence.
apply_mut_single("MEEPQ", "M1A", "E2S")
```

    Converted: M1A
    Converted: E2S

    'ASEPQ'

``` python
# Apply a composite mutation string to a protein sequence.
her2_seq = "LRKVKVLGSGAFGTVYKGIWIPDGENVKIPVAIKVLRENTSPKANKEILDEAYVMAGVGSPYVSRLLGICLTSTVQLVTQLMPYGCLLDHVRENRGRLGSQDLLNWCMQIAKGMSYLEDVRLVHRDLAARNVLVKSPNHVKITDFGLARLLDIDETEYHADGGKVPIKWMALESILRRRFTHQSDVWSYGVTVWELMTFGAKPYDGIPAREIPDLLEKGERLPQPPICTIDVYMIMVKCWMIDSECRPRFRELVSEFSRMARDPQRFV"
apply_mut_complex(her2_seq, "G776delinsVC/S783C", start_pos=720)[:25]
```

    'LRKVKVLGSGAFGTVYKGIWIPDGE'

``` python
# Align two protein sequences and summarize the differences.
print(compare_seq("MEEPQ", "MAEPQ", return_text=True))
```

    Original       1-5    : MEEPQ
    Mutant                : MAEPQ
                             ^   

    Differences:
      substitution at    2: E → A

### 02 onehot kmeans

``` python
from kprot.onehot import onehot_encode, onehot_encode_df, run_kmeans, filter_range_columns, get_clusters_elbow
```

``` python
import pandas as pd

# Set up the objects used by the examples below.
df = pd.DataFrame(
    {
        "site_seq": [
            "AASTYGVAKR",
            "GGSTYGVAKR",
            "AASTFGVAKR",
            "PPSTYGVAKK",
            "VVSTYGIARR",
        ]
    }
)
df.shape

df.head()
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&#10;    .dataframe tbody tr th {
        vertical-align: top;
    }
&#10;    .dataframe thead th {
        text-align: right;
    }
</style>

<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">site_seq</th>
</tr>
</thead>
<tbody>
<tr>
<td data-quarto-table-cell-role="th">0</td>
<td>AASTYGVAKR</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">1</td>
<td>GGSTYGVAKR</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">2</td>
<td>AASTFGVAKR</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">3</td>
<td>PPSTYGVAKK</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">4</td>
<td>VVSTYGIARR</td>
</tr>
</tbody>
</table>

</div>

``` python
# One-hot encode aligned protein sequence windows.
onehot_encode(df["site_seq"]).head()
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&#10;    .dataframe tbody tr th {
        vertical-align: top;
    }
&#10;    .dataframe thead th {
        text-align: right;
    }
</style>

<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">-20A</th>
<th data-quarto-table-cell-role="th">-20G</th>
<th data-quarto-table-cell-role="th">-20P</th>
<th data-quarto-table-cell-role="th">-20V</th>
<th data-quarto-table-cell-role="th">-19A</th>
<th data-quarto-table-cell-role="th">-19G</th>
<th data-quarto-table-cell-role="th">-19P</th>
<th data-quarto-table-cell-role="th">-19V</th>
<th data-quarto-table-cell-role="th">-18S</th>
<th data-quarto-table-cell-role="th">-17T</th>
<th data-quarto-table-cell-role="th">-16F</th>
<th data-quarto-table-cell-role="th">-16Y</th>
<th data-quarto-table-cell-role="th">-15G</th>
<th data-quarto-table-cell-role="th">-14I</th>
<th data-quarto-table-cell-role="th">-14V</th>
<th data-quarto-table-cell-role="th">-13A</th>
<th data-quarto-table-cell-role="th">-12K</th>
<th data-quarto-table-cell-role="th">-12R</th>
<th data-quarto-table-cell-role="th">-11K</th>
<th data-quarto-table-cell-role="th">-11R</th>
</tr>
</thead>
<tbody>
<tr>
<td data-quarto-table-cell-role="th">0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">1</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">2</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">3</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">4</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
</tr>
</tbody>
</table>

</div>

``` python
# One-hot encode a sequence column from a dataframe.
onehot = onehot_encode_df(df, seq_col="site_seq")
onehot.head()
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&#10;    .dataframe tbody tr th {
        vertical-align: top;
    }
&#10;    .dataframe thead th {
        text-align: right;
    }
</style>

<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">-20A</th>
<th data-quarto-table-cell-role="th">-20G</th>
<th data-quarto-table-cell-role="th">-20P</th>
<th data-quarto-table-cell-role="th">-20V</th>
<th data-quarto-table-cell-role="th">-19A</th>
<th data-quarto-table-cell-role="th">-19G</th>
<th data-quarto-table-cell-role="th">-19P</th>
<th data-quarto-table-cell-role="th">-19V</th>
<th data-quarto-table-cell-role="th">-18S</th>
<th data-quarto-table-cell-role="th">-17T</th>
<th data-quarto-table-cell-role="th">-16F</th>
<th data-quarto-table-cell-role="th">-16Y</th>
<th data-quarto-table-cell-role="th">-15G</th>
<th data-quarto-table-cell-role="th">-14I</th>
<th data-quarto-table-cell-role="th">-14V</th>
<th data-quarto-table-cell-role="th">-13A</th>
<th data-quarto-table-cell-role="th">-12K</th>
<th data-quarto-table-cell-role="th">-12R</th>
<th data-quarto-table-cell-role="th">-11K</th>
<th data-quarto-table-cell-role="th">-11R</th>
</tr>
</thead>
<tbody>
<tr>
<td data-quarto-table-cell-role="th">0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">1</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">2</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">3</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">4</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>0.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>1.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
<td>0.0</td>
<td>1.0</td>
</tr>
</tbody>
</table>

</div>

``` python
# Fit KMeans to one-hot encoded features and return the assigned labels.
run_kmeans(onehot, n=2)
```

    array([0, 0, 0, 0, 1], dtype=int32)

``` python
# Filter one-hot columns to a position window around the center residue.
onehot_10 = filter_range_columns(onehot, low=-10, high=10)
onehot_10.head()
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&#10;    .dataframe tbody tr th {
        vertical-align: top;
    }
&#10;    .dataframe thead th {
        text-align: right;
    }
</style>

<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th"></th>
</tr>
</thead>
<tbody>
<tr>
<td data-quarto-table-cell-role="th">0</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">1</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">2</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">3</td>
</tr>
<tr>
<td data-quarto-table-cell-role="th">4</td>
</tr>
</tbody>
</table>

</div>

``` python
# Plot the elbow curve for a range of KMeans cluster counts.
get_clusters_elbow(onehot, max_cluster=5, interval=2)
```

![](index_files/figure-commonmark/cell-17-output-1.png)

### 03 embeddings

``` python
from kprot.embeddings import get_esm, get_t5, get_t5_bfd
```

``` python
import pandas as pd

# Set up the objects used by the examples below.
df = pd.DataFrame(
    {
        "sequence": [
            "MKWVTFISLLLLFSSAYSRGVFRRDAHKSEVAHRFKDLGE",
            "GSSHHHHHHSSGLVPRGSHMNNIRRVAILAALVAGQALA",
        ]
    }
)
df.shape

df.head()

run_model_examples = False
```

``` python
# Run the example.
df = pd.DataFrame(
    {
        "sequence": [
            "MKWVTFISLLLLFSSAYSRGVFRRDAHKSEVAHRFKDLGE",
            "GSSHHHHHHSSGLVPRGSHMNNIRRVAILAALVAGQALA",
        ]
    }
)
df.shape
```

    (2, 1)

``` python
# Extract ESM2 embeddings (mean pooled per sequence).
if run_model_examples:
    get_esm(df, "sequence").head()
else:
    print("Skipped get_esm example: set run_model_examples=True to allow model downloads.")
```

    Skipped get_esm example: set run_model_examples=True to allow model downloads.

``` python
# Extract ProtT5-XL-uniref50 embeddings from protein sequences in a dataframe.
if run_model_examples:
    get_t5(df, "sequence").head()
else:
    print("Skipped get_t5 example: set run_model_examples=True to allow model downloads.")
```

    Skipped get_t5 example: set run_model_examples=True to allow model downloads.

``` python
# Extract ProtT5-XL-BFD embeddings from protein sequences in a dataframe.
if run_model_examples:
    get_t5_bfd(df, "sequence").head()
else:
    print("Skipped get_t5_bfd example: set run_model_examples=True to allow model downloads.")
```

    Skipped get_t5_bfd example: set run_model_examples=True to allow model downloads.
